From b745ca4c7d23eeef875a11d8d7f2394fddfce89e Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Fri, 23 Mar 2012 17:08:53 +0400 Subject: [PATCH 01/58] Reverted change for Formatter exception fix (invalid characters in HTML), a deeper problem --- .../src/com/intellij/psi/formatter/FormatterUtil.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/formatter/FormatterUtil.java b/platform/lang-impl/src/com/intellij/psi/formatter/FormatterUtil.java index 6b321f41f16c..c40a94360506 100644 --- a/platform/lang-impl/src/com/intellij/psi/formatter/FormatterUtil.java +++ b/platform/lang-impl/src/com/intellij/psi/formatter/FormatterUtil.java @@ -203,11 +203,11 @@ public class FormatterUtil { if (isWhitespaceOrEmpty(node)) return true; for (WhiteSpaceFormattingStrategy strategy : WhiteSpaceFormattingStrategyFactory.getAllStrategies()) { - if (!strategy.containsWhitespacesOnly(node)) { - return false; + if (strategy.containsWhitespacesOnly(node)) { + return true; } } - return true; + return false; } public static void replaceWhiteSpace(final String whiteSpace, From 1aa8e5089dff22490aefe27ed38c3ca38123b74f Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Fri, 23 Mar 2012 17:16:58 +0400 Subject: [PATCH 02/58] bundle android-designer plugin to IDEA 12 --- build/scripts/layouts.gant | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index 734760c5262c..8eb8b0c745d7 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -392,6 +392,12 @@ public def layoutCommunityPlugins(String home) { jar("android-jps-plugin.jar") { module("android-jps-plugin") } } } + + layoutPlugin("android-designer") { + jar("android-designer.jar") { + module("android-designer") + } + } } } From 2660fd60ae9c6cacf6551ede020d81792ff54712 Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Fri, 23 Mar 2012 18:12:11 +0400 Subject: [PATCH 03/58] Get rid of faulty FormatterUtils.containsWhiteSpacesOnly() method for now (a better fix for EA-31140) --- .../intellij/psi/formatter/xml/AbstractXmlBlock.java | 12 ++++++++++-- .../src/com/intellij/psi/formatter/xml/XmlBlock.java | 4 ++-- .../com/intellij/psi/formatter/xml/XmlTagBlock.java | 6 ++---- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/xml/impl/src/com/intellij/psi/formatter/xml/AbstractXmlBlock.java b/xml/impl/src/com/intellij/psi/formatter/xml/AbstractXmlBlock.java index e5eeab72f3cf..c64b5e032af8 100644 --- a/xml/impl/src/com/intellij/psi/formatter/xml/AbstractXmlBlock.java +++ b/xml/impl/src/com/intellij/psi/formatter/xml/AbstractXmlBlock.java @@ -22,7 +22,8 @@ import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettings; -import com.intellij.psi.formatter.FormatterUtil; +import com.intellij.psi.formatter.WhiteSpaceFormattingStrategy; +import com.intellij.psi.formatter.WhiteSpaceFormattingStrategyFactory; import com.intellij.psi.formatter.common.AbstractBlock; import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.impl.source.tree.LeafElement; @@ -273,7 +274,7 @@ public abstract class AbstractXmlBlock extends AbstractBlock { ASTNode resultNode = child; ASTNode currentChild = child.getTreeNext(); while (currentChild != null && currentChild.getElementType() != XmlElementType.XML_END_TAG_START) { - if (!FormatterUtil.containsWhiteSpacesOnly(currentChild)) { + if (!containsWhiteSpacesOnly(currentChild)) { currentChild = processChild(result, currentChild, wrap, alignment, indent); resultNode = currentChild; } @@ -466,4 +467,11 @@ public abstract class AbstractXmlBlock extends AbstractBlock { return myNode.getElementType() == XmlElementType.XML_CDATA_END; } + public static boolean containsWhiteSpacesOnly(ASTNode node) { + WhiteSpaceFormattingStrategy strategy = WhiteSpaceFormattingStrategyFactory.getStrategy(node.getPsi().getLanguage()); + String nodeText = node.getText(); + int length = nodeText.length(); + return strategy.check(nodeText, 0, length) >= length; + } + } diff --git a/xml/impl/src/com/intellij/psi/formatter/xml/XmlBlock.java b/xml/impl/src/com/intellij/psi/formatter/xml/XmlBlock.java index 29068c340968..2886be8ed06e 100644 --- a/xml/impl/src/com/intellij/psi/formatter/xml/XmlBlock.java +++ b/xml/impl/src/com/intellij/psi/formatter/xml/XmlBlock.java @@ -23,7 +23,6 @@ import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.TokenType; -import com.intellij.psi.formatter.FormatterUtil; import com.intellij.psi.formatter.common.AbstractBlock; import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.templateLanguages.OuterLanguageElement; @@ -112,7 +111,7 @@ public class XmlBlock extends AbstractXmlBlock { final ArrayList result = new ArrayList(5); ASTNode child = myNode.getFirstChildNode(); while (child != null) { - if (!FormatterUtil.containsWhiteSpacesOnly(child) && child.getTextLength() > 0) { + if (!containsWhiteSpacesOnly(child) && child.getTextLength() > 0) { child = processChild(result, child, getDefaultWrap(child), null, getChildDefaultIndent()); } if (child != null) { @@ -127,6 +126,7 @@ public class XmlBlock extends AbstractXmlBlock { } } + private List splitAttribute(ASTNode node, XmlFormattingPolicy formattingPolicy) { final ArrayList result = new ArrayList(3); ASTNode child = node.getFirstChildNode(); diff --git a/xml/impl/src/com/intellij/psi/formatter/xml/XmlTagBlock.java b/xml/impl/src/com/intellij/psi/formatter/xml/XmlTagBlock.java index 3d0d78fa4601..2e2ead783bea 100644 --- a/xml/impl/src/com/intellij/psi/formatter/xml/XmlTagBlock.java +++ b/xml/impl/src/com/intellij/psi/formatter/xml/XmlTagBlock.java @@ -18,8 +18,6 @@ package com.intellij.psi.formatter.xml; import com.intellij.formatting.*; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; -import com.intellij.psi.codeStyle.CodeStyleSettings; -import com.intellij.psi.formatter.FormatterUtil; import com.intellij.psi.tree.IElementType; import com.intellij.psi.xml.XmlElementType; import com.intellij.psi.xml.XmlTag; @@ -64,7 +62,7 @@ public class XmlTagBlock extends AbstractXmlBlock{ boolean insideTag = true; while (child != null) { - if (!FormatterUtil.containsWhiteSpacesOnly(child) && child.getTextLength() > 0){ + if (!containsWhiteSpacesOnly(child) && child.getTextLength() > 0){ Wrap wrap = chooseWrap(child, tagBeginWrap, attrWrap, textWrap); Alignment alignment = chooseAlignment(child, attrAlignment, textAlignment); @@ -176,7 +174,7 @@ public class XmlTagBlock extends AbstractXmlBlock{ final Alignment alignment ) { while (child != null) { - if (!FormatterUtil.containsWhiteSpacesOnly(child) && child.getTextLength() > 0){ + if (!XmlBlock.containsWhiteSpacesOnly(child) && child.getTextLength() > 0){ final Indent indent = getChildrenIndent(); child = processChild(list,child, wrap, alignment, indent); if (child == null) return child; From 6a67561d30d4eee825241bf92e9313877e2ee99a Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 23 Mar 2012 15:52:22 +0100 Subject: [PATCH 04/58] reflection support (completion + refs) --- .../impl/JavaLangClassMemberReference.java | 150 ++++++++++++++++++ .../JavaReflectionCompletionConfidence.java | 47 ++++++ .../JavaReflectionReferenceContributor.java | 44 +++++ .../impl/JavaReflectionReferenceProvider.java | 50 ++++++ resources/src/META-INF/IdeaPlugin.xml | 3 + 5 files changed, 294 insertions(+) create mode 100644 java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaLangClassMemberReference.java create mode 100644 java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionCompletionConfidence.java create mode 100644 java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceContributor.java create mode 100644 java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceProvider.java diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaLangClassMemberReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaLangClassMemberReference.java new file mode 100644 index 000000000000..7190236fd735 --- /dev/null +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaLangClassMemberReference.java @@ -0,0 +1,150 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.impl.source.resolve.reference.impl; + +import com.intellij.codeInsight.completion.InsertHandler; +import com.intellij.codeInsight.completion.InsertionContext; +import com.intellij.codeInsight.completion.JavaLookupElementBuilder; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiTypesUtil; +import com.intellij.psi.util.PsiUtilCore; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Konstantin Bulenkov + */ +public class JavaLangClassMemberReference extends PsiReferenceBase implements InsertHandler { + private final PsiClassObjectAccessExpression myContext; + + public JavaLangClassMemberReference(PsiLiteralExpression literal, PsiClassObjectAccessExpression context) { + super(literal); + myContext = context; + } + + @Override + public PsiElement resolve() { + final String name = (String)getElement().getValue(); + final Type type = getType(); + + if (type != null) { + final PsiClass psiClass = getPsiClass(); + if (psiClass != null) { + PsiMember member; + if (type == Type.FIELD || type == Type.DECLARED_FIELD) { + member = psiClass.findFieldByName(name, false); + } else { + final PsiMethod[] methods = psiClass.findMethodsByName(name, false); + member = methods.length == 0 ? null : methods[0]; + } + + return member; + } + } + + return null; + } + + @Nullable + private PsiClass getPsiClass() { + return PsiTypesUtil.getPsiClass(myContext.getOperand().getType()); + } + + @Nullable + private Type getType() { + boolean selfFound = false; + for (PsiElement child : myContext.getParent().getChildren()) { + if (!selfFound) { + if (child == myContext) { + selfFound = true; + } + continue; + } + + if (child instanceof PsiIdentifier) { + return Type.fromString(child.getText()); + } + } + return null; + } + + @NotNull + @Override + public Object[] getVariants() { + final Type type = getType(); + final PsiClass psiClass = getPsiClass(); + if (psiClass != null && type != null) { + if (type == Type.DECLARED_FIELD) { + return psiClass.getFields(); + } else if (type == Type.DECLARED_METHOD) { + final List elements = new ArrayList(); + for (PsiMethod method : psiClass.getMethods()) { + elements.add(JavaLookupElementBuilder.forMethod(method, PsiSubstitutor.EMPTY).setInsertHandler(this)); + } + return elements.toArray(); + } + } + return EMPTY_ARRAY; + } + + @Override + public void handleInsert(InsertionContext context, LookupElement item) { + final Object object = item.getObject(); + if (object instanceof PsiMethod) { + final PsiElement newElement = PsiUtilCore.getElementAtOffset(context.getFile(), context.getStartOffset()); + final int start = newElement.getTextRange().getEndOffset(); + final PsiElement params = newElement.getParent().getParent(); + final int end = params.getTextRange().getEndOffset() - 1; + final String types = getMethodTypes((PsiMethod)object); + context.getDocument().replaceString(start, end, types); + context.commitDocument(); + final PsiElement firstParam = PsiUtilCore.getElementAtOffset(context.getFile(), context.getStartOffset()); + final PsiMethodCallExpression methodCall = PsiTreeUtil.getParentOfType(firstParam, PsiMethodCallExpression.class); + if (methodCall != null) { + JavaCodeStyleManager.getInstance(context.getProject()).shortenClassReferences(methodCall); + } + } + } + + private static String getMethodTypes(PsiMethod method) { + final StringBuilder buf = new StringBuilder(); + for (PsiParameter parameter : method.getParameterList().getParameters()) { + buf.append(", ").append(parameter.getType().getCanonicalText()).append(".class"); + } + return buf.toString(); + } + + + enum Type { + FIELD, DECLARED_FIELD, METHOD, DECLARED_METHOD; + + @Nullable + static Type fromString(String s) { + if ("getField".equals(s)) return FIELD; + if ("getDeclaredField".equals(s)) return DECLARED_FIELD; + if ("getMethod".equals(s)) return METHOD; + if ("getDeclaredMethod".equals(s)) return DECLARED_METHOD; + return null; + } + } +} diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionCompletionConfidence.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionCompletionConfidence.java new file mode 100644 index 000000000000..6b77a6dcb752 --- /dev/null +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionCompletionConfidence.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.impl.source.resolve.reference.impl; + +import com.intellij.codeInsight.completion.CompletionConfidence; +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.util.ThreeState; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Konstantin Bulenkov + */ +public class JavaReflectionCompletionConfidence extends CompletionConfidence { + @NotNull + @Override + public ThreeState shouldFocusLookup(@NotNull CompletionParameters parameters) { + return ThreeState.UNSURE; + } + + @NotNull + @Override + public ThreeState shouldSkipAutopopup(@Nullable PsiElement contextElement, @NotNull PsiFile psiFile, int offset) { + if (contextElement != null) { + final PsiElement literal = contextElement.getParent(); + if (literal != null && JavaReflectionReferenceContributor.PATTERN.accepts(literal)) { + return ThreeState.NO; + } + } + return super.shouldSkipAutopopup(contextElement, psiFile, offset); + } +} diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceContributor.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceContributor.java new file mode 100644 index 000000000000..06e5d4a672f4 --- /dev/null +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceContributor.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.impl.source.resolve.reference.impl; + +import com.intellij.patterns.PsiJavaElementPattern; +import com.intellij.psi.PsiLiteral; +import com.intellij.psi.PsiReferenceContributor; +import com.intellij.psi.PsiReferenceRegistrar; + +import static com.intellij.patterns.PsiJavaPatterns.psiExpression; +import static com.intellij.patterns.PsiJavaPatterns.psiLiteral; +import static com.intellij.patterns.PsiJavaPatterns.psiMethod; +import static com.intellij.patterns.StandardPatterns.string; +import static com.intellij.psi.CommonClassNames.JAVA_LANG_CLASS; + +/** + * @author Konstantin Bulenkov + */ +public class JavaReflectionReferenceContributor extends PsiReferenceContributor { + public static final PsiJavaElementPattern.Capture PATTERN = + psiLiteral().inside(psiExpression().methodCall(psiMethod().withName(string().oneOf("getDeclaredField", + "getField", + "getMethod", + "getDeclaredMethod")) + .definedInClass(JAVA_LANG_CLASS))); + + @Override + public void registerReferenceProviders(PsiReferenceRegistrar registrar) { + registrar.registerReferenceProvider(PATTERN, new JavaReflectionReferenceProvider()); + } +} diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceProvider.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceProvider.java new file mode 100644 index 000000000000..6a29dcb93197 --- /dev/null +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceProvider.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.impl.source.resolve.reference.impl; + +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Konstantin Bulenkov + */ +public class JavaReflectionReferenceProvider extends PsiReferenceProvider { + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + if (element instanceof PsiLiteralExpression) { + String value = getValue(((PsiLiteralExpression)element)); + final PsiElement expressionList; + if (value != null && (expressionList = element.getParent()) instanceof PsiExpressionList) { + final PsiElement methodCall = expressionList.getParent(); + final PsiClassObjectAccessExpression classAccess; + if (methodCall != null && (classAccess = PsiTreeUtil.findChildOfType(methodCall, PsiClassObjectAccessExpression.class)) != null) { + return new PsiReference[]{new JavaLangClassMemberReference((PsiLiteralExpression)element, classAccess)}; + } + } + } + return PsiReference.EMPTY_ARRAY; + } + + @Nullable + private static String getValue(PsiLiteralExpression element) { + final Object value = element.getValue(); + return value instanceof String ? (String)value : null; + } +} diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 11c8763e1679..e30a42bfee3b 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -211,6 +211,7 @@ + + + From e330b72433531296b33449a68842cde7935e95ec Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Fri, 23 Mar 2012 15:53:50 +0100 Subject: [PATCH 05/58] 32-bit tests on Mac --- build/scripts/tests.gant | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/build/scripts/tests.gant b/build/scripts/tests.gant index ab0bbdf38c05..35b0b19f6314 100644 --- a/build/scripts/tests.gant +++ b/build/scripts/tests.gant @@ -1,10 +1,14 @@ -import static org.jetbrains.jps.idea.IdeaProjectLoader.* +import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome includeTargets << new File("${guessHome(this)}/build/scripts/common_tests.gant") setProperty("testcases", ["com.intellij.AllTests"]) -setProperty("jvm_args", [ - "-Xmx350m", - "-XX:MaxPermSize=320m", - ]) +def isMac = System.getProperty("os.name").toLowerCase().startsWith("mac") +def args = [ + "-Xmx350m", + "-XX:MaxPermSize=320m", +] +if (isMac) args << "-d32"; + +setProperty("jvm_args", args) From ebcb33cd8c466a976d845bd84bffb20621f83b2b Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 23 Mar 2012 16:06:57 +0100 Subject: [PATCH 06/58] IDEA-67262 Sometimes after mouse selection changes view tree selection quickly returns where it was before --- .../src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java index 407129c27df1..6ae6c1041c14 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java @@ -131,7 +131,7 @@ public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEvent } int button1 = MouseEvent.BUTTON1_MASK | MouseEvent.BUTTON1_DOWN_MASK; final boolean pureMouse1Event = (me.getModifiersEx() | button1) == button1; - if (pureMouse1Event && me.getClickCount() == 1 && !me.isPopupTrigger()) { + if (pureMouse1Event && me.getClickCount() <= 1 && !me.isPopupTrigger()) { final Point point = SwingUtilities.convertPoint(meComponent, me.getPoint(), myRootPane.getContentPane()); if (myRootPane.getMenuBar() != null && myRootPane.getMenuBar().isVisible()) { From 947fdfdd49f701383a082c9eb43e97ba2a0958b7 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 23 Mar 2012 13:55:12 +0400 Subject: [PATCH 07/58] not null --- .../openapi/vfs/newvfs/NewVirtualFile.java | 17 +++++++++++++++-- .../vfs/newvfs/impl/VirtualFileImpl.java | 6 ++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/NewVirtualFile.java b/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/NewVirtualFile.java index da635f475b1a..8c1807ce7904 100644 --- a/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/NewVirtualFile.java +++ b/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/NewVirtualFile.java @@ -34,36 +34,43 @@ import java.util.Collection; public abstract class NewVirtualFile extends VirtualFile implements VirtualFileWithId { private volatile long myModificationStamp = LocalTimeCounter.currentTime(); + @Override public boolean isValid() { ApplicationManager.getApplication().assertReadAccessAllowed(); return exists(); } + @Override @NotNull public byte[] contentsToByteArray() throws IOException { throw new IOException("not applicable to the "+this); } + @Override @NotNull public abstract NewVirtualFileSystem getFileSystem(); + @Override public abstract NewVirtualFile getParent(); + @Override @Nullable public abstract NewVirtualFile getCanonicalFile(); + @Override @Nullable public abstract NewVirtualFile findChild(@NotNull @NonNls final String name); @Nullable - public abstract NewVirtualFile refreshAndFindChild(final String name); + public abstract NewVirtualFile refreshAndFindChild(@NotNull String name); @Nullable - public abstract NewVirtualFile findChildIfCached(final String name); + public abstract NewVirtualFile findChildIfCached(@NotNull String name); public abstract void setTimeStamp(final long time) throws IOException; + @Override public abstract int getId(); @Nullable @@ -72,10 +79,12 @@ public abstract class NewVirtualFile extends VirtualFile implements VirtualFileW @Nullable public abstract NewVirtualFile findChildByIdIfCached(int id); + @Override public void refresh(final boolean asynchronous, final boolean recursive, final Runnable postRunnable) { RefreshQueue.getInstance().refresh(asynchronous, recursive, postRunnable, this); } + @Override public long getModificationStamp() { return myModificationStamp; } @@ -94,6 +103,7 @@ public abstract class NewVirtualFile extends VirtualFile implements VirtualFileW public abstract void markClean(); + @Override public void move(final Object requestor, @NotNull final VirtualFile newParent) throws IOException { if (!exists()) { throw new IOException("File to move does not exist: " + getPath()); @@ -113,6 +123,7 @@ public abstract class NewVirtualFile extends VirtualFile implements VirtualFileW } EncodingRegistry.doActionAndRestoreEncoding(this, new ThrowableComputable() { + @Override public VirtualFile compute() throws IOException { getFileSystem().moveFile(requestor, NewVirtualFile.this, newParent); return NewVirtualFile.this; @@ -120,8 +131,10 @@ public abstract class NewVirtualFile extends VirtualFile implements VirtualFileW }); } + @NotNull public abstract Collection getCachedChildren(); + @NotNull /** iterated children will NOT contain NullVirtualFile.INSTANCE */ public abstract Iterable iterInDbChildren(); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileImpl.java index 326902eab68d..74ead49b63c6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileImpl.java @@ -45,11 +45,13 @@ public class VirtualFileImpl extends VirtualFileSystemEntry { return null; } + @NotNull @Override public Collection getCachedChildren() { return Collections.emptyList(); } + @NotNull @Override public Iterable iterInDbChildren() { return ContainerUtil.emptyIterable(); @@ -65,13 +67,13 @@ public class VirtualFileImpl extends VirtualFileSystemEntry { @Override @Nullable - public NewVirtualFile refreshAndFindChild(final String name) { + public NewVirtualFile refreshAndFindChild(@NotNull final String name) { return null; } @Override @Nullable - public NewVirtualFile findChildIfCached(final String name) { + public NewVirtualFile findChildIfCached(@NotNull final String name) { return null; } From 452077f7df8983c5ccf846ad2309d75e5c40c805 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 23 Mar 2012 13:56:23 +0400 Subject: [PATCH 08/58] optimisation: less calls to FileTypeManager.isIgnored --- .../history/integration/IdeaGateway.java | 71 ++++++++++--------- .../revertion/SelectionReverterTest.java | 3 +- .../ui/models/SelectionCalculatorTest.java | 3 +- 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java b/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java index 26c99517ea82..4b13d2a3929c 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java @@ -50,43 +50,44 @@ public class IdeaGateway { private static final Key SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY = Key.create("LocalHistory.SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY"); - public boolean isVersioned(VirtualFile f) { + public boolean isVersioned(@NotNull VirtualFile f) { if (!f.isInLocalFileSystem()) return false; String fileName = f.getName(); if (!f.isDirectory() && fileName.endsWith(".class")) return false; - for (Project each : ProjectManager.getInstance().getOpenProjects()) { + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); + for (Project each : openProjects) { if (each.isDefault()) continue; if (!each.isInitialized()) continue; if (each.getWorkspaceFile() == f) return false; if (ProjectRootManager.getInstance(each).getFileIndex().isIgnored(f)) return false; } - return !FileTypeManager.getInstance().isFileIgnored(f); + // optimisation: FileTypeManager.isFileIgnored(f) already checked inside ProjectFileIndex.isIgnored() + return openProjects.length != 0 || !FileTypeManager.getInstance().isFileIgnored(f); } - public boolean areContentChangesVersioned(VirtualFile f) { - if (!isVersioned(f) || f.isDirectory()) return false; - return areContentChangesVersioned(f.getName()); + public boolean areContentChangesVersioned(@NotNull VirtualFile f) { + return isVersioned(f) && !f.isDirectory() && areContentChangesVersioned(f.getName()); } - public boolean areContentChangesVersioned(String fileName) { + public boolean areContentChangesVersioned(@NotNull String fileName) { return !FileTypeManager.getInstance().getFileTypeByFileName(fileName).isBinary(); } - public boolean ensureFilesAreWritable(Project p, List ff) { + public boolean ensureFilesAreWritable(@NotNull Project p, @NotNull List ff) { ReadonlyStatusHandler h = ReadonlyStatusHandler.getInstance(p); return !h.ensureFilesWritable(VfsUtil.toVirtualFileArray(ff)).hasReadonlyFiles(); } @Nullable - public VirtualFile findVirtualFile(String path) { + public VirtualFile findVirtualFile(@NotNull String path) { return LocalFileSystem.getInstance().findFileByPath(path); } @NotNull - public VirtualFile findOrCreateFileSafely(VirtualFile parent, String name, boolean isDirectory) throws IOException { + public VirtualFile findOrCreateFileSafely(@NotNull VirtualFile parent, @NotNull String name, boolean isDirectory) throws IOException { VirtualFile f = parent.findChild(name); if (f != null && f.isDirectory() != isDirectory) { f.delete(this); @@ -101,7 +102,7 @@ public class IdeaGateway { } @NotNull - public VirtualFile findOrCreateFileSafely(String path, boolean isDirectory) throws IOException { + public VirtualFile findOrCreateFileSafely(@NotNull String path, boolean isDirectory) throws IOException { VirtualFile f = findVirtualFile(path); if (f != null && f.isDirectory() != isDirectory) { f.delete(this); @@ -117,13 +118,14 @@ public class IdeaGateway { return f; } - public List getAllFilesFrom(String path) { + public List getAllFilesFrom(@NotNull String path) { VirtualFile f = findVirtualFile(path); if (f == null) return Collections.emptyList(); return collectFiles(f, new ArrayList()); } - private List collectFiles(VirtualFile f, List result) { + @NotNull + private static List collectFiles(@NotNull VirtualFile f, @NotNull List result) { if (f.isDirectory()) { for (VirtualFile child : iterateDBChildren(f)) { collectFiles(child, result); @@ -135,12 +137,14 @@ public class IdeaGateway { return result; } + @NotNull public static Collection iterateDBChildren(VirtualFile f) { if (!(f instanceof NewVirtualFile)) return Collections.emptyList(); NewVirtualFile nf = (NewVirtualFile)f; return nf.getCachedChildren(); } + @NotNull public RootEntry createTransientRootEntry() { ApplicationManager.getApplication().assertReadAccessAllowed(); RootEntry root = new RootEntry(); @@ -149,19 +153,19 @@ public class IdeaGateway { } @Nullable - public Entry createTransientEntry(VirtualFile file) { + public Entry createTransientEntry(@NotNull VirtualFile file) { ApplicationManager.getApplication().assertReadAccessAllowed(); return doCreateEntry(file, false); } @Nullable - public Entry createEntryForDeletion(VirtualFile file) { + public Entry createEntryForDeletion(@NotNull VirtualFile file) { ApplicationManager.getApplication().assertReadAccessAllowed(); return doCreateEntry(file, true); } @Nullable - private Entry doCreateEntry(VirtualFile file, boolean forDeletion) { + private Entry doCreateEntry(@NotNull VirtualFile file, boolean forDeletion) { if (!file.isDirectory()) { if (!isVersioned(file)) return null; @@ -182,18 +186,19 @@ public class IdeaGateway { return newDir; } - private void doCreateChildren(DirectoryEntry parent, Collection children, final boolean forDeletion) { + private void doCreateChildren(@NotNull DirectoryEntry parent, Collection children, final boolean forDeletion) { List entries = ContainerUtil.mapNotNull(children, new NullableFunction() { @Override - public Entry fun(VirtualFile each) { + public Entry fun(@NotNull VirtualFile each) { return doCreateEntry(each, forDeletion); } }); parent.addChildren(entries); } - public void registerUnsavedDocuments(final LocalHistoryFacade vcs) { + public void registerUnsavedDocuments(@NotNull final LocalHistoryFacade vcs) { ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override public void run() { vcs.beginChangeSet(); for (Document d : FileDocumentManager.getInstance().getUnsavedDocuments()) { @@ -206,12 +211,11 @@ public class IdeaGateway { }); } - private boolean shouldRegisterDocument(VirtualFile f) { - if (f == null || !f.isValid()) return false; - return areContentChangesVersioned(f); + private boolean shouldRegisterDocument(@Nullable VirtualFile f) { + return f != null && f.isValid() && areContentChangesVersioned(f); } - private void registerDocumentContents(LocalHistoryFacade vcs, VirtualFile f, Document d) { + private void registerDocumentContents(@NotNull LocalHistoryFacade vcs, @NotNull VirtualFile f, Document d) { Pair contentAndStamp = acquireAndUpdateActualContent(f, d); if (contentAndStamp != null) { vcs.contentChanged(f.getPath(), contentAndStamp.first, contentAndStamp.second); @@ -220,7 +224,7 @@ public class IdeaGateway { // returns null is content has not been changes since last time @Nullable - public Pair acquireAndUpdateActualContent(VirtualFile f, @Nullable Document d) { + public Pair acquireAndUpdateActualContent(@NotNull VirtualFile f, @Nullable Document d) { ContentAndTimestamps contentAndStamp = f.getUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY); if (contentAndStamp == null) { if (d != null) saveDocumentContent(f, d); @@ -241,7 +245,7 @@ public class IdeaGateway { return Pair.create(contentAndStamp.content, contentAndStamp.registeredTimestamp); } - private void saveDocumentContent(VirtualFile f, Document d) { + private static void saveDocumentContent(@NotNull VirtualFile f, @NotNull Document d) { f.putUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY, new ContentAndTimestamps(Clock.getTime(), StoredContent.acquireContent(bytesFromDocument(d)), @@ -249,7 +253,7 @@ public class IdeaGateway { } @NotNull - public Pair acquireAndClearCurrentContent(VirtualFile f, @Nullable Document d) { + public Pair acquireAndClearCurrentContent(@NotNull VirtualFile f, @Nullable Document d) { ContentAndTimestamps contentAndStamp = f.getUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY); f.putUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY, null); @@ -274,7 +278,7 @@ public class IdeaGateway { } @NotNull - private Pair getActualContentNoAcquire(VirtualFile f) { + private static Pair getActualContentNoAcquire(@NotNull VirtualFile f) { ContentAndTimestamps result = f.getUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY); if (result == null) { return Pair.create(StoredContent.transientContent(f), f.getTimeStamp()); @@ -282,7 +286,7 @@ public class IdeaGateway { return Pair.create(result.content, result.registeredTimestamp); } - private byte[] bytesFromDocument(Document d) { + private static byte[] bytesFromDocument(@NotNull Document d) { try { return d.getText().getBytes(getFile(d).getCharset().name()); } @@ -291,7 +295,7 @@ public class IdeaGateway { } } - public String stringFromBytes(byte[] bytes, String path) { + public String stringFromBytes(@NotNull byte[] bytes, @NotNull String path) { try { VirtualFile file = findVirtualFile(path); if (file == null) { @@ -308,15 +312,18 @@ public class IdeaGateway { FileDocumentManager.getInstance().saveAllDocuments(); } - private VirtualFile getFile(Document d) { + @Nullable + private static VirtualFile getFile(@NotNull Document d) { return FileDocumentManager.getInstance().getFile(d); } - public Document getDocument(String path) { + @Nullable + public Document getDocument(@NotNull String path) { return FileDocumentManager.getInstance().getDocument(findVirtualFile(path)); } - public FileType getFileType(String fileName) { + @NotNull + public FileType getFileType(@NotNull String fileName) { return FileTypeManager.getInstance().getFileTypeByFileName(fileName); } diff --git a/platform/platform-tests/testSrc/com/intellij/history/integration/revertion/SelectionReverterTest.java b/platform/platform-tests/testSrc/com/intellij/history/integration/revertion/SelectionReverterTest.java index 3ed82848a13b..7cff8dfa5e49 100644 --- a/platform/platform-tests/testSrc/com/intellij/history/integration/revertion/SelectionReverterTest.java +++ b/platform/platform-tests/testSrc/com/intellij/history/integration/revertion/SelectionReverterTest.java @@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Clock; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.text.DateFormatUtil; +import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.util.ArrayList; @@ -91,7 +92,7 @@ public class SelectionReverterTest extends IntegrationTestCase { final List files = new ArrayList(); myGateway = new IdeaGateway() { @Override - public boolean ensureFilesAreWritable(Project p, List ff) { + public boolean ensureFilesAreWritable(@NotNull Project p, @NotNull List ff) { files.addAll(ff); return true; } diff --git a/platform/platform-tests/testSrc/com/intellij/history/integration/ui/models/SelectionCalculatorTest.java b/platform/platform-tests/testSrc/com/intellij/history/integration/ui/models/SelectionCalculatorTest.java index b87a187f54c4..c56c80608df2 100644 --- a/platform/platform-tests/testSrc/com/intellij/history/integration/ui/models/SelectionCalculatorTest.java +++ b/platform/platform-tests/testSrc/com/intellij/history/integration/ui/models/SelectionCalculatorTest.java @@ -24,6 +24,7 @@ import com.intellij.history.core.revisions.Revision; import com.intellij.history.core.tree.RootEntry; import com.intellij.history.integration.IdeaGateway; import com.intellij.util.diff.FilesTooBigForDiffException; +import org.jetbrains.annotations.NotNull; import org.junit.Test; import java.util.List; @@ -133,7 +134,7 @@ public class SelectionCalculatorTest extends LocalHistoryTestCase { private static class MyIdeaGateway extends IdeaGateway { @Override - public String stringFromBytes(byte[] bytes, String path) { + public String stringFromBytes(@NotNull byte[] bytes, @NotNull String path) { return new String(bytes); } } From 4f0973d47df6d382e8362b4ff2f5ffe079861bea Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 23 Mar 2012 16:47:21 +0400 Subject: [PATCH 09/58] cleanup --- .../openapi/vcs/ex/LineStatusTracker.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java index 7f45bdc8aa32..a9ef16c50e68 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java @@ -87,7 +87,9 @@ public class LineStatusTracker { myUpToDateDocument.putUserData(UndoConstants.DONT_RECORD_UNDO, Boolean.TRUE); myProject = project; myBaseLoaded = BaseLoadState.LOADING; - myRanges = new ArrayList(); + synchronized (myLock) { + myRanges = new ArrayList(); + } myAnathemaThrown = false; myFileEditorManager = FileEditorManager.getInstance(myProject); } @@ -205,7 +207,6 @@ public class LineStatusTracker { } removeAnathema(); removeHighlightersFromMarkupModel(); - myRanges.clear(); myReleased = true; } } @@ -238,7 +239,6 @@ public class LineStatusTracker { myBulkUpdate = true; removeAnathema(); removeHighlightersFromMarkupModel(); - myRanges.clear(); } } @@ -249,6 +249,7 @@ public class LineStatusTracker { range.getHighlighter().dispose(); } } + myRanges.clear(); } } @@ -279,9 +280,7 @@ public class LineStatusTracker { myUpToDateDocument.setReadOnly(true); removeAnathema(); removeHighlightersFromMarkupModel(); - myRanges.clear(); myBaseLoaded = BaseLoadState.LOADING; - return; } } @@ -299,7 +298,7 @@ public class LineStatusTracker { synchronized (myLock) { if (myReleased) return; - if (myBulkUpdate || myAnathemaThrown || (BaseLoadState.LOADED != myBaseLoaded)) return; + if (myBulkUpdate || myAnathemaThrown || BaseLoadState.LOADED != myBaseLoaded) return; try { myFirstChangedLine = myDocument.getLineNumber(e.getOffset()); myLastChangedLine = myDocument.getLineNumber(e.getOffset() + e.getOldLength()); @@ -317,7 +316,7 @@ public class LineStatusTracker { myUpToDateFirstLine = firstChangedRange.getUOffset1(); } else { - myUpToDateFirstLine = firstChangedRange.getUOffset2() + (myFirstChangedLine - firstChangedRange.getOffset2()); + myUpToDateFirstLine = firstChangedRange.getUOffset2() + myFirstChangedLine - firstChangedRange.getOffset2(); } Range myLastChangedRange = getLastRangeBeforeLine(myLastChangedLine); @@ -330,7 +329,7 @@ public class LineStatusTracker { myLastChangedLine = myLastChangedRange.getOffset2(); } else { - myUpToDateLastLine = myLastChangedRange.getUOffset2() + (myLastChangedLine - myLastChangedRange.getOffset2()); + myUpToDateLastLine = myLastChangedRange.getUOffset2() + myLastChangedLine - myLastChangedRange.getOffset2(); } } catch (ProcessCanceledException ignore) { } @@ -353,7 +352,7 @@ public class LineStatusTracker { synchronized (myLock) { if (myReleased) return; - if (myBulkUpdate || myAnathemaThrown || (BaseLoadState.LOADED != myBaseLoaded)) return; + if (myBulkUpdate || myAnathemaThrown || BaseLoadState.LOADED != myBaseLoaded) return; try { int line = myDocument.getLineNumber(e.getOffset() + e.getNewLength()); @@ -415,7 +414,6 @@ public class LineStatusTracker { } catch (FilesTooBigForDiffException e1) { installAnathema(); removeHighlightersFromMarkupModel(); - myRanges.clear(); } } } From c5eac23d3ca65b00371e5c66bd0a11abbcdca3f8 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 23 Mar 2012 17:05:12 +0400 Subject: [PATCH 10/58] hotspot --- .../intellij/compiler/make/Dependency.java | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/make/Dependency.java b/java/compiler/impl/src/com/intellij/compiler/make/Dependency.java index cf50003bc0e4..bd2c5cf9017c 100644 --- a/java/compiler/impl/src/com/intellij/compiler/make/Dependency.java +++ b/java/compiler/impl/src/com/intellij/compiler/make/Dependency.java @@ -138,7 +138,7 @@ public class Dependency { private static String[] parseParameterDescriptors(String signature) { ArrayList list = new ArrayList(); String paramSignature = parseFieldType(signature); - while (paramSignature != null && !"".equals(paramSignature)) { + while (paramSignature != null && !paramSignature.isEmpty()) { list.add(paramSignature); signature = signature.substring(paramSignature.length()); paramSignature = parseFieldType(signature); @@ -147,39 +147,40 @@ public class Dependency { } private static String parseFieldType(@NonNls String signature) { - if (signature.length() == 0) { + if (signature.isEmpty()) { return null; } - if (signature.charAt(0) == 'B') { - return "B"; - } - if (signature.charAt(0) == 'C') { - return "C"; - } - if (signature.charAt(0) == 'D') { - return "D"; - } - if (signature.charAt(0) == 'F') { - return "F"; - } - if (signature.charAt(0) == 'I') { + char first = signature.charAt(0); + if (first == 'I') { return "I"; } - if (signature.charAt(0) == 'J') { + if (first == 'L') { + return signature.substring(0, signature.indexOf(';') + 1); + } + if (first == 'B') { + return "B"; + } + if (first == 'C') { + return "C"; + } + if (first == 'D') { + return "D"; + } + if (first == 'F') { + return "F"; + } + if (first == 'J') { return "J"; } - if (signature.charAt(0) == 'S') { + if (first == 'S') { return "S"; } - if (signature.charAt(0) == 'Z') { + if (first == 'Z') { return "Z"; } - if (signature.charAt(0) == 'L') { - return signature.substring(0, signature.indexOf(";") + 1); - } - if (signature.charAt(0) == '[') { + if (first == '[') { String s = parseFieldType(signature.substring(1)); - return (s != null)? ("[" + s) : null; + return s == null ? null : "[" + s; } return null; } From 37123a8477cbc1e58c4e9879a357f245cba06a1d Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 23 Mar 2012 18:32:56 +0400 Subject: [PATCH 11/58] optimisation: cache virtual file - speeds up "show diff" action dramatically --- .../impl/stores/DefaultProjectStoreImpl.java | 29 +++++++++ .../impl/stores/FileBasedStorage.java | 62 +++++++++++++------ .../components/impl/stores/StorageUtil.java | 7 ++- .../impl/stores/XmlElementStorage.java | 18 ++++++ 4 files changed, 95 insertions(+), 21 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java index 7c807f5ffed9..587d9e5b8f89 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java @@ -71,15 +71,18 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl { final XmlElementStorage storage = new XmlElementStorage(pathMacroManager.createTrackingSubstitutor(), componentManager, ROOT_TAG_NAME, StreamProvider.DEFAULT, "", ComponentRoamingManager.getInstance(), ComponentVersionProvider.EMPTY) { + @Override @Nullable protected Document loadDocument() throws StateStorageException { return document; } + @Override protected MySaveSession createSaveSession(final MyExternalizationSession externalizationSession) { return new DefaultSaveSession(externalizationSession); } + @Override @NotNull protected StorageData createStorageData() { return new BaseStorageData(ROOT_TAG_NAME); @@ -90,14 +93,17 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl { super(externalizationSession); } + @Override protected void doSave() throws StateStorageException { myProjectManager.setDefaultProjectRootElement(getDocumentToSave().getRootElement()); } + @Override public Collection getStorageFilesToSave() throws StateStorageException { return Collections.emptyList(); } + @Override public List getAllStorageFiles() { return Collections.emptyList(); } @@ -105,75 +111,92 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl { }; return new StateStorageManager() { + @Override public void addMacro(String macro, String expansion) { throw new UnsupportedOperationException("Method addMacro not implemented in " + getClass()); } + @Override @Nullable public TrackingPathMacroSubstitutor getMacroSubstitutor() { return null; } + @Override @Nullable public StateStorage getStateStorage(@NotNull Storage storageSpec) throws StateStorageException { return storage; } + @Override @Nullable public StateStorage getFileStateStorage(String fileName) { return storage; } + @Override public void clearStateStorage(@NotNull String file) { } + @Override public ExternalizationSession startExternalization() { return new MyExternalizationSession(storage); } + @Override public SaveSession startSave(final ExternalizationSession externalizationSession) { return new MySaveSession(storage, externalizationSession); } + @Override public void finishSave(SaveSession saveSession) { storage.finishSave(((MySaveSession)saveSession).saveSession); } + @Override public String expandMacroses(final String file) { throw new UnsupportedOperationException("Method expandMacroses not implemented in " + getClass()); } + @Override @Nullable public StateStorage getOldStorage(Object component, final String componentName, final StateStorageOperation operation) throws StateStorageException { return storage; } + @Override public void registerStreamProvider(final StreamProvider streamProvider, final RoamingType type) { throw new UnsupportedOperationException("Method registerStreamProvider not implemented in " + getClass()); } + @Override public void unregisterStreamProvider(final StreamProvider streamProvider, final RoamingType roamingType) { throw new UnsupportedOperationException("Method unregisterStreamProvider not implemented in " + getClass()); } + @Override public StreamProvider[] getStreamProviders(final RoamingType roamingType) { throw new UnsupportedOperationException("Method getStreamProviders not implemented in " + getClass()); } + @Override public Collection getStorageFileNames() { throw new UnsupportedOperationException("Method getStorageFileNames not implemented in " + getClass()); } + @Override public void reset() { } }; } + @Override public String getLocation() { throw new UnsupportedOperationException("Method getLocation not implemented in " + getClass()); } + @Override public void load() throws IOException, StateStorageException { if (myElement == null) return; super.load(); @@ -186,11 +209,13 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl { externalizationSession = storage.startExternalization(); } + @Override public void setState(@NotNull final Storage[] storageSpecs, final Object component, final String componentName, final Object state) throws StateStorageException { externalizationSession.setState(component, componentName, state, null); } + @Override public void setStateInOldStorage(final Object component, final String componentName, final Object state) throws StateStorageException { externalizationSession.setState(component, componentName, state, null); } @@ -204,19 +229,23 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl { } //returns set of component which were changed, null if changes are much more than just component state. + @Override @Nullable public Set analyzeExternalChanges(Set> files) { throw new UnsupportedOperationException("Method analyzeExternalChanges not implemented in " + getClass()); } + @Override public List getAllStorageFilesToSave() throws StateStorageException { return Collections.emptyList(); } + @Override public List getAllStorageFiles() { return Collections.emptyList(); } + @Override public void save() throws StateStorageException { saveSession.save(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java index 356244d76a30..e0493ce493cc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java @@ -28,17 +28,16 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.options.StreamProvider; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileAdapter; -import com.intellij.openapi.vfs.VirtualFileEvent; +import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.tracker.VirtualFileTracker; +import com.intellij.util.io.fs.FileSystem; import com.intellij.util.io.fs.IFile; import com.intellij.util.messages.MessageBus; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.picocontainer.PicoContainer; @@ -50,8 +49,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import static com.intellij.util.io.fs.FileSystem.FILE_SYSTEM; - public class FileBasedStorage extends XmlElementStorage { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.FileBasedStorage"); @@ -60,6 +57,7 @@ public class FileBasedStorage extends XmlElementStorage { protected final String myRootElementName; private static boolean myConfigDirectoryRefreshed = false; + private volatile VirtualFile myCachedVirtualFile; public FileBasedStorage(@Nullable TrackingPathMacroSubstitutor pathMacroManager, StreamProvider streamProvider, @@ -84,7 +82,7 @@ public class FileBasedStorage extends XmlElementStorage { myRootElementName = rootElementName; myFilePath = filePath; - myFile = FILE_SYSTEM.createFile(myFilePath); + myFile = FileSystem.FILE_SYSTEM.createFile(myFilePath); VirtualFileTracker virtualFileTracker = (VirtualFileTracker)picoContainer.getComponentInstanceOfType(VirtualFileTracker.class); MessageBus messageBus = (MessageBus)picoContainer.getComponentInstanceOfType(MessageBus.class); @@ -96,8 +94,21 @@ public class FileBasedStorage extends XmlElementStorage { final Listener listener = messageBus.syncPublisher(STORAGE_TOPIC); virtualFileTracker.addTracker(fileUrl, new VirtualFileAdapter() { + @Override + public void fileMoved(VirtualFileMoveEvent event) { + myCachedVirtualFile = null; + } + + @Override + public void fileDeleted(VirtualFileEvent event) { + myCachedVirtualFile = null; + } + + @Override public void contentsChanged(final VirtualFileEvent event) { - if (!isDisposed()) listener.storageFileChanged(event, FileBasedStorage.this); + if (!isDisposed()) { + listener.storageFileChanged(event, FileBasedStorage.this); + } } }, false, this); } @@ -125,6 +136,7 @@ public class FileBasedStorage extends XmlElementStorage { } } + @Override protected MySaveSession createSaveSession(final MyExternalizationSession externalizationSession) { return new FileSaveSession(externalizationSession); } @@ -135,7 +147,7 @@ public class FileBasedStorage extends XmlElementStorage { } - protected class FileSaveSession extends MySaveSession { + private class FileSaveSession extends MySaveSession { protected FileSaveSession(MyExternalizationSession externalizationSession) { super(externalizationSession); } @@ -156,16 +168,19 @@ public class FileBasedStorage extends XmlElementStorage { return hash; } + @Override protected void doSave() throws StateStorageException { - if (!myBlockSavingTheContent) { - if (ApplicationManager.getApplication().isUnitTestMode() && myFile != null && StringUtil.startsWithChar(myFile.getPath(), '$')) { - throw new StateStorageException("It seems like some macros were not expanded for path: " + myFile.getPath()); - } - - StorageUtil.save(myFile, getDocumentToSave(), this); + if (myBlockSavingTheContent) { + return; } + if (ApplicationManager.getApplication().isUnitTestMode() && myFile != null && StringUtil.startsWithChar(myFile.getPath(), '$')) { + throw new StateStorageException("It seems like some macros were not expanded for path: " + myFile.getPath()); + } + + myCachedVirtualFile = StorageUtil.save(myFile, getDocumentToSave(), this); } + @Override public Collection getStorageFilesToSave() throws StateStorageException { boolean needsSave = needsSave(); if (needsSave) { @@ -179,18 +194,21 @@ public class FileBasedStorage extends XmlElementStorage { } } + @Override public List getAllStorageFiles() { return Collections.singletonList(myFile); } } + @Override protected void loadState(final StorageData result, final Element element) throws StateStorageException { ((FileStorageData)result).myFileName = myFile.getAbsolutePath(); ((FileStorageData)result).myFilePath = myFile.getAbsolutePath(); super.loadState(result, element); } + @Override @NotNull protected StorageData createStorageData() { return new FileStorageData(myRootElementName); @@ -210,10 +228,12 @@ public class FileBasedStorage extends XmlElementStorage { myFilePath = storageData.myFilePath; } + @Override public StorageData clone() { return new FileStorageData(this); } + @NonNls public String toString() { return "FileStorageData[" + myFileName + "]"; } @@ -221,13 +241,18 @@ public class FileBasedStorage extends XmlElementStorage { @Nullable public VirtualFile getVirtualFile() { - return StorageUtil.getVirtualFile(myFile); + VirtualFile virtualFile = myCachedVirtualFile; + if (virtualFile == null) { + myCachedVirtualFile = virtualFile = StorageUtil.getVirtualFile(myFile); + } + return virtualFile; } public File getFile() { return new File(myFile.getPath()); } + @Override @Nullable protected Document loadDocument() throws StateStorageException { myBlockSavingTheContent = false; @@ -289,14 +314,14 @@ public class FileBasedStorage extends XmlElementStorage { return myFilePath; } + @Override public void setDefaultState(final Element element) { element.setName(myRootElementName); super.setDefaultState(element); } protected boolean physicalContentNeedsSave(final Document doc) { - if (!myFile.exists()) return true; - return !StorageUtil.contentEquals(doc, myFile); + return !myFile.exists() || !StorageUtil.contentEquals(doc, myFile); } @Nullable @@ -307,7 +332,6 @@ public class FileBasedStorage extends XmlElementStorage { File file = new File(myFile.getAbsolutePath()); JDOMUtil.writeDocument(document, file, "\n"); return file; - } return null; diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java index b6624845f61f..6db45036ca44 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java @@ -90,7 +90,8 @@ public class StorageUtil { } } - static void save(final IFile file, final Parent element, final Object requestor) throws StateStorageException { + static VirtualFile save(final IFile file, final Parent element, final Object requestor) throws StateStorageException { + final VirtualFile[] result = new VirtualFile[1]; final String filePath = file.getCanonicalPath(); try { final Ref refIOException = Ref.create(null); @@ -98,7 +99,7 @@ public class StorageUtil { final Pair pair = loadFile(file); final byte[] text = JDOMUtil.writeParent(element, pair.second).getBytes(CharsetToolkit.UTF8); if (file.exists()) { - if (new String(text).equals(pair.first)) return; + if (new String(text).equals(pair.first)) return null; IFile backupFile = deleteBackup(filePath); file.renameTo(backupFile); } @@ -114,6 +115,7 @@ public class StorageUtil { final VirtualFile virtualFile = getOrCreateVirtualFile(requestor, file); virtualFile.setBinaryContent(text, -1, -1, requestor); + result[0] = virtualFile; } catch (IOException e) { refIOException.set(e); @@ -129,6 +131,7 @@ public class StorageUtil { catch (IOException e) { throw new StateStorageException(e); } + return result[0]; } static IFile deleteBackup(final String path) { diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java index b439c3e212dc..64d4a01d6682 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java @@ -72,6 +72,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { protected Map myProviderVersions = null; protected ComponentVersionListener myListener = new ComponentVersionListener(){ + @Override public void componentStateChanged(String componentName) { myLocalVersionProvider.changeVersion(componentName, System.currentTimeMillis()); } @@ -97,6 +98,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { myLocalVersionProvider = localComponentVersionsProvider; myRemoteVersionProvider = new ComponentVersionProvider(){ + @Override public long getVersion(String name) { if (myProviderVersions == null) { loadProviderVersions(); @@ -106,6 +108,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { } + @Override public void changeVersion(String name, long version) { if (myProviderVersions == null) { loadProviderVersions(); @@ -138,11 +141,13 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { return state; } + @Override public boolean hasState(final Object component, final String componentName, final Class aClass, final boolean reloadData) throws StateStorageException { final StorageData storageData = getStorageData(reloadData); return storageData.hasState(componentName); } + @Override @Nullable public T getState(final Object component, final String componentName, Class stateClass, @Nullable T mergeInto) throws StateStorageException { final Element element = getState(componentName); @@ -229,6 +234,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { } } + @Override @NotNull public ExternalizationSession startExternalization() { try { @@ -242,6 +248,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { } } + @Override @NotNull public SaveSession startSave(final ExternalizationSession externalizationSession) { assert mySession == externalizationSession; @@ -253,18 +260,22 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { private SaveSession createNullSession() { return new SaveSession(){ + @Override public void save() throws StateStorageException { } + @Override public Set analyzeExternalChanges(final Set> changedFiles) { return Collections.emptySet(); } + @Override public Collection getStorageFilesToSave() throws StateStorageException { return Collections.emptySet(); } + @Override public List getAllStorageFiles() { return Collections.emptyList(); } @@ -273,6 +284,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { protected abstract MySaveSession createSaveSession(final MyExternalizationSession externalizationSession); + @Override public void finishSave(final SaveSession saveSession) { try { LOG.assertTrue(mySession == saveSession, "mySession=" + mySession + " saveSession=" + saveSession); @@ -294,6 +306,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { myListener = listener; } + @Override public void setState(final Object component, final String componentName, final Object state, final Storage storageSpec) throws StateStorageException { assert mySession == this; @@ -401,6 +414,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { return null; } + @Override public final void save() throws StateStorageException { assert mySession == this; @@ -483,6 +497,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { return myStorageData; } + @Override @Nullable public Set analyzeExternalChanges(final Set> changedFiles) { try { @@ -532,6 +547,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { return result; } + @Override public void dispose() { myDisposed = true; } @@ -647,6 +663,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { clearHash(); } + @Override public StorageData clone() { return new StorageData(this); } @@ -724,6 +741,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable { myLoadedData = null; } + @Override public void reload(@NotNull final Set changedComponents) throws StateStorageException { final StorageData storageData = loadData(false, myListener); From 79bbc37f1674e00e835e54c3ea8271b9deb3939c Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 23 Mar 2012 18:35:36 +0400 Subject: [PATCH 12/58] severities compare optimisation: map instead of array --- .../daemon/impl/SeverityRegistrar.java | 129 ++++++++++++------ .../ex/SeverityEditorDialog.java | 16 ++- .../lang/annotation/HighlightSeverity.java | 7 +- .../util/JDOMExternalizableStringList.java | 13 ++ 4 files changed, 121 insertions(+), 44 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java index 85d351a90410..5126b9042f6c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java @@ -32,6 +32,8 @@ import com.intellij.profile.codeInspection.InspectionProfileManager; import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; +import gnu.trove.TObjectIntHashMap; +import gnu.trove.TObjectIntProcedure; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -52,7 +54,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator ourRendererColors = new THashMap(); @NonNls private static final String COLOR = "color"; - private final JDOMExternalizableStringList myOrder = new JDOMExternalizableStringList(); + private final TObjectIntHashMap myOrder = new TObjectIntHashMap(); private JDOMExternalizableStringList myReadOrder; private static final Map STANDARD_SEVERITIES = new THashMap(); @@ -161,38 +163,51 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator knownSeverities = getDefaultOrder(); - myOrder.retainAll(knownSeverities); + myReadOrder.readExternal(element); + for (int i = 0; i < myReadOrder.size(); i++) { + String name = myReadOrder.get(i); + HighlightSeverity severity = getSeverity(name); + if (severity == null) continue; + myOrder.put(severity, i); + } + final List knownSeverities = getDefaultOrder(); + myOrder.retainEntries(new TObjectIntProcedure() { + @Override + public boolean execute(HighlightSeverity severity, int order) { + return knownSeverities.contains(severity); + } + }); if (myOrder.isEmpty()) { - myOrder.addAll(knownSeverities); + setFromList(knownSeverities); } //enforce include all known + List list = getOrderAsList(); for (int i = 0; i < knownSeverities.size(); i++) { - String stdSeverity = knownSeverities.get(i); - if (!myOrder.contains(stdSeverity)) { - for (int oIdx = 0; oIdx < myOrder.size(); oIdx++) { - final String orderSeverity = myOrder.get(oIdx); - final HighlightInfoType type = STANDARD_SEVERITIES.get(orderSeverity); - if (type != null && knownSeverities.indexOf(type.getSeverity(null).toString()) > i) { - myOrder.add(oIdx, stdSeverity); + HighlightSeverity stdSeverity = knownSeverities.get(i); + if (!list.contains(stdSeverity)) { + for (int oIdx = 0; oIdx < list.size(); oIdx++) { + HighlightSeverity orderSeverity = list.get(oIdx); + HighlightInfoType type = STANDARD_SEVERITIES.get(orderSeverity.toString()); + if (type != null && knownSeverities.indexOf(type.getSeverity(null)) > i) { + list.add(oIdx, stdSeverity); myReadOrder = null; break; } } } } + setFromList(list); } @Override public void writeExternal(Element element) throws WriteExternalException { - for (String severity : getOrder()) { + List list = getOrderAsList(); + for (HighlightSeverity s : list) { Element info = new Element(INFO); + String severity = s.toString(); final SeverityBasedTextAttributes infoType = ourMap.get(severity); if (infoType != null) { infoType.writeExternal(info); @@ -203,29 +218,57 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator() { + @Override + public boolean execute(HighlightSeverity orderSeverity, int oIdx) { + ext.set(oIdx, orderSeverity.toString()); + return true; + } + }); + ext.writeExternal(element); } } + @NotNull + private List getOrderAsList() { + List list = new ArrayList(); + for (Object o : getOrder().keys()) { + list.add((HighlightSeverity)o); + } + Collections.sort(list, this); + return list; + } + public int getSeveritiesCount() { return createCurrentSeverities().size(); } public HighlightSeverity getSeverityByIndex(final int i) { - return getSeverity(getOrder().get(i)); + final HighlightSeverity[] found = new HighlightSeverity[1]; + getOrder().forEachEntry(new TObjectIntProcedure() { + @Override + public boolean execute(HighlightSeverity severity, int order) { + if (order == i) { + found[0] = severity; + return false; + } + return true; + } + }); + return found[0]; } public int getSeverityMaxIndex() { return getOrder().size(); } - public HighlightSeverity getSeverity(final String name) { + public HighlightSeverity getSeverity(@NotNull String name) { final HighlightInfoType type = STANDARD_SEVERITIES.get(name); if (type != null) return type.getSeverity(null); final SeverityBasedTextAttributes attributes = ourMap.get(name); @@ -233,6 +276,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator createCurrentSeverities() { List list = new ArrayList(); list.addAll(STANDARD_SEVERITIES.keySet()); @@ -241,7 +285,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator order = getOrder(); + return order.get(s1) - order.get(s2); } - private JDOMExternalizableStringList getOrder() { + + @NotNull + private TObjectIntHashMap getOrder() { if (myOrder.isEmpty()) { - myOrder.addAll(getDefaultOrder()); + List order = getDefaultOrder(); + setFromList(order); } return myOrder; } - private List getDefaultOrder() { + private void setFromList(@NotNull List order) { + myOrder.clear(); + for (int i = 0; i < order.size(); i++) { + HighlightSeverity severity = order.get(i); + myOrder.put(severity, i); + } + } + + @NotNull + private List getDefaultOrder() { Collection values = ourMap.values(); List order = new ArrayList(STANDARD_SEVERITIES.size() + values.size()); for (HighlightInfoType type : STANDARD_SEVERITIES.values()) { @@ -277,29 +334,23 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator result = new ArrayList(order.size()); - for (HighlightSeverity severity : order) { - result.add(severity.toString()); - } - return result; + return order; } - public void setOrder(List order) { - myOrder.clear(); - myOrder.addAll(order); - + public void setOrder(@NotNull List order) { + setFromList(order); myReadOrder = null; } public int getSeverityIdx(@NotNull HighlightSeverity severity) { - return getOrder().indexOf(severity.toString()); + return getOrder().get(severity); } - public boolean isDefaultSeverity(HighlightSeverity severity) { + public boolean isDefaultSeverity(@NotNull HighlightSeverity severity) { return STANDARD_SEVERITIES.containsKey(severity.myName); } - public static boolean isGotoBySeverityEnabled(HighlightSeverity minSeverity) { + public static boolean isGotoBySeverityEnabled(@NotNull HighlightSeverity minSeverity) { for (SeveritiesProvider provider : Extensions.getExtensions(SeveritiesProvider.EP_NAME)) { if (provider.isGotoBySeverityEnabled(minSeverity)) return true; } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java index d2542b5a7def..97e0745594d3 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java @@ -80,6 +80,7 @@ public class SeverityEditorDialog extends DialogWrapper { super(parent, true); mySeverityRegistrar = severityRegistrar; myOptionsList.setCellRenderer(new DefaultListCellRenderer() { + @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { final Component rendererComponent = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value instanceof SeverityBasedTextAttributes) { @@ -89,6 +90,7 @@ public class SeverityEditorDialog extends DialogWrapper { } }); myOptionsList.addListSelectionListener(new ListSelectionListener() { + @Override public void valueChanged(ListSelectionEvent e) { if (myCurrentSelection != null) { apply(myCurrentSelection); @@ -110,6 +112,7 @@ public class SeverityEditorDialog extends DialogWrapper { InspectionsBundle.message("highlight.severity.create.dialog.title"), Messages.getQuestionIcon(), "", new InputValidator() { + @Override public boolean checkInput(final String inputString) { final ListModel listModel = myOptionsList.getModel(); for (int i = 0; i < listModel.getSize(); i++) { @@ -119,6 +122,7 @@ public class SeverityEditorDialog extends DialogWrapper { return true; } + @Override public boolean canClose(final String inputString) { return checkInput(inputString); } @@ -201,6 +205,7 @@ public class SeverityEditorDialog extends DialogWrapper { final JPanel disabled = new JPanel(new GridBagLayout()); final JButton button = new JButton(InspectionsBundle.message("severities.default.settings.message")); button.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent e) { editColorsAndFonts(); } @@ -230,6 +235,7 @@ public class SeverityEditorDialog extends DialogWrapper { final SearchableConfigurable javaPage = colorAndFontOptions.findSubConfigurable(InspectionColorSettingsPage.class); LOG.assertTrue(javaPage != null); optionsEditor.select(javaPage).doWhenDone(new Runnable() { + @Override public void run() { final Runnable runnable = javaPage.enableSearch(toConfigure); if (runnable != null) { @@ -261,6 +267,7 @@ public class SeverityEditorDialog extends DialogWrapper { final List infoTypes = new ArrayList(); infoTypes.addAll(mySeverityRegistrar.getRegisteredHighlightingInfoTypes()); Collections.sort(infoTypes, new Comparator() { + @Override public int compare(SeverityBasedTextAttributes attributes1, SeverityBasedTextAttributes attributes2) { return -mySeverityRegistrar.compare(attributes1.getSeverity(), attributes2.getSeverity()); @@ -306,16 +313,17 @@ public class SeverityEditorDialog extends DialogWrapper { myOptionsPanel.reset(description); } + @Override protected void doOKAction() { apply((SeverityBasedTextAttributes)myOptionsList.getSelectedValue()); final Collection infoTypes = new HashSet(mySeverityRegistrar.getRegisteredHighlightingInfoTypes()); final ListModel listModel = myOptionsList.getModel(); - final List order = new ArrayList(); + final List order = new ArrayList(); for (int i = listModel.getSize() - 1; i >= 0; i--) { final SeverityBasedTextAttributes info = (SeverityBasedTextAttributes)listModel.getElementAt(i); - order.add(info.getSeverity().myName); + order.add(info.getSeverity()); if (!mySeverityRegistrar.isDefaultSeverity(info.getSeverity())) { infoTypes.remove(info); final Color stripeColor = info.getAttributes().getErrorStripeColor(); @@ -329,6 +337,7 @@ public class SeverityEditorDialog extends DialogWrapper { super.doOKAction(); } + @Override @Nullable protected JComponent createCenterPanel() { return myPanel; @@ -349,15 +358,18 @@ public class SeverityEditorDialog extends DialogWrapper { super(name, group, attributes, type, null, null, null); } + @Override public void apply(EditorColorsScheme scheme) { } + @Override public boolean isErrorStripeEnabled() { return true; } + @Override public TextAttributes getTextAttributes() { return super.getTextAttributes(); } diff --git a/platform/platform-api/src/com/intellij/lang/annotation/HighlightSeverity.java b/platform/platform-api/src/com/intellij/lang/annotation/HighlightSeverity.java index e3c3026e9e8a..3553925ff9a3 100644 --- a/platform/platform-api/src/com/intellij/lang/annotation/HighlightSeverity.java +++ b/platform/platform-api/src/com/intellij/lang/annotation/HighlightSeverity.java @@ -92,14 +92,17 @@ public class HighlightSeverity implements Comparable, JDOMExt return myName; } + @Override public int compareTo(final HighlightSeverity highlightSeverity) { return myVal - highlightSeverity.myVal; } + @Override public void readExternal(Element element) throws InvalidDataException { DefaultJDOMExternalizer.readExternal(this, element); } + @Override public void writeExternal(final Element element) throws WriteExternalException { DefaultJDOMExternalizer.writeExternal(this, element); } @@ -111,9 +114,7 @@ public class HighlightSeverity implements Comparable, JDOMExt final HighlightSeverity that = (HighlightSeverity)o; - if (!myName.equals(that.myName)) return false; - - return true; + return myName.equals(that.myName); } public int hashCode() { diff --git a/platform/util/src/com/intellij/openapi/util/JDOMExternalizableStringList.java b/platform/util/src/com/intellij/openapi/util/JDOMExternalizableStringList.java index b98c0a1dd0a1..9f754b895819 100644 --- a/platform/util/src/com/intellij/openapi/util/JDOMExternalizableStringList.java +++ b/platform/util/src/com/intellij/openapi/util/JDOMExternalizableStringList.java @@ -17,9 +17,11 @@ package com.intellij.openapi.util; import com.intellij.openapi.diagnostic.Logger; import org.jdom.Element; +import org.jetbrains.annotations.NotNull; import sun.reflect.Reflection; import java.util.ArrayList; +import java.util.Collection; @SuppressWarnings({"HardCodedStringLiteral"}) public class JDOMExternalizableStringList extends ArrayList implements JDOMExternalizable { @@ -32,6 +34,17 @@ public class JDOMExternalizableStringList extends ArrayList implements J private static final String ATTR_CLASS = "class"; private static final String ATTR_VALUE = "itemvalue"; + public JDOMExternalizableStringList(int initialCapacity) { + super(initialCapacity); + } + + public JDOMExternalizableStringList() { + } + + public JDOMExternalizableStringList(@NotNull Collection c) { + super(c); + } + public void readExternal(Element element) throws InvalidDataException { clear(); From b0abdbd77ed1654153fe01c05c545f9b84d1589b Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 23 Mar 2012 18:38:11 +0400 Subject: [PATCH 13/58] more checks --- .../src/com/intellij/openapi/editor/impl/CharArray.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java index 437c4edac2a9..625acc8a0a93 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java @@ -180,8 +180,6 @@ abstract class CharArray implements CharSequenceBackedByArray { } private void assertConsistency() { - if (!myDebug) return; - if (isDeferredChangeMode()) { assert myOriginalSequence == null; } @@ -194,6 +192,8 @@ abstract class CharArray implements CharSequenceBackedByArray { int count = myCount + myDeferredShift; assert count == origLen || origLen==-1; assert count == stringLen || stringLen==-1; + + if (!myDebug) return; final String stringFromCharArray; if (myArray != null) { From 522dce86894b2dc0cdf62cec87348dd0282160c0 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Sat, 17 Mar 2012 11:25:03 +0400 Subject: [PATCH 14/58] Optimization: avoid calling 'path.toLowerCase()' when SystemInfo.isFileSystemCaseSensitive == false --- .../openapi/vfs/impl/jar/JarFileSystemImpl.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java index c7b85297e3f1..3ee71c67efc1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java @@ -29,6 +29,7 @@ import com.intellij.openapi.vfs.newvfs.*; import com.intellij.openapi.vfs.newvfs.events.VFileEvent; import com.intellij.util.containers.ConcurrentHashSet; import com.intellij.util.messages.MessageBus; +import com.intellij.util.text.CaseInsensitiveStringHashingStrategy; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,7 +42,10 @@ import java.util.*; import java.util.zip.ZipFile; public class JarFileSystemImpl extends JarFileSystem implements ApplicationComponent { - private final Set myNoCopyJarPaths = new ConcurrentHashSet(); + private final Set myNoCopyJarPaths = SystemInfo.isFileSystemCaseSensitive ? + new ConcurrentHashSet() : + new ConcurrentHashSet(CaseInsensitiveStringHashingStrategy.INSTANCE); + @NonNls private static final String IDEA_JARS_NOCOPY = "idea.jars.nocopy"; private File myNoCopyJarDir; @@ -149,9 +153,6 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo if (index < 0) return; String path = pathInJar.substring(0, index); path = path.replace('/', File.separatorChar); - if (!SystemInfo.isFileSystemCaseSensitive) { - path = path.toLowerCase(); - } myNoCopyJarPaths.add(path); } @@ -268,12 +269,7 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo String property = System.getProperty(IDEA_JARS_NOCOPY); if (Boolean.TRUE.toString().equalsIgnoreCase(property)) return false; - String path = originalJar.getPath(); - if (!SystemInfo.isFileSystemCaseSensitive) { - path = path.toLowerCase(); - } - - if (myNoCopyJarPaths.contains(path)) return false; + if (myNoCopyJarPaths.contains(originalJar.getPath())) return false; if (myNoCopyJarDir!=null && FileUtil.isAncestor(myNoCopyJarDir, originalJar, false)) return false; return true; From 8ff93e2250d8f466623b0e1fdf56a1c1e863707f Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Fri, 23 Mar 2012 19:40:54 +0400 Subject: [PATCH 15/58] IDEA-76393 (IntelliJ does not resolve maven project properties inside dependency element) --- .../idea/maven/dom/MavenPropertyResolver.java | 22 ------------------- .../maven/project/MavenProjectReader.java | 13 +++++++++-- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java index e42b84800af2..8fd863215ef6 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java @@ -243,28 +243,6 @@ public class MavenPropertyResolver { result = mavenProject.getProperties().getProperty(propName); if (result != null) return result; - if (unprefixed.equals("groupId")) { - return selectedProject.getMavenId().getGroupId(); - } - if (unprefixed.equals("artifactId")) { - return selectedProject.getMavenId().getArtifactId(); - } - if (unprefixed.equals("version")) { - return selectedProject.getMavenId().getVersion(); - } - if (unprefixed.equals("buildDirectory")) { - return selectedProject.getBuildDirectory(); - } - if (unprefixed.equals("finalName")) { - return selectedProject.getFinalName(); - } - if (unprefixed.equals("outputDirectory")) { - return selectedProject.getOutputDirectory(); - } - if (unprefixed.equals("testOutputDirectory")) { - return selectedProject.getTestOutputDirectory(); - } - return null; } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectReader.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectReader.java index 5612282b46b0..cc9fdd942cb0 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectReader.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectReader.java @@ -56,8 +56,17 @@ public class MavenProjectReader { File basedir = getBaseDir(file); MavenModel model = MavenServerManager.getInstance().interpolateAndAlignModel(readResult.first.model, basedir); + Map modelMap = new HashMap(); + modelMap.put("groupId", model.getMavenId().getGroupId()); + modelMap.put("artifactId", model.getMavenId().getArtifactId()); + modelMap.put("version", model.getMavenId().getVersion()); + modelMap.put("build.outputDirectory", model.getBuild().getOutputDirectory()); + modelMap.put("build.testOutputDirectory", model.getBuild().getTestOutputDirectory()); + modelMap.put("build.finalName", model.getBuild().getFinalName()); + modelMap.put("build.directory", model.getBuild().getDirectory()); + return new MavenProjectReaderResult(model, - Collections.emptyMap(), + modelMap, readResult.second, null, readResult.first.problems, @@ -162,7 +171,7 @@ public class MavenProjectReader { } } - private List collectResources(List xmlResources) { + private static List collectResources(List xmlResources) { List result = new ArrayList(); for (Element each : xmlResources) { result.add(new MavenResource(MavenJDOMUtil.findChildValueByPath(each, "directory"), From 17e79da2ab53db2b171056777276bf1f177d3e3d Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Fri, 23 Mar 2012 19:41:56 +0400 Subject: [PATCH 16/58] IDEA-77267 com.intellij.tasks.Task.getCustomIcon()Ljava/lang/String;: com.intellij.tasks.Task.getCustomIcon()Ljava/lang/String; api restored --- .../src/main/java/com/intellij/tasks/jira/JiraTask.java | 5 ----- plugins/tasks/tasks-api/src/com/intellij/tasks/Task.java | 4 +++- .../src/com/intellij/tasks/github/GitHubRepository.java | 5 ----- .../com/intellij/tasks/lighthouse/LighthouseRepository.java | 5 ----- .../src/com/intellij/tasks/redmine/RedmineRepository.java | 5 ----- .../tasks-tests/test/com/intellij/tasks/TaskVcsTest.java | 5 ----- 6 files changed, 3 insertions(+), 26 deletions(-) diff --git a/plugins/tasks/jira-connector/src/main/java/com/intellij/tasks/jira/JiraTask.java b/plugins/tasks/jira-connector/src/main/java/com/intellij/tasks/jira/JiraTask.java index c7df1e689fd2..b9ef96425f32 100644 --- a/plugins/tasks/jira-connector/src/main/java/com/intellij/tasks/jira/JiraTask.java +++ b/plugins/tasks/jira-connector/src/main/java/com/intellij/tasks/jira/JiraTask.java @@ -144,9 +144,4 @@ class JiraTask extends Task { public String getIssueUrl() { return myJiraIssue.getIssueUrl(); } - - @Override - public String getCustomIcon() { - return null; - } } diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/Task.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/Task.java index 3cec728645c5..e946785b0ebd 100644 --- a/plugins/tasks/tasks-api/src/com/intellij/tasks/Task.java +++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/Task.java @@ -64,7 +64,9 @@ public abstract class Task { public abstract boolean isClosed(); @Nullable - public abstract String getCustomIcon(); + public String getCustomIcon() { + return null; + } /** * @return true if bugtracking issue is associated diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/github/GitHubRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/github/GitHubRepository.java index 2e2050ba5129..f09fa7dd790a 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/github/GitHubRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/github/GitHubRepository.java @@ -224,11 +224,6 @@ public class GitHubRepository extends BaseRepositoryImpl { public String getPresentableName() { return getId() + ": " + getSummary(); } - - @Override - public String getCustomIcon() { - return null; - } }; } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/lighthouse/LighthouseRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/lighthouse/LighthouseRepository.java index c0b09fc4720d..c8492cb88007 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/lighthouse/LighthouseRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/lighthouse/LighthouseRepository.java @@ -198,11 +198,6 @@ public class LighthouseRepository extends BaseRepositoryImpl { public String getPresentableName() { return getId() + ": " + getSummary(); } - - @Override - public String getCustomIcon() { - return null; - } }; } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java index 934bba605fa1..646265f8991c 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java @@ -165,11 +165,6 @@ public class RedmineRepository extends BaseRepositoryImpl { public String getPresentableName() { return getId() + ": " + getSummary(); } - - @Override - public String getCustomIcon() { - return null; - } }; } diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskVcsTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskVcsTest.java index 67415fd57c86..52d955f914c9 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskVcsTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskVcsTest.java @@ -144,11 +144,6 @@ public class TaskVcsTest extends TaskManagerTestCase { return false; } - @Override - public String getCustomIcon() { - return null; - } - @Override public boolean isIssue() { return false; From 7776bd832d702afbef7f66da2713bc6d9fe53e21 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 23 Mar 2012 16:25:17 +0100 Subject: [PATCH 17/58] IDEA-83399 Event Log: link from a balloon is not shown --- plugins/git4idea/src/git4idea/push/GitPushResult.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/git4idea/src/git4idea/push/GitPushResult.java b/plugins/git4idea/src/git4idea/push/GitPushResult.java index 4a0226c846c4..e8ac07d4f6e1 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushResult.java +++ b/plugins/git4idea/src/git4idea/push/GitPushResult.java @@ -277,7 +277,7 @@ class GitPushResult { sb.append(successReport); if (!updatedFiles.isEmpty()) { - sb.append("View files updated during the push"); + sb.append("View files updated during the push"); } NotificationListener viewUpdateFilesListener = new ViewUpdatedFilesNotificationListener(updatedFiles); From 346fac04258a1b50d486a91a6c22b5c7be5c1938 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 23 Mar 2012 16:43:54 +0100 Subject: [PATCH 18/58] don't assert read access in Document which is for non-AWT use --- .../openapi/editor/impl/DocumentImpl.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java index efbace051a9c..437d7233a42c 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java @@ -72,7 +72,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { private int myCheckGuardedBlocks = 0; private boolean myGuardsSuppressed = false; private boolean myEventsHandling = false; - private final boolean myAssertWriteAccess; + private final boolean myAssertThreading; private volatile boolean myDoingBulkUpdate = false; private volatile boolean myAcceptSlashR = false; private boolean myChangeInProgress; @@ -90,7 +90,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { myLineSet.documentCreated(this); setCyclicBufferSize(0); setModificationStamp(LocalTimeCounter.currentTime()); - myAssertWriteAccess = !forUseInNonAWTThread; + myAssertThreading = !forUseInNonAWTThread; } public boolean setAcceptSlashR(boolean accept) { @@ -424,7 +424,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { } private void assertWriteAccess() { - if (myAssertWriteAccess) { + if (myAssertThreading) { final Application application = ApplicationManager.getApplication(); if (application != null) { application.assertWriteAccessAllowed(); @@ -826,14 +826,12 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { @Override protected void assertReadAccess() { - DocumentImpl.assertReadAccess(); - } - } - - private static void assertReadAccess() { - final Application application = ApplicationManager.getApplication(); - if (application != null) { - application.assertReadAccessAllowed(); + if (myAssertThreading) { + final Application application = ApplicationManager.getApplication(); + if (application != null) { + application.assertReadAccessAllowed(); + } + } } } } From 3f8e4814ae3ec7f8d0f6a467a2e4c07db4554e7c Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 23 Mar 2012 16:47:05 +0100 Subject: [PATCH 19/58] testing delayed notifications --- .../impl/actions/NotificationTestAction.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/notification/impl/actions/NotificationTestAction.java b/platform/platform-impl/src/com/intellij/notification/impl/actions/NotificationTestAction.java index a1e9e584c843..a8a6054a8898 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/actions/NotificationTestAction.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/actions/NotificationTestAction.java @@ -64,6 +64,13 @@ public class NotificationTestAction extends AnAction implements DumbAware { "You can
close this very

very very very long notification by clicking this link. Long long long long. It should be long. Very long. Too long. And even longer.", type, listener); - messageBus.syncPublisher(Notifications.TOPIC).notify(notification); + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + //DebugUtil.sleep(1000); + messageBus.syncPublisher(Notifications.TOPIC).notify(notification); + } + }); + } } From ab3a58a66497d027857423ddcbbbf509f22681d6 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 23 Mar 2012 18:04:43 +0100 Subject: [PATCH 20/58] reflection fix + tests --- .../impl/JavaLangClassMemberReference.java | 18 +++++- .../completion/reflection/DeclaredField.java | 26 ++++++++ .../reflection/DeclaredField_after.java | 26 ++++++++ .../completion/reflection/DeclaredMethod.java | 30 +++++++++ .../reflection/DeclaredMethod2.java | 30 +++++++++ .../reflection/DeclaredMethod2_after.java | 30 +++++++++ .../reflection/DeclaredMethod_after.java | 30 +++++++++ .../completion/reflection/Field.java | 26 ++++++++ .../completion/reflection/Field_after.java | 26 ++++++++ .../completion/reflection/Method.java | 30 +++++++++ .../completion/reflection/Method_after.java | 30 +++++++++ .../JavaReflectionCompletionTest.java | 62 +++++++++++++++++++ 12 files changed, 362 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/reflection/DeclaredField.java create mode 100644 java/java-tests/testData/codeInsight/completion/reflection/DeclaredField_after.java create mode 100644 java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod.java create mode 100644 java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod2.java create mode 100644 java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod2_after.java create mode 100644 java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod_after.java create mode 100644 java/java-tests/testData/codeInsight/completion/reflection/Field.java create mode 100644 java/java-tests/testData/codeInsight/completion/reflection/Field_after.java create mode 100644 java/java-tests/testData/codeInsight/completion/reflection/Method.java create mode 100644 java/java-tests/testData/codeInsight/completion/reflection/Method_after.java create mode 100644 java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaReflectionCompletionTest.java diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaLangClassMemberReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaLangClassMemberReference.java index 7190236fd735..8b93c386d07c 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaLangClassMemberReference.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaLangClassMemberReference.java @@ -96,10 +96,20 @@ public class JavaLangClassMemberReference extends PsiReferenceBase fields = new ArrayList(); + for (PsiField field : psiClass.getFields()) { + if (isPublic(field)) { + fields.add(field); + } + } + return fields.toArray(); + } else if (type == Type.DECLARED_METHOD || type == Type.METHOD) { final List elements = new ArrayList(); for (PsiMethod method : psiClass.getMethods()) { - elements.add(JavaLookupElementBuilder.forMethod(method, PsiSubstitutor.EMPTY).setInsertHandler(this)); + if (type == Type.DECLARED_METHOD || isPublic(method)) { + elements.add(JavaLookupElementBuilder.forMethod(method, PsiSubstitutor.EMPTY).setInsertHandler(this)); + } } return elements.toArray(); } @@ -126,6 +136,10 @@ public class JavaLangClassMemberReference extends PsiReferenceBase"); + } +} + +class Test { + public int num; + public int num2; + int num3; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/reflection/DeclaredField_after.java b/java/java-tests/testData/codeInsight/completion/reflection/DeclaredField_after.java new file mode 100644 index 000000000000..924c8f05deca --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/reflection/DeclaredField_after.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class DeclaredField { + void foo() { + Test.class.getDeclaredField("num2"); + } +} + +class Test { + public int num; + public int num2; + int num3; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod.java b/java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod.java new file mode 100644 index 000000000000..5abc4c462133 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class DecalredMethod { + void foo() { + Test.class.getDeclaredMethod(""); + } +} + +class Test { + public void method(){} + public void method2(A a, B b){} + public void method3(){} +} + +class A {} +class B {} +class C {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod2.java b/java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod2.java new file mode 100644 index 000000000000..7c63f9b3fb11 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod2.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class DecalredMethod2 { + void foo() { + Test.class.getDeclaredMethod("m", A.class, B.class); + } +} + +class Test { + void method(){} + void method2(A a, B b){} + void method3(){} +} + +class A {} +class B {} +class C {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod2_after.java b/java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod2_after.java new file mode 100644 index 000000000000..f9d56a003ff2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod2_after.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class DecalredMethod2 { + void foo() { + Test.class.getDeclaredMethod("method3"); + } +} + +class Test { + void method(){} + void method2(A a, B b){} + void method3(){} +} + +class A {} +class B {} +class C {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod_after.java b/java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod_after.java new file mode 100644 index 000000000000..c6c0d5bce7d3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/reflection/DeclaredMethod_after.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class DecalredMethod { + void foo() { + Test.class.getDeclaredMethod("method2", A.class, B.class); + } +} + +class Test { + public void method(){} + public void method2(A a, B b){} + public void method3(){} +} + +class A {} +class B {} +class C {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/reflection/Field.java b/java/java-tests/testData/codeInsight/completion/reflection/Field.java new file mode 100644 index 000000000000..1d39408e856d --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/reflection/Field.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class Field { + void foo() { + Test.class.getField(""); + } +} + +class Test { + public int num; + public int num2; + int num3; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/reflection/Field_after.java b/java/java-tests/testData/codeInsight/completion/reflection/Field_after.java new file mode 100644 index 000000000000..352645d05ae8 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/reflection/Field_after.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class Field { + void foo() { + Test.class.getField("num2"); + } +} + +class Test { + public int num; + public int num2; + int num3; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/reflection/Method.java b/java/java-tests/testData/codeInsight/completion/reflection/Method.java new file mode 100644 index 000000000000..d6e0b9625f6e --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/reflection/Method.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class DecalredMethod { + void foo() { + Test.class.getMethod(""); + } +} + +class Test { + public void method(){} + public void method2(A a, B b){} + void method3(){} +} + +class A {} +class B {} +class C {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/reflection/Method_after.java b/java/java-tests/testData/codeInsight/completion/reflection/Method_after.java new file mode 100644 index 000000000000..986c6e2078b6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/reflection/Method_after.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class DecalredMethod { + void foo() { + Test.class.getMethod("method2", A.class, B.class); + } +} + +class Test { + public void method(){} + public void method2(A a, B b){} + void method3(){} +} + +class A {} +class B {} +class C {} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaReflectionCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaReflectionCompletionTest.java new file mode 100644 index 000000000000..86351f99e964 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaReflectionCompletionTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.completion; + +import com.intellij.JavaTestUtil; + +/** + * @author Konstantin Bulenkov + */ +public class JavaReflectionCompletionTest extends LightFixtureCompletionTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @Override + protected String getBasePath() { + return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/completion/reflection/"; + } + + public void testField() throws Exception { + doTest(1, "num", "num2"); + } + + public void testDeclaredField() throws Exception { + doTest(1, "num", "num2", "num3"); + } + + public void testDeclaredMethod() throws Exception { + doTest(1, "method", "method2", "method3"); + } + + public void testDeclaredMethod2() throws Exception { + doTest(2, "method", "method2", "method3"); + } + + public void testMethod() throws Exception { + doTest(1, "method", "method2"); + } + + + private void doTest(int index, String... expected) { + configureByFile(getTestName(false) + ".java"); + assertStringItems(expected); + selectItem(getLookup().getItems().get(index)); + myFixture.checkResultByFile(getTestName(false) + "_after.java"); + } +} From 82eebf04acc11e84f4825b7a23648b43dff59eeb Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Fri, 23 Mar 2012 21:14:52 +0400 Subject: [PATCH 21/58] use com.intellij.uiDesigner.SerializedComponentData instead of *.clipboard.SerializedComponentData --- .../actions/CommonEditActionsProvider.java | 2 +- .../clipboard/SerializedComponentData.java | 33 ------------------- 2 files changed, 1 insertion(+), 34 deletions(-) delete mode 100644 plugins/ui-designer/ui-designer-new/src/com/intellij/designer/clipboard/SerializedComponentData.java diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java index b0d8928027d1..340cdb6bcd35 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java @@ -16,7 +16,7 @@ package com.intellij.designer.actions; import com.intellij.designer.DesignerBundle; -import com.intellij.designer.clipboard.SerializedComponentData; +import com.intellij.uiDesigner.SerializedComponentData; import com.intellij.designer.clipboard.SimpleTransferable; import com.intellij.designer.designSurface.DesignerEditorPanel; import com.intellij.designer.designSurface.EditableArea; diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/clipboard/SerializedComponentData.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/clipboard/SerializedComponentData.java deleted file mode 100644 index c2ec117fe37a..000000000000 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/clipboard/SerializedComponentData.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.designer.clipboard; - -/** - * This class must be in main classloader because of JVM's restrictions (it's used as DataFlavor class) - * - * @author yole - */ -public final class SerializedComponentData { - private final String mySerializedComponents; - - public SerializedComponentData(String components) { - mySerializedComponents = components; - } - - public String getSerializedComponents() { - return mySerializedComponents; - } -} \ No newline at end of file From 99c2cc3420f0d40eac4ac502dc5d8d2336df5d4e Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Fri, 23 Mar 2012 21:15:35 +0400 Subject: [PATCH 22/58] android-ui-designer: load icons with a correct classloader --- .../src/com/intellij/designer/model/MetaModel.java | 2 +- .../src/com/intellij/designer/palette/Item.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaModel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaModel.java index add10d839504..399439f46fc9 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaModel.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaModel.java @@ -84,7 +84,7 @@ public class MetaModel { if (myIconPath == null) { return myPaletteItem.getIcon(); } - myIcon = IconLoader.getIcon(myIconPath); + myIcon = IconLoader.findIcon(myIconPath, myModel); } return myIcon; } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/Item.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/Item.java index 5da043ce8e45..3794bb28fb49 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/Item.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/Item.java @@ -19,7 +19,6 @@ import com.intellij.designer.model.MetaModel; import com.intellij.ide.dnd.DnDDragStartBean; import com.intellij.ide.palette.PaletteItem; import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.intellij.ui.ColoredListCellRenderer; @@ -50,7 +49,7 @@ public final class Item implements PaletteItem { public Icon getIcon() { if (myIcon == null) { - myIcon = IconLoader.getIcon(myIconPath); + myIcon = IconLoader.findIcon(myIconPath, myMetaModel.getModel()); } return myIcon; } From 27395b61e6e81228e796e6cab2ddf01ec25ecef2 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Fri, 23 Mar 2012 21:16:14 +0400 Subject: [PATCH 23/58] bundle "ui-designer-new" plugin to IDEA 12 --- build/scripts/layouts.gant | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index 8eb8b0c745d7..e78e38697911 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -218,7 +218,7 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir public def layoutCommunityPlugins(String home) { dir("plugins") { - def simplePlugins = ["commander", "copyright", "properties", "java-i18n", "devkit", "eclipse", "hg4idea", "github"] + def simplePlugins = ["commander", "copyright", "properties", "java-i18n", "devkit", "eclipse", "hg4idea", "github", "ui-designer-new"] simplePlugins.each { layoutPlugin it From 9ac67b08ad5153b6ea2c15c5bc17257b506702b5 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 23 Mar 2012 18:24:10 +0100 Subject: [PATCH 24/58] on mac, mouse clicked event comes later than frame activation (IDEA-82182) --- .../intellij/openapi/wm/impl/ToolWindowManagerImpl.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index 8f3336f59026..018f663200d2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -1333,7 +1333,14 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements FrameStateManager.getInstance().getApplicationActive().doWhenDone(new Runnable() { @Override public void run() { - ((BalloonImpl)balloon).setHideOnClickOutside(true); + final Alarm alarm = new Alarm(); + alarm.addRequest(new Runnable() { + @Override + public void run() { + ((BalloonImpl)balloon).setHideOnClickOutside(true); + Disposer.dispose(alarm); + } + }, 100); } }); listenerWrapper.myBalloon = balloon; From fe6b2c32e6c9f25eb0c5e1a42f4270ba47b55b9b Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 23 Mar 2012 21:33:50 +0400 Subject: [PATCH 25/58] introduce field for better performance [cdr] --- .../psi/impl/source/tree/injected/LeafPatcher.java | 14 +++++++++++--- .../tree/injected/XmlTextLiteralEscaper.java | 8 +++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/LeafPatcher.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/LeafPatcher.java index d58e5ac4aeff..c4f5e014907f 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/LeafPatcher.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/LeafPatcher.java @@ -39,6 +39,7 @@ class LeafPatcher extends RecursiveTreeElementWalkingVisitor { private String prevElementTail; private int shredNo; private String hostText; + private TextRange rangeInHost; private final Place myShreds; private final List> myEscapers; final Map newTexts = new THashMap(); @@ -74,7 +75,11 @@ class LeafPatcher extends RecursiveTreeElementWalkingVisitor { private StringBuilder constructTextFromHostPSI(int startOffset, int endOffset) { PsiLanguageInjectionHost.Shred current = myShreds.get(shredNo); - if (hostText == null) hostText = current.getHost().getText(); + if (hostText == null) { + hostText = current.getHost().getText(); + rangeInHost = current.getRangeInsideHost(); + } + StringBuilder text = new StringBuilder(endOffset-startOffset); while (startOffset < endOffset) { TextRange shredRange = current.getRange(); @@ -82,6 +87,7 @@ class LeafPatcher extends RecursiveTreeElementWalkingVisitor { if (startOffset >= shredRange.getEndOffset()) { current = myShreds.get(++shredNo); hostText = current.getHost().getText(); + rangeInHost = current.getRangeInsideHost(); continue; } assert startOffset >= shredRange.getStartOffset(); @@ -96,9 +102,11 @@ class LeafPatcher extends RecursiveTreeElementWalkingVisitor { String suffix = current.getSuffix(); if (startOffset < shredRange.getEndOffset() - suffix.length()) { // inside host body, cut out from the host text - int startOffsetInHost = myEscapers.get(shredNo).getOffsetInHost(startOffset - shredRange.getStartOffset() - prefix.length(), current.getRangeInsideHost()); + int startOffsetInHost = myEscapers.get(shredNo).getOffsetInHost( + startOffset - shredRange.getStartOffset() - prefix.length(), rangeInHost); int endOffsetCut = Math.min(endOffset, shredRange.getEndOffset() - suffix.length()); - int endOffsetInHost = myEscapers.get(shredNo).getOffsetInHost(endOffsetCut - shredRange.getStartOffset() - prefix.length(), current.getRangeInsideHost()); + int endOffsetInHost = myEscapers.get(shredNo).getOffsetInHost( + endOffsetCut - shredRange.getStartOffset() - prefix.length(), rangeInHost); if (endOffsetInHost != -1) { text.append(hostText, startOffsetInHost, endOffsetInHost); startOffset = endOffsetCut; diff --git a/xml/impl/src/com/intellij/psi/impl/source/tree/injected/XmlTextLiteralEscaper.java b/xml/impl/src/com/intellij/psi/impl/source/tree/injected/XmlTextLiteralEscaper.java index 3182a969f016..ca6154728968 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/tree/injected/XmlTextLiteralEscaper.java +++ b/xml/impl/src/com/intellij/psi/impl/source/tree/injected/XmlTextLiteralEscaper.java @@ -38,11 +38,13 @@ public class XmlTextLiteralEscaper extends LiteralTextEscaper { } public int getOffsetInHost(final int offsetInDecoded, @NotNull final TextRange rangeInsideHost) { - int displayStart = myHost.physicalToDisplay(rangeInsideHost.getStartOffset()); + final int rangeInsideHostStartOffset = rangeInsideHost.getStartOffset(); + int displayStart = myHost.physicalToDisplay(rangeInsideHostStartOffset); int i = myHost.displayToPhysical(offsetInDecoded + displayStart); - if (i < rangeInsideHost.getStartOffset()) i = rangeInsideHost.getStartOffset(); - if (i > rangeInsideHost.getEndOffset()) i = rangeInsideHost.getEndOffset(); + if (i < rangeInsideHostStartOffset) i = rangeInsideHostStartOffset; + final int rangeInsideHostEndOffset = rangeInsideHost.getEndOffset(); + if (i > rangeInsideHostEndOffset) i = rangeInsideHostEndOffset; return i; } From 271cc1916b4d1261cfb6c09390d0346524dc8e49 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 23 Mar 2012 18:40:09 +0100 Subject: [PATCH 26/58] if server's sdk version is older than project's sdk version, use the latest sdk used in the project for running javac server --- .../compiler/CompileServerManager.java | 4 +- .../org/jetbrains/jps/api/GlobalOptions.java | 2 - .../jps/incremental/CompileContext.java | 78 +++++++++---------- .../jps/incremental/IncProjectBuilder.java | 9 +-- .../jps/incremental/java/JavaBuilder.java | 51 +++++++++--- .../jps/javac/JavacServerBootstrap.java | 15 ++-- .../jps/server/ClasspathBootstrap.java | 44 ++++++++--- .../jps/server/ProjectDescriptor.java | 20 +++++ .../src/org/jetbrains/jps/JavaSdk.groovy | 16 +++- .../src/org/jetbrains/jps/JavaSdkImpl.groovy | 14 +++- 10 files changed, 169 insertions(+), 84 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java b/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java index 9f1f7e80af35..fc7c7d7b7eb8 100644 --- a/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java @@ -70,7 +70,8 @@ import org.jetbrains.jps.client.CompileServerClient; import org.jetbrains.jps.server.ClasspathBootstrap; import org.jetbrains.jps.server.Server; -import javax.tools.*; +import javax.tools.JavaCompiler; +import javax.tools.ToolProvider; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -611,7 +612,6 @@ public class CompileServerManager implements ApplicationComponent{ cmdLine.addParameter("-D"+ GlobalOptions.USE_EXTERNAL_JAVAC_OPTION + "=true"); } cmdLine.addParameter("-D"+ GlobalOptions.HOSTNAME_OPTION + "=" + NetUtils.getLocalHostString()); - cmdLine.addParameter("-D"+ GlobalOptions.VM_EXE_PATH_OPTION + "=" + FileUtil.toSystemIndependentName(vmExecutablePath)); // javac's VM should use the same default locale that IDEA uses in order for javac to print messages in 'correct' language final String lang = System.getProperty("user.language"); diff --git a/jps/jps-builders/src/org/jetbrains/jps/api/GlobalOptions.java b/jps/jps-builders/src/org/jetbrains/jps/api/GlobalOptions.java index 547f8135d93d..f2fdd71e4b0d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/api/GlobalOptions.java +++ b/jps/jps-builders/src/org/jetbrains/jps/api/GlobalOptions.java @@ -5,10 +5,8 @@ package org.jetbrains.jps.api; * Date: 1/24/12 */ public interface GlobalOptions { - String USE_MEMORY_TEMP_CACHE_OPTION = "use.memory.temp.cache"; String USE_EXTERNAL_JAVAC_OPTION = "use.external.javac.process"; String HOSTNAME_OPTION = "localhost.name"; - String VM_EXE_PATH_OPTION = "vm.executable.path"; String PING_INTERVAL_MS_OPTION = "server.ping.interval"; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java index b2b4b95ac98e..93613fbd9a0c 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java @@ -13,6 +13,7 @@ import org.jetbrains.jps.incremental.messages.UptoDateFilesSavedEvent; import org.jetbrains.jps.incremental.storage.BuildDataManager; import org.jetbrains.jps.incremental.storage.SourceToOutputMapping; import org.jetbrains.jps.incremental.storage.TimestampStorage; +import org.jetbrains.jps.server.ProjectDescriptor; import java.io.File; import java.io.IOException; @@ -29,51 +30,40 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler private final boolean myIsProjectRebuild; private final ProjectChunks myProductionChunks; private final ProjectChunks myTestChunks; - private final FSState myFsState; private final MessageHandler myDelegateMessageHandler; private volatile boolean myCompilingTests = false; - private final BuildDataManager myDataManager; - private final ModuleRootsIndex myRootsIndex; - private final Set> myNonIncrementalModules = new HashSet>(); private final ProjectPaths myProjectPaths; private volatile boolean myErrorsFound = false; private final long myCompilationStartStamp; + private final ProjectDescriptor myProjectDescriptor; private final TimestampStorage myTsStorage; - private final BuildLoggingManager myLoggingManager; private final Map myBuilderParams; private final CanceledStatus myCancelStatus; private float myDone = -1.0f; public CompileContext(CompileScope scope, - boolean isMake, + ProjectDescriptor pd, boolean isMake, boolean isProjectRebuild, ProjectChunks productionChunks, ProjectChunks testChunks, - FSState fsState, - final BuildDataManager dataManager, - TimestampStorage tsStorage, MessageHandler delegateMessageHandler, - final ModuleRootsIndex rootsIndex, - BuildLoggingManager loggingManager, Map builderParams, + Map builderParams, CanceledStatus cancelStatus) throws ProjectBuildException { - myTsStorage = tsStorage; - myLoggingManager = loggingManager; + myProjectDescriptor = pd; + myTsStorage = myProjectDescriptor.timestamps.getStorage(); myBuilderParams = Collections.unmodifiableMap(builderParams); myCancelStatus = cancelStatus; myCompilationStartStamp = System.currentTimeMillis(); myScope = scope; myIsProjectRebuild = isProjectRebuild; - myIsMake = isProjectRebuild? false : isMake; + myIsMake = !isProjectRebuild && isMake; myProductionChunks = productionChunks; myTestChunks = testChunks; - myFsState = fsState; myDelegateMessageHandler = delegateMessageHandler; - myDataManager = dataManager; final Project project = scope.getProject(); myProjectPaths = new ProjectPaths(project); - myRootsIndex = rootsIndex; } public Project getProject() { @@ -93,7 +83,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler } public BuildLoggingManager getLoggingManager() { - return myLoggingManager; + return myProjectDescriptor.getLoggingManager(); } @Nullable @@ -104,26 +94,26 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler public void markDirty(final File file) throws IOException { final RootDescriptor descriptor = getModuleAndRoot(file); if (descriptor != null) { - myFsState.markDirty(file, descriptor, myTsStorage); + myProjectDescriptor.fsState.markDirty(file, descriptor, myTsStorage); } } public void markDirtyIfNotDeleted(final File file) throws IOException { final RootDescriptor descriptor = getModuleAndRoot(file); if (descriptor != null) { - myFsState.markDirtyIfNotDeleted(file, descriptor, myTsStorage); + myProjectDescriptor.fsState.markDirtyIfNotDeleted(file, descriptor, myTsStorage); } } public void markDeleted(File file) throws IOException { final RootDescriptor descriptor = getModuleAndRoot(file); if (descriptor != null) { - myFsState.registerDeleted(descriptor.module, file, descriptor.isTestRoot, myTsStorage); + myProjectDescriptor.fsState.registerDeleted(descriptor.module, file, descriptor.isTestRoot, myTsStorage); } } public void markDirty(final ModuleChunk chunk) throws IOException { - myFsState.clearContextRoundData(); + myProjectDescriptor.fsState.clearContextRoundData(); final Set modules = chunk.getModules(); for (Module module : modules) { markDirtyFiles(module, myTsStorage, true, isCompilingTests()? DirtyMarkScope.TESTS : DirtyMarkScope.PRODUCTION, null); @@ -182,7 +172,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler } public Mappings createDelta() { - return myDataManager.getMappings().createDelta(); + return getDataManager().getMappings().createDelta(); } public boolean isCompilingTests() { @@ -208,18 +198,18 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler } void beforeCompileRound(@NotNull ModuleChunk chunk) { - myFsState.beforeNextRoundStart(); + myProjectDescriptor.fsState.beforeNextRoundStart(); } public void onChunkBuildStart(ModuleChunk chunk) { - myFsState.setContextChunk(chunk); + myProjectDescriptor.fsState.setContextChunk(chunk); } void onChunkBuildComplete(@NotNull ModuleChunk chunk) throws IOException { - myDataManager.closeSourceToOutputStorages(chunk, isCompilingTests()); - myDataManager.flush(true); - myFsState.clearContextRoundData(); - myFsState.clearContextChunk(); + getDataManager().closeSourceToOutputStorages(chunk, isCompilingTests()); + getDataManager().flush(true); + myProjectDescriptor.fsState.clearContextRoundData(); + myProjectDescriptor.fsState.clearContextChunk(); if (!myErrorsFound && !myCancelStatus.isCanceled()) { final boolean compilingTests = isCompilingTests(); @@ -231,12 +221,12 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler myNonIncrementalModules.remove(new Pair(module, dirtyScope)); } if (isProjectRebuild()) { - myFsState.markInitialScanPerformed(module, compilingTests); + myProjectDescriptor.fsState.markInitialScanPerformed(module, compilingTests); } - final List roots = myRootsIndex.getModuleRoots(module); + final List roots = myProjectDescriptor.rootsIndex.getModuleRoots(module); for (RootDescriptor descriptor : roots) { if (compilingTests? descriptor.isTestRoot : !descriptor.isTestRoot) { - marked |= myFsState.markAllUpToDate(getScope(), descriptor, myTsStorage, myCompilationStartStamp); + marked |= myProjectDescriptor.fsState.markAllUpToDate(getScope(), descriptor, myTsStorage, myCompilationStartStamp); } } } @@ -251,7 +241,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler } public BuildDataManager getDataManager() { - return myDataManager; + return myProjectDescriptor.dataManager; } public TimestampStorage getTimestampStorage() { @@ -274,7 +264,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler public void processFilesToRecompile(ModuleChunk chunk, FileProcessor processor) throws IOException { for (Module module : chunk.getModules()) { - myFsState.processFilesToRecompile(this, module, processor); + myProjectDescriptor.fsState.processFilesToRecompile(this, module, processor); } } @@ -285,7 +275,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler } else { if (isMake()) { - if (myFsState.markInitialScanPerformed(module, isCompilingTests())) { + if (myProjectDescriptor.fsState.markInitialScanPerformed(module, isCompilingTests())) { initModuleFSState(module); } } @@ -310,7 +300,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler // can check if the file exists final File file = new File(path); if (!currentFiles.contains(file)) { - myFsState.registerDeleted(module, file, isCompilingTests(), myTsStorage); + myProjectDescriptor.fsState.registerDeleted(module, file, isCompilingTests(), myTsStorage); } } } @@ -322,16 +312,16 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler @Nullable public RootDescriptor getModuleAndRoot(File file) { - return myRootsIndex.getModuleAndRoot(file); + return getRootsIndex().getModuleAndRoot(file); } @NotNull public List getModuleRoots(Module module) { - return myRootsIndex.getModuleRoots(module); + return getRootsIndex().getModuleRoots(module); } public ModuleRootsIndex getRootsIndex() { - return myRootsIndex; + return myProjectDescriptor.rootsIndex; } public void setDone(float done) { @@ -339,6 +329,10 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler //processMessage(new ProgressMessage("", done)); } + public ProjectDescriptor getProjectDescriptor() { + return myProjectDescriptor; + } + public static enum DirtyMarkScope{ PRODUCTION, TESTS, BOTH } @@ -362,8 +356,8 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler if (!rd.root.exists()) { continue; } - myFsState.clearRecompile(rd); - myFsState.clearDeletedPaths(module, isCompilingTests()); + myProjectDescriptor.fsState.clearRecompile(rd); + myProjectDescriptor.fsState.clearDeletedPaths(module, isCompilingTests()); traverseRecursively(rd, rd.root, excludes, tsStorage, forceMarkDirty, currentFiles); } } @@ -386,7 +380,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler // if it is full project rebuild, all storages are already completely cleared; // so passing null because there is no need to access the storage to clear non-existing data final TimestampStorage _tsStorage = isProjectRebuild() ? null : tsStorage; - myFsState.markDirty(file, rd, _tsStorage); + myProjectDescriptor.fsState.markDirty(file, rd, _tsStorage); } if (currentFiles != null) { currentFiles.add(file); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index 5d1d585234df..f59e2c6a0da9 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -19,7 +19,6 @@ import org.jetbrains.jps.incremental.messages.ProgressMessage; import org.jetbrains.jps.incremental.storage.BuildDataManager; import org.jetbrains.jps.incremental.storage.SourceToFormMapping; import org.jetbrains.jps.incremental.storage.SourceToOutputMapping; -import org.jetbrains.jps.incremental.storage.TimestampStorage; import org.jetbrains.jps.server.ProjectDescriptor; import java.io.File; @@ -217,13 +216,9 @@ public class IncProjectBuilder { } private CompileContext createContext(CompileScope scope, boolean isMake, final boolean isProjectRebuild) throws ProjectBuildException { - final TimestampStorage tsStorage = myProjectDescriptor.timestamps.getStorage(); - final FSState fsState = myProjectDescriptor.fsState; - final ModuleRootsIndex rootsIndex = myProjectDescriptor.rootsIndex; - final BuildDataManager dataManager = myProjectDescriptor.dataManager; return new CompileContext( - scope, isMake, isProjectRebuild, myProductionChunks, myTestChunks, fsState, dataManager, tsStorage, myMessageDispatcher, rootsIndex, - myProjectDescriptor.getLoggingManager(), myBuilderParams, myCancelStatus + scope, myProjectDescriptor, isMake, isProjectRebuild, myProductionChunks, myTestChunks, myMessageDispatcher, + myBuilderParams, myCancelStatus ); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 2b58b2b00d05..7a9f8686f656 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -11,6 +11,7 @@ import com.intellij.uiDesigner.compiler.*; import com.intellij.uiDesigner.core.GridConstraints; import com.intellij.uiDesigner.lw.CompiledClassPropertiesProvider; import com.intellij.uiDesigner.lw.LwRootContainer; +import com.intellij.util.SystemProperties; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.ether.dependencyView.Callbacks; @@ -30,7 +31,8 @@ import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; import org.objectweb.asm.commons.EmptyVisitor; -import javax.tools.*; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; import java.io.*; import java.net.MalformedURLException; import java.net.ServerSocket; @@ -46,6 +48,7 @@ import java.util.concurrent.TimeUnit; */ public class JavaBuilder extends ModuleLevelBuilder { public static final String BUILDER_NAME = "java"; + private static final String FORMS_BUILDER_NAME = "forms"; private static final String JAVA_EXTENSION = ".java"; private static final String FORM_EXTENSION = ".form"; public static final boolean USE_EMBEDDED_JAVAC = System.getProperty(GlobalOptions.USE_EXTERNAL_JAVAC_OPTION) == null; @@ -421,21 +424,31 @@ public class JavaBuilder extends ModuleLevelBuilder { }); } - - private static JavacServerClient ensureJavacServerLaunched(CompileContext context) throws Exception { final ExternalJavacDescriptor descriptor = ExternalJavacDescriptor.KEY.get(context); if (descriptor != null) { return descriptor.client; } // start server here - final String vmExecPath = System.getProperty(GlobalOptions.VM_EXE_PATH_OPTION, System.getProperty("java.home") + "/bin/java"); final String hostString = System.getProperty(GlobalOptions.HOSTNAME_OPTION, "localhost"); final int port = findFreePort(); final int heapSize = getJavacServerHeapSize(context); + // defaulting to the same jdk that used to run the server + String javaHome = SystemProperties.getJavaHome(); + int javaVersion = convertToNumber(SystemProperties.getJavaVersion()); + + for (JavaSdk sdk : context.getProjectDescriptor().getProjectJavaSdks()) { + final String version = sdk.getVersion(); + final int ver = convertToNumber(version); + if (ver > javaVersion) { + javaVersion = ver; + javaHome = sdk.getHomePath(); + } + } + final BaseOSProcessHandler processHandler = JavacServerBootstrap.launchJavacServer( - vmExecPath, heapSize, port, Paths.getSystemRoot(), getCompilationVMOptions(context) + javaHome, heapSize, port, Paths.getSystemRoot(), getCompilationVMOptions(context) ); final JavacServerClient client = new JavacServerClient(); try { @@ -449,6 +462,26 @@ public class JavaBuilder extends ModuleLevelBuilder { return client; } + private static int convertToNumber(final String ver) { + final String prefix = "1."; + if (ver.startsWith(prefix)) { + final String versionNumberString; + final int dotIndex = ver.indexOf(".", prefix.length()); + if (dotIndex > 0) { + versionNumberString = ver.substring(prefix.length(), dotIndex); + } + else { + versionNumberString = ver.substring(prefix.length()); + } + try { + return Integer.parseInt(versionNumberString); + } + catch (NumberFormatException ignored) { + } + } + return 0; + } + private static int findFreePort() { try { final ServerSocket serverSocket = new ServerSocket(0); @@ -711,7 +744,7 @@ public class JavaBuilder extends ModuleLevelBuilder { if (alreadyProcessedForm != null) { context.processMessage( new CompilerMessage( - BUILDER_NAME, BuildMessage.Kind.WARNING, + FORMS_BUILDER_NAME, BuildMessage.Kind.WARNING, formFile.getAbsolutePath() + ": The form is bound to the class " + classToBind + ".\nAnother form " + alreadyProcessedForm.getAbsolutePath() + " is also bound to this class", formFile.getAbsolutePath()) ); @@ -737,7 +770,7 @@ public class JavaBuilder extends ModuleLevelBuilder { final FormErrorInfo[] warnings = codeGenerator.getWarnings(); for (final FormErrorInfo warning : warnings) { context.processMessage( - new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.WARNING, warning.getErrorMessage(), formFile.getAbsolutePath())); + new CompilerMessage(FORMS_BUILDER_NAME, BuildMessage.Kind.WARNING, warning.getErrorMessage(), formFile.getAbsolutePath())); } final FormErrorInfo[] errors = codeGenerator.getErrors(); @@ -750,7 +783,7 @@ public class JavaBuilder extends ModuleLevelBuilder { } message.append(formFile.getAbsolutePath()).append(": ").append(error.getErrorMessage()); } - context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, message.toString())); + context.processMessage(new CompilerMessage(FORMS_BUILDER_NAME, BuildMessage.Kind.ERROR, message.toString())); } else { final File sourceFile = outputClassFile.getSourceFile(); @@ -761,7 +794,7 @@ public class JavaBuilder extends ModuleLevelBuilder { } catch (Exception e) { success = false; - context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Forms instrumentation failed" + e.getMessage(), + context.processMessage(new CompilerMessage(FORMS_BUILDER_NAME, BuildMessage.Kind.ERROR, "Forms instrumentation failed" + e.getMessage(), formFile.getAbsolutePath())); } finally { diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerBootstrap.java index aece320b89a0..8452f1d9b1e6 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerBootstrap.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerBootstrap.java @@ -22,14 +22,9 @@ import java.util.List; */ public class JavacServerBootstrap { - public static BaseOSProcessHandler launchJavacServer(String vmExecutablePath, - int heapSize, - int port, - File workingDir, - List vmOptions) throws Exception { - + public static BaseOSProcessHandler launchJavacServer(String sdkHomePath, int heapSize, int port, File workingDir, List vmOptions) throws Exception { final List cmdLine = new ArrayList(); - appendParam(cmdLine, vmExecutablePath); + appendParam(cmdLine, getVMExecutablePath(sdkHomePath)); appendParam(cmdLine, "-server"); appendParam(cmdLine, "-XX:MaxPermSize=150m"); //appendParam(cmdLine, "-XX:ReservedCodeCacheSize=64m"); @@ -64,7 +59,7 @@ public class JavacServerBootstrap { appendParam(cmdLine, "-classpath"); - final List cp = ClasspathBootstrap.getJavacServerClasspath(); + final List cp = ClasspathBootstrap.getJavacServerClasspath(sdkHomePath); final StringBuilder classpath = new StringBuilder(); for (File file : cp) { if (classpath.length() > 0) { @@ -155,4 +150,8 @@ public class JavacServerBootstrap { } cmdLine.add(param); } + + public static String getVMExecutablePath(String sdkHome) { + return sdkHome + "/bin/java"; + } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java index be4dec0b646a..45502bed0f72 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java +++ b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java @@ -18,8 +18,11 @@ package org.jetbrains.jps.server; import com.google.protobuf.Message; import com.intellij.compiler.notNullVerification.NotNullVerifyingInstrumenter; import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.uiDesigner.compiler.AlienFormFileException; import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.util.SystemProperties; import com.jgoodies.forms.layout.CellConstraints; import net.n3.nanoxml.IXMLBuilder; import org.codehaus.groovy.GroovyException; @@ -30,16 +33,21 @@ import org.jetbrains.jps.javac.JavacServer; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.commons.EmptyVisitor; -import javax.tools.*; +import javax.tools.JavaCompiler; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; /** * @author Eugene Zhuravlev * Date: 9/12/11 */ public class ClasspathBootstrap { - public static final String JPS_RUNTIME_PATH = "rt/jps-incremental"; + private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.server.ClasspathBootstrap"); private static class OptimizedFileManagerClassHolder { static final String CLASS_NAME = "org.jetbrains.jps.javac.OptimizedFileManager"; @@ -119,31 +127,47 @@ public class ClasspathBootstrap { return new ArrayList(cp); } - public static List getJavacServerClasspath() { + public static List getJavacServerClasspath(String sdkHome) { final Set cp = new LinkedHashSet(); - cp.add(getResourcePath(JavacServer.class)); - for (String path : PathManager.getUtilClassPath()) { cp.add(new File(path)); } // util + cp.add(getResourcePath(JavacServer.class)); // self + // util + for (String path : PathManager.getUtilClassPath()) { + cp.add(new File(path)); + } cp.add(getResourcePath(Message.class)); // protobuf cp.add(getResourcePath(Version.class)); // netty final Class optimizedFileManagerClass = getOptimizedFileManagerClass(); if (optimizedFileManagerClass != null) { - cp.add(getResourcePath(optimizedFileManagerClass)); // optimizedFileManager + cp.add(getResourcePath(optimizedFileManagerClass)); // optimizedFileManager, if applicable } try { final Class cmdLineWrapper = Class.forName("com.intellij.rt.execution.CommandLineWrapper"); cp.add(getResourcePath(cmdLineWrapper)); // idea_rt.jar } - catch (Throwable ignored) { + catch (Throwable th) { + LOG.info(th); } final JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler(); if (systemCompiler != null) { try { - cp.add(getResourcePath(systemCompiler.getClass())); // tools.jar + final String localJarPath = FileUtil.toSystemIndependentName(getResourcePath(systemCompiler.getClass()).getPath()); + final String localJavaHome = SystemProperties.getJavaHome(); + String relPath = FileUtil.getRelativePath(FileUtil.toSystemIndependentName(localJavaHome), localJarPath, '/'); + if (relPath != null) { + if (relPath.contains("..")) { + relPath = FileUtil.getRelativePath(FileUtil.toSystemIndependentName(new File(localJavaHome).getParent()), localJarPath, '/'); + } + if (relPath != null) { + final File targetFile = new File(sdkHome +"/" +relPath); + cp.add(targetFile); // tools.jar + } + } } - catch (Throwable ignored) { + catch (Throwable th) { + LOG.info(th); } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/ProjectDescriptor.java b/jps/jps-builders/src/org/jetbrains/jps/server/ProjectDescriptor.java index 456f57f4964e..c15821806570 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/server/ProjectDescriptor.java +++ b/jps/jps-builders/src/org/jetbrains/jps/server/ProjectDescriptor.java @@ -1,6 +1,9 @@ package org.jetbrains.jps.server; +import org.jetbrains.jps.JavaSdk; +import org.jetbrains.jps.Module; import org.jetbrains.jps.Project; +import org.jetbrains.jps.Sdk; import org.jetbrains.jps.incremental.BuildLoggingManager; import org.jetbrains.jps.incremental.FSState; import org.jetbrains.jps.incremental.ModuleRootsIndex; @@ -8,6 +11,8 @@ import org.jetbrains.jps.incremental.storage.BuildDataManager; import org.jetbrains.jps.incremental.storage.ProjectTimestamps; import java.io.IOException; +import java.util.HashSet; +import java.util.Set; /** * @author Eugene Zhuravlev @@ -21,6 +26,7 @@ public final class ProjectDescriptor { private final BuildLoggingManager myLoggingManager; public ModuleRootsIndex rootsIndex; private int myUseCounter = 1; + private Set myProjectJavaSdks; public ProjectDescriptor(Project project, FSState fsState, @@ -33,6 +39,20 @@ public final class ProjectDescriptor { this.dataManager = dataManager; myLoggingManager = loggingManager; this.rootsIndex = new ModuleRootsIndex(project); + myProjectJavaSdks = new HashSet(); + for (Module module : project.getModules().values()) { + final Sdk sdk = module.getSdk(); + if (sdk instanceof JavaSdk && !myProjectJavaSdks.contains(sdk)) { + final JavaSdk javaSdk = (JavaSdk)sdk; + if (javaSdk.getVersion() != null && javaSdk.getHomePath() != null) { + myProjectJavaSdks.add(javaSdk); + } + } + } + } + + public Set getProjectJavaSdks() { + return myProjectJavaSdks; } public BuildLoggingManager getLoggingManager() { diff --git a/jps/model/src/org/jetbrains/jps/JavaSdk.groovy b/jps/model/src/org/jetbrains/jps/JavaSdk.groovy index 132d69a2c49d..d7496afcdac0 100644 --- a/jps/model/src/org/jetbrains/jps/JavaSdk.groovy +++ b/jps/model/src/org/jetbrains/jps/JavaSdk.groovy @@ -1,5 +1,7 @@ package org.jetbrains.jps +import org.jetbrains.annotations.Nullable + /** * @author Eugene.Kudelevsky */ @@ -12,7 +14,17 @@ public abstract class JavaSdk extends Sdk { super(project, name, initializer) } - abstract String getJavacExecutable(); + @Nullable + public String getHomePath() { + return null; + } - abstract String getJavaExecutable(); + @Nullable + public String getVersion() { + return null; + } + + public abstract String getJavacExecutable(); + + public abstract String getJavaExecutable(); } \ No newline at end of file diff --git a/jps/model/src/org/jetbrains/jps/JavaSdkImpl.groovy b/jps/model/src/org/jetbrains/jps/JavaSdkImpl.groovy index 0f220220bfc4..f6a37f44a8f5 100644 --- a/jps/model/src/org/jetbrains/jps/JavaSdkImpl.groovy +++ b/jps/model/src/org/jetbrains/jps/JavaSdkImpl.groovy @@ -15,11 +15,21 @@ class JavaSdkImpl extends JavaSdk { this.jdkPath = jdkPath } - String getJavacExecutable() { + @Override + public String getHomePath() { + return jdkPath; + } + + @Override + public String getVersion() { + return version; + } + + public String getJavacExecutable() { return jdkPath + File.separator + "bin" + File.separator + "javac"; } - String getJavaExecutable() { + public String getJavaExecutable() { return jdkPath + File.separator + "bin" + File.separator + "java"; } } From b8d122582f23256eb959a20abb6ba86cd39d73ac Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Fri, 23 Mar 2012 22:00:50 +0400 Subject: [PATCH 27/58] Fix error with cut operation --- .../actions/CommonEditActionsProvider.java | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java index 340cdb6bcd35..927ae68ee52f 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java @@ -142,21 +142,24 @@ public class CommonEditActionsProvider implements DeleteProvider, CopyProvider, } private boolean doCopy() { - return myDesigner.getToolProvider().execute(new ThrowableRunnable() { - @Override - public void run() throws Exception { - Element root = new Element("designer"); - root.setAttribute("target", myDesigner.getPlatformTarget()); + try { + Element root = new Element("designer"); + root.setAttribute("target", myDesigner.getPlatformTarget()); - List components = RadComponent.getPureSelection(myDesigner.getActionsArea().getSelection()); - for (RadComponent component : components) { - component.copyTo(root); - } - - SerializedComponentData data = new SerializedComponentData(new XMLOutputter().outputString(root)); - CopyPasteManager.getInstance().setContents(new SimpleTransferable(data, DATA_FLAVOR)); + List components = RadComponent.getPureSelection(myDesigner.getActionsArea().getSelection()); + for (RadComponent component : components) { + component.copyTo(root); } - }); + + SerializedComponentData data = new SerializedComponentData(new XMLOutputter().outputString(root)); + CopyPasteManager.getInstance().setContents(new SimpleTransferable(data, DATA_FLAVOR)); + + return true; + } + catch (Throwable e) { + myDesigner.showError("Copy error:", e); + return false; + } } ////////////////////////////////////////////////////////////////////////////////////////// // From d9f19cc9295a415d4ee12c749c24e9205da56fcc Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Fri, 23 Mar 2012 22:11:08 +0400 Subject: [PATCH 28/58] IDEA-83431 fix android logcat colors preview --- .../android/logcat/AndroidLogcatColorPage.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/android/src/org/jetbrains/android/logcat/AndroidLogcatColorPage.java b/plugins/android/src/org/jetbrains/android/logcat/AndroidLogcatColorPage.java index 19720c5477cc..27bf9aeae10d 100644 --- a/plugins/android/src/org/jetbrains/android/logcat/AndroidLogcatColorPage.java +++ b/plugins/android/src/org/jetbrains/android/logcat/AndroidLogcatColorPage.java @@ -48,12 +48,12 @@ public class AndroidLogcatColorPage implements ColorSettingsPage { "08-04 16:24:11.166: ASSERT/Assertion(4687): Expected true but was false"; static { - ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("verbose.level.title", AndroidLogcatConstants.VERBOSE_OUTPUT_KEY); - ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("debug.level.title", AndroidLogcatConstants.DEBUG_OUTPUT_KEY); - ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("info.level.title", AndroidLogcatConstants.INFO_OUTPUT_KEY); - ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("warning.level.title", AndroidLogcatConstants.WARNING_OUTPUT_KEY); - ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("error.level.title", AndroidLogcatConstants.ERROR_OUTPUT_KEY); - ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("assert.level.title", AndroidLogcatConstants.ASSERT_OUTPUT_KEY); + ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("verbose", AndroidLogcatConstants.VERBOSE_OUTPUT_KEY); + ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("debug", AndroidLogcatConstants.DEBUG_OUTPUT_KEY); + ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("info", AndroidLogcatConstants.INFO_OUTPUT_KEY); + ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("warning", AndroidLogcatConstants.WARNING_OUTPUT_KEY); + ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("error", AndroidLogcatConstants.ERROR_OUTPUT_KEY); + ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("assert", AndroidLogcatConstants.ASSERT_OUTPUT_KEY); } private static final AttributesDescriptor[] ATTRIBUTES_DESCRIPTORS = From 8cc6dfbe735b0db158c7f8750ae1360c657d196c Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Mar 2012 20:03:11 +0100 Subject: [PATCH 29/58] setting background Ctrl-Shift-A --- .../src/com/intellij/ide/util/gotoByName/GotoActionModel.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java index 356016c1dc16..87b750510819 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java @@ -31,6 +31,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.LayeredIcon; +import com.intellij.ui.LightColors; import com.intellij.ui.components.JBLabel; import com.intellij.util.ArrayUtil; import com.intellij.util.ui.EmptyIcon; @@ -156,6 +157,9 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C label.setIcon(EMPTY_ICON); panel.add(label, BorderLayout.WEST); panel.add(new JBLabel("Settings"), BorderLayout.EAST); + if (!isSelected) { + panel.setBackground(LightColors.SLIGHTLY_GRAY); + } } else if (value instanceof String) { final JBLabel label = new JBLabel((String)value); label.setIcon(EMPTY_ICON); From 7746d7748f0441f749191aa8fdb16043529450d2 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Mar 2012 20:03:42 +0100 Subject: [PATCH 30/58] import default values on change signature (IDEA-83331) --- .../changeSignature/JavaChangeSignatureDialog.java | 11 +++++++++-- .../JavaChangeSignatureUsageProcessor.java | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java index c5b5432c58ce..95ad17bdbe61 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.completion.CompletionResultSet; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CustomShortcutSet; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorFontType; @@ -29,6 +30,7 @@ import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; @@ -558,7 +560,7 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase item = parameterInfos.get(i); + final ParameterTableModelItemBase item = parameterInfos.get(i); if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(item.parameter.getName())) { return RefactoringMessageUtil.getIncorrectIdentifierMessage(item.parameter.getName()); @@ -582,7 +584,12 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase() { + @Override + public String compute() { + return JavaCodeStyleManager.getInstance(myProject).qualifyClassReferences(item.defaultValueCodeFragment).getText(); + } + }); String def = item.parameter.defaultValue; def = def.trim(); if (!(type instanceof PsiEllipsisType)) { diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java index a931ba654458..98c263f5103f 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java @@ -375,7 +375,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr else { newArg = factory.createExpressionFromText(info.getName(), list); } - list.add(newArg); + JavaCodeStyleManager.getInstance(list.getProject()).shortenClassReferences(list.add(newArg)); } } else { @@ -630,7 +630,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr else { actualArg = changeInfo.getValue(i, callExpression); } - callExpression.getArgumentList().add(actualArg); + JavaCodeStyleManager.getInstance(callExpression.getProject()).shortenClassReferences(callExpression.getArgumentList().add(actualArg)); } } From 2f6fec6309ef21ded3a5805445f20a106c32fc71 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Mar 2012 20:04:26 +0100 Subject: [PATCH 31/58] scope view: collapsable view on rename (IDEA-83335) --- .../ide/scopeView/ScopeTreeViewPanel.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java index 3abc03715a52..e5dfd6c99b84 100644 --- a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java @@ -210,6 +210,10 @@ public class ScopeTreeViewPanel extends JPanel implements Disposable { }); } }; + doWhenDone(runnable); + } + + private void doWhenDone(Runnable runnable) { if (myActionCallback == null || ApplicationManager.getApplication().isUnitTestMode()) { runnable.run(); } @@ -646,7 +650,7 @@ public class ScopeTreeViewPanel extends JPanel implements Disposable { }, false); } else if (propertyName.equals(PsiTreeChangeEvent.PROP_DIRECTORY_NAME)) { - queueRefreshScope(scope); + queueRefreshScope(scope, (PsiDirectory)element); } } } @@ -665,7 +669,7 @@ public class ScopeTreeViewPanel extends JPanel implements Disposable { } } else if (element instanceof PsiDirectory && element.isValid()) { - queueRefreshScope(scope); + queueRefreshScope(scope, (PsiDirectory)element); } } @@ -673,11 +677,22 @@ public class ScopeTreeViewPanel extends JPanel implements Disposable { return InjectedLanguageManager.getInstance(myProject).isInjectedFragment(psiFile); } - private void queueRefreshScope(final NamedScope scope) { + private void queueRefreshScope(final NamedScope scope, final PsiDirectory dir) { myUpdateQueue.cancelAllUpdates(); queueUpdate(new Runnable() { public void run() { + myTreeExpansionMonitor.freeze(); refreshScope(scope); + doWhenDone(new Runnable() { + @Override + public void run() { + myTreeExpansionMonitor.restore(); + final PackageDependenciesNode dirNode = myBuilder.findNode(dir, dir); + if (dirNode != null) { + TreeUtil.selectPath(myTree, new TreePath(dirNode.getPath())); + } + } + }); } }, false); } From e91aed14f81f6319e5e718a8e02953e98cd34988 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Mar 2012 20:05:24 +0100 Subject: [PATCH 32/58] update external repository plugins fix from installed view --- .../ide/plugins/ActionInstallPlugin.java | 10 ++++++-- .../plugins/InstalledPluginsTableModel.java | 4 +++ .../intellij/ide/plugins/PluginInstaller.java | 25 ++++++++++++++++++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java index 5bcda3846d13..e6379e4b3982 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java @@ -103,10 +103,13 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { pluginNode = (PluginNode)descr; } else if (descr instanceof IdeaPluginDescriptorImpl) { - pluginNode = new PluginNode(descr.getPluginId()); + final PluginId pluginId = descr.getPluginId(); + pluginNode = new PluginNode(pluginId); pluginNode.setName(descr.getName()); pluginNode.setDepends(Arrays.asList(descr.getDependentPluginIds()), descr.getOptionalDependentPluginIds()); pluginNode.setSize("-1"); + pluginNode.setRepositoryName(((InstalledPluginsTableModel)host.getPluginsModel()) + .getPluginHostUrl(pluginId.getIdString())); } if (pluginNode != null) { @@ -162,7 +165,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { } } - private static void suggestToEnableInstalledPlugins(final InstalledPluginsTableModel pluginsModel, + private static boolean suggestToEnableInstalledPlugins(final InstalledPluginsTableModel pluginsModel, final Set disabled, final Set disabledDependants, final ArrayList list) { @@ -201,6 +204,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { Messages.showYesNoCancelDialog(message + "", CommonBundle.getWarningTitle(), "Enable all", "Enable updated plugin" + (disabled.size() > 1 ? "s" : ""), CommonBundle.getCancelButtonText(), Messages.getQuestionIcon()); + if (result == DialogWrapper.NEXT_USER_EXIT_CODE) return false; } else { message += "
Would you like to enable "; if (!disabled.isEmpty()) { @@ -211,6 +215,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { } message += "?"; result = Messages.showOkCancelDialog(message, CommonBundle.getWarningTitle(), Messages.getQuestionIcon()); + if (result == DialogWrapper.CANCEL_EXIT_CODE) return false; } if (result == DialogWrapper.OK_EXIT_CODE) { @@ -220,6 +225,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { pluginsModel.enableRows(disabled.toArray(new IdeaPluginDescriptor[disabled.size()]), true); } } + return true; } private void installedPluginsToModel(ArrayList list) { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java index 58c70ea71f84..3a9a4121ea82 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java @@ -103,6 +103,10 @@ public class InstalledPluginsTableModel extends PluginTableModel { } } + public String getPluginHostUrl(String idString) { + return myPlugin2host.get(idString); + } + public static int getCheckboxColumn() { return 0; } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java index 29bd4cc0e189..08cc5c2d995f 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java @@ -24,6 +24,8 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.updateSettings.impl.PluginDownloader; +import com.intellij.openapi.updateSettings.impl.UpdateChecker; +import com.intellij.openapi.util.Comparing; import com.intellij.ui.GuiUtils; import com.intellij.util.ArrayUtil; @@ -156,7 +158,28 @@ public class PluginInstaller { } synchronized (PluginManager.lock) { - final PluginDownloader downloader = PluginDownloader.createDownloader(pluginNode); + PluginDownloader downloader = null; + final String repositoryName = pluginNode.getRepositoryName(); + if (repositoryName != null) { + try { + final ArrayList downloaders = new ArrayList(); + if (!UpdateChecker.checkPluginsHost(repositoryName, downloaders)) { + return false; + } + for (PluginDownloader pluginDownloader : downloaders) { + if (Comparing.strEqual(pluginDownloader.getPluginId(), pluginNode.getPluginId().getIdString())) { + downloader = pluginDownloader; + break; + } + } + if (downloader == null) return false; + } + catch (Exception e) { + return false; + } + } else { + downloader = PluginDownloader.createDownloader(pluginNode); + } if (downloader.prepareToInstall(ProgressManager.getInstance().getProgressIndicator())) { downloader.install(); pluginNode.setStatus(PluginNode.STATUS_DOWNLOADED); From dae3690e623ffdd732c011a148411c58fb6bc6e7 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Mar 2012 20:52:13 +0100 Subject: [PATCH 33/58] IDEA-83344: restore state after escaped introduce correctly (cherry picked from commit 161240ac4eb414839985b2adef7732fc9a8d2e00) --- .../JavaVariableInplaceIntroducer.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java index c9a9d826bd82..d9d0dc41135a 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java @@ -28,6 +28,7 @@ import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; @@ -189,13 +190,15 @@ public class JavaVariableInplaceIntroducer extends InplaceVariableIntroducer Date: Fri, 23 Mar 2012 21:20:37 +0100 Subject: [PATCH 34/58] IDEA-83419: plugins: do not suggest to restart when all updated plugins remain disabled --- .../ide/plugins/ActionInstallPlugin.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java index e6379e4b3982..f1399ec5e82b 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java @@ -122,7 +122,6 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { @Override public void run() { installedPluginsToModel(list); - installed.setRequireShutdown(true); if (!installed.isDisposed()) { getPluginTable().updateUI(); final InstalledPluginsTableModel pluginsModel = (InstalledPluginsTableModel)installed.getPluginsModel(); @@ -143,10 +142,23 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { } } } - suggestToEnableInstalledPlugins(pluginsModel, disabled, disabledDependants, list); + if (suggestToEnableInstalledPlugins(pluginsModel, disabled, disabledDependants, list)) { + installed.setRequireShutdown(true); + } } else { - notifyPluginsWereInstalled(); + boolean needToRestart = false; + for (PluginNode node : list) { + final IdeaPluginDescriptor pluginDescriptor = PluginManager.getPlugin(node.getPluginId()); + if (pluginDescriptor == null || pluginDescriptor.isEnabled()) { + needToRestart = true; + break; + } + } + + if (needToRestart) { + notifyPluginsWereInstalled(); + } } } }; From 3a3b8b83dba2d9ac5ee25178f65e467a2b8ae2ad Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Sat, 24 Mar 2012 03:34:47 +0400 Subject: [PATCH 35/58] Taking into account synthetic/bridge attributes (compile-server). --- .../jetbrains/ether/dependencyView/ClassfileAnalyzer.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java b/jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java index 3968e164c634..8d898122d8d1 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java @@ -365,7 +365,9 @@ class ClassfileAnalyzer { public FieldVisitor visitField(int access, String n, String desc, String signature, Object value) { processSignature(signature); - fields.add(new FieldRepr(context, access, context.get(n), context.get(desc), context.get(signature), value)); + if ((access & Opcodes.ACC_SYNTHETIC) == 0) { + fields.add(new FieldRepr(context, access, context.get(n), context.get(desc), context.get(signature), value)); + } return new EmptyVisitor() { @Override @@ -388,7 +390,9 @@ class ClassfileAnalyzer { return new EmptyVisitor() { @Override public void visitEnd() { - methods.add(new MethodRepr(context, access, context.get(n), context.get(signature), desc, exceptions, defaultValue.get())); + if ((access & Opcodes.ACC_SYNTHETIC) == 0 || (access & Opcodes.ACC_BRIDGE) > 0) { + methods.add(new MethodRepr(context, access, context.get(n), context.get(signature), desc, exceptions, defaultValue.get())); + } } @Override From 3241e083d753132eb8254a871b03aa732c5a14ec Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 24 Mar 2012 08:15:31 +0100 Subject: [PATCH 36/58] IDEA-83451 Make it more clear what closure folding is --- .../src/messages/ApplicationBundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties index 1783df737381..0d597d8fdfa0 100644 --- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties +++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties @@ -338,7 +338,7 @@ checkbox.mark.modified.tabs.with.asterisk=Mark modified tabs with asterisk group.code.folding=Code Folding checkbox.collapse.xml.tags=XML tags checkbox.collapse.anonymous.classes=Anonymous classes -checkbox.collapse.closures=Closures +checkbox.collapse.closures="Closures" (anonymous classes implementing one method) checkbox.collapse.generic.constructor.parameters=Generic constructor and method parameters checkbox.collapse.i18n.messages=I18n Strings checkbox.collapse.annotations=Annotations From fa271053a5915df53661076d7ae01149dd7a8798 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 24 Mar 2012 10:02:34 +0100 Subject: [PATCH 37/58] IDEA-83433 Basic Code Completion doesn't work properly when using upper case --- .../com/intellij/psi/util/NameUtilTest.java | 8 +++ .../com/intellij/psi/codeStyle/NameUtil.java | 71 ++++++++++--------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java index 1a27747841da..184e051fe81e 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java +++ b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java @@ -289,6 +289,13 @@ public class NameUtilTest extends UsefulTestCase { TextRange.from(0, 2)); } + public void testPreferCapsMatching() { + String sample = "getCurrentUser"; + // 0 4 10 + assertOrderedEquals(new NameUtil.MinusculeMatcher("getCU", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + TextRange.from(0, 4), TextRange.from(10, 1)); + } + public void testMatchingDegree() { assertPreference("OCO", "OneCoolObject", "OCObject"); assertPreference("MUp", "MavenUmlProvider", "MarkUp"); @@ -296,6 +303,7 @@ public class NameUtilTest extends UsefulTestCase { assertPreference("CertificateExce", "CertificateEncodingException", "CertificateException"); assertPreference("boo", "Boolean", "boolean", NameUtil.MatchingCaseSensitivity.NONE); assertPreference("Boo", "boolean", "Boolean", NameUtil.MatchingCaseSensitivity.NONE); + assertPreference("getCU", "getCurrentSomething", "getCurrentUser"); } private static void assertPreference(@NonNls String pattern, diff --git a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java index 8c61b6c90e1d..db3833081524 100644 --- a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java +++ b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java @@ -423,6 +423,9 @@ public class NameUtil { if (patternIndex == myPattern.length) { return FList.emptyList(); } + if ('*' == myPattern[patternIndex]) { + return skipChars(name, patternIndex, nameIndex, true); + } if (nameIndex == name.length()) { return null; } @@ -430,9 +433,6 @@ public class NameUtil { if ('.' == myPattern[patternIndex] && name.charAt(nameIndex) != '.') { return skipChars(name, patternIndex, nameIndex, false); } - if ('*' == myPattern[patternIndex]) { - return skipChars(name, patternIndex, nameIndex, true); - } if (patternIndex == 0 && myOptions != MatchingCaseSensitivity.NONE && name.charAt(nameIndex) != myPattern[0]) { return null; @@ -455,26 +455,22 @@ public class NameUtil { int nextStart = NameUtil.nextWord(name, nameIndex); - boolean uppers = isWordStart(myPattern[patternIndex]); + int lastUpper = isWordStart(myPattern[patternIndex]) ? 0 : -1; int i = 1; while (true) { - if (patternIndex + i == myPattern.length) { - //end of pattern reached, the last word matches - return FList.emptyList().prepend(TextRange.from(nameIndex, i)); - } - if (i + nameIndex == nextStart) { - //whole word match + if (patternIndex + i == myPattern.length || i + nameIndex == nextStart) { break; } char p = myPattern[patternIndex + i]; - if (uppers && isWordStart(p) && myOptions != MatchingCaseSensitivity.ALL) { + char w = name.charAt(i + nameIndex); + if (lastUpper == i - 1 && isWordStart(p) && myOptions != MatchingCaseSensitivity.ALL) { + if (p == w) { + lastUpper = i; + } p = StringUtil.toLowerCase(p); - } else { - uppers = false; } - char w = name.charAt(i + nameIndex); if (myOptions != MatchingCaseSensitivity.ALL) { w = StringUtil.toLowerCase(w); } @@ -484,29 +480,38 @@ public class NameUtil { i++; } - if (myPattern[patternIndex + i] == '*') { - nextStart = nameIndex + i; + if (isFinalSpaceMatch(name, patternIndex, nameIndex, nextStart, i)) { + return FList.emptyList().prepend(TextRange.from(nameIndex, i)); } - // there's more in the pattern, but no more words - if (nextStart == name.length()) { - if (patternIndex + i == myPattern.length - 1) { - char last = myPattern[patternIndex + i]; - if (' ' == last && (i == 1 && isWordStart(myPattern[patternIndex]) || i + nameIndex == name.length()) || - '*' == last) { - return FList.emptyList().prepend(TextRange.from(nameIndex, i)); + return matchAfterFragment(name, patternIndex, nameIndex, nextStart, lastUpper, i); + } + + private boolean isFinalSpaceMatch(String name, int patternIndex, int nameIndex, int nextStart, int i) { + return nextStart == name.length() && + patternIndex + i == myPattern.length - 1 && + ' ' == myPattern[patternIndex + i] && + (i == 1 && isWordStart(myPattern[patternIndex]) || i + nameIndex == name.length()); + } + + @Nullable + private FList matchAfterFragment(String name, int patternIndex, int nameIndex, int nextStart, int lastUpper, int matchLen) { + int star = patternIndex + matchLen < myPattern.length && myPattern[patternIndex + matchLen] == '*' ? matchLen : -1; + if (lastUpper >= 0) { + FList ranges = matchName(name, patternIndex + lastUpper + 1, lastUpper == star ? nameIndex + lastUpper : nextStart); + if (ranges != null) { + return prependRange(ranges, nameIndex, lastUpper + 1); + } + } + + while (matchLen > 0) { + if (matchLen != lastUpper) { + FList ranges = matchName(name, patternIndex + matchLen, matchLen == star ? matchLen + lastUpper : nextStart); + if (ranges != null) { + return prependRange(ranges, nameIndex, matchLen); } } - - return null; - } - - while (i > 0) { - FList ranges = matchName(name, patternIndex + i, nextStart); - if (ranges != null) { - return prependRange(ranges, nameIndex, i); - } - i--; + matchLen--; } return null; } From f361bb995f64c006711dac77f6f144906f9d162d Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Sun, 25 Mar 2012 12:38:23 +0400 Subject: [PATCH 38/58] Fix maven test --- .../jetbrains/idea/maven/dom/MavenPackagingCompletionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenPackagingCompletionTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenPackagingCompletionTest.java index e98eb0fc34e0..b495e61b5c9b 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenPackagingCompletionTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenPackagingCompletionTest.java @@ -27,7 +27,7 @@ public class MavenPackagingCompletionTest extends MavenDomTestCase { ""); - assertCompletionVariants(myProjectPom, "jar", "pom", "war", "ejb", "ejb-client", "ear", "bundle"); + assertCompletionVariants(myProjectPom, "jar", "pom", "war", "ejb", "ejb-client", "ear", "bundle", "maven-plugin"); } public void testDoNotHighlightUnknownPackagingTypes() throws Throwable { From 80f57234ac6b244f68bcfbdd93d89b58b45bca9c Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Sun, 25 Mar 2012 14:52:34 +0400 Subject: [PATCH 39/58] Replace StringBuffer to StringBuilder. --- .../com/intellij/openapi/editor/impl/SelectionModelImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java index 6e7232d25313..cb0947dbdcf6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java @@ -629,7 +629,7 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi int[] starts = getBlockSelectionStarts(); int[] ends = getBlockSelectionEnds(); int width = Math.abs(myBlockEnd.column - myBlockStart.column); - final StringBuffer buf = new StringBuffer(); + final StringBuilder buf = new StringBuilder(); for (int i = 0; i < starts.length; i++) { if (i > 0) buf.append('\n'); final int len = ends[i] - starts[i]; @@ -644,7 +644,7 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi return text.subSequence(selectionStart, selectionEnd).toString(); } - private static void appendCharSequence(@NotNull StringBuffer buf, @NotNull CharSequence s, int srcOffset, int len) { + private static void appendCharSequence(@NotNull StringBuilder buf, @NotNull CharSequence s, int srcOffset, int len) { if (srcOffset < 0 || len < 0 || srcOffset > s.length() - len) { throw new IndexOutOfBoundsException("srcOffset " + srcOffset + ", len " + len + ", s.length() " + s.length()); } From 4e0ab057fd203f9733ce425559571834ed460014 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Sun, 25 Mar 2012 15:01:32 +0400 Subject: [PATCH 40/58] Minor code changes. --- .../com/intellij/openapi/progress/impl/ProgressManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java index 1682512f118e..f0813ecb738b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java @@ -47,7 +47,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{ private static volatile int ourLockedCheckCounter = 0; @NonNls private static final String NAME = "Progress Cancel Checker"; - private static final boolean DISABLED = Comparing.equal(System.getProperty(PROCESS_CANCELED_EXCEPTION), "disabled"); + private static final boolean DISABLED = "disabled".equals(System.getProperty(PROCESS_CANCELED_EXCEPTION)); private volatile boolean enabled = true; From 81ddca9aad295cb57ea0b6e500f635018e35d4a8 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 25 Mar 2012 15:19:28 +0400 Subject: [PATCH 41/58] IDEA-64945 Don't show master password prompt if the master password is empty --- .../impl/providers/masterKey/MasterPasswordDialog.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterPasswordDialog.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterPasswordDialog.java index ce19098caa15..c93a98dfa242 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterPasswordDialog.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterPasswordDialog.java @@ -104,6 +104,11 @@ public class MasterPasswordDialog extends DialogWrapper { * @throws PasswordSafeException if the master password is not provided. */ public static void askPassword(Project project, MasterKeyPasswordSafe safe) throws PasswordSafeException { + // trying empty password: people who have set up empty password, don't want to get disturbed by the prompt. + if (safe.setMasterPassword("")) { + return; + } + String error = null; retries: for (int count = 0; count < NUMBER_OF_RETRIES; count++) { From 0fc7905e66dc8e363a8078e34144d785795b4556 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 25 Mar 2012 15:27:03 +0400 Subject: [PATCH 42/58] IDEA-80799 Limit the output written to the VCS console by Git Otherwise it might lead to a hang in DocumentImpl (IDEA-83397). --- plugins/git4idea/src/git4idea/GitVcs.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/git4idea/src/git4idea/GitVcs.java b/plugins/git4idea/src/git4idea/GitVcs.java index 8bee54c341f3..7dd147df97cb 100644 --- a/plugins/git4idea/src/git4idea/GitVcs.java +++ b/plugins/git4idea/src/git4idea/GitVcs.java @@ -135,6 +135,7 @@ public class GitVcs extends AbstractVcs { private GitBranchWidget myBranchWidget; private GitVersion myVersion = GitVersion.NULL; // version of Git which this plugin uses. + private static final int MAX_CONSOLE_OUTPUT_SIZE = 10000; @Nullable public static GitVcs getInstance(Project project) { @@ -409,6 +410,9 @@ public class GitVcs extends AbstractVcs { * @param style a style to use */ private void showMessage(@NotNull String message, final TextAttributes style) { + if (message.length() > MAX_CONSOLE_OUTPUT_SIZE) { + message = message.substring(0, MAX_CONSOLE_OUTPUT_SIZE); + } myVcsManager.addMessageToConsoleWindow(message, style); } From adea98d81dc74b3f3821c344c2cfca67a2bf0e66 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 25 Mar 2012 15:45:35 +0400 Subject: [PATCH 43/58] Fix direct call of dispose() --- .../com/intellij/openapi/vcs/changes/ShortDiffDetails.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShortDiffDetails.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShortDiffDetails.java index b65831f7b667..f02da16a136d 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShortDiffDetails.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShortDiffDetails.java @@ -19,7 +19,6 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Getter; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.vcs.Details; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.FilePathImpl; @@ -27,7 +26,6 @@ import com.intellij.openapi.vcs.GenericDetailsLoader; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import com.intellij.util.PairConsumer; -import com.intellij.util.ThreeState; import com.intellij.util.containers.SLRUMap; import com.intellij.vcsUtil.UIVcsUtil; import org.jetbrains.annotations.Nullable; @@ -198,7 +196,7 @@ public class ShortDiffDetails implements RefreshablePanel, Disposable { @Override public void dispose() { if (myDetailsLoader != null) { - myDetailsLoader.dispose(); + Disposer.dispose(myDetailsLoader); } myDetailsPanel.clear(); myDetailsCache.clear(); From 7d30efde0a2b4d767545a3a2318319606f727b15 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 25 Mar 2012 15:46:14 +0400 Subject: [PATCH 44/58] Fix NPE --- .../com/intellij/openapi/vcs/changes/ShortDiffDetails.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShortDiffDetails.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShortDiffDetails.java index f02da16a136d..5c30d2039e35 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShortDiffDetails.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShortDiffDetails.java @@ -198,7 +198,9 @@ public class ShortDiffDetails implements RefreshablePanel, Disposable { if (myDetailsLoader != null) { Disposer.dispose(myDetailsLoader); } - myDetailsPanel.clear(); + if (myDetailsPanel != null) { + myDetailsPanel.clear(); + } myDetailsCache.clear(); } From 674c5390eb6880b709edd98f6b34fa45019ba3c6 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 25 Mar 2012 15:59:55 +0400 Subject: [PATCH 45/58] IDEA-83406 Optimize containsAll when creating Commit dialog and performing commit. containsAll on lists are O(n^2), on hashes - O(n). --- .../openapi/vcs/changes/ui/CommitChangeListDialog.java | 2 +- .../src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java index 6ebdde5566dc..94922be67ab2 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java @@ -236,7 +236,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj throw new IllegalArgumentException("nothing found to execute commit with"); } - myAllOfDefaultChangeListChangesIncluded = changes.containsAll(defaultChangeList.getChanges()); + myAllOfDefaultChangeListChangesIncluded = new HashSet(changes).containsAll(new HashSet(defaultChangeList.getChanges())); myIsAlien = isAlien; if (isAlien) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java index 8c6817faa73d..436b293b1f29 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java @@ -42,12 +42,12 @@ import com.intellij.openapi.vcs.update.RefreshVFsSynchronously; import com.intellij.util.Consumer; import com.intellij.util.NullableFunction; import com.intellij.util.WaitForProgressToShow; -import com.intellij.util.containers.hash.HashSet; import com.intellij.util.ui.ConfirmationDialog; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.List; public class CommitHelper { @@ -326,7 +326,7 @@ public class CommitHelper { myAfterVcsRefreshModification = ChangeListsModificationAfterCommit.NOTHING; if (myChangeList instanceof LocalChangeList) { final LocalChangeList localList = (LocalChangeList) myChangeList; - final boolean containsAll = myIncludedChanges.containsAll(myChangeList.getChanges()); + final boolean containsAll = new HashSet(myIncludedChanges).containsAll(new HashSet(myChangeList.getChanges())); if (containsAll && !localList.isDefault() && !localList.isReadOnly()) { myAfterVcsRefreshModification = ChangeListsModificationAfterCommit.DELETE_LIST; } From 45852a26ad1390f6fc1c8edbeee15a82ec0cb008 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 25 Mar 2012 17:06:44 +0400 Subject: [PATCH 46/58] GitHandler: Don't lock on read operations. Read operations of a Git repository can be performed during a write operation on the same repository. Only write operations can't be executed simultaneously. --- plugins/git4idea/src/git4idea/commands/GitHandler.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/plugins/git4idea/src/git4idea/commands/GitHandler.java b/plugins/git4idea/src/git4idea/commands/GitHandler.java index 201606677a34..a71aa65e5030 100644 --- a/plugins/git4idea/src/git4idea/commands/GitHandler.java +++ b/plugins/git4idea/src/git4idea/commands/GitHandler.java @@ -621,10 +621,8 @@ public abstract class GitHandler { boolean suspendable = false; switch (myCommand.lockingPolicy()) { case META: - // do nothing no locks are taken for metadata - break; case READ: - vcs.getCommandLock().readLock().lock(); + // need to lock only write operations: reads can be performed even when a write operation is going on break; case WRITE_SUSPENDABLE: suspendable = true; @@ -716,10 +714,7 @@ public abstract class GitHandler { finally { switch (myCommand.lockingPolicy()) { case META: - // do nothing no locks are taken for metadata - break; case READ: - vcs.getCommandLock().readLock().unlock(); break; case WRITE_SUSPENDABLE: case WRITE: From 011d5e6f6741803e8c317d6217773aa1ddf561db Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 25 Mar 2012 17:54:17 +0400 Subject: [PATCH 47/58] IDEA-78716 Master password prompt is "hidden" Use WaitForProgressToShow not to let "modal dialogs deadlock" when loading project. --- .../impl/providers/masterKey/MasterKeyPasswordSafe.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java index d8574f77d5eb..5a516066e7b7 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java @@ -25,7 +25,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; -import com.intellij.util.ui.UIUtil; +import com.intellij.util.WaitForProgressToShow; import java.io.UnsupportedEncodingException; import java.util.HashMap; @@ -182,7 +182,7 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider { } if (key.get() == null) { final Ref ex = new Ref(); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { + WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(new Runnable() { public void run() { if (key.get() == null) { try { From ace22ddf1c0e012f011bbbcd887c5bd3dca64e29 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 23 Mar 2012 18:22:14 +0400 Subject: [PATCH 48/58] project structure dialog: optimizations & show first 100 errors only (IDEA-77603, IDEA-83170, IDEA-80148) (cherry picked from commit fb6cb3c) --- .../ConfigurationErrorsComponent.java | 141 ++++++++++++------ 1 file changed, 92 insertions(+), 49 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationErrorsComponent.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationErrorsComponent.java index 9233ad1d8c88..fac049f3440d 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationErrorsComponent.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationErrorsComponent.java @@ -18,16 +18,15 @@ package com.intellij.openapi.roots.ui.configuration; import com.intellij.openapi.Disposable; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.wm.impl.content.GraphicsConfig; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.components.JBList; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.components.labels.LinkLabel; import com.intellij.ui.components.labels.LinkListener; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.BaseButtonBehavior; import com.intellij.util.ui.TimedDeadzone; @@ -45,6 +44,7 @@ import java.awt.event.ComponentEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.RoundRectangle2D; +import java.util.AbstractList; import java.util.ArrayList; import java.util.List; @@ -52,6 +52,7 @@ import java.util.List; * User: spLeaner */ public class ConfigurationErrorsComponent extends JPanel implements Disposable, ListDataListener { + private static final int MAX_ERRORS_TO_SHOW = SystemInfo.getIntProperty("idea.project.structure.max.errors.to.show", 100); private static final boolean ONE_LINE = true; private static final boolean MULTI_LINE = false; @@ -95,7 +96,7 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable, private void ensureCurrentViewIs(final boolean oneLine, @Nullable final Object data) { if (oneLine) { if (myCurrentView instanceof OneLineErrorComponent) return; - myConfigurationErrorsListModel.setFilter(null); + myConfigurationErrorsListModel.setFilter(true, true); OneLineErrorComponent c = new OneLineErrorComponent(myConfigurationErrorsListModel) { @Override public void onViewChange(Object data) { @@ -109,14 +110,9 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable, } myCurrentView = c; - } else { - Condition filter = data == null ? null : new Condition() { - @Override - public boolean value(ConfigurationError error) { - return data == null ? true : "Ignored".equals(data) ? error.isIgnored() : !error.isIgnored(); - } - }; - myConfigurationErrorsListModel.setFilter(filter); + } + else { + myConfigurationErrorsListModel.setFilter(data == null || !"Ignored".equals(data), data == null || "Ignored".equals(data)); if (myCurrentView instanceof MultiLineErrorComponent) return; MultiLineErrorComponent c = new MultiLineErrorComponent(myConfigurationErrorsListModel) { @Override @@ -568,13 +564,13 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable, if (errors.size() == 1) { mySingleErrorLabel.setText(myModel.getErrors().get(0).getPlainTextTitle()); } else { - myErrorsLabel.setText(String.format("%s errors found", errors.size())); + myErrorsLabel.setText(String.format("%s errors found", getErrorsCount(errors.size()))); } } final List ignoredErrors = myModel.getIgnoredErrors(); if (ignoredErrors.size() > 0) { - myIgnoredErrorsLabel.setText(String.format("%s ignored error%s", ignoredErrors.size(), ignoredErrors.size() == 1 ? "" : "s")); + myIgnoredErrorsLabel.setText(String.format("%s ignored error%s", getErrorsCount(ignoredErrors.size()), ignoredErrors.size() == 1 ? "" : "s")); } removeAll(); @@ -595,6 +591,10 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable, repaint(); } + private static String getErrorsCount(final int size) { + return size < MAX_ERRORS_TO_SHOW ? String.valueOf(size) : MAX_ERRORS_TO_SHOW + "+"; + } + private JComponent wrapLabel(@NotNull final JLabel label, @NotNull final ConfigurationError configurationError) { final JPanel result = new JPanel(new BorderLayout()); result.setBackground(label.getBackground()); @@ -653,7 +653,9 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable, public void onClick(MouseEvent e) { final Object o = myModel.getElementAt(0); if (o instanceof ConfigurationError) { - ((ConfigurationError)o).ignore(!((ConfigurationError)o).isIgnored()); + final ConfigurationError error = (ConfigurationError)o; + error.ignore(!error.isIgnored()); + myModel.update(error); updateView(); } } @@ -678,72 +680,92 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable, } } + //todo[nik] move to ContainerUtil after 11.1 + @NotNull + private static List concat(@NotNull final List list1, @NotNull final List list2) { + return new AbstractList() { + public T get(int index) { + if (index < list1.size()) { + return list1.get(index); + } + + return list2.get(index - list1.size()); + } + + public int size() { + return list1.size() + list2.size(); + } + }; + } + private static class ConfigurationErrorsListModel extends AbstractListModel implements ConfigurationErrors, Disposable { private MessageBusConnection myConnection; - private List myErrorsList = new ArrayList(); - private Condition myFilter; + private List myNotIgnoredErrors = new ArrayList(); + private List myAllErrors; + private List myIgnoredErrors = new ArrayList(); private ConfigurationErrorsListModel(@NotNull final Project project) { + setFilter(true, true); myConnection = project.getMessageBus().connect(); myConnection.subscribe(TOPIC, this); } - public void setFilter(Condition filter) { - myFilter = filter; + public void setFilter(boolean showNotIgnored, boolean showIgnored) { + if (showIgnored && showNotIgnored) { + myAllErrors = concat(myNotIgnoredErrors, myIgnoredErrors); + } + else if (showIgnored) { + myAllErrors = myIgnoredErrors; + } + else { + myAllErrors = myNotIgnoredErrors; + } } @Override public int getSize() { - return myFilter == null ? myErrorsList.size() : ContainerUtil.filter(myErrorsList, myFilter).size(); + return Math.min(myAllErrors.size(), MAX_ERRORS_TO_SHOW); } @Override public Object getElementAt(int index) { - return myFilter == null ? myErrorsList.get(index) : ContainerUtil.filter(myErrorsList, myFilter).get(index); + return myAllErrors.get(index); } - private boolean accept(ConfigurationError error) { - return myFilter == null || myFilter.value(error); - } - @Override public void addError(@NotNull ConfigurationError error) { - if (!myErrorsList.contains(error) && accept(error)) { - int ndx = 0; - if (error.isIgnored()) { - ndx = myErrorsList.size(); + if (!myAllErrors.contains(error)) { + List targetList = error.isIgnored() ? myIgnoredErrors : myNotIgnoredErrors; + if (targetList.size() < MAX_ERRORS_TO_SHOW) { + targetList.add(0, error); + } + else { + targetList.add(error); } - myErrorsList.add(ndx, error); - fireIntervalAdded(this, ndx, ndx); + int i = myAllErrors.indexOf(error); + if (i != -1 && i < MAX_ERRORS_TO_SHOW) { + fireIntervalAdded(this, i, i); + } } } @Override public void removeError(@NotNull ConfigurationError error) { - if (myErrorsList.contains(error)) { - final int ndx = myErrorsList.indexOf(error); - myErrorsList.remove(ndx); - fireIntervalRemoved(this, ndx, ndx); + final int i = myAllErrors.indexOf(error); + myIgnoredErrors.remove(error); + myNotIgnoredErrors.remove(error); + if (i != -1 && i < MAX_ERRORS_TO_SHOW) { + fireIntervalRemoved(this, i, i); } } public List getErrors() { - return ContainerUtil.filter(myErrorsList, new Condition() { - @Override - public boolean value(final ConfigurationError error) { - return !error.isIgnored(); - } - }); + return myNotIgnoredErrors; } public List getIgnoredErrors() { - return ContainerUtil.filter(myErrorsList, new Condition() { - @Override - public boolean value(final ConfigurationError error) { - return error.isIgnored(); - } - }); + return myIgnoredErrors; } @Override @@ -755,9 +777,30 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable, } public void update(final ConfigurationError error) { - final int ndx = myErrorsList.indexOf(error); - if (ndx >= 0) { - fireContentsChanged(this, ndx, ndx); + final int i0 = myAllErrors.indexOf(error); + if (error.isIgnored()) { + if (myNotIgnoredErrors.remove(error)) { + myIgnoredErrors.add(0, error); + } + } + else { + if (myIgnoredErrors.remove(error)) { + myNotIgnoredErrors.add(0, error); + } + } + final int i1 = myAllErrors.indexOf(error); + if (i0 == i1 && i0 != -1) { + if (i0 < MAX_ERRORS_TO_SHOW) { + fireContentsChanged(this, i0, i0); + } + } + else { + if (i0 != -1 && i0 < MAX_ERRORS_TO_SHOW) { + fireIntervalRemoved(this, i0, i0); + } + if (i1 != -1 && i1 < MAX_ERRORS_TO_SHOW) { + fireIntervalAdded(this, i1, i1); + } } } } From 69421b9e074e5b02679a4c132f4f66a8dfdbeb1c Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 23 Mar 2012 18:22:54 +0400 Subject: [PATCH 49/58] IDEA-79927: "Create project from existing sources" doesn't work with HTML/JS only projects (cherry picked from commit 9f17876) --- .../importSources/ProjectFromSourcesBuilder.java | 2 ++ .../impl/ProjectFromSourcesBuilderImpl.java | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/ProjectFromSourcesBuilder.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/ProjectFromSourcesBuilder.java index 568311359726..fc28f8f6bf6d 100644 --- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/ProjectFromSourcesBuilder.java +++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/ProjectFromSourcesBuilder.java @@ -42,4 +42,6 @@ public interface ProjectFromSourcesBuilder { @NotNull WizardContext getContext(); + + boolean hasRootsFromOtherDetectors(ProjectStructureDetector thisDetector); } diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java index 1ed00b0c054a..2980c4e25b09 100644 --- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java +++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java @@ -32,6 +32,7 @@ import com.intellij.ide.util.projectWizard.importSources.ProjectStructureDetecto import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.*; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; @@ -262,6 +263,15 @@ public class ProjectFromSourcesBuilderImpl extends ProjectBuilder implements Pro myUpdaters.add(updater); } + public boolean hasRootsFromOtherDetectors(ProjectStructureDetector thisDetector) { + for (ProjectStructureDetector projectStructureDetector : Extensions.getExtensions(ProjectStructureDetector.EP_NAME)) { + if (projectStructureDetector != thisDetector && !getProjectRoots(projectStructureDetector).isEmpty()) { + return true; + } + } + return false; + } + @NotNull private static Module createModule(ProjectDescriptor projectDescriptor, final ModuleDescriptor descriptor, final Map projectLibs, final ModifiableModuleModel moduleModel) From 78231e4cf49a768243ec75110aab5eb31e908cc1 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 23 Mar 2012 18:23:07 +0400 Subject: [PATCH 50/58] IDEA-83077: UI locked up after dismissing project settings [rev by Dmitry A.] (cherry picked from commit b60cdcf) --- .../com/intellij/compiler/ModuleCompilerUtil.java | 14 ++++++++------ .../GeneralProjectSettingsElement.java | 13 ++++++------- .../ui/configuration/ModulesConfigurator.java | 6 +++--- .../openapi/roots/ModifiableRootModel.java | 4 ---- .../intellij/openapi/roots/ModuleRootModel.java | 6 ++++++ .../openapi/roots/impl/ModuleRootManagerImpl.java | 12 ++++++++++++ 6 files changed, 35 insertions(+), 20 deletions(-) diff --git a/java/compiler/openapi/src/com/intellij/compiler/ModuleCompilerUtil.java b/java/compiler/openapi/src/com/intellij/compiler/ModuleCompilerUtil.java index bf4cce63dc53..185648ac146e 100644 --- a/java/compiler/openapi/src/com/intellij/compiler/ModuleCompilerUtil.java +++ b/java/compiler/openapi/src/com/intellij/compiler/ModuleCompilerUtil.java @@ -24,6 +24,7 @@ import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModel; import com.intellij.openapi.util.Pair; import com.intellij.util.Chunk; import com.intellij.util.containers.ContainerUtil; @@ -106,15 +107,16 @@ public final class ModuleCompilerUtil { } } - public static GraphGenerator createGraphGenerator(final Map models) { - return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph() { - public Collection getNodes() { + + public static GraphGenerator createGraphGenerator(final Map models) { + return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph() { + public Collection getNodes() { return models.values(); } - public Iterator getIn(final ModifiableRootModel model) { + public Iterator getIn(final ModuleRootModel model) { final Module[] modules = model.getModuleDependencies(); - final List dependencies = new ArrayList(); + final List dependencies = new ArrayList(); for (Module module : modules) { dependencies.add(models.get(module)); } @@ -162,7 +164,7 @@ public final class ModuleCompilerUtil { return null; } - public static Collection> buildChunks(final Map models) { + public static Collection> buildChunks(final Map models) { return toChunkGraph(createGraphGenerator(models)).getNodes(); } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/GeneralProjectSettingsElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/GeneralProjectSettingsElement.java index 10bdcd813327..68688e1cbee0 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/GeneralProjectSettingsElement.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/GeneralProjectSettingsElement.java @@ -18,7 +18,7 @@ package com.intellij.openapi.roots.ui.configuration; import com.intellij.compiler.ModuleCompilerUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; -import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootModel; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.*; import com.intellij.openapi.util.text.StringUtil; @@ -49,14 +49,13 @@ public class GeneralProjectSettingsElement extends ProjectStructureElement { @Override public void check(ProjectStructureProblemsHolder problemsHolder) { - final Graph> graph = ModuleCompilerUtil.toChunkGraph( - myContext.getModulesConfigurator().createGraphGenerator()); - final Collection> chunks = graph.getNodes(); + final Graph> graph = ModuleCompilerUtil.toChunkGraph(myContext.getModulesConfigurator().createGraphGenerator()); + final Collection> chunks = graph.getNodes(); List cycles = new ArrayList(); - for (Chunk chunk : chunks) { - final Set modules = chunk.getNodes(); + for (Chunk chunk : chunks) { + final Set modules = chunk.getNodes(); List names = new ArrayList(); - for (ModifiableRootModel model : modules) { + for (ModuleRootModel model : modules) { names.add(model.getModule().getName()); } if (modules.size() > 1) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java index 35fcf40f66f7..8f60ad874018 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java @@ -213,10 +213,10 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change myAllModulesChangeListeners.add(listener); } - public GraphGenerator createGraphGenerator() { - final Map models = new HashMap(); + public GraphGenerator createGraphGenerator() { + final Map models = new HashMap(); for (ModuleEditor moduleEditor : myModuleEditors) { - models.put(moduleEditor.getModule(), moduleEditor.getModifiableRootModel()); + models.put(moduleEditor.getModule(), moduleEditor.getRootModel()); } return ModuleCompilerUtil.createGraphGenerator(models); } diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ModifiableRootModel.java b/platform/lang-api/src/com/intellij/openapi/roots/ModifiableRootModel.java index 4a355e58d60c..2277d4f19954 100644 --- a/platform/lang-api/src/com/intellij/openapi/roots/ModifiableRootModel.java +++ b/platform/lang-api/src/com/intellij/openapi/roots/ModifiableRootModel.java @@ -172,10 +172,6 @@ public interface ModifiableRootModel extends ModuleRootModel { void setExcludeExplodedDirectory(boolean excludeExplodedDir); - @NotNull Module[] getModuleDependencies(); - - @NotNull Module[] getModuleDependencies(boolean includeTests); - boolean isWritable(); void setRootUrls(OrderRootType orderRootType, String[] urls); diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ModuleRootModel.java b/platform/lang-api/src/com/intellij/openapi/roots/ModuleRootModel.java index ba8b609dacad..70bc9e503190 100644 --- a/platform/lang-api/src/com/intellij/openapi/roots/ModuleRootModel.java +++ b/platform/lang-api/src/com/intellij/openapi/roots/ModuleRootModel.java @@ -193,4 +193,10 @@ public interface ModuleRootModel { @NotNull String[] getRootUrls(OrderRootType rootType); T getModuleExtension(Class klass); + + @NotNull + Module[] getModuleDependencies(); + + @NotNull + Module[] getModuleDependencies(boolean includeTests); } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java index de4ec3acdf7a..18f6aa3d2a02 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java @@ -267,6 +267,18 @@ public class ModuleRootManagerImpl extends ModuleRootManager implements ModuleCo return myRootModel.getModuleDependencies(includeTests); } + @NotNull + @Override + public Module[] getModuleDependencies() { + return myRootModel.getModuleDependencies(); + } + + @NotNull + @Override + public Module[] getModuleDependencies(boolean includeTests) { + return myRootModel.getModuleDependencies(includeTests); + } + public boolean isDependsOn(Module module) { return myRootModel.isDependsOn(module); } From a8256b2bce8da307d0c6a82ad32e42955215c9ca Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 23 Mar 2012 18:23:45 +0400 Subject: [PATCH 51/58] IDEA-81163: GWT facets get added to every new module [rev by Anton] (cherry picked from commit edc1628) --- .../org/jetbrains/idea/maven/project/MavenProject.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java index 258972e1bb52..5f3f6e99157a 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java @@ -31,7 +31,6 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.SmartList; import com.intellij.util.containers.CollectionFactory; import com.intellij.util.containers.ContainerUtil; -import gnu.trove.THashMap; import gnu.trove.THashSet; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -737,7 +736,13 @@ public class MavenProject { @Nullable public MavenPlugin findPlugin(@Nullable String groupId, @Nullable String artifactId) { - for (MavenPlugin each : getPlugins()) { + return findPlugin(groupId, artifactId, false); + } + + @Nullable + public MavenPlugin findPlugin(@Nullable String groupId, @Nullable String artifactId, final boolean explicitlyDeclaredOnly) { + final List plugins = explicitlyDeclaredOnly ? getDeclaredPlugins() : getPlugins(); + for (MavenPlugin each : plugins) { if (each.getMavenId().equals(groupId, artifactId)) return each; } return null; From 673780a93edf3995081a2492673068d8dbc120ed Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 26 Mar 2012 10:53:10 +0400 Subject: [PATCH 52/58] IDEA-64195 JPA 2.0 persistence.xml is not supported (cherry picked from commit 3c52197) --- .../xml/actions/ValidateXmlActionHandler.java | 35 +++++++++++++------ ...kXmlFileWithXercesValidatorInspection.java | 1 + 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/xml/impl/src/com/intellij/xml/actions/ValidateXmlActionHandler.java b/xml/impl/src/com/intellij/xml/actions/ValidateXmlActionHandler.java index 638bbf5e63ce..2275976cd61a 100644 --- a/xml/impl/src/com/intellij/xml/actions/ValidateXmlActionHandler.java +++ b/xml/impl/src/com/intellij/xml/actions/ValidateXmlActionHandler.java @@ -32,6 +32,9 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.xml.*; import com.intellij.ui.content.*; +import com.intellij.util.ArrayUtil; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.ErrorTreeView; import com.intellij.util.ui.MessageCategory; import com.intellij.xml.XmlBundle; @@ -56,10 +59,7 @@ import javax.xml.parsers.SAXParserFactory; import java.io.FileNotFoundException; import java.io.StringReader; import java.net.*; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.concurrent.Future; /** @@ -70,9 +70,11 @@ public class ValidateXmlActionHandler { private static final Key KEY = Key.create("ValidateXmlAction.KEY"); @NonNls private static final String SCHEMA_FULL_CHECKING_FEATURE_ID = "http://apache.org/xml/features/validation/schema-full-checking"; private static final String GRAMMAR_FEATURE_ID = Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; + private static final Key GRAMMAR_POOL_KEY = Key.create("GrammarPoolKey"); private static final Key GRAMMAR_POOL_TIME_STAMP_KEY = Key.create("GrammarPoolTimeStampKey"); private static final Key DEPENDENT_FILES_KEY = Key.create("GrammarPoolFilesKey"); + private static final Key KNOWN_NAMESPACES_KEY = Key.create("KnownNamespacesKey"); private Project myProject; private XmlFile myFile; @@ -418,6 +420,7 @@ public class ValidateXmlActionHandler { myFile.putUserData(DEPENDENT_FILES_KEY, files); myFile.putUserData(GRAMMAR_POOL_TIME_STAMP_KEY, new Long(calculateTimeStamp(files, myProject))); } + myFile.putUserData(KNOWN_NAMESPACES_KEY, getNamespaces(myFile)); } catch (SAXException e) { LOG.debug(e); @@ -490,9 +493,7 @@ public class ValidateXmlActionHandler { XMLGrammarPool grammarPool = null; // check if the pool is valid - if (!forceChecking && - !isValidationDependentFilesOutOfDate(file) - ) { + if (!forceChecking && !isValidationDependentFilesOutOfDate(file)) { grammarPool = previousGrammarPool; } @@ -511,10 +512,13 @@ public class ValidateXmlActionHandler { public static boolean isValidationDependentFilesOutOfDate(XmlFile myFile) { final VirtualFile[] files = myFile.getUserData(DEPENDENT_FILES_KEY); final Long grammarPoolTimeStamp = myFile.getUserData(GRAMMAR_POOL_TIME_STAMP_KEY); + String[] ns = myFile.getUserData(KNOWN_NAMESPACES_KEY); - if (grammarPoolTimeStamp != null && - files != null - ) { + if (!Arrays.equals(ns, getNamespaces(myFile))) { + return true; + } + + if (grammarPoolTimeStamp != null && files != null) { long dependentFilesTimestamp = calculateTimeStamp(files,myFile.getProject()); if (dependentFilesTimestamp == grammarPoolTimeStamp.longValue()) { @@ -525,6 +529,17 @@ public class ValidateXmlActionHandler { return true; } + private static String[] getNamespaces(XmlFile file) { + XmlTag rootTag = file.getRootTag(); + if (rootTag == null) return ArrayUtil.EMPTY_STRING_ARRAY; + return ContainerUtil.mapNotNull(rootTag.getAttributes(), new Function() { + @Override + public String fun(XmlAttribute attribute) { + return attribute.getValue(); + } + }, ArrayUtil.EMPTY_STRING_ARRAY); + } + private static long calculateTimeStamp(final VirtualFile[] files, Project myProject) { long timestamp = 0; diff --git a/xml/impl/src/com/intellij/xml/util/CheckXmlFileWithXercesValidatorInspection.java b/xml/impl/src/com/intellij/xml/util/CheckXmlFileWithXercesValidatorInspection.java index 900ae8ed9455..8a664c544030 100644 --- a/xml/impl/src/com/intellij/xml/util/CheckXmlFileWithXercesValidatorInspection.java +++ b/xml/impl/src/com/intellij/xml/util/CheckXmlFileWithXercesValidatorInspection.java @@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull; /** * @author Maxim Mossienko + * @see com.intellij.xml.impl.ExternalDocumentValidator */ public class CheckXmlFileWithXercesValidatorInspection extends XmlSuppressableInspectionTool implements UnfairLocalInspectionTool { public static final @NonNls String SHORT_NAME = "CheckXmlFileWithXercesValidator"; From 8f887cfec28ee9d16db177e0b30bd9dad0189cd3 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Mon, 26 Mar 2012 11:45:02 +0400 Subject: [PATCH 53/58] IDEA-83394 Gradle: project refresh does nothing after removing Gradle home from Template Project Settings 1. Using per-project slave gradle process now; 2. Corrected GradleConfigurable balloon processing; (cherry picked from commit 7dd904a) --- plugins/gradle/src/META-INF/plugin.xml | 4 +- .../action/GradleRefreshProjectAction.java | 3 +- .../gradle/config/GradleConfigurable.java | 57 ++++++-- .../importing/GradleModulesImporter.java | 2 +- .../gradle/remote/GradleApiFacadeManager.java | 132 ++++++++++++------ .../gradle/task/AbstractGradleTask.java | 15 +- .../gradle/task/GradleResolveProjectTask.java | 14 +- .../gradle/task/GradleTaskManager.java | 12 +- .../gradle/util/GradleLibraryManager.java | 9 -- .../plugins/gradle/util/GradleUtil.java | 2 +- 10 files changed, 171 insertions(+), 79 deletions(-) diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml index 7afc8950dde5..46b953b6956c 100644 --- a/plugins/gradle/src/META-INF/plugin.xml +++ b/plugins/gradle/src/META-INF/plugin.xml @@ -53,7 +53,6 @@ - org.jetbrains.plugins.gradle.notification.GradleConfigNotificationManager + + org.jetbrains.plugins.gradle.task.GradleTaskManager + diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java index 52007519dc49..e47bc21333b3 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java @@ -2,7 +2,6 @@ package org.jetbrains.plugins.gradle.action; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.Presentation; -import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; @@ -32,7 +31,7 @@ public class GradleRefreshProjectAction extends AbstractGradleLinkedProjectActio @Override protected void doUpdate(@NotNull Presentation presentation, @NotNull Project project, @NotNull String linkedProjectPath) { boolean enabled = false; - final GradleTaskManager taskManager = ServiceManager.getService(GradleTaskManager.class); + final GradleTaskManager taskManager = project.getComponent(GradleTaskManager.class); if (taskManager != null) { enabled = !taskManager.hasTaskOfTypeInProgress(GradleTaskType.RESOLVE_PROJECT); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java index 5c42b3763ba2..7416ae2ec650 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java @@ -37,6 +37,8 @@ import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.io.File; import java.util.concurrent.TimeUnit; @@ -117,6 +119,22 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable. } } }; + myComponent.addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (!"ancestor".equals(evt.getPropertyName())) { + return; + } + + // Configure the balloon to show on initial configurable drawing. + myShowBalloonIfNecessary = evt.getNewValue() != null && evt.getOldValue() == null; + + if (evt.getNewValue() == null && evt.getOldValue() != null) { + // Cancel delayed balloons when the configurable is hidden. + myAlarm.cancelAllRequests(); + } + } + }); GridBagConstraints constraints = new GridBagConstraints(); constraints.gridwidth = GridBagConstraints.REMAINDER; constraints.weightx = 1; @@ -151,7 +169,6 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable. @Override public boolean isModified() { - myShowBalloonIfNecessary = true; if (!myPathManuallyModified) { return false; } @@ -169,17 +186,25 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable. useNormalColorForPath(); String path = myGradleHomeComponent.getPath(); GradleSettings.applyGradleHome(path, myProject); - - // There is a possible case that user defines gradle home for particular open project. We want to apply that value - // to the default project as well if it's still non-defined. - Project defaultProject = ProjectManager.getInstance().getDefaultProject(); - if (defaultProject == myProject) { + + if (isValidGradleHome(path)) { + myGradleHomeSettingType = GradleHomeSettingType.EXPLICIT_CORRECT; + // There is a possible case that user defines gradle home for particular open project. We want to apply that value + // to the default project as well if it's still non-defined. + Project defaultProject = ProjectManager.getInstance().getDefaultProject(); + if (defaultProject != myProject && !isValidGradleHome(GradleSettings.getInstance(defaultProject).getGradleHome())) { + GradleSettings.applyGradleHome(path, defaultProject); + } return; } - if (isValidGradleHome(path) && !isValidGradleHome(GradleSettings.getInstance(defaultProject).getGradleHome())) { - GradleSettings.applyGradleHome(path, defaultProject); - } + if (StringUtil.isEmpty(path)) { + myGradleHomeSettingType = GradleHomeSettingType.UNKNOWN; + } + else { + myGradleHomeSettingType = GradleHomeSettingType.EXPLICIT_INCORRECT; + new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run(); + } } private boolean isValidGradleHome(@Nullable String path) { @@ -203,7 +228,7 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable. GradleHomeSettingType.EXPLICIT_CORRECT : GradleHomeSettingType.EXPLICIT_INCORRECT; if (myGradleHomeSettingType == GradleHomeSettingType.EXPLICIT_INCORRECT) { - new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType).run(); + new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run(); } else { myAlarm.cancelAllRequests(); @@ -283,9 +308,13 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable. private final long myTriggerTime; DelayedBalloonInfo(@NotNull MessageType messageType, @NotNull GradleHomeSettingType settingType) { + this(messageType, settingType, BALLOON_DELAY_MILLIS); + } + + DelayedBalloonInfo(@NotNull MessageType messageType, @NotNull GradleHomeSettingType settingType, long delayMillis) { myMessageType = messageType; myText = settingType.getDescription(); - myTriggerTime = System.currentTimeMillis() + BALLOON_DELAY_MILLIS; + myTriggerTime = System.currentTimeMillis() + delayMillis; } @Override @@ -296,11 +325,15 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable. myAlarm.addRequest(this, diff); return; } - if (myGradleHomeComponent == null || !myGradleHomeComponent.getPathComponent().isShowing()) { + if (myGradleHomeComponent == null) { myAlarm.cancelAllRequests(); myAlarm.addRequest(this, 200); return; } + if (!myGradleHomeComponent.getPathComponent().isShowing()) { + // Don't schedule the balloon if the configurable is hidden. + return; + } GradleUtil.showBalloon(myGradleHomeComponent.getPathComponent(), myMessageType, myText); } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java index 1c192c1cef84..edc0ea2d1184 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java @@ -338,7 +338,7 @@ public class GradleModulesImporter { public void run(@NotNull final ProgressIndicator indicator) { GradleResolveProjectTask task = new GradleResolveProjectTask(intellijProject, gradleProjectPath, true); task.execute(indicator); - GradleProject projectWithResolvedLibraries = task.getProject(); + GradleProject projectWithResolvedLibraries = task.getGradleProject(); gradleProjectRef.set(projectWithResolvedLibraries); ApplicationManager.getApplication().invokeLater(setupExternalDependenciesTask, ModalityState.NON_MODAL); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java index beafc16f69e6..a54979f44b8d 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java @@ -14,11 +14,15 @@ import com.intellij.execution.process.ProcessTerminatedListener; import com.intellij.execution.rmi.RemoteProcessSupport; import com.intellij.execution.runners.ProgramRunner; import com.intellij.ide.actions.OpenProjectFileChooserDescriptor; +import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.projectRoots.*; import com.intellij.openapi.roots.DependencyScope; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.ShutDownTracker; import com.intellij.openapi.util.text.StringUtil; @@ -27,8 +31,10 @@ import com.intellij.psi.PsiBundle; import com.intellij.util.Alarm; import com.intellij.util.PathUtil; import com.intellij.util.SystemProperties; +import com.intellij.util.containers.ConcurrentWeakHashMap; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManager; import org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManagerImpl; import org.jetbrains.plugins.gradle.remote.impl.GradleApiFacadeImpl; @@ -49,8 +55,8 @@ import java.rmi.server.UnicastRemoteObject; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; /** * Entry point to work with remote {@link GradleApiFacade}. @@ -62,15 +68,19 @@ import java.util.concurrent.atomic.AtomicReference; */ public class GradleApiFacadeManager { + private static final Pair NULL_VALUE = Pair.empty(); + private static final String REMOTE_PROCESS_TTL_IN_MS_KEY = "gradle.remote.process.ttl.ms"; private static final String MAIN_CLASS_NAME = GradleApiFacadeImpl.class.getName(); private static final int REMOTE_FAIL_RECOVERY_ATTEMPTS_NUMBER = 3; - private final AtomicReference> myFacade - = new AtomicReference>(); - private final AtomicReference myExportedProgressManager - = new AtomicReference(); + private final ConcurrentMap myFacadeWrappers + = new ConcurrentWeakHashMap(); + private final ConcurrentMap myRemoteNotificationManagers + = new ConcurrentWeakHashMap(); + private final ConcurrentMap> myRemoteFacades + = new ConcurrentWeakHashMap>(); @NotNull private final GradleLibraryManager myGradleLibraryManager; @NotNull private final GradleProgressNotificationManagerImpl myProgressManager; @@ -78,13 +88,12 @@ public class GradleApiFacadeManager { // Please note that we don't use RemoteGradleProcessSettings as the 'Configuration' type parameter here because we need // to apply the settings to the newly created process. I.e. every time new process is created we need to call // 'GradleApiFacade.applySettings()'. So, we need to hold reference to the last returned 'GradleApiFacade' stub anyway. - private final RemoteProcessSupport mySupport; - private final GradleApiFacade myApiFacade; + private final RemoteProcessSupport mySupport; public GradleApiFacadeManager(@NotNull GradleLibraryManager gradleLibraryManager, @NotNull GradleProgressNotificationManager manager) { myGradleLibraryManager = gradleLibraryManager; myProgressManager = (GradleProgressNotificationManagerImpl)manager; - mySupport = new RemoteProcessSupport(GradleApiFacade.class) { + mySupport = new RemoteProcessSupport(GradleApiFacade.class) { @Override protected void fireModificationCountChanged() { } @@ -95,13 +104,10 @@ public class GradleApiFacadeManager { } @Override - protected RunProfileState getRunProfileState(Object o, Object configuration, Executor executor) throws ExecutionException { - return createRunProfileState(); + protected RunProfileState getRunProfileState(Object o, String configuration, Executor executor) throws ExecutionException { + return createRunProfileState(findProjectByName(configuration)); } }; - myApiFacade = (GradleApiFacade)Proxy.newProxyInstance( - GradleApiFacadeManager.class.getClassLoader(), new Class[]{GradleApiFacade.class}, new MyHandler() - ); ShutDownTracker.getInstance().registerShutdownTask(new Runnable() { public void run() { @@ -110,10 +116,21 @@ public class GradleApiFacadeManager { }); } - private RunProfileState createRunProfileState() { + @NotNull + private static Project findProjectByName(@NotNull String name) { + final ProjectManager projectManager = ProjectManager.getInstance(); + for (Project project : projectManager.getOpenProjects()) { + if (name.equals(project.getName())) { + return project; + } + } + return projectManager.getDefaultProject(); + } + + private RunProfileState createRunProfileState(@Nullable final Project project) { return new CommandLineState(null) { private SimpleJavaParameters createJavaParameters() throws ExecutionException { - Collection gradleLibraries = myGradleLibraryManager.getAllLibraries(); + Collection gradleLibraries = myGradleLibraryManager.getAllLibraries(project); GradleLog.LOG.assertTrue(gradleLibraries != null, GradleBundle.message("gradle.generic.text.error.sdk.undefined")); if (gradleLibraries == null) { throw new ExecutionException("Can't find gradle libraries"); @@ -193,19 +210,29 @@ public class GradleApiFacadeManager { * @throws Exception in case of inability to return the facade */ @NotNull - public GradleApiFacade getFacade() throws Exception { - return myApiFacade; + public GradleApiFacade getFacade(@Nullable Project project) throws Exception { + if (project == null) { + project = ProjectManager.getInstance().getDefaultProject(); + } + final GradleApiFacade facade = myFacadeWrappers.get(project.getName()); + if (facade == null) { + final GradleApiFacade newFacade = (GradleApiFacade)Proxy.newProxyInstance( + GradleApiFacadeManager.class.getClassLoader(), new Class[]{GradleApiFacade.class}, new MyHandler(project) + ); + myFacadeWrappers.putIfAbsent(project.getName(), newFacade); + } + return myFacadeWrappers.get(project.getName()); } - public Object doInvoke(Method method, Object[] args, int invocationNumber) throws Throwable { - GradleApiFacade facade = doGetFacade(); + public Object doInvoke(@NotNull Project project, Method method, Object[] args, int invocationNumber) throws Throwable { + GradleApiFacade facade = doGetFacade(project); try { return method.invoke(facade, args); } catch (InvocationTargetException e) { if (e.getTargetException() instanceof RemoteException && invocationNumber > 0) { Thread.sleep(1000); - return doInvoke(method, args, invocationNumber - 1); + return doInvoke(project, method, args, invocationNumber - 1); } else { throw e; @@ -213,43 +240,57 @@ public class GradleApiFacadeManager { } } + @SuppressWarnings("ConstantConditions") @NotNull - private GradleApiFacade doGetFacade() throws Exception { - if (!GradleUtil.isGradleAvailable()) { + private GradleApiFacade doGetFacade(@NotNull Project project) throws Exception { + if (project.isDisposed() || !GradleUtil.isGradleAvailable(project)) { return GradleApiFacade.NULL_OBJECT; } - Pair pair = myFacade.get(); + Pair pair = myRemoteFacades.get(project.getName()); if (pair != null) { - if (isValid(pair)) { + if (isValid(pair, project)) { return pair.first; } mySupport.stopAll(true); - myFacade.compareAndSet(pair, null); + myFacadeWrappers.clear(); + myRemoteFacades.clear(); + final Pair p = myRemoteFacades.putIfAbsent(project.getName(), NULL_VALUE); + if (p != null && p != NULL_VALUE) { + return p.first; + } } - final GradleApiFacade facade = mySupport.acquire(this, ""); + final GradleApiFacade facade = mySupport.acquire(this, project.getName()); if (facade == null) { - throw new IllegalStateException("Can't obtain facade to working with gradle api at the remote process"); + throw new IllegalStateException("Can't obtain facade to working with gradle api at the remote process. Project: " + project); } + Disposer.register(project, new Disposable() { + @Override + public void dispose() { + mySupport.stopAll(true); + myFacadeWrappers.clear(); + myRemoteFacades.clear(); + } + }); final GradleApiFacade result = new GradleApiFacadeWrapper(facade, myProgressManager); Pair newPair - = new Pair(result, getRemoteSettings()); - if (!myFacade.compareAndSet(null, newPair)) { - GradleLog.LOG.warn("Detected unexpected duplicate tooling api facade instance creation"); - return myFacade.get().first; + = new Pair(result, getRemoteSettings(project)); + if (myRemoteFacades.putIfAbsent(project.getName(), newPair) != null && !myRemoteFacades.replace(project.getName(), NULL_VALUE, newPair)) { + GradleLog.LOG.warn("Detected unexpected duplicate tooling api facade instance creation. Project: " + project); + return myRemoteFacades.get(project.getName()).first; } if (!StringUtil.isEmpty(newPair.second.getJavaHome())) { GradleLog.LOG.info("Instructing gradle to use java from " + newPair.second.getJavaHome()); } result.applySettings(newPair.second); - RemoteGradleProgressNotificationManager exported = myExportedProgressManager.get(); + RemoteGradleProgressNotificationManager exported = myRemoteNotificationManagers.get(project.getName()); if (exported == null) { try { exported = (RemoteGradleProgressNotificationManager)UnicastRemoteObject.exportObject(myProgressManager, 0); - myExportedProgressManager.set(exported); + myRemoteNotificationManagers.putIfAbsent(project.getName(), exported); } catch (RemoteException e) { - exported = myExportedProgressManager.get(); + exported = myRemoteNotificationManagers.get(project.getName()); } } if (exported == null) { @@ -261,7 +302,11 @@ public class GradleApiFacadeManager { return result; } - private boolean isValid(@NotNull Pair pair) { + private boolean isValid(@NotNull Pair pair, @Nullable Project project) { + if (pair == NULL_VALUE) { + return false; + } + // Check remote process is alive. try { pair.first.getResolver(); @@ -272,8 +317,8 @@ public class GradleApiFacadeManager { // Check that significant settings are not changed RemoteGradleProcessSettings oldSettings = pair.second; - RemoteGradleProcessSettings currentSettings = getRemoteSettings(); - + RemoteGradleProcessSettings currentSettings = getRemoteSettings(project); + // We restart the slave process because there is a possible case that it was started with the incorrect classpath. // For example, it could be started with gradle milestone-3 and that means that its classpath doesn't contain BasicIdeaProject.class. // So, even if the user defines gradle milestone-7 to use, the slave process still is unable to operate because its classpath @@ -285,8 +330,8 @@ public class GradleApiFacadeManager { } @NotNull - private RemoteGradleProcessSettings getRemoteSettings() { - File gradleHome = myGradleLibraryManager.getGradleHome(); + private RemoteGradleProcessSettings getRemoteSettings(@Nullable Project project) { + File gradleHome = myGradleLibraryManager.getGradleHome(project); RemoteGradleProcessSettings result = new RemoteGradleProcessSettings(gradleHome.getAbsolutePath()); String ttlAsString = System.getProperty(REMOTE_PROCESS_TTL_IN_MS_KEY); if (ttlAsString != null) { @@ -304,9 +349,16 @@ public class GradleApiFacadeManager { } private class MyHandler implements InvocationHandler { + + @NotNull private final String myProjectName; + + MyHandler(@NotNull Project project) { + myProjectName = project.getName(); + } + @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - return doInvoke(method, args, REMOTE_FAIL_RECOVERY_ATTEMPTS_NUMBER); + return doInvoke(findProjectByName(myProjectName), method, args, REMOTE_FAIL_RECOVERY_ATTEMPTS_NUMBER); } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/task/AbstractGradleTask.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/task/AbstractGradleTask.java index 535ab6660ea1..0d848c744f29 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/task/AbstractGradleTask.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/task/AbstractGradleTask.java @@ -3,7 +3,9 @@ package org.jetbrains.plugins.gradle.task; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManager; import org.jetbrains.plugins.gradle.notification.GradleTaskNotificationEvent; import org.jetbrains.plugins.gradle.notification.GradleTaskNotificationListener; @@ -28,9 +30,11 @@ public abstract class AbstractGradleTask implements GradleTask { private final AtomicReference myState = new AtomicReference(GradleTaskState.NOT_STARTED); private final AtomicReference myError = new AtomicReference(); - private final GradleTaskId myId; + @Nullable transient private final Project myIntellijProject; + @NotNull private final GradleTaskId myId; - protected AbstractGradleTask(@NotNull GradleTaskType type) { + protected AbstractGradleTask(Project project, @NotNull GradleTaskType type) { + myIntellijProject = project; myId = GradleTaskId.create(type); } @@ -53,13 +57,18 @@ public abstract class AbstractGradleTask implements GradleTask { return myError.get(); } + @Nullable + public Project getIntellijProject() { + return myIntellijProject; + } + public void refreshState() { if (getState() != GradleTaskState.IN_PROGRESS) { return; } final GradleApiFacadeManager manager = ServiceManager.getService(GradleApiFacadeManager.class); try { - final GradleApiFacade facade = manager.getFacade(); + final GradleApiFacade facade = manager.getFacade(myIntellijProject); setState(facade.isTaskInProgress(getId()) ? GradleTaskState.IN_PROGRESS : GradleTaskState.FAILED); } catch (Throwable e) { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/task/GradleResolveProjectTask.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/task/GradleResolveProjectTask.java index 8cc02d6d86fa..476ed753861d 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/task/GradleResolveProjectTask.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/task/GradleResolveProjectTask.java @@ -21,20 +21,19 @@ public class GradleResolveProjectTask extends AbstractGradleTask { private final AtomicReference myGradleProject = new AtomicReference(); - private final Project myIntellijProject; + private final String myProjectPath; private final boolean myResolveLibraries; public GradleResolveProjectTask(@Nullable Project project, @NotNull String projectPath, boolean resolveLibraries) { - super(GradleTaskType.RESOLVE_PROJECT); - myIntellijProject = project; + super(project, GradleTaskType.RESOLVE_PROJECT); myProjectPath = projectPath; myResolveLibraries = resolveLibraries; } protected void doExecute() throws Exception { final GradleApiFacadeManager manager = ServiceManager.getService(GradleApiFacadeManager.class); - GradleProjectResolver resolver = manager.getFacade().getResolver(); + GradleProjectResolver resolver = manager.getFacade(getIntellijProject()).getResolver(); setState(GradleTaskState.IN_PROGRESS); final GradleProject project = resolver.resolveProjectInfo(getId(), myProjectPath, myResolveLibraries); if (project == null) { @@ -42,10 +41,11 @@ public class GradleResolveProjectTask extends AbstractGradleTask { } myGradleProject.set(project); setState(GradleTaskState.FINISHED); - if (myIntellijProject == null || myIntellijProject.isDisposed()) { + final Project intellijProject = getIntellijProject(); + if (intellijProject == null || intellijProject.isDisposed()) { return; } - final GradleProjectStructureChangesModel model = myIntellijProject.getComponent(GradleProjectStructureChangesModel.class); + final GradleProjectStructureChangesModel model = intellijProject.getComponent(GradleProjectStructureChangesModel.class); if (model != null) { // This task may be called during the 'import from gradle' processing, hence, no project-level IoC is up. // Model update is necessary for the correct tool window project structure diff showing but we don't have @@ -55,7 +55,7 @@ public class GradleResolveProjectTask extends AbstractGradleTask { } @Nullable - public GradleProject getProject() { + public GradleProject getGradleProject() { return myGradleProject.get(); } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/task/GradleTaskManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/task/GradleTaskManager.java index 86ae3f72762d..ba0199f94ce0 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/task/GradleTaskManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/task/GradleTaskManager.java @@ -1,5 +1,7 @@ package org.jetbrains.plugins.gradle.task; +import com.intellij.openapi.components.AbstractProjectComponent; +import com.intellij.openapi.project.Project; import com.intellij.util.Alarm; import com.intellij.util.containers.ConcurrentHashMap; import org.jetbrains.annotations.NotNull; @@ -23,7 +25,7 @@ import java.util.concurrent.TimeUnit; * @author Denis Zhdanov * @since 2/8/12 1:52 PM */ -public class GradleTaskManager implements GradleTaskNotificationListener { +public class GradleTaskManager extends AbstractProjectComponent implements GradleTaskNotificationListener { /** * We receive information about the tasks being enqueued to the slave gradle projects here. However, there is a possible @@ -46,7 +48,11 @@ public class GradleTaskManager implements GradleTaskNotificationListener { @NotNull private final GradleApiFacadeManager myFacadeManager; - public GradleTaskManager(@NotNull GradleApiFacadeManager facadeManager, @NotNull GradleProgressNotificationManager notificationManager) { + public GradleTaskManager(@NotNull Project project, + @NotNull GradleApiFacadeManager facadeManager, + @NotNull GradleProgressNotificationManager notificationManager) + { + super(project); myFacadeManager = facadeManager; notificationManager.addNotificationListener(this); myAlarm.addRequest(new Runnable() { @@ -106,7 +112,7 @@ public class GradleTaskManager implements GradleTaskNotificationListener { public void update() { try { - final Map> currentState = myFacadeManager.getFacade().getTasksInProgress(); + final Map> currentState = myFacadeManager.getFacade(myProject).getTasksInProgress(); myTasksInProgress.clear(); for (Set ids : currentState.values()) { for (GradleTaskId id : ids) { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java index 864978764d17..b07a24120186 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java @@ -44,15 +44,6 @@ public class GradleLibraryManager { GRADLE_ENV_PROPERTY_NAME = System.getProperty("gradle.home.env.key", "GRADLE_HOME"); } - @Nullable - public Collection getAllLibraries() { - final Project[] projects = ProjectManager.getInstance().getOpenProjects(); - if (projects.length == 1) { - return getAllLibraries(projects[0]); - } - return getAllLibraries(null); - } - /** * Allows to get file handles for the gradle binaries to use. * diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java index 0f346153bb13..892958e6fd22 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java @@ -208,7 +208,7 @@ public class GradleUtil { public void execute(@NotNull ProgressIndicator indicator) { GradleResolveProjectTask task = new GradleResolveProjectTask(project, gradleProjectPath, resolveLibraries); task.execute(indicator); - gradleProject.set(task.getProject()); + gradleProject.set(task.getGradleProject()); final Throwable error = task.getError(); if (error == null) { return; From c45d56b47137505ff9069e6dbf3cd23316c0a1be Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Mon, 26 Mar 2012 11:46:21 +0400 Subject: [PATCH 54/58] Fix incorrect test. --- .../idea/maven/dom/MavenPropertyResolver.java | 11 +++++++++-- .../idea/maven/dom/MavenPropertyResolverTest.java | 8 ++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java index 8fd863215ef6..fe4b96434501 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java @@ -216,10 +216,17 @@ public class MavenPropertyResolver { MavenId parentId = selectedProject.getParentId(); if (parentId == null) return null; + unprefixed = unprefixed.substring("parent.".length()); + + if (unprefixed.equals("groupId")) { + return parentId.getGroupId(); + } + if (unprefixed.equals("artifactId")) { + return parentId.getArtifactId(); + } + selectedProject = projectsManager.findProject(parentId); if (selectedProject == null) return null; - - unprefixed = unprefixed.substring("parent.".length()); } if (unprefixed.equals("basedir") || (hasPrefix && mavenProject == selectedProject && unprefixed.equals("baseUri"))) { diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenPropertyResolverTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenPropertyResolverTest.java index 378866fdd985..e9d469bc0f17 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenPropertyResolverTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenPropertyResolverTest.java @@ -123,10 +123,10 @@ public class MavenPropertyResolverTest extends MavenImportingTestCase { assertEquals("parent.value", resolve("${parentProp}", f)); assertEquals("module.value", resolve("${moduleProp}", f)); - assertEquals("parent.value", resolve("${project.parentProp}", f)); - assertEquals("parent.value", resolve("${pom.parentProp}", f)); - assertEquals("module.value", resolve("${project.moduleProp}", f)); - assertEquals("module.value", resolve("${pom.moduleProp}", f)); + assertEquals("${project.parentProp}", resolve("${project.parentProp}", f)); + assertEquals("${pom.parentProp}", resolve("${pom.parentProp}", f)); + assertEquals("${project.moduleProp}", resolve("${project.moduleProp}", f)); + assertEquals("${pom.moduleProp}", resolve("${pom.moduleProp}", f)); } public void testProjectPropertiesRecursively() throws Exception { From d3e15d42308c88ebd50c99ea7b3f470bfc625d5b Mon Sep 17 00:00:00 2001 From: Nikolay Matveev Date: Mon, 26 Mar 2012 12:29:09 +0400 Subject: [PATCH 55/58] IDEA-83313 Custom file templates EAP PS-114.158 (cherry picked from commit 536e453) --- .../ide/fileTemplates/FileTemplateUtil.java | 9 ++++++++- .../actions/CreateFromTemplateAction.java | 6 +++--- .../fileTemplates/impl/FileTemplateTabAsList.java | 6 +++--- .../ide/fileTemplates/ui/SelectTemplateDialog.java | 14 ++++++++++++-- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateUtil.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateUtil.java index 0d0ec3f10408..747312d7ee40 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateUtil.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; @@ -55,6 +56,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.io.*; import java.util.*; @@ -351,4 +353,9 @@ public class FileTemplateUtil{ CreateFromTemplateHandler handler = findHandler(template); return handler.canCreate(dirs); } + + @Nullable + public static Icon getIcon(@NotNull FileTemplate fileTemplate) { + return FileTypeManager.getInstance().getFileTypeByExtension(fileTemplate.getExtension()).getIcon(); + } } diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/actions/CreateFromTemplateAction.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/actions/CreateFromTemplateAction.java index c3108ade53d3..6f02e0f73e20 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/actions/CreateFromTemplateAction.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/actions/CreateFromTemplateAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ package com.intellij.ide.fileTemplates.actions; import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateUtil; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; -import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDirectory; import org.jetbrains.annotations.Nullable; @@ -30,7 +30,7 @@ public class CreateFromTemplateAction extends CreateFromTemplateActionBase { private final FileTemplate myTemplate; public CreateFromTemplateAction(FileTemplate template){ - super(template.getName(), null, FileTypeManagerEx.getInstanceEx().getFileTypeByExtension(template.getExtension()).getIcon()); + super(template.getName(), null, FileTemplateUtil.getIcon(template)); myTemplate = template; } diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsList.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsList.java index c548fba03d92..0ba5720650ba 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsList.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsList.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ package com.intellij.ide.fileTemplates.impl; import com.intellij.ide.fileTemplates.FileTemplate; -import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.ide.fileTemplates.FileTemplateUtil; import com.intellij.ui.components.JBList; import org.jetbrains.annotations.NotNull; @@ -52,7 +52,7 @@ abstract class FileTemplateTabAsList extends FileTemplateTab { Icon icon = null; if (value instanceof FileTemplate) { FileTemplate template = (FileTemplate) value; - icon = FileTypeManager.getInstance().getFileTypeByExtension(template.getExtension()).getIcon(); + icon = FileTemplateUtil.getIcon(template); final boolean internalTemplate = AllFileTemplatesConfigurable.isInternalTemplate(template.getName(), getTitle()); if (internalTemplate) { setFont(getFont().deriveFont(Font.BOLD)); diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/ui/SelectTemplateDialog.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/ui/SelectTemplateDialog.java index 1ad5a2cf2b9a..c29e101e0216 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/ui/SelectTemplateDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/ui/SelectTemplateDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,11 @@ package com.intellij.ide.fileTemplates.ui; +import com.intellij.ide.IdeBundle; import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; import com.intellij.ide.fileTemplates.FileTemplateUtil; -import com.intellij.ide.IdeBundle; +import com.intellij.ide.ui.ListCellRendererWrapper; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.FixedSizeButton; @@ -80,6 +81,15 @@ public class SelectTemplateDialog extends DialogWrapper{ } if(myCbxTemplates == null){ myCbxTemplates = new JComboBox(model); + myCbxTemplates.setRenderer(new ListCellRendererWrapper(myCbxTemplates.getRenderer()) { + @Override + public void customize(JList list, FileTemplate fileTemplate, int index, boolean selected, boolean hasFocus) { + if (fileTemplate != null) { + setIcon(FileTemplateUtil.getIcon(fileTemplate)); + setText(fileTemplate.getName()); + } + } + }); } else{ Object selected = myCbxTemplates.getSelectedItem(); From 3064d7633b84387f032cc256247b4d9fd06fc313 Mon Sep 17 00:00:00 2001 From: Vassiliy Kudryashov Date: Mon, 26 Mar 2012 12:34:09 +0400 Subject: [PATCH 56/58] IDEA-66794 Help Topics window opens behind main IDEA frame with certain conditions (cherry picked from commit 9bad095) --- .../intellij/help/impl/IdeaHelpBroker.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/help/impl/IdeaHelpBroker.java b/platform/platform-impl/src/com/intellij/help/impl/IdeaHelpBroker.java index a7555f94361f..5df8dd779802 100644 --- a/platform/platform-impl/src/com/intellij/help/impl/IdeaHelpBroker.java +++ b/platform/platform-impl/src/com/intellij/help/impl/IdeaHelpBroker.java @@ -15,7 +15,10 @@ */ package com.intellij.help.impl; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.openapi.wm.impl.IdeFocusManagerHeadless; import com.intellij.ui.AppUIUtil; +import com.intellij.util.Alarm; import org.jetbrains.annotations.NotNull; import javax.help.*; @@ -207,6 +210,9 @@ class IdeaHelpBroker extends DefaultHelpBroker implements KeyListener{ //myFrame.setLocationRelativeTo(null); myFrame.setVisible(visible); myFrame.setState(JFrame.NORMAL); + IdeFocusManager focusManager = IdeFocusManager.findInstance(); + JComponent target = focusManager.getFocusTargetFor(myFrame.getRootPane()); + focusManager.requestFocus(target != null ? target : myFrame, true); } } @@ -671,8 +677,9 @@ class IdeaHelpBroker extends DefaultHelpBroker implements KeyListener{ if(myDialog.isShowing()){ myDialog.hide(); } - if(myOwnerWindow!=null) + if (myOwnerWindow != null) { myOwnerWindow.removeWindowListener(dl); + } myOwnerWindow=null; modalDeactivated=true; } @@ -694,22 +701,24 @@ class IdeaHelpBroker extends DefaultHelpBroker implements KeyListener{ } } } else{ - if(myFrame==null){ - myFrame=new JFrame(helpTitle); + if (myFrame == null) { + myFrame = new JFrame(helpTitle); resize = true; AppUIUtil.updateFrameIcon(myFrame); - WindowListener l=new WindowAdapter(){ - public void windowClosing(WindowEvent e){ + WindowListener l = new WindowAdapter() { + public void windowClosing(WindowEvent e) { myFrame.setVisible(false); } - public void windowClosed(WindowEvent e){ + public void windowClosed(WindowEvent e) { myFrame.setVisible(false); } }; myFrame.addWindowListener(l); - } else + } + else { pos = myFrame.getLocation(); + } if(myDialog!=null){ pos=myDialog.getLocation(); size=myDialog.getSize(); From 34aadafeb8c785980c29229c6ae12e44e244b199 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Mon, 26 Mar 2012 13:22:03 +0400 Subject: [PATCH 57/58] IDEA-83394 Gradle: project refresh does nothing after removing Gradle home from Template Project Settings Fix memory leak --- .../plugins/gradle/task/GradleTaskManager.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/task/GradleTaskManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/task/GradleTaskManager.java index ba0199f94ce0..9f4acf10fec4 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/task/GradleTaskManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/task/GradleTaskManager.java @@ -1,5 +1,6 @@ package org.jetbrains.plugins.gradle.task; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.AbstractProjectComponent; import com.intellij.openapi.project.Project; import com.intellij.util.Alarm; @@ -47,6 +48,7 @@ public class GradleTaskManager extends AbstractProjectComponent implements Gradl @NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); @NotNull private final GradleApiFacadeManager myFacadeManager; + @NotNull private final GradleProgressNotificationManager myProgressNotificationManager; public GradleTaskManager(@NotNull Project project, @NotNull GradleApiFacadeManager facadeManager, @@ -54,6 +56,11 @@ public class GradleTaskManager extends AbstractProjectComponent implements Gradl { super(project); myFacadeManager = facadeManager; + myProgressNotificationManager = notificationManager; + if (ApplicationManager.getApplication().isUnitTestMode()) { + return; + } + notificationManager.addNotificationListener(this); myAlarm.addRequest(new Runnable() { @Override @@ -73,7 +80,12 @@ public class GradleTaskManager extends AbstractProjectComponent implements Gradl } }, DETECT_HANGED_TASKS_FREQUENCY_MILLIS); } - + + @Override + public void disposeComponent() { + myProgressNotificationManager.removeNotificationListener(this); + } + /** * Allows to check if any task of the given type is being executed at the moment. * From c8cbc19ebdc191354962dbe1ad63530718b0624c Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Mon, 26 Mar 2012 13:33:44 +0400 Subject: [PATCH 58/58] IDEA-83405 Cannot understand, when Copy reference should be available on the context menu of the Groovy Shell --- .../codeInsight/TargetElementUtilBase.java | 22 ++++++++++++++++--- .../ide/actions/CopyReferenceAction.java | 5 +++-- .../editor/event/EditorMouseListener.java | 6 ++++- .../editor/actions/EditorActionUtil.java | 16 ++++++++++++++ .../openapi/editor/impl/EditorImpl.java | 5 +++++ 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtilBase.java b/platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtilBase.java index 0d5a094c5e71..cd9ada8bbbae 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtilBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtilBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actions.EditorActionUtil; import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; @@ -82,7 +83,14 @@ public class TargetElementUtilBase { @Nullable public static PsiReference findReference(Editor editor) { - return findReference(editor, editor.getCaretModel().getOffset()); + PsiReference result = findReference(editor, editor.getCaretModel().getOffset()); + if (result == null) { + final Integer offset = editor.getUserData(EditorActionUtil.EXPECTED_CARET_OFFSET); + if (offset != null) { + result = findReference(editor, offset); + } + } + return result; } @Nullable @@ -124,7 +132,15 @@ public class TargetElementUtilBase { public static PsiElement findTargetElement(Editor editor, int flags) { ApplicationManager.getApplication().assertIsDispatchThread(); - return getInstance().findTargetElement(editor, flags, editor.getCaretModel().getOffset()); + final PsiElement result = getInstance().findTargetElement(editor, flags, editor.getCaretModel().getOffset()); + if (result != null) { + return result; + } + final Integer offset = editor.getUserData(EditorActionUtil.EXPECTED_CARET_OFFSET); + if (offset != null) { + return getInstance().findTargetElement(editor, flags, offset); + } + return result; } public static boolean inVirtualSpace(Editor editor, int offset) { diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java index 72e144cffe77..9627f6444924 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import com.intellij.ide.IdeBundle; import com.intellij.ide.dnd.FileCopyPasteUtil; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actions.EditorActionUtil; import com.intellij.openapi.editor.colors.EditorColors; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.markup.TextAttributes; @@ -109,7 +110,7 @@ public class CopyReferenceAction extends AnAction { private static PsiElement getElementToCopy(final Editor editor, final DataContext dataContext) { PsiElement element = null; if (editor != null) { - PsiReference reference = TargetElementUtilBase.findReference(editor, editor.getCaretModel().getOffset()); + PsiReference reference = TargetElementUtilBase.findReference(editor); if (reference != null) { element = reference.getElement(); } diff --git a/platform/platform-api/src/com/intellij/openapi/editor/event/EditorMouseListener.java b/platform/platform-api/src/com/intellij/openapi/editor/event/EditorMouseListener.java index 7aa1d8f8dc78..0e0eba4c0d87 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/event/EditorMouseListener.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/event/EditorMouseListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,8 +25,12 @@ import java.util.EventListener; * @see EditorMouseMotionListener */ public interface EditorMouseListener extends EventListener { + /** * Called when a mouse button is pressed over the editor. + *

+ * Note: this callback is assumed to be at the very start of 'mouse press' processing, i.e. common actions + * like 'caret position change', 'selection change' etc implied by the 'mouse press' have not been performed yet. * * @param e the event containing information about the mouse press. */ diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java index 04582bc98034..7371f18b4a69 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java @@ -33,6 +33,7 @@ import com.intellij.openapi.actionSystem.ActionPopupMenu; import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.event.EditorMouseEvent; import com.intellij.openapi.editor.event.EditorMouseEventArea; +import com.intellij.openapi.editor.event.EditorMouseListener; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.editor.impl.EditorImpl; @@ -49,6 +50,21 @@ import java.awt.event.MouseEvent; import java.util.List; public class EditorActionUtil { + + /** + * Editor actions may be invoked multiple ways - programmatically, via keyboard/mouse shortcut, main/context menu etc. + * Action processing may also interfere with standard editor behavior (caret position change, selection change etc). + *

+ * E.g. consider a situation when context menu is shown on right mouse click - + * {@link EditorMouseListener#mousePressed(EditorMouseEvent) the contract says} that no common actions have been performed yet. + * However, some actions may operate on an 'active element' (an element under caret), hence, they would incorrectly because the + * caret position has not been changed yet. + *

+ * We address that problem by providing a special key that is intended to hold 'expected caret offset', i.e. offset where we + * expect the caret to be located at the near future. + */ + public static final Key EXPECTED_CARET_OFFSET = Key.create("expectedEditorOffset"); + protected static final Object EDIT_COMMAND_GROUP = Key.create("EditGroup"); public static final Object DELETE_COMMAND_GROUP = Key.create("DeleteGroup"); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index b44e8d539581..9179a8ce4f7d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -41,6 +41,7 @@ import com.intellij.openapi.command.UndoConfirmationPolicy; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.actionSystem.*; +import com.intellij.openapi.editor.actions.EditorActionUtil; import com.intellij.openapi.editor.colors.*; import com.intellij.openapi.editor.colors.impl.DelegateColorScheme; import com.intellij.openapi.editor.event.*; @@ -5078,6 +5079,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi TooltipController.getInstance().cancelTooltip(FOLDING_TOOLTIP_GROUP, e, true); } private void runMousePressedCommand(@NotNull final MouseEvent e) { + + final int clickOffset = logicalPositionToOffset(xyToLogicalPosition(e.getPoint())); + putUserData(EditorActionUtil.EXPECTED_CARET_OFFSET, clickOffset); + mySelectionTweaked = false; myMousePressedEvent = e; EditorMouseEvent event = new EditorMouseEvent(EditorImpl.this, e, getMouseEventArea(e));