From 5ea19b499e764c9233b1dfe631b24f5e2383646a Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Fri, 22 Nov 2013 14:12:49 +0400 Subject: [PATCH 01/91] IDEA-116862 Added Maven Dependency (via Quick Fix) added with incorrect scope --- .../idea/maven/dom/intentions/AddMavenDependencyQuickFix.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/intentions/AddMavenDependencyQuickFix.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/intentions/AddMavenDependencyQuickFix.java index a7e2e5acd4c2..773829819cf7 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/intentions/AddMavenDependencyQuickFix.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/intentions/AddMavenDependencyQuickFix.java @@ -90,7 +90,7 @@ public class AddMavenDependencyQuickFix implements IntentionAction, LowPriorityA VirtualFile virtualFile = file.getOriginalFile().getVirtualFile(); if (virtualFile != null) { - isTestSource = ProjectRootManager.getInstance(project).getFileIndex().isInSourceContent(virtualFile); + isTestSource = ProjectRootManager.getInstance(project).getFileIndex().isInTestSourceContent(virtualFile); } for (MavenId each : ids) { From 8b7f449c1eed730377c2edf25ff98b78a53d0c8d Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Fri, 22 Nov 2013 14:12:21 +0400 Subject: [PATCH 02/91] IDEA-116318 Mercurial Log: on very first context menu invocation NewBranch etc actions are available *your action templatePresentation should not be modified in update action, use e.getPresentation() modification instead --- .../src/git4idea/actions/GitLogSingleCommitAction.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/git4idea/src/git4idea/actions/GitLogSingleCommitAction.java b/plugins/git4idea/src/git4idea/actions/GitLogSingleCommitAction.java index 0ec2ab63e877..16f5a41fb2ce 100644 --- a/plugins/git4idea/src/git4idea/actions/GitLogSingleCommitAction.java +++ b/plugins/git4idea/src/git4idea/actions/GitLogSingleCommitAction.java @@ -67,8 +67,8 @@ public abstract class GitLogSingleCommitAction extends DumbAwareAction { public void update(AnActionEvent e) { Data data = Data.collect(e); boolean enabled = data.isValid() && data.log.getSelectedCommits().size() == 1; - getTemplatePresentation().setVisible(data.isValid()); - getTemplatePresentation().setEnabled(enabled); + e.getPresentation().setVisible(data.isValid()); + e.getPresentation().setEnabled(enabled); } private static class Data { From 3b019b5efae1938ea2a7bee1824b481378ae6efb Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 21 Nov 2013 22:11:27 +0100 Subject: [PATCH 03/91] registry cleanup --- platform/platform-resources-en/src/misc/registry.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index ce1cc8bf1d74..26d1936f2401 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -189,13 +189,12 @@ compiler.automake.trigger.delay.description=Delay in milliseconds before trigger compiler.document.save.trigger.delay=1500 # suppress inspection "UnusedProperty" -compiler.document.save.trigger.delay.description=Delay in milliseconds before triggering save of unchenged documents in response to document changed events +compiler.document.save.trigger.delay.description=Delay in milliseconds before triggering save in response to document changes vcs.show.colored.annotations=true vcs.showConsole=true psi.incremental.reparse.depth.limit=1000 -psi.viewer.selection.color=0,153,153 psi.deferIconLoading=true find.search.in.project.files=false From 5bd841b2ba881c90f6df96d8a1aafec1f81bf9b0 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Fri, 22 Nov 2013 14:33:51 +0400 Subject: [PATCH 04/91] IDEA-111702 Java Rearranger illegal forward reference on fields rearrangement [CR-IC-3034] --- .../psi/formatter/java/AbstractJavaBlock.java | 12 +- .../psi/formatter/java/JavaFormatterUtil.java | 51 ++++---- .../java/JavaSpacePropertyProcessor.java | 2 +- .../java/ParametersAlignment_after.java | 3 +- .../java/JavaFormatterIndentationTest.java | 115 +++++++++++++++--- .../formatter/java/JavaFormatterWrapTest.java | 3 +- 6 files changed, 132 insertions(+), 54 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java index d392d7a7a481..8855474a098d 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java @@ -1178,7 +1178,6 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo } private boolean shouldEnforceIndentToChildren(@NotNull ASTNode node) { - // Filter only anonymous class instances as method call arguments if (myNode.getElementType() != JavaElementType.EXPRESSION_LIST) { return false; } @@ -1186,13 +1185,10 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo if (parent == null || parent.getElementType() != JavaElementType.METHOD_CALL_EXPRESSION) { return false; } - if (!isAnonymousClass(node) || !JavaFormatterUtil.hasAnonymousClassesArguments((PsiExpressionList)myNode.getPsi(), 2)) { - return false; - } - - // Enforce indent only if anonymous class instance expression doesn't start new line and have anonymous class expression sibling. - ASTNode prev = node.getTreePrev(); - return prev != null && !(StringUtil.containsLineBreak(prev.getChars()) && prev.getElementType() != TokenType.WHITE_SPACE); + + PsiExpressionList methodParamsList = (PsiExpressionList)myNode.getPsi(); + return JavaFormatterUtil.hasMultilineArguments(methodParamsList) + && JavaFormatterUtil.isMultilineExceptArguments(methodParamsList); } private static boolean isAnonymousClass(@Nullable ASTNode node) { diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaFormatterUtil.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaFormatterUtil.java index 2f6c7f9b6a54..3f63eda2fb11 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaFormatterUtil.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaFormatterUtil.java @@ -19,10 +19,10 @@ import com.intellij.lang.ASTNode; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiExpressionList; import com.intellij.psi.PsiPolyadicExpression; +import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.HashSet; import java.util.Set; @@ -75,35 +75,36 @@ public class JavaFormatterUtil { return expression1.getOperationTokenType() == expression2.getOperationTokenType(); } - /** - * Allows to check if given expression list has given number of anonymous classes. - * - * @param count interested number of anonymous classes used at the given expression list - * @return true if given expression list contains given number of anonymous classes; - * false otherwise - */ - public static boolean hasAnonymousClassesArguments(@NotNull PsiExpressionList expressionList, int count) { - int found = 0; - for (PsiExpression expression : expressionList.getExpressions()) { - ASTNode node = expression.getNode(); - if (isAnonymousClass(node)) { - found++; - } - if (found >= count) { + + public static boolean hasMultilineArguments(@NotNull PsiExpressionList list) { + PsiExpression[] arguments = list.getExpressions(); + + for (PsiExpression argument: arguments) { + ASTNode node = argument.getNode(); + if (node.textContains('\n')) return true; - } } + return false; } - private static boolean isAnonymousClass(@Nullable final ASTNode node) { - if (node == null) { - return false; + public static boolean isMultilineExceptArguments(@NotNull PsiExpressionList list) { + PsiExpression[] arguments = list.getExpressions(); + + for (PsiExpression argument : arguments) { + ASTNode beforeArgument = argument.getNode().getTreePrev(); + if (isWhiteSpaceWithLineFeed(beforeArgument)) + return true; } - ASTNode nodeToCheck = node; - if (node.getElementType() == JavaElementType.NEW_EXPRESSION) { - nodeToCheck = node.getLastChildNode(); - } - return nodeToCheck != null && nodeToCheck.getElementType() == JavaElementType.ANONYMOUS_CLASS; + + PsiExpression lastArgument = arguments[arguments.length - 1]; + ASTNode afterLastArgument = lastArgument.getNode().getTreeNext(); + return isWhiteSpaceWithLineFeed(afterLastArgument); } + + private static boolean isWhiteSpaceWithLineFeed(@NotNull ASTNode node) { + return node instanceof PsiWhiteSpace + && node.textContains('\n'); + } + } diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java index 8f090b072d16..1dfe426c28ec 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java @@ -1135,7 +1135,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor { createParenthSpace(mySettings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE, mySettings.SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES); } else if (myRole2 == ChildRole.RPARENTH) { - if (JavaFormatterUtil.hasAnonymousClassesArguments(list, 2)) { + if (JavaFormatterUtil.hasMultilineArguments(list) && JavaFormatterUtil.isMultilineExceptArguments(list)) { myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, 0); } else { diff --git a/java/java-tests/testData/psi/formatter/java/ParametersAlignment_after.java b/java/java-tests/testData/psi/formatter/java/ParametersAlignment_after.java index 0e0dee8f9cf8..cf135bfa6837 100644 --- a/java/java-tests/testData/psi/formatter/java/ParametersAlignment_after.java +++ b/java/java-tests/testData/psi/formatter/java/ParametersAlignment_after.java @@ -7,6 +7,7 @@ class Foo { settings, indentOptions, child2.getTextRange(), - false); + false + ); } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java index b34720759c8a..ec41ee6842ff 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java @@ -340,10 +340,11 @@ public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest { "});", "foo(1,\n" + " 2, new Runnable() {\n" + - " @Override\n" + - " public void run() {\n" + - " }\n" + - "});" + " @Override\n" + + " public void run() {\n" + + " }\n" + + " }\n" + + ");" ); doMethodTest( @@ -446,16 +447,95 @@ public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest { " }\n" + " });", "foo(new Runnable() {\n" + - " public void run() {\n" + - " }\n" + - " }, new Runnable() {\n" + - " public void run() {\n" + - " }\n" + + " public void run() {\n" + " }\n" + - ");" + "}, new Runnable() {\n" + + " public void run() {\n" + + " }\n" + + "});" ); } - + + public void testAlignMultipleAnonymousClasses_PassedAsMethodParameters() throws Exception { + String text = "test(new Runnable() {\n" + + " @Override\n" + + " public void run() {\n" + + " System.out.println(\"AAA!\");\n" + + " }\n" + + "}, new Runnable() {\n" + + " @Override\n" + + " public void run() {\n" + + " System.out.println(\"BBB!\");\n" + + " }\n" + + "});\n"; + doMethodTest(text, text); + } + + public void testAlignmentAdditionalParamsWithMultipleAnonymousClasses_PassedAsMethodParameters() throws Exception { + String text = "foo(1221, new Runnable() {\n" + + " @Override\n" + + " public void run() {\n" + + " System.out.println(\"A\");\n" + + " }\n" + + "}, new Runnable() {\n" + + " @Override\n" + + " public void run() {\n" + + " System.out.println(\"BB\");\n" + + " }\n" + + "});"; + doMethodTest(text, text); + } + + public void testAlignmentMultipleParamsWithAnonymousClass_PassedAsMethodParams() throws Exception { + getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + String text = "test(1000,\n" + + " new Runnable() {\n" + + " @Override\n" + + " public void run() {\n" + + " System.out.println(\"BBB\");\n" + + " }\n" + + " }\n" + + ");"; + doMethodTest(text, text); + } + + public void testAlignmentMultipleAnonymousClassesOnNewLines() throws Exception { + getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + String text = "test(1000,\n" + + " new Runnable() {\n" + + " @Override\n" + + " public void run() {\n" + + " System.out.println(\"BBB\");\n" + + " }\n" + + " },\n" + + " new Runnable() {\n" + + " @Override\n" + + " public void run() {\n" + + " System.out.println(\"BBB\");\n" + + " }\n" + + " }\n" + + ");"; + doMethodTest(text, text); + } + + public void testEnforceChildrenIndent_OfAnonymousClasses_IfAnyOfParamsIsLocatedOnNewLine() throws Exception { + getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + String text = "test(\"Suuuuuuuuuuuuuuuuuper loooooooooooong string\",\n" + + " \"Next loooooooooooooooooooooong striiiiiiiiiiing\", new Runnable() {\n" + + " @Override\n" + + " public void run() {\n" + + "\n" + + " }\n" + + " }, new Runnable() {\n" + + " @Override\n" + + " public void run() {\n" + + "\n" + + " }\n" + + " }\n" + + ");\n"; + doMethodTest(text, text); + } + public void testPackagePrivateAnnotation() { // Inspired by IDEA-67294 @@ -480,13 +560,12 @@ public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest { " }\n" + " }, )", "test(new Runnable() {\n" + - " public void run() {\n" + - " }\n" + - " }, new Runnable() {\n" + - " public void run() {\n" + - " }\n" + - " },\n" + - ")" + " public void run() {\n" + + " }\n" + + "}, new Runnable() {\n" + + " public void run() {\n" + + " }\n" + + "}, )" ); } diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterWrapTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterWrapTest.java index c867bf141e68..c5853deddbec 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterWrapTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterWrapTest.java @@ -325,7 +325,8 @@ public class JavaFormatterWrapTest extends AbstractJavaFormatterTest { "test(1,\n" + " 2,\n" + " Test.\n" + - " loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongMethod());\n" + + " loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongMethod()\n" + + ");\n" + "int i = 1;\n" + "int j = 2;"; doMethodTest(text, text); From 810199ff2800a9204071071e0698fa3d9380a899 Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Fri, 22 Nov 2013 14:38:14 +0400 Subject: [PATCH 05/91] IDEA-116824 Gradle: Provide an inspection & quickfix for multiple custom maven repo links --- .../MultipleRepositoryUrls.html | 6 + plugins/gradle/src/META-INF/plugin.xml | 5 + .../codeInspection/GradleBaseInspection.java | 31 +++++ .../GradleInspectionBundle.properties | 3 +- .../MultipleRepositoryUrlsFix.java | 75 ++++++++++++ .../MultipleRepositoryUrlsInspection.java | 113 ++++++++++++++++++ 6 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 plugins/gradle/resources/inspectionDescriptions/MultipleRepositoryUrls.html create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/GradleBaseInspection.java create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/MultipleRepositoryUrlsFix.java create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/MultipleRepositoryUrlsInspection.java diff --git a/plugins/gradle/resources/inspectionDescriptions/MultipleRepositoryUrls.html b/plugins/gradle/resources/inspectionDescriptions/MultipleRepositoryUrls.html new file mode 100644 index 000000000000..f8c19bf9b4a4 --- /dev/null +++ b/plugins/gradle/resources/inspectionDescriptions/MultipleRepositoryUrls.html @@ -0,0 +1,6 @@ + + +This inspection reports usage of multiple urls per repository(maven or ivy) block. +The problem is that no more than one url will be picked up for the repo and others will be ignored. + + \ No newline at end of file diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml index 653c626c467e..93e9448c7745 100644 --- a/plugins/gradle/src/META-INF/plugin.xml +++ b/plugins/gradle/src/META-INF/plugin.xml @@ -80,6 +80,11 @@ + + diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/GradleBaseInspection.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/GradleBaseInspection.java new file mode 100644 index 000000000000..91e6756b760a --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/GradleBaseInspection.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.gradle.codeInspection; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.codeInspection.BaseInspection; + +/** + * @author Vladislav.Soroka + * @since 11/21/13 + */ +public abstract class GradleBaseInspection extends BaseInspection { + @NotNull + @Override + public String[] getGroupPath() { + return new String[]{"Gradle", getGroupDisplayName()}; + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/GradleInspectionBundle.properties b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/GradleInspectionBundle.properties index e2ef587835e1..0f2bed413857 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/GradleInspectionBundle.properties +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/GradleInspectionBundle.properties @@ -17,4 +17,5 @@ # ######################################################################################################################## group.other=Other - +multiple.repository.urls=Multiple repository urls +multiple.repository.urls.fix.name=Replace multiple repository urls with separate repository blocks diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/MultipleRepositoryUrlsFix.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/MultipleRepositoryUrlsFix.java new file mode 100644 index 000000000000..99ec0b4cdd84 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/MultipleRepositoryUrlsFix.java @@ -0,0 +1,75 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.gradle.codeInspection; + +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.codeInspection.GroovyFix; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Vladislav.Soroka + * @since 11/21/13 + */ +public class MultipleRepositoryUrlsFix extends GroovyFix { + private final GrClosableBlock myClosure; + private final String myRepoType; + + public MultipleRepositoryUrlsFix(@NotNull GrClosableBlock closure, @NotNull String repoType) { + myClosure = closure; + myRepoType = repoType; + } + + @Override + protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { + List statements = MultipleRepositoryUrlsInspection.findUrlCallExpressions(myClosure); + if (statements.size() <= 1) return; + statements.remove(0); + + List elements = new ArrayList(statements); + for (GrCallExpression statement : statements) { + PsiElement newLineCandidate = statement.getNextSibling(); + if (PsiUtil.isNewLine(newLineCandidate)) { + elements.add(newLineCandidate); + } + } + + myClosure.removeElements(elements.toArray(new PsiElement[elements.size()])); + GrClosableBlock closableBlock = PsiTreeUtil.getParentOfType(myClosure, GrClosableBlock.class); + if (closableBlock == null) return; + + GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(project); + for (GrCallExpression statement : statements) { + closableBlock.addStatementBefore(elementFactory.createStatementFromText(myRepoType + '{' + statement.getText() + '}'), null); + } + } + + @NotNull + @Override + public String getName() { + return GradleInspectionBundle.message("multiple.repository.urls.fix.name"); + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/MultipleRepositoryUrlsInspection.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/MultipleRepositoryUrlsInspection.java new file mode 100644 index 000000000000..e29d9170155c --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInspection/MultipleRepositoryUrlsInspection.java @@ -0,0 +1,113 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.gradle.codeInspection; + +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression; + +import java.util.Collections; +import java.util.List; + +/** + * @author Vladislav.Soroka + * @since 11/21/13 + */ +public class MultipleRepositoryUrlsInspection extends GradleBaseInspection { + + @NotNull + @Override + protected BaseInspectionVisitor buildVisitor() { + return new MyVisitor(); + } + + @Nls + @NotNull + @Override + public String getGroupDisplayName() { + return PROBABLE_BUGS; + } + + + @Override + protected String buildErrorString(Object... args) { + return GradleInspectionBundle.message("multiple.repository.urls", args); + } + + @Nls + @NotNull + @Override + public String getDisplayName() { + return GradleInspectionBundle.message("multiple.repository.urls"); + } + + private static class MyVisitor extends BaseInspectionVisitor { + @Override + public void visitClosure(GrClosableBlock closure) { + super.visitClosure(closure); + GrMethodCall mavenMethodCall = PsiTreeUtil.getParentOfType(closure, GrMethodCall.class); + if (mavenMethodCall == null) return; + GrExpression mavenMethodExpression = mavenMethodCall.getInvokedExpression(); + if (mavenMethodExpression == null || + !ArrayUtil.contains(mavenMethodExpression.getText(), "maven", "ivy")) { + return; + } + + GrMethodCall repositoryMethodCall = PsiTreeUtil.getParentOfType(mavenMethodCall, GrMethodCall.class); + if (repositoryMethodCall == null) return; + GrExpression repositoryMethodExpression = repositoryMethodCall.getInvokedExpression(); + if (repositoryMethodExpression == null || !repositoryMethodExpression.getText().equals("repositories")) return; + + List statements = findUrlCallExpressions(closure); + if (statements.size() > 1) { + registerError(closure); + + registerError(closure, GradleInspectionBundle.message("multiple.repository.urls"), + new LocalQuickFix[]{new MultipleRepositoryUrlsFix(closure, mavenMethodExpression.getText())}, + ProblemHighlightType.GENERIC_ERROR); + } + } + } + + @NotNull + static List findUrlCallExpressions(@NotNull GrClosableBlock closure) { + GrCallExpression[] applicationStatements = PsiTreeUtil.getChildrenOfType(closure, GrCallExpression.class); + if (applicationStatements == null) return Collections.emptyList(); + + List statements = ContainerUtil.newArrayList(); + for (GrCallExpression statement : applicationStatements) { + GrReferenceExpression[] referenceExpressions = PsiTreeUtil.getChildrenOfType(statement, GrReferenceExpression.class); + if (referenceExpressions == null) continue; + for (GrReferenceExpression expression : referenceExpressions) { + String expressionText = expression.getText(); + if ("url".equals(expressionText) || "setUrl".equals(expressionText)) { + statements.add(statement); + } + } + } + return statements; + } +} From c550498455020b4a4deee5ce8cca5d921b729a3e Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 22 Nov 2013 09:59:44 +0100 Subject: [PATCH 06/91] NPE fix (cherry picked from commit 0885584a2176553a97c5e0fdbb1b64d64bb9d06d) --- .../com/intellij/ide/ui/laf/darcula/ui/DarculaTextFieldUI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTextFieldUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTextFieldUI.java index 7fd004f45f6d..a6686fe1b9fb 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTextFieldUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTextFieldUI.java @@ -115,7 +115,7 @@ public class DarculaTextFieldUI extends BasicTextFieldUI { } protected Rectangle getDrawingRect() { - final JTextComponent c = getComponent(); + final JTextComponent c = myTextField; final JBInsets i = JBInsets.create(c.getInsets()); final int x = i.right - 4 - 16; final int y = i.top - 3; From ad7e85e2ffd0def859cd34caf0a59afc6ecc4305 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 22 Nov 2013 10:04:54 +0100 Subject: [PATCH 07/91] redesign and add checkbox (cherry picked from commit 261be382ee67cccad1c37cb22630c53eb1566149) --- .../ide/actions/SearchEverywhereAction.java | 67 ++++++++++++++++--- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java index 2c3d3b956b3c..2c39b36a70d4 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java @@ -80,6 +80,7 @@ import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBList; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.components.OnOffButton; +import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.popup.AbstractPopup; import com.intellij.ui.popup.PopupPositionManager; import com.intellij.util.*; @@ -136,6 +137,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA private Alarm myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, ApplicationManager.getApplication()); private Alarm myUpdateAlarm = new Alarm(ApplicationManager.getApplication()); private JBList myList = new JBList(myListModel); + private JCheckBox myNonProjectCheckBox = new JCheckBox(); private AnActionEvent myActionEvent; private Component myContextComponent; private CalcThread myCalcThread; @@ -311,6 +313,30 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA } } }); + + myNonProjectCheckBox.setOpaque(false); + myNonProjectCheckBox.setAlignmentX(1.0f); + myNonProjectCheckBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (showAll.get() != myNonProjectCheckBox.isSelected()) { + showAll.set(!showAll.get()); + final JTextField editor = UIUtil.findComponentOfType(myBalloon.getContent(), JTextField.class); + if (editor != null) { + final String pattern = editor.getText(); + myAlarm.cancelAllRequests(); + myAlarm.addRequest(new Runnable() { + @Override + public void run() { + if (editor.hasFocus()) { + rebuildList(pattern); + } + } + }, 30); + } + } + } + }); //noinspection SSBasedInspection SwingUtilities.invokeLater(new Runnable() { public void run() { @@ -321,13 +347,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA } private void initTooltip(JLabel label) { - final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(IdeActions.ACTION_SEARCH_EVERYWHERE); final String shortcutText; - if (shortcuts.length == 0) { - shortcutText = "Double " + (SystemInfo.isMac ? MacKeymapUtil.SHIFT : "Shift"); - } else { - shortcutText = KeymapUtil.getShortcutsText(shortcuts); - } + shortcutText = getShortcut(); label.setToolTipText("Search Everywhere
Press " + shortcutText @@ -335,6 +356,17 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA } + private static String getShortcut() { + String shortcutText; + final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(IdeActions.ACTION_SEARCH_EVERYWHERE); + if (shortcuts.length == 0) { + shortcutText = "Double " + (SystemInfo.isMac ? MacKeymapUtil.SHIFT : "Shift"); + } else { + shortcutText = KeymapUtil.getShortcutsText(shortcuts); + } + return shortcutText; + } + private void initSearchField(final MySearchTextField search) { final JTextField editor = search.getTextEditor(); // onFocusLost(); @@ -355,8 +387,14 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA } }); editor.addFocusListener(new FocusAdapter() { + boolean skip = false; + @Override public void focusGained(FocusEvent e) { + if (skip) { + skip = false; + return; + } search.setText(""); search.getTextEditor().setForeground(UIUtil.getLabelForeground()); myTitleIndexes = new TitleIndexes(); @@ -384,6 +422,11 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA && ((myList == e.getOppositeComponent()) || ((AbstractPopup)myPopup).getPopupWindow() == e.getOppositeComponent())) { return; } + if (myNonProjectCheckBox == e.getOppositeComponent()) { + skip = true; + editor.requestFocus(); + return; + } onFocusLost(); } }); @@ -535,7 +578,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA public void actionPerformed(AnActionEvent e, MouseEvent me) { if (myBalloon != null && myBalloon.isVisible()) { showAll.set(!showAll.get()); - myPopupField.getTextEditor().setBackground(showAll.get() ? new JBColor(new Color(0xffffe4), new Color(0x494539)) : UIUtil.getTextFieldBackground()); + myNonProjectCheckBox.setSelected(showAll.get()); +// myPopupField.getTextEditor().setBackground(showAll.get() ? new JBColor(new Color(0xffffe4), new Color(0x494539)) : UIUtil.getTextFieldBackground()); rebuildList(myPopupField.getText()); return; } @@ -566,15 +610,19 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA g.fillRect(0, 0, getWidth(), getHeight()); } }; - final JLabel title = new JLabel(" Search Everywhere:"); + final JLabel title = new JLabel(" Search Everywhere: "); + final JPanel topPanel = new NonOpaquePanel(new BorderLayout()); title.setForeground(new JBColor(Gray._50, Gray._180)); if (SystemInfo.isMac) { title.setFont(title.getFont().deriveFont(Font.BOLD, title.getFont().getSize() - 1f)); } else { title.setFont(title.getFont().deriveFont(Font.BOLD)); } - panel.add(title, BorderLayout.WEST); + topPanel.add(title, BorderLayout.WEST); + myNonProjectCheckBox.setText("Include non-project items (" + getShortcut() + ")"); + topPanel.add(myNonProjectCheckBox, BorderLayout.EAST); panel.add(myPopupField, BorderLayout.CENTER); + panel.add(topPanel, BorderLayout.NORTH); panel.setBorder(IdeBorderFactory.createEmptyBorder(3, 5, 4, 5)); final ComponentPopupBuilder builder = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, myPopupField.getTextEditor()); myBalloon = builder @@ -1435,6 +1483,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA myCalcThread = null; myPopup = null; showAll.set(false); + myNonProjectCheckBox.setSelected(false); ActionToolbarImpl.updateAllToolbarsImmediately(); if (myActionEvent != null && myActionEvent.getInputEvent() instanceof MouseEvent) { final Component component = myActionEvent.getInputEvent().getComponent(); From 7a0250aa6fd20a1268c67fc0ada7cc88e8ed9327 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 22 Nov 2013 10:15:51 +0100 Subject: [PATCH 08/91] better colors (cherry picked from commit 6e5d827cede1fddd5319ec81c8e3e17dae064a15) --- .../intellij/ide/actions/SearchEverywhereAction.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java index 2c39b36a70d4..0d1c34300e42 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java @@ -250,8 +250,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA @Override protected void paintComponent(Graphics g) { if (myBalloon != null && !myBalloon.isDisposed() && myActionEvent != null && myActionEvent.getInputEvent() instanceof MouseEvent) { - ((Graphics2D)g).setPaint(new GradientPaint(0,0, new JBColor(new Color(101, 136, 242), new Color(48, 87, 186)), 0, getHeight(), - new JBColor(new Color(44, 96, 238), new Color(48, 87, 186)))); + ((Graphics2D)g).setPaint(new GradientPaint(0,0, new JBColor(new Color(147, 162, 174), new Color(64, 80, 94)), 0, getHeight(), + new JBColor(new Color(116, 128, 143), new Color(53, 65, 87)))); g.fillRect(0,0,getWidth(), getHeight()); } else { super.paintComponent(g); @@ -605,8 +605,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA final JPanel panel = new JPanel(new BorderLayout()) { @Override protected void paintComponent(Graphics g) { - ((Graphics2D)g).setPaint(new GradientPaint(0,0, new JBColor(new Color(211, 232, 253), new Color(64, 80, 94)), 0, getHeight(), - new JBColor(new Color(200, 215, 239), new Color(53, 65, 87)))); + ((Graphics2D)g).setPaint(new GradientPaint(0,0, new JBColor(new Color(147, 162, 174), new Color(64, 80, 94)), 0, getHeight(), + new JBColor(new Color(116, 128, 143), new Color(53, 65, 87)))); g.fillRect(0, 0, getWidth(), getHeight()); } }; @@ -643,7 +643,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA showPoint = new RelativePoint(button, new Point(button.getWidth() - panel.getPreferredSize().width, button.getHeight())); } else { if (parent != null) { - int height = UISettings.getInstance().SHOW_MAIN_TOOLBAR ? 95 : 75; + int height = UISettings.getInstance().SHOW_MAIN_TOOLBAR ? 135 : 115; if (parent instanceof IdeFrameImpl && ((IdeFrameImpl)parent).isInFullScreen()) { height -= 20; } From 1a0e32129a753be4081d7e2924c928dcd7870970 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Fri, 22 Nov 2013 15:15:26 +0400 Subject: [PATCH 09/91] IDEA-107909 Rearrange entries, permanent change arrangement of elements [CR-IC-3214] --- .../JavaRearrangerGrouperTest.groovy | 48 +++++++++++++++++++ .../arrangement/engine/ArrangementEngine.java | 6 ++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerGrouperTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerGrouperTest.groovy index e730a41d59ef..e30b1a8849de 100644 --- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerGrouperTest.groovy +++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerGrouperTest.groovy @@ -126,6 +126,7 @@ class Sub extends Base { void test2() {} }''') } + void "test overriden and utility methods"() { doTest( initial: '''\ @@ -188,4 +189,51 @@ class Test { }''' ) } + + + void "test keep dependent methods together multiple times produce same result"() { + def groups = [group(DEPENDENT_METHODS, BREADTH_FIRST)] + def before = "public class SuperClass {\n" + + "\n" + + " public void doSmth1() {\n" + + " }\n" + + "\n" + + " public void doSmth2() {\n" + + " }\n" + + "\n" + + " public void doSmth3() {\n" + + " }\n" + + "\n" + + " public void doSmth4() {\n" + + " }\n" + + "\n" + + " public void doSmth() {\n" + + " this.doSmth1();\n" + + " this.doSmth2();\n" + + " this.doSmth3();\n" + + " this.doSmth4();\n" + + " }\n" + + "}" + def after = "public class SuperClass {\n" + + "\n" + + " public void doSmth() {\n" + + " this.doSmth1();\n" + + " this.doSmth2();\n" + + " this.doSmth3();\n" + + " this.doSmth4();\n" + + " }\n" + + " public void doSmth1() {\n" + + " }\n" + + " public void doSmth2() {\n" + + " }\n" + + " public void doSmth3() {\n" + + " }\n" + + " public void doSmth4() {\n" + + " }\n" + + "}" + doTest(initial: before, expected: after, groups: groups) + doTest(initial: after, expected: after, groups: groups) + } + + } diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java index d792e8db13b2..9090bc371b1f 100644 --- a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java @@ -273,14 +273,18 @@ public class ArrangementEngine { for (int i = 0; i < arranged.size() && !dependent.isEmpty(); i++) { E e = arranged.get(i); + List shouldBeAddedAfterCurrentElement = ContainerUtil.newArrayList(); + for (Iterator, E>> iterator = dependent.iterator(); iterator.hasNext(); ) { Pair, E> pair = iterator.next(); pair.first.remove(e); if (pair.first.isEmpty()) { iterator.remove(); - arranged.add(i + 1, pair.second); + shouldBeAddedAfterCurrentElement.add(pair.second); } } + + arranged.addAll(i + 1, shouldBeAddedAfterCurrentElement); } return arranged; From eaea89ea47a356fd3fd141d93695affb3c593460 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 22 Nov 2013 15:23:08 +0400 Subject: [PATCH 10/91] correctly handle request for the not-canonically named child --- .../vfs/newvfs/impl/VirtualDirectoryImpl.java | 78 +++++++++++-------- .../com/intellij/openapi/vfs/VfsUtilTest.java | 38 +++++++-- 2 files changed, 74 insertions(+), 42 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java index 8a0406d4f4e0..1906270aa400 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java @@ -103,7 +103,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { boolean ensureCanonicalName, @NotNull NewVirtualFileSystem delegate) { boolean ignoreCase = !delegate.isCaseSensitive(); - Comparator comparator = getComparator(name, ignoreCase); + Comparator comparator = getComparator(ignoreCase); VirtualFileSystemEntry result = doFindChild(name, ensureCanonicalName, delegate, comparator); if (result == NULL_VIRTUAL_FILE) { @@ -115,16 +115,16 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } if (result == null) { - addToAdoptedChildren(name, !delegate.isCaseSensitive(), comparator); + addToAdoptedChildren(!delegate.isCaseSensitive(), name, comparator); } return result; } - private synchronized void addToAdoptedChildren(@NotNull final String name, - final boolean ignoreCase, + private synchronized void addToAdoptedChildren(final boolean ignoreCase, + @NotNull final String name, @NotNull Comparator comparator) { - long r = findIndexInBoth(myChildren, comparator); + long r = findIndexInBoth(myChildren, name, comparator); int indexInReal = (int)(r >> 32); int indexInAdopted = (int)r; if (indexInAdopted >= 0) return; //already added @@ -147,9 +147,9 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } @Nullable // null if there can't be a child with this name, NULL_VIRTUAL_FILE - private synchronized VirtualFileSystemEntry doFindChildInArray(@NotNull Comparator comparator) { + private synchronized VirtualFileSystemEntry doFindChildInArray(@NotNull String name, @NotNull Comparator comparator) { VirtualFileSystemEntry[] array = myChildren; - long r = findIndexInBoth(array, comparator); + long r = findIndexInBoth(array, name, comparator); int indexInReal = (int)(r >> 32); int indexInAdopted = (int)r; if (indexInAdopted >= 0) return NULL_VIRTUAL_FILE; @@ -169,7 +169,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { return null; } - VirtualFileSystemEntry found = doFindChildInArray(comparator); + VirtualFileSystemEntry found = doFindChildInArray(name, comparator); if (found != null) return found; if (allChildrenLoaded()) { @@ -185,7 +185,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { synchronized (this) { // maybe another doFindChild() sneaked in the middle VirtualFileSystemEntry[] array = myChildren; - long r = findIndexInBoth(array, comparator); + long r = findIndexInBoth(array, name, comparator); int indexInReal = (int)(r >> 32); int indexInAdopted = (int)r; if (indexInAdopted >= 0) return NULL_VIRTUAL_FILE; @@ -216,14 +216,21 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } } + private static final Comparator CASE_SENSITIVE = new Comparator() { + @Override + public int compareFileNameTo(@NotNull String myName, @NotNull VirtualFileSystemEntry file) { + return -file.compareNameTo(myName, false); + } + }; + private static final Comparator CASE_INSENSITIVE = new Comparator() { + @Override + public int compareFileNameTo(@NotNull String myName, @NotNull VirtualFileSystemEntry file) { + return -file.compareNameTo(myName, true); + } + }; @NotNull - private static Comparator getComparator(@NotNull final String name, final boolean ignoreCase) { - return new Comparator() { - @Override - public int compareMyKeyTo(@NotNull VirtualFileSystemEntry file) { - return -file.compareNameTo(name, ignoreCase); - } - }; + private static Comparator getComparator(final boolean ignoreCase) { + return ignoreCase ? CASE_INSENSITIVE : CASE_SENSITIVE; } private synchronized VirtualFileSystemEntry[] getArraySafely() { @@ -391,19 +398,21 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { int start, int end, final boolean isAdopted, - @NotNull final Comparator comparator) { - return binSearch(array, start, end, new Comparator() { + @NotNull String name, @NotNull final Comparator comparator) { + return binSearch(array, start, end, name, new Comparator() { @Override - public int compareMyKeyTo(@NotNull VirtualFileSystemEntry file) { + public int compareFileNameTo(@NotNull String myName, @NotNull VirtualFileSystemEntry file) { if (isAdopted && !isAdoptedChild(file)) return 1; if (!isAdopted && isAdoptedChild(file)) return -1; - return comparator.compareMyKeyTo(file); + return comparator.compareFileNameTo(myName, file); } }); } // returns two int indices packed into one long. left index is for the real file array half, right is for the adopted children name array - private static long findIndexInBoth(@NotNull VirtualFileSystemEntry[] array, @NotNull Comparator comparator) { + private static long findIndexInBoth(@NotNull VirtualFileSystemEntry[] array, + @NotNull String name, + @NotNull Comparator comparator) { int high = array.length - 1; if (high == -1) { return pack(-1, -1); @@ -412,7 +421,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { boolean startInAdopted = isAdoptedChild(array[low]); boolean endInAdopted = isAdoptedChild(array[high]); if (startInAdopted == endInAdopted) { - int index = findIndexInOneHalf(array, low, high + 1, startInAdopted, comparator); + int index = findIndexInOneHalf(array, low, high + 1, startInAdopted, name, comparator); int otherIndex = startInAdopted ? -1 : -array.length - 1; return startInAdopted ? pack(otherIndex, index) : pack(index, otherIndex); } @@ -423,15 +432,15 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { while (low <= high) { mid = low + high >>> 1; VirtualFileSystemEntry file = array[mid]; - cmp = comparator.compareMyKeyTo(file); + cmp = comparator.compareFileNameTo(name, file); adopted = isAdoptedChild(file); if (cmp == 0) { foundIndex = mid; break; } if ((adopted || cmp <= 0) && (!adopted || cmp >= 0)) { - int indexInAdopted = findIndexInOneHalf(array, mid + 1, high + 1, true, comparator); - int indexInReal = findIndexInOneHalf(array, low, mid, false, comparator); + int indexInAdopted = findIndexInOneHalf(array, mid + 1, high + 1, true, name, comparator); + int indexInReal = findIndexInOneHalf(array, low, mid, false, name, comparator); return pack(indexInReal, indexInAdopted); } @@ -447,7 +456,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { if (cmp != 0) foundIndex = -low-1; int newStart = adopted ? low : mid + 1; int newEnd = adopted ? mid + 1 : high + 1; - int theOtherHalfIndex = newStart < newEnd ? findIndexInOneHalf(array, newStart, newEnd, !adopted, comparator) : -newStart-1; + int theOtherHalfIndex = newStart < newEnd ? findIndexInOneHalf(array, newStart, newEnd, !adopted, name, comparator) : -newStart-1; return adopted ? pack(theOtherHalfIndex, foundIndex) : pack(foundIndex, theOtherHalfIndex); } @@ -459,8 +468,8 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { @Nullable public synchronized NewVirtualFile findChildIfCached(@NotNull String name) { final boolean ignoreCase = !getFileSystem().isCaseSensitive(); - Comparator comparator = getComparator(name, ignoreCase); - VirtualFileSystemEntry found = doFindChildInArray(comparator); + Comparator comparator = getComparator(ignoreCase); + VirtualFileSystemEntry found = doFindChildInArray(name, comparator); return found == NULL_VIRTUAL_FILE ? null : found; } @@ -637,7 +646,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { VirtualFileSystemEntry[] array = myChildren; final String childName = child.getName(); final boolean ignoreCase = !getFileSystem().isCaseSensitive(); - long r = findIndexInBoth(array, getComparator(childName, ignoreCase)); + long r = findIndexInBoth(array, childName, getComparator(ignoreCase)); int indexInReal = (int)(r >> 32); int indexInAdopted = (int)r; @@ -666,7 +675,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { boolean ignoreCase = !getFileSystem().isCaseSensitive(); String name = file.getName(); - addToAdoptedChildren(name, ignoreCase, getComparator(name, ignoreCase)); + addToAdoptedChildren(ignoreCase, name, getComparator(ignoreCase)); assertConsistency(myChildren, ignoreCase, file); } @@ -699,9 +708,9 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } private int getAdoptedChildrenStart() { - int index = binSearch(myChildren, 0, myChildren.length, new Comparator() { + int index = binSearch(myChildren, 0, myChildren.length, "", new Comparator() { @Override - public int compareMyKeyTo(@NotNull VirtualFileSystemEntry v) { + public int compareFileNameTo(@NotNull String myName, @NotNull VirtualFileSystemEntry v) { return isAdoptedChild(v) ? -1 : 1; } }); @@ -713,12 +722,13 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } private interface Comparator { - int compareMyKeyTo(@NotNull VirtualFileSystemEntry file); + int compareFileNameTo(@NotNull String myName, @NotNull VirtualFileSystemEntry file); } private static int binSearch(@NotNull VirtualFileSystemEntry[] array, int start, int end, + @NotNull String name, @NotNull Comparator comparator) { int low = start; int high = end - 1; @@ -726,7 +736,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { while (low <= high) { int mid = low + high >>> 1; - int cmp = comparator.compareMyKeyTo(array[mid]); + int cmp = comparator.compareFileNameTo(name, array[mid]); if (cmp > 0) { low = mid + 1; } diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/VfsUtilTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/VfsUtilTest.java index c27a18de57ba..5dc480257786 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/VfsUtilTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/VfsUtilTest.java @@ -372,17 +372,17 @@ public class VfsUtilTest extends PlatformLangTestCase { assertNotNull(vDir); assertTrue(vDir.isDirectory()); - for (int i=0; i<10000; i++) { - final String name = i + ".txt"; - new WriteCommandAction.Simple(getProject()) { - @Override - protected void run() throws Throwable { + new WriteCommandAction.Simple(getProject()) { + @Override + protected void run() throws Throwable { + for (int i=0; i<10000; i++) { + final String name = i + ".txt"; vDir.createChildData(vDir, name); } - }.execute().throwException(); - } + } + }.execute(); final VirtualFile theChild = vDir.findChild("5111.txt"); - + System.out.println("Start searching..."); PlatformTestUtil.startPerformanceTest("find child is slow", 450, new ThrowableRunnable() { @Override public void run() throws Throwable { @@ -456,4 +456,26 @@ public class VfsUtilTest extends PlatformLangTestCase { } }).assertTiming(); } + + public void testNotCanonicallyNamedChild() { + File tempDir = new WriteAction() { + @Override + protected void run(Result result) throws Throwable { + File res = createTempDirectory(); + new File(res, "libFiles").createNewFile(); + new File(res, "CssInvalidElement").createNewFile(); + new File(res, "extFiles").createNewFile(); + result.setResult(res); + } + }.execute().getResultObject(); + final VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDir); + assertNotNull(vDir); + assertTrue(vDir.isDirectory()); + + assertNotNull(vDir.findChild("libFiles")); + assertNotNull(vDir.findChild("CssInvalidElement")); + + VirtualFile ext = vDir.findChild("/extFiles/"); + assertNotNull(ext); + } } From 3fadd9aa3afbcd948c329181a15f10ae52348255 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 22 Nov 2013 15:23:45 +0400 Subject: [PATCH 11/91] avoid unexpected read action --- .../psi/impl/search/PsiSearchHelperImpl.java | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java index bc0fb118071a..f0393574996a 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java @@ -22,13 +22,18 @@ import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.impl.LoadTextUtil; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.openapi.progress.util.TooManyUsagesStatus; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; -import com.intellij.openapi.util.*; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -40,6 +45,7 @@ import com.intellij.psi.search.*; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.CommonProcessors; import com.intellij.util.Processor; +import com.intellij.util.SmartList; import com.intellij.util.codeInsight.CommentUtilCore; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; @@ -344,13 +350,14 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { final AtomicBoolean canceled = new AtomicBoolean(false); AsyncFutureResult asyncFutureResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); - final List failedFiles = new ArrayList(); + final List failedFiles = Collections.synchronizedList(new SmartList()); try { boolean completed = JobLauncher.getInstance().invokeConcurrentlyUnderProgress(files, progress, false, false, new Processor() { @Override public boolean process(final VirtualFile vfile) { try { + TooManyUsagesStatus.getFrom(progress).pauseProcessingIfTooManyUsages(); processVirtualFile(vfile, progress, localProcessor, canceled, counter, totalSize); } catch (CannotRunReadActionException action) { @@ -361,6 +368,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { }); if (!failedFiles.isEmpty()) { for (final VirtualFile vfile : failedFiles) { + TooManyUsagesStatus.getFrom(progress).pauseProcessingIfTooManyUsages(); // we failed to run read action in job launcher thread // run read action in our thread instead ApplicationManager.getApplication().runReadAction(new Runnable() { @@ -381,10 +389,12 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { return asyncFutureResult; } - private void processVirtualFile(final VirtualFile vfile, + private void processVirtualFile(@NotNull final VirtualFile vfile, final ProgressIndicator progress, - final Processor localProcessor, - final AtomicBoolean canceled, AtomicInteger counter, int totalSize) { + @NotNull final Processor localProcessor, + @NotNull final AtomicBoolean canceled, + @NotNull AtomicInteger counter, + int totalSize) { final PsiFile file = tryRead(new Computable() { @Override public PsiFile compute() { @@ -392,19 +402,16 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { } }); if (file != null && !(file instanceof PsiBinaryFile)) { - file.getViewProvider().getContents(); // load contents outside read action - if (myManager.getProject().isDisposed()) throw new ProcessCanceledException(); - final List psiRoots = tryRead(new Computable>() { - @Override - public List compute() { - return file.getViewProvider().getAllFiles(); - } - }); - final Set processed = new THashSet(psiRoots.size() * 2, (float)0.5); - TooManyUsagesStatus.getFrom(progress).pauseProcessingIfTooManyUsages(); + // load contents outside read action + if (FileDocumentManager.getInstance().getCachedDocument(vfile) == null) { + LoadTextUtil.loadText(vfile); // cache bytes in vfs + } tryRead(new Computable() { @Override public Void compute() { + if (myManager.getProject().isDisposed()) throw new ProcessCanceledException(); + List psiRoots = file.getViewProvider().getAllFiles(); + Set processed = new THashSet(psiRoots.size() * 2, (float)0.5); for (final PsiFile psiRoot : psiRoots) { checkCanceled(progress); assert psiRoot != null : "One of the roots of file " + file + " is null. All roots: " + psiRoots + From 0c6d5f07e3f5ffe1176666ccd35d11fbec44f1a7 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 22 Nov 2013 12:23:05 +0100 Subject: [PATCH 12/91] EA-51155 (IOOBE: CharArrayCharSequence.) --- .../ReplaceOctalEscapeWithUnicodeEscapeIntention.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/ReplaceOctalEscapeWithUnicodeEscapeIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/ReplaceOctalEscapeWithUnicodeEscapeIntention.java index 564db76755e5..1d479be7129c 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/ReplaceOctalEscapeWithUnicodeEscapeIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/ReplaceOctalEscapeWithUnicodeEscapeIntention.java @@ -150,8 +150,14 @@ public class ReplaceOctalEscapeWithUnicodeEscapeIntention extends Intention { } final SelectionModel selectionModel = editor.getSelectionModel(); if (selectionModel.hasSelection()) { - final String selectedText = selectionModel.getSelectedText(); - return selectedText != null && indexOfOctalEscape(selectedText, 1) >= 0; + final int start = selectionModel.getSelectionStart(); + final int end = selectionModel.getSelectionEnd(); + if (start < 0 || end < 0 || start > end) { + // shouldn't happen but http://ea.jetbrains.com/browser/ea_problems/51155 + return false; + } + final String text = editor.getDocument().getCharsSequence().subSequence(start, end).toString(); + return indexOfOctalEscape(text, 1) >= 0; } else if (element instanceof PsiLiteralExpression) { final PsiLiteralExpression literalExpression = (PsiLiteralExpression)element; From d006433f6bb753a28bef356062834a0cfc0e587b Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 22 Nov 2013 12:23:49 +0100 Subject: [PATCH 13/91] EA-50192 (IOOBE: CharArrayCharSequence.) --- .../siyeh/ipp/unicode/UnicodeUnescapeIntention.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java index e885764e6ecd..0137f987a32e 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/unicode/UnicodeUnescapeIntention.java @@ -140,14 +140,19 @@ public class UnicodeUnescapeIntention extends Intention { return false; } final SelectionModel selectionModel = editor.getSelectionModel(); + final Document document = editor.getDocument(); if (selectionModel.hasSelection()) { - final String text = selectionModel.getSelectedText(); - // an editor can have a selection, but still null for selected text (because of threading?). - return text != null && indexOfUnicodeEscape(text, 1) >= 0; + final int start = selectionModel.getSelectionStart(); + final int end = selectionModel.getSelectionEnd(); + if (start < 0 || end < 0 || start > end) { + // shouldn't happen but http://ea.jetbrains.com/browser/ea_problems/50192 + return false; + } + final String text = document.getCharsSequence().subSequence(start, end).toString(); + return indexOfUnicodeEscape(text, 1) >= 0; } else { final CaretModel caretModel = editor.getCaretModel(); - final Document document = editor.getDocument(); final int lineNumber = document.getLineNumber(caretModel.getOffset()); final String line = document.getText(new TextRange(document.getLineStartOffset(lineNumber), document.getLineEndOffset(lineNumber))); final int column = caretModel.getLogicalPosition().column; From 981282ee527b161d3857c62341e4fd0c950fa995 Mon Sep 17 00:00:00 2001 From: Konstantin Ulitin Date: Fri, 22 Nov 2013 15:43:33 +0400 Subject: [PATCH 14/91] IDEA-105131 fix inplace introduce of JSExpressionStatement --- .../introduce/inplace/AbstractInplaceIntroducer.java | 2 +- .../introduce/inplace/InplaceVariableIntroducer.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java index cf4eaf6fd04e..e761e9a3f2f3 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java @@ -81,7 +81,7 @@ public abstract class AbstractInplaceIntroducer extends In myExprMarker = exprMarker; } + @Nullable public E getExpr() { return myExpr != null && myExpr.isValid() && myExpr.isPhysical() ? myExpr : null; } From 9059b86b672a97d149083a7655131804a6abf3ab Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Fri, 22 Nov 2013 16:02:53 +0400 Subject: [PATCH 15/91] IDEA-116784 Error Parsing Regex /\s/ in Groovy --- .../jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java index 11348e734474..4cc4db1233da 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java @@ -690,6 +690,10 @@ public class GrStringUtil { break; default: outChars.append('\\').append(c); + if (sourceOffsets != null) { + sourceOffsets[outChars.length() - outOffset] = index; + } + } } return true; From eee493c10ee3a49315ba70b567f25ac040b2e67f Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Fri, 22 Nov 2013 16:04:53 +0400 Subject: [PATCH 16/91] rearranger test fix --- .../arrangement/JavaRearrangerFieldReferenceTest.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy index a2a996a36048..2ec1fb2a439a 100644 --- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy +++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy @@ -84,8 +84,8 @@ public class CodeFormatTest { public static String TEST = "OK!"; public static String BOOK = "ATLAS"; private static String PREFIX = "prefix."; - private static String PRIVATE_NAME = PREFIX + "private name"; public static String NAME = PREFIX + "name"; + private static String PRIVATE_NAME = PREFIX + "private name"; } ''', rules: defaultFieldsArrangement From bcf55e05e133fe566b41e2bf74aa3e1a23ec488e Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 22 Nov 2013 15:39:25 +0400 Subject: [PATCH 17/91] inverse COLLAPSE handling & sync GPUB with GK version --- .../lang/parser/GeneratedParserUtilBase.java | 66 +++++++++++-------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java index 382e6eed58d7..10d3bdf1623c 100644 --- a/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java +++ b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java @@ -35,11 +35,18 @@ import java.util.LinkedList; /** * @author gregsh */ -@SuppressWarnings("StringEquality") public class GeneratedParserUtilBase { private static final Logger LOG = Logger.getInstance("org.intellij.grammar.parser.GeneratedParserUtilBase"); + private static final int MAX_RECURSION_LEVEL = 1000; + private static final int MAX_VARIANTS_SIZE = 10000; + private static final int MAX_VARIANTS_TO_DISPLAY = 50; + + private static final int INITIAL_VARIANTS_SIZE = 1000; + private static final int VARIANTS_POOL_SIZE = 10000; + private static final int FRAMES_POOL_SIZE = 500; + public static final IElementType DUMMY_BLOCK = new DummyBlockElementType(); public interface Parser { @@ -67,8 +74,8 @@ public class GeneratedParserUtilBase { } public static boolean recursion_guard_(PsiBuilder builder_, int level_, String funcName_) { - if (level_ > 1000) { - builder_.error("Maximum recursion level (" + 1000 + ") reached in " + funcName_); + if (level_ > MAX_RECURSION_LEVEL) { + builder_.error("Maximum recursion level (" + MAX_RECURSION_LEVEL + ") reached in " + funcName_); return false; } return true; @@ -282,6 +289,8 @@ public class GeneratedParserUtilBase { public static final String _SECTION_RECOVER_ = "_SECTION_RECOVER_"; public static final String _SECTION_GENERAL_ = "_SECTION_GENERAL_"; + @SuppressWarnings("StringEquality") + @Deprecated public static void enterErrorRecordingSection(PsiBuilder builder_, int level, @NotNull String sectionType, @Nullable String frameName) { int modifiers = sectionType == _SECTION_GENERAL_ ? _NONE_ : sectionType == _SECTION_NOT_ ? _NOT_ : @@ -289,6 +298,7 @@ public class GeneratedParserUtilBase { enter_section_impl_(builder_, level, modifiers, frameName); } + @Deprecated public static boolean exitErrorRecordingSection(PsiBuilder builder_, int level, boolean result, @@ -356,7 +366,7 @@ public class GeneratedParserUtilBase { public static void exit_section_(PsiBuilder builder_, int level, PsiBuilder.Marker marker, - IElementType elementType, + @Nullable IElementType elementType, boolean result, boolean pinned, @Nullable Parser eatMore) { @@ -464,7 +474,9 @@ public class GeneratedParserUtilBase { if ((frame.modifiers & _COLLAPSE_) != 0) { LighterASTNode last = result || pinned? builder_.getLatestDoneMarker() : null; if (last != null && last.getStartOffset() == frame.offset && state.typeExtends(last.getTokenType(), elementType)) { - marker.drop(); + IElementType resultType = last.getTokenType(); + ((PsiBuilder.Marker)last).drop(); + marker.done(resultType); return; } } @@ -527,7 +539,7 @@ public class GeneratedParserUtilBase { public static void report_error_(PsiBuilder builder_, ErrorState state, boolean advance) { Frame frame = state.frameStack.isEmpty()? null : state.frameStack.getLast(); if (frame == null) { - LOG.error("Unbalanced error section: got null , expected " + frame); + LOG.error("unbalanced enter/exit section call: got null"); return; } int offset = builder_.getCurrentOffset(); @@ -628,10 +640,10 @@ public class GeneratedParserUtilBase { public boolean altMode; private int lastExpectedVariantOffset = -1; - public MyList variants = new MyList(500); - public MyList unexpected = new MyList(10); + public MyList variants = new MyList(INITIAL_VARIANTS_SIZE); + public MyList unexpected = new MyList(INITIAL_VARIANTS_SIZE / 10); - final LimitedPool VARIANTS = new LimitedPool(1000, new LimitedPool.ObjectFactory() { + final LimitedPool VARIANTS = new LimitedPool(VARIANTS_POOL_SIZE, new LimitedPool.ObjectFactory() { @Override public Variant create() { return new Variant(); @@ -641,7 +653,7 @@ public class GeneratedParserUtilBase { public void cleanup(final Variant o) { } }); - final LimitedPool FRAMES = new LimitedPool(100, new LimitedPool.ObjectFactory() { + final LimitedPool FRAMES = new LimitedPool(FRAMES_POOL_SIZE, new LimitedPool.ObjectFactory() { @Override public Frame create() { return new Frame(); @@ -677,7 +689,6 @@ public class GeneratedParserUtilBase { return sb.toString(); } - private static final int MAX_VARIANTS_TO_DISPLAY = Integer.MAX_VALUE; private boolean addExpected(StringBuilder sb, int offset, boolean expected) { MyList list = expected ? variants : unexpected; String[] strings = new String[list.size()]; @@ -729,14 +740,13 @@ public class GeneratedParserUtilBase { } boolean typeExtends(IElementType child_, IElementType parent_) { - if (extendsSets == null) { - return child_ == parent_ || - altExtendsChecker != null && altExtendsChecker.process(child_, parent_); + if (child_ == parent_) return true; + if (extendsSets != null) { + for (TokenSet set : extendsSets) { + if (set.contains(child_) && set.contains(parent_)) return true; + } } - for (TokenSet set : extendsSets) { - if (set.contains(child_) && set.contains(parent_)) return true; - } - return false; + return altExtendsChecker != null && altExtendsChecker.process(child_, parent_); } } @@ -816,15 +826,6 @@ public class GeneratedParserUtilBase { } } - @Nullable - private static IElementType getClosingBracket(ErrorState state, IElementType type) { - if (state.braces == null) return null; - for (BracePair pair : state.braces) { - if (type == pair.getLeftBraceType()) return pair.getRightBraceType(); - } - return null; - } - private static final int MAX_CHILDREN_IN_TREE = 10; public static boolean parseAsTree(ErrorState state, final PsiBuilder builder_, int level, final IElementType chunkType, @@ -961,7 +962,16 @@ public class GeneratedParserUtilBase { } protected void setSize(int fromIndex) { - super.removeRange(fromIndex, size()); + removeRange(fromIndex, size()); + } + + @Override + public void ensureCapacity(int minCapacity) { + int size = size(); + if (size >= MAX_VARIANTS_SIZE) { + removeRange(MAX_VARIANTS_SIZE / 4, size - MAX_VARIANTS_SIZE / 4); + } + super.ensureCapacity(minCapacity); } } } From 1a5a951557f8b2ee07fddb737767701fced36fd8 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Fri, 22 Nov 2013 16:10:11 +0400 Subject: [PATCH 18/91] test fix (stupid type error fixed) --- .../testSrc/hg4idea/test/history/HgBrowseChangesTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/hg4idea/testSrc/hg4idea/test/history/HgBrowseChangesTest.java b/plugins/hg4idea/testSrc/hg4idea/test/history/HgBrowseChangesTest.java index 3f87aff5da78..edfd46d63806 100644 --- a/plugins/hg4idea/testSrc/hg4idea/test/history/HgBrowseChangesTest.java +++ b/plugins/hg4idea/testSrc/hg4idea/test/history/HgBrowseChangesTest.java @@ -53,8 +53,7 @@ public class HgBrowseChangesTest extends HgPlatformTest { hg("commit -m add"); java.util.Calendar now = java.util.Calendar.getInstance(); int year = java.util.Calendar.YEAR; - now.set(year, - +1); + now.set(year, now.get(year) + 1); dateBefore = ChangeBrowserSettings.DATE_FORMAT.format(now.getTime()); now.set(year, 1970); dateAfter = ChangeBrowserSettings.DATE_FORMAT.format(now.getTime()); From 8f15d7feabf7228ad60ef17064a35bf3ed365751 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Fri, 22 Nov 2013 16:12:37 +0400 Subject: [PATCH 19/91] IDEA-116784 Error Parsing Regex /\s/ in Groovy. test --- .../groovy/lang/GroovyRegexFindExpressionTest.groovy | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyRegexFindExpressionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyRegexFindExpressionTest.groovy index 617dd41d704b..73ea9170b78d 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyRegexFindExpressionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyRegexFindExpressionTest.groovy @@ -53,4 +53,10 @@ class A { myFixture.checkHighlighting(true, false, true) } + + public void testRegex() { + myFixture.configureByText('a.groovy', '\'foo\' =~ /\\s/') + myFixture.checkHighlighting(true, false, true) + } + } From 0b4bf6c354706925281e82c2b5eb10d35d7eceec Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 22 Nov 2013 13:22:04 +0100 Subject: [PATCH 20/91] update threads icons --- .../debugger/threadStates/daemon_sign@2x.png | Bin 0 -> 1326 bytes .../threadStates/daemon_sign@2x_dark.png | Bin 0 -> 1306 bytes .../debugger/threadStates/daemon_sign_dark.png | Bin 0 -> 1086 bytes .../src/debugger/threadStates/edtBusy@2x.png | Bin 0 -> 1720 bytes .../src/debugger/threadStates/exception@2x.png | Bin 0 -> 1656 bytes .../threadStates/exception@2x_dark.png | Bin 0 -> 1655 bytes .../debugger/threadStates/exception_dark.png | Bin 0 -> 1301 bytes .../icons/src/debugger/threadStates/idle.png | Bin 724 -> 1492 bytes .../src/debugger/threadStates/idle@2x.png | Bin 0 -> 2286 bytes .../icons/src/debugger/threadStates/io@2x.png | Bin 0 -> 1085 bytes .../src/debugger/threadStates/locked@2x.png | Bin 0 -> 2379 bytes .../debugger/threadStates/locked@2x_dark.png | Bin 0 -> 2358 bytes .../src/debugger/threadStates/locked_dark.png | Bin 0 -> 1466 bytes .../src/debugger/threadStates/paused@2x.png | Bin 0 -> 1130 bytes .../src/debugger/threadStates/running@2x.png | Bin 0 -> 1701 bytes .../src/debugger/threadStates/socket@2x.png | Bin 0 -> 2063 bytes .../debugger/threadStates/socket@2x_dark.png | Bin 0 -> 2095 bytes .../src/debugger/threadStates/socket_dark.png | Bin 0 -> 1371 bytes .../debugger/threadStates/threaddump@2x.png | Bin 0 -> 1703 bytes .../threadStates/threaddump@2x_dark.png | Bin 0 -> 1702 bytes .../debugger/threadStates/threaddump_dark.png | Bin 0 -> 1272 bytes 21 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 platform/icons/src/debugger/threadStates/daemon_sign@2x.png create mode 100644 platform/icons/src/debugger/threadStates/daemon_sign@2x_dark.png create mode 100644 platform/icons/src/debugger/threadStates/daemon_sign_dark.png create mode 100644 platform/icons/src/debugger/threadStates/edtBusy@2x.png create mode 100644 platform/icons/src/debugger/threadStates/exception@2x.png create mode 100644 platform/icons/src/debugger/threadStates/exception@2x_dark.png create mode 100644 platform/icons/src/debugger/threadStates/exception_dark.png create mode 100644 platform/icons/src/debugger/threadStates/idle@2x.png create mode 100644 platform/icons/src/debugger/threadStates/io@2x.png create mode 100644 platform/icons/src/debugger/threadStates/locked@2x.png create mode 100644 platform/icons/src/debugger/threadStates/locked@2x_dark.png create mode 100644 platform/icons/src/debugger/threadStates/locked_dark.png create mode 100644 platform/icons/src/debugger/threadStates/paused@2x.png create mode 100644 platform/icons/src/debugger/threadStates/running@2x.png create mode 100644 platform/icons/src/debugger/threadStates/socket@2x.png create mode 100644 platform/icons/src/debugger/threadStates/socket@2x_dark.png create mode 100644 platform/icons/src/debugger/threadStates/socket_dark.png create mode 100644 platform/icons/src/debugger/threadStates/threaddump@2x.png create mode 100644 platform/icons/src/debugger/threadStates/threaddump@2x_dark.png create mode 100644 platform/icons/src/debugger/threadStates/threaddump_dark.png diff --git a/platform/icons/src/debugger/threadStates/daemon_sign@2x.png b/platform/icons/src/debugger/threadStates/daemon_sign@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f3f8198ff92a4c137876003aafa07ccb9c410fc8 GIT binary patch literal 1326 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%!-*I5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s0;1ij}L0lcS-zv9YOVL91WY_2COp*wIq-C!ng>kmMZi>@m9T6c0|Vn?PZ!6K zid%1{8~Pt|5IMenN=U2NhO0|AS#%pN^h|8bxDg}MVaTVqsE#v@&A!2J)23760?8!{ zJ!5^!*;*SNe7u%uF8#XK&BsH=GV-13|2zNR#a_C-ID~scX3qAXf9r?Vh_>dt_QMfU*1W8P&ax2u(11QuWnp00i_>zopr04;ahA^-pY literal 0 HcmV?d00001 diff --git a/platform/icons/src/debugger/threadStates/daemon_sign@2x_dark.png b/platform/icons/src/debugger/threadStates/daemon_sign@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd336db1d1bb21b4b9410d10de3917fb9d28807 GIT binary patch literal 1306 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%!-*I5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s0;1ij|v*iK&aRi=(NLg}I@jtFfhpfsvb~rHiYj zi@CF@g%M1zOMY@`Zfaf$Om7N8uMVL91WY_2COp*wIq-C!ng>kmMZi>j^>Eid1_s7{PZ!6K zid%1{7%{|EMx_wSZ?AKakbC-2TU;y z+y#t!AKtTi?2S8qpdoevmyG{PzigiC3L4VpB4z@OwV|P>mj=C5nCq9nXkzZ|_scTv zq}mo9{=&yH$8E9Te^G|4wPDtQB2Ql|XZ>6Ef7{ipScfX!V~%&2) wvBPrdloK~a zH?4c3^kj|ChH2-Y^FJ*4mhje3$iG3f+jUR&q>08ZUY_^mmrRkkT5#a%6vZ4>#SI!= zkIdA(PczNzQ7@L?*v5SCC|k=`7nX(<{LD9OmVDN={Mjm&y6^q$89VyCk3CM{TjOi} zi1|>u5>xZR2Q_LBcFN6h5orABv*7ycyUrEfE(>nv+_UH_?h-!#`9y(5&jFeC)X4B% z>+BtV&1yNoWbmrQ>U^uyLsx+ondBVNtbMO{rER}$o4x(^bc6aP`HLQxx7=Xe$0EUS XDN*ECndJXxpwi0I)z4*}Q$iB}xU1EC literal 0 HcmV?d00001 diff --git a/platform/icons/src/debugger/threadStates/daemon_sign_dark.png b/platform/icons/src/debugger/threadStates/daemon_sign_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..93d0ef4c232cccc391279a0a7e21a9aa98282221 GIT binary patch literal 1086 zcmaJ=TWHfz7|u2rvJ31%g!!OZHbGh2B<6%SJ zt0)_aiim;(=X~-(1kr&YGVy|lp!lGm4|6*4b>5g4#CbB;>4PR6kYz;lf=R+Qua+D{7-o@!Avg}Pub%1I_5LJG_PGNws=AOR$0XwO5? zLJ(zjYBGgV@$G^PHIL+AJhoPt^m|+|4P9RFweL&Bd9x5dr;b z+pr0`hTD_!@PN!KRB$udVhdP614trmZMSX-c7R&c74X_QrYUj}f(8QAZ&RswCmDez zAUO}`mKnB*Z00>I$2R#{7wKhKAIcX|M=pI7j%F&oLPFfS6btVHR6jz7 zK-0Ng&Xeu2z$^+-*y-;S zG-Fv-x0cF;3r5?LL9-slNvQyg$Nvx2v}Lq~65x;De+pa4Ap_6}V8N^@L5_InouJb zGZxh1UP49nmbglBFX5tG8k?b=d;RO43rDzloaJ)Y;>~j3106TJiM#r|%VpyiaV;i> zlJ?8YkA;O`*}4Ox`7pEV_N9`ZvQ#=qZ+2d06VpUJ+3s-~d z-uu}{9pyFEZx2?9r-dh?IXTD$-fyN**J6OaOJJruAQGh r-fvVdygS=^V$IIdmBEh7B}7R%k-rgcJUKYM$$8PSXuEhN+;i|3#|mch literal 0 HcmV?d00001 diff --git a/platform/icons/src/debugger/threadStates/edtBusy@2x.png b/platform/icons/src/debugger/threadStates/edtBusy@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..435807e004caeb9e8c7e637bafe1b52baaed45a1 GIT binary patch literal 1720 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%!-*I5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s0;1ij|46v9XD(vx}*bg}I@jtFfh_i;IPUi@AlV zrK^jRt2s=sOMY@`Zfaf$Om7N8uPaWypp=kX0JPa9wJ5VJHN~wcKUV?lW2;QuZgIkC z9#n4%Znrq&)TVL91WY_2COp*wIq-C!ng>kmMZi=ocTnRbFtg}-x;TbZ z+FA-usFsrOy_V^l2~$zPcQYQ+xD3s@347DMp>nHskKe6u`E8n^ZUG~^Qzxn zusOfD;>D5Pa{~TvcW-sv7ZK*4VETY(fzSf>6O6(Q&l|Rd?rY4L!oc+S=Ye+&T^vmh zj7+uWhpqKVitLLnTK}R>cej4AO+D+EyA5m&x`})ZAGH$Rig=#tF8=;Wt+{W?=?vHJ zcg0+kT&~9D1pQ!gG)b8K^mnfD(+4NmXVi0jkXo;9vVN-VZdj)C&w2aYTYcC!X+}izt(f-c0P7@$rb&Q{`5c9AE1h2TzLPs5n=9>|hm^l-l~O!gF7i^*#H#-zRs!DCze;=`g+a=F}&xYKNT! zJ|1}dd9mvB_C{N)>)8u-?yRhRzGcgn6=B(7mF;Ubh;qHU^x}%m^z;kIMNgbKBGYu{ zvFWrGt{G;tx8Gse;xB!Be^~uLyR~P%u20gOD1EVZVZy*OW<$X&o1YwS|C z+cv~ptUL8IQ{?Gmrx|~}nRqfi_o0>Z-L1tFd%pA3aXLH;ONh{aW!N>9vq0$QAI30^ z^ut}Z`Adz=Oi$l_u;aiEW|!rR$%|wpyhxSw3MuVZhtWHfFFZwRZ2D*Qj8fx&=q_7uEe5-QNkViP9U2_%l1@4M3;vFvkXOzj_C{;+4Z>Vq9UBBqcZKZF^ nO=bx``fuOl;wshqkHdgr)5X>=Ik~@_Ky`_ytDnm{r-UW|NSKU+ literal 0 HcmV?d00001 diff --git a/platform/icons/src/debugger/threadStates/exception@2x.png b/platform/icons/src/debugger/threadStates/exception@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..00d7dcc291c7de35726f0a38c7f9d9defe077a1e GIT binary patch literal 1656 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 Tu2;|VKLwhkmFgpjx()vT+h}%* literal 0 HcmV?d00001 diff --git a/platform/icons/src/debugger/threadStates/exception_dark.png b/platform/icons/src/debugger/threadStates/exception_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..f5fcdcb2e40e77ec92d2bf0142d4fa3f803b484d GIT binary patch literal 1301 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m=!ZaB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxR5#hc&_u!9QqR!T z(8R(}N5ROz&{*HVSl`fC*U-qyz|zXlQ~?TIxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7KMf<|~|UP^v> zu_jo#udkJ7UU5lcUUI6Zi>(sS0KLr26f0vlGiM`5b2C#T3nN2AS7S>HXEQf5H%C_k zS0e)hXA_uSm;B_?+|;}hnBEkGUUQs!K`9}(0BEyIYEfocYKmJ?ey#%8$5xrR-C}~% zJgD9j+-@<&saGH97=2K@BE>UI2$*<4On9mVa^UGcH4m8Bi-4(GfOica0|R51r;B4q z#jT`2|Nq-FbNI|M;XHJJSE^x$;IWgZPcvWk;W^UGqOi_gJmuh`34+}cCrbMq_Q;>g zKa$zd*2dQMPTD-LVa4wodk!_7-kYDk^YG0@0pWYM&F0`!zv%pv=X9e*(b@VrY=6Z4 zZg-wJ&mv{P>>@18_MpI_tZ`Xi!}b|{2kOt3Uof~LID_x28?&PLoYY@Gm;L#Fb5G{~ ze}5R;RfG-hNk~dc=g0iLkl@h6ePs*FtNQ%2Xy$wHaZ?}I_U-v)x$Jf{L%!jXs z?~KaVE{=R!Az@(=xuKoWrs3EeLnqekLJ``_b+~S%nKb{ z*v>wZ=YRd@(ImUdc*XC!6Y{&X1pl^4lo?KHGSrt Sox5g&3Mx-mKbLh*2~7aZkKZ%^ literal 0 HcmV?d00001 diff --git a/platform/icons/src/debugger/threadStates/idle.png b/platform/icons/src/debugger/threadStates/idle.png index 1f02c73f1c79ba33ad17a693888ae59ca6224373..b6703024d0181f149e31cbcb48d3e0903a376bdb 100644 GIT binary patch literal 1492 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 literal 0 HcmV?d00001 diff --git a/platform/icons/src/debugger/threadStates/locked@2x.png b/platform/icons/src/debugger/threadStates/locked@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0371a1e18c4d5087013edb37c7d53d72026d65a3 GIT binary patch literal 2379 zcmaJ@dpy&7A0G={T{5Ijo!K}pu?uE4OxcW;IcS(jX8W0CH`~};4oA9)5>l#DghR)9 z)U-;uR6=qd+F>f?)>#)S#Lsf1g#$*DeQv zK&vReq#(@-U3i!3YQEy+$aq2x8w7IqlnEKkI6wl82G|_F2kdqI4H%Te@_>b6s3@wC z2*h%HlSRO`WPchnIgW{A!8{32cNtzIzyl-n%aM=0S4_|OGKMzkP7;sMiS`gaLD;TKuH_;Z^y4MWNpLL?f2S}17|NTvRND3A9A zEtUiU|K$5Wg~hZaA%F}5#DWA7Q!}_2_(CWlo+tts5`l;&5O5c}7!WIv2*j}hA(Tjj z+JtiWEP+&P`w32^;wgNwgu!P56p{x_BY@y=Sa=sA28DL@a>h8iI-$|tPB>>W%GKG+ z$=lf(hr&3yE^hau=My6KW!p01+n4u?S#LbDC&2+*V zHMqPdHply4lqNI6YHH89z;(u8$}?L@W$^O8wkxwmr`?{+>+ALM*?lj~ik{YD-JIUf zDLsY>cYTimHLsE=*c@t?#})xA8lX%0dIl5QHY{WNeia@vrqZF(<{@9pEusp1Eu=}}HEJapn zaJQCugP!(d!`=o$q0qLfZtE)D=%y-j?sm&tkX-3c51Q8A&WUir_4LhtJh8&eY-7dc z_NaW{hw(yfd#gSvIP$lQ$`zvP{`OY2;RAoHI@)?m@sb|qZDk4%DVrM1qtU+KdgbCt z={q)4S5dlLarb7Hx9pgO&-1Q>yTm8=tfs=qV@tiR^&3yL-AZ`d@$Gqef`du~Tef{Q z-27wA`x*Ma@WA5H?vVBq9&)47th&8ifmL<9zJ0m*oY{2Le}rDaKMaOu78Z7RI<)u> zWLd^`k)2YJEh^pI4<=zLj6`0;Sv&h?vNbm;YKnMqfPU3(`Fgrv^_@oB`e!C1sp2re zWb{;rx?jVjly|4TF7^m*#k!EyMi;`#Lt}DuXyV3=u|zzr9CJHErzZ`bc4XFSL%Ml^ z39I|5KXlZv?auqtJ&0`hs1idXM&wO$-9GHwyQ;RYaSu0r>sV?fMYi#B+t{-b8!Eq8 zx#1Vp93O=|VD*U5v4)?Vp(_m}L?Ymwx%H2bN-8iu+&W=kvJ6JXakWQIp=vR-TIrb6Wt&OFG}v6Z)`h;;?`bkAq`RJOtS4~pbw zk@Ace>~~#5Rod0@1rwH+#jUxVHR&T|FVKn|TZd(Fu%xhlE6%H`e?P$-WMyZ{Ra?4L z=B|u6@|D*m@AedcJp*TdoJRjS(>xQg&pg>wF>t9ltwdmR%*7#mF3bW!J}l3aH`1~< z?L4Ne;DxhN0`u;#(Ib>47G5n@zF0poM~{h;|7@n_r5o%tE;c&ggA%z78`chIfk(2t z#ME9`b#VFQwF2-^pw%|Lka2^~p04;XgZncX=|NYn8mQxbom=Xrcz|1aycbSSlpT0R z_MsDw_pJ;s<ExkwYB=y^_LlmroBgN=snhG9&ax;60TU*jJTt3 zpvcRxREaIlZB2(sC`W;ABhMMKi9aR3G;!R1D{-XW73*d(Sc9egx~+Gp^h1F4se$=t^^cA4USL`Y z_w4+0$ZykyN2g9WizesKsiaM$;K{(M!*zF#*f=W#8t0*gWm4n7y4p;aOPM-2ft_jb zmf(n@!}aHKlFgk1ycG%gX_f6KD4u>5e*%^(8>qL(b#ep8eh+xVNjypDB;h_bLxK`A ifA}f#!mFKHx}as_Th8Fr!PN`DHxzGw(s{3_-G2dHl;0`< literal 0 HcmV?d00001 diff --git a/platform/icons/src/debugger/threadStates/locked@2x_dark.png b/platform/icons/src/debugger/threadStates/locked@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..e1ba1ec934d909078797699bc839936e08ab06fe GIT binary patch literal 2358 zcmaJ@dpuNmA0AXBlRXOsWc&3EhU?HN1OKjuEga$lp->o;ZH4@!`VJCc(yfqwcru2}aex?1 zXE7J@5qnT*;&7S;9cg0?SPF?U0T#rk0zy^1!<6$qLEf^EpH`S|AXh1g0pM8-@lgEG*C%EEl>QK_lEw- z_kRlWC?XDo_J(+HB$p-|++O{~P#mHI7ozfEE(L}omb&Q4fcY?w0doKc2VjdIlTC*O zyscm0WHQl(&Er$qG{}Wyg_H@Pm`pm+%-qr5(cX-J$C{ghprfgUoju;%43D)Zm=Q2o zEM|#If@zT~h|OQ((*NPg(BI)MI)TNJMJ7R9W)wts;=(N8OT|Ry_jAF0SMMvA{{39= z-{qoZ$)FeK`d@Qix{{e^ar@1+vcosuLu{GZxiVKbJyfG25X&#SknAYJ-r+R22#T*( zLtB53dtZ8miiu=h@rC7JrI*$+3KG?Yh?nl;Z=Zr z{jaqVV~J?H)fij(-79{iPd_p!)X+C|b-E9fmU*0dC3cZW zFuz?}Geef!{?n0rN^Wf!(iS4$(3L8MjW%+$gC=21q_l@#+sjVB?H zo@Q(4@6h|RT$^TX#V?@do6SXqy@R&J7r_IE@J1Pd@pZ?#M{bGUZ_T(9a4G$M^=BXL zO)gjM)qDQ+fNSaI1*~E^Zu*cBXPrU%rD@sCKShU%i^1K&_m%Ja1V1Y~{o(v-+-l6x z-&VzKFgbf!?L_xy{s#c($~-@Td^<3VH;937N2>3BDlbT81lkQHc?PUEGTsUePdMr_ zl0VT8-bP5RFS(Mpm(*SA>tM?H#@D+rW^-ocm_5+du)4qd*Na@AddqD#oDOsuSuB?pX85XwN>Wf{f zEgOuCVlGo!HFc9&3lRnh*MC=pl5V8=J;N_diE*h-Fbb34qjZmL_%`9<__XrS#xpw; zSND~A1UMaknxFi1qLMba2aN7IUL>u(-+8)~a_Q~NVzBgWt^ctu~y-rlT`19kbv+c-hs>AQn{SeQ* z4183zZ$4(5dF>CrlQ;Qc6qB~LXYOQ{QAfzWhrzFb%&-$7e}!bOZ(Md=g=Sbr8f>@i z4Nfgh3Ruo;Vvx9%KMqITxzgXYvmo$HXi!PQ(W;TC6Hl{5>l2r`)hnKb0u{46>$XMY?k0OC18%U+3Mz6eE(9Gw7>Mepq5w}6>cMF&7^P<2HNt);Iu~? z>uEHqsCP~;T^F%ol+=GJebsRDN_3|%efpDGw!>s$R##fa&8j;0QQZq`8YiCT#NjiY z17B2E8fHDWnQGk4{}es6_R+qFE%EhzE8AkkM0>w>o!f7kdRZ@Kz|fi&mVVN#@jj6P zb3XUVM-^ztrp=qzw7g0E!$!66L4X6L+V`^Qjhx|zP-Bq7mCEi1P_hw!?4T>Dl=B7bh2RG%9*xG?|rBP_Q9u`3;46d6#N QzxXHP;^;xTY9Dg=KMm9H^8f$< literal 0 HcmV?d00001 diff --git a/platform/icons/src/debugger/threadStates/locked_dark.png b/platform/icons/src/debugger/threadStates/locked_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..47f25d7b66a7ef8bd376540bb1ee5b1601782b38 GIT binary patch literal 1466 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 literal 0 HcmV?d00001 diff --git a/platform/icons/src/debugger/threadStates/socket@2x_dark.png b/platform/icons/src/debugger/threadStates/socket@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..9e2d4e9a2a784dd37591cd818786609d80f7716b GIT binary patch literal 2095 zcmaJ?dpMN&9)D?Aght3F@tUkd88h#U5yKe65GNz|TTx@?#Vj-L+%S~UN;P(^aFEv8 zTvloivyMYc^mLojqA1rQw>r^j9jBy7a%S4J=a1vO&-1>&%k%kszPHcwyg32>d-QZn zbpQa+^Yx(zDOXVSYH2FJqV)7v%4MtAD?%KM#EDaxLKvX2kyse?pAehNc6Z{Ih z0>B1KPDq3}g5gJIAzXW=3S%$f@|A1=aHUH4OjaT+24mrP4v&JFYrBF0Icy3hoW#I0 z_?~bA$0uC~2dDdou+kG*&TI_T4Rn=|l>%H?%mgLeB%X*Yp^Flo$VnKnTs!)8grx0d}5n%{|B&~HZAOR60q6CBwdU}F3 z;T#?tNfp_CfHN3mU!F+JLG>>Zg$+gPEC*Q+7rP+l_S6?@$4gvt`M_)QEMDlR-bYg;8 zs8PpUyT$VDuV)7rj%Q<{#DTW5dIQvmyPc_J|NTE}?9$2bp)OWf6fFW?sI!5=BQ{w@ zJCFO25~u?q4N|;q9X52?mlHO`xK#G&Oh$LtYWaic_`U~s6rk}*vwuCgTfV&d=N zs6=3P@<8V|OFcktZf?sg_V|si@9>vj$NjRhIBKeKM{W3WL;Np4yUkzBJWw~@$6Eb1 zl%(h|%ux)Ejg6U)&doSDx&k-QCt&$wiGB6?PCr8N0ng=2GQ_VYh|S~WrJTZT0zB+; zr}-v6<|^iv{DbE!U)kDr<^NTF`DJZT zr4QilccbuCqg%OOeLLy&%KUHQo~Qm(`>w9)r=0MgCnT9@JRH~;v%hd-!;00}E{kY^ zmyjN6Ty>uCR#unz)(Dg%i)qzWHsy+O)F@GwW24tu(*an9-*9WgySQw>V)sH`=aX&f zS^-S;Yc7jh3O_ElN&f{nI%U<|y})PCJ;)iC+;$cr}#zad&4X3bU4YFBSRm0zQlG21dAL4hP3 zNN;z_Ym3g$HYvUp)EI+vLpxd@wsC%jI|V{*!y{7?O&9lTCRE8eGEa#V^@5MAi6iZBEwwq zP8W1b@W3l_2AWmYbtdbjf*)9SK}qccR^d41I2=P2ULu4>ZX{;7L4#WZ>T z;+M@*;RWL+3sBDmRekWxBp|E(sW|Ff7%`>)dECSE+n_$YMiWQtO6~K|;Gv)P+E1>~ ze5%JY{m&k&&obV2^U0nNcf8;I?);*A7tLZzt<|);t?2KkfmfyNV=c7@e?EC=$=jm- zMXs+VRj4}^*&EZzj&%9A_YOm<=7?t5OA7J*D%Br1uy7jK05~=}g^|n}$5g*?UoU^U J+~ZKze*hq;QX&8V literal 0 HcmV?d00001 diff --git a/platform/icons/src/debugger/threadStates/socket_dark.png b/platform/icons/src/debugger/threadStates/socket_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..7a8094aceead147966319625fa3c6757b520e030 GIT binary patch literal 1371 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m=!ZaB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxR5#hc&_u!9QqR!T z(8R(}N5ROz&{*HVSl`fC*U-qyz|zXlQ~?TIxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7KMf<|~|UP^v> zu_jo#udkJ7UU5lcUUI6Zi>(sS0KLr26e}}hV{>Oib5~O%3o}DQS7S#LOEX6UR~Iug zV+#XkGgFvem;B_?+|;}hnBEkGUN@Y2K`9}(0BEyIYEfocYKmJ?ey#%8$5xrR-QtYX zJgD9j+-`BfsaGH97=2K@BE>UI2$*<4On9mVa^UGcH4m8Bi-4&*W5yp11_s6po-U3d z6}OW9{QqyytlGfpa%P5MbHvxZ4u2#%)Eg`$B_(-$ZiK9~i(QcOrSfYY`?I-99*6!q z#IPLsbRuh`l!C6d=IKMH-hBFd`+IbNv%@Uz1!m$-u|W-&8_M(V-<>pR>a4>D&uLZs zoqj9X<`uo zE0&fD$%x2Ese5~>K6}J}xopGx?6u7G`qj3M*LxBf%=w?Y)H%k5)z!(d$;IihrKPED zP;^>!=yTmjc|LkEmX<AG3e0n&XXB=p=5fBrNJ8|fc%CE=2`?pH4 z#fWq~`2GERJaf@07qgbmi5nk&J$-#?%$*p!`nvymj^+)b9rEvfK0WvO@$vP?>i-Au zGP1qUS5sToqwKS9eR*B+t*SQbCq}y%V;pQ`J5Fz_E&B8S@$vIs3$o*yVm?1Ve}D4* zeSbIH{C+%H?c5#)memb6Bs+dLSjc8{NKJTG@c72rZLiy3>(|U=e%7?up@v}zXUEcp nAKV@jCZq`@EHSZWW|3fsR9L&sW`+hcsJQcV^>bP0l+XkK2sZU` literal 0 HcmV?d00001 diff --git a/platform/icons/src/debugger/threadStates/threaddump@2x.png b/platform/icons/src/debugger/threadStates/threaddump@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..56abf46294bdab34b79767b870a92c65570a7f0b GIT binary patch literal 1703 zcmaJ?X;2eq7!DJ~7)GEPJizJ_yfN7vM3PjFkbp!J20{iRqGU-Hh#}b}SxkfqcuEm?Dl8$?y?yz9d)tYs|{(!-rW|xB`nsQZN%_fC&OMk_-c49h3^oU`V|& z<2JmUKp^^RJm55cTzyS}LGX2T|iW zQic>2!fBewECU>y6(v_?X;nNmH6$2VZsy|xIv9fhvo2k4W~)MJpDrZ@VHDu`gC z%Ai3p4Wb8}icm6=i3L${ryo<$p<}Xo<4BqCf`MiT1(|e)Go?|WRQmr=oo)3OoIwPxD-EUD3mWWzz~KQ@+5D3BoBX|MfB7sme z$`v81OdYJpM!D)w+-2i(ot>aV@yH_BpxFScBMgWR7|xil8Q%+gT)h#ldVDVd<8ndV z4Cp-9f1UH_7T!G0=~&m|i?P0k^?0)z@UFgQy(hsh%WSboAUE5);u}}VV<@$AUuPd~ ze8645LzgI;aGIPl&)&Httw;>)ttgnDZ=K$eOwK%dF3ne9O;g4Ca&LjNi_aH&l@%P4e5_c^0?3`7fWnfBGfuk-x&eGP|(t z6dJ-V?&|8ggTdv6x8-Nc-c;n<9#17|wOX2&@=z_axro2d(b-d^IY3hF?5of}U3TM} zj-No@h^*PCNTqe?r@@ZQTQ*l+Bl=(wZcwiF;8)4D)P%Z>IrG zEdb?Uip*WvoLF^@e5>k0%eEz3THSZ75hcNaY7wkI{*2|X?AFNfW&C7f~}bm&4V zbdfxGGJ_S(d*8qIyv*(s^^2*5;*m?bexOj`DIo^;L4U?^;#|)?2OIsaXIm;(Zc_@5 z*+kWOr2EkB7|KE-Sb1ddL6jD)rYw*?fn|JcMpVXiVdPZbH zx+iu0%uB^Gom&jWwf6_dPF^MPvT#rFRI#sjOclp{@Qq?twdAeW{9N~tQxh(e95cfx z;>ljc4q30u@t&fvV{gx}>Kt9A)vGt}>1f$kM{Zv;&6d8brD=CeW(^lfz)0TJ;)2kL z@fFPj`HPBm105CF$9sFCI>GIdzbT36=Z^Er6NyVacHPfizovlNBKfK;SXj1ptDk^k z3*A)rqGm-;$ZYB`UG%o()z^&Db z=f<=O=0SnBb=ujzdrwaqMWIa&`i_Qd2z6#!jDfr(l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s0;1ij|v_tFw`_v$?5}g`uILtFe=bg@LoPn~ABj zo1+U*5T@59Ke;qFHLnDwHwB^B0;gV3O2{n$+U$~Alv$RV;#QQOs{r<~RVHq?nBp`K zsy79@f8O!^%=>xYXB$Uo zw({M+bm>yygEu_>etu?+EPs=K$2(}9ySsJg_t+1oB1JB2TAPF-~Bn2;#Nk=*lTbzYR%p()Rf>RYn*+xqq}o-RCgP;ik*;YtDFO@d#e z9zPI%`^`b7ahEgi;`qc%7CSPTodllzzNM>h?Y4r*tkfXBgsU;@_i>%b-*&r2tL=Wj zQdrVNhdHO!u3J30uX4&^t<;VyCT={JWiIhn{J6bYBdYz+W);a5=VCrLXZ=i2iM<~i zX!A>vCEcnm(SrNOhvPSIJ1*kMs1As8Y5FeYK9%!elZR_(f}-G@!*a2Pul7sLx%a1<1YTC~wRk*!FBe-ToO)o>+DZ$Z`F3h9VjP0LOFyM9y(PBDf=5K> zxZHMG>5_H@Rn-Wj+aa8YM^_%l7&wQy0ToBKSpT8n81+uTV7OV?e$J4J{mlxfUbUUVR!M-UD)tY@QfgMa=72D729bD|m zzjXbN=;^nP-I^D_JN4O~cO~I!OBcVbHkR7|<HhC!teM5N@9MT`zPH~tuFQCG!ta72 zQ;Wu`YyBL8VXxl&@8#dKzopr06|icwg3PC literal 0 HcmV?d00001 diff --git a/platform/icons/src/debugger/threadStates/threaddump_dark.png b/platform/icons/src/debugger/threadStates/threaddump_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..a655ebd2f940d23f415a24eb0dc34d7eccb8a2b1 GIT binary patch literal 1272 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m=!ZaB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxR5#hc&_u!9QqR!T z(8R(}N5ROz&{*HVSl`fC*U-qyz|zXlQ~?TIxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7KMf<|~|UP^v> zu_jo#udkJ7UU5lcUUI6Zi>(sS0KLr26e}keOIIUf0}E3l3qwOgS7S?Hh&vfOxj7mc zIJ+5{n!xnBem*Q)>He<57#;R&I#I79p3Xz zF8BO9=Oy2-c$U3xZMCv!xaKSJey5_Zz>8!17sg92<$s=*&@1tQgWc;mkInh$p2lU4 zZVS(N`7 Date: Fri, 22 Nov 2013 13:27:34 +0100 Subject: [PATCH 21/91] Retina for general icons --- platform/icons/src/general/autohideOff.png | Bin 562 -> 1188 bytes platform/icons/src/general/autohideOff@2x.png | Bin 0 -> 1433 bytes .../icons/src/general/autohideOff@2x_dark.png | Bin 0 -> 1353 bytes .../icons/src/general/autohideOffInactive.png | Bin 352 -> 1172 bytes .../src/general/autohideOffInactive@2x.png | Bin 0 -> 1431 bytes .../general/autohideOffInactive@2x_dark.png | Bin 0 -> 1359 bytes .../src/general/autohideOffInactive_dark.png | Bin 0 -> 1183 bytes .../icons/src/general/autohideOff_dark.png | Bin 0 -> 1196 bytes platform/icons/src/general/balloonClose.png | Bin 1097 -> 2154 bytes .../icons/src/general/balloonClose@2x.png | Bin 0 -> 3659 bytes platform/icons/src/general/error@2x.png | Bin 0 -> 1824 bytes platform/icons/src/general/floating.png | Bin 492 -> 1029 bytes platform/icons/src/general/floating@2x.png | Bin 0 -> 1054 bytes .../icons/src/general/floating@2x_dark.png | Bin 0 -> 1039 bytes platform/icons/src/general/floating_dark.png | Bin 0 -> 1016 bytes platform/icons/src/general/help_small.png | Bin 329 -> 1189 bytes platform/icons/src/general/help_small@2x.png | Bin 0 -> 1542 bytes platform/icons/src/general/ijLogo@2x.png | Bin 0 -> 1791 bytes platform/icons/src/general/information.png | Bin 468 -> 1295 bytes platform/icons/src/general/information@2x.png | Bin 0 -> 1866 bytes .../src/general/inspectionInProgress.png | Bin 219 -> 1117 bytes .../src/general/inspectionInProgress@2x.png | Bin 0 -> 1493 bytes platform/icons/src/general/mouse.png | Bin 1991 -> 2288 bytes platform/icons/src/general/mouse@2x.png | Bin 0 -> 4264 bytes platform/icons/src/general/mouse@2x_dark.png | Bin 0 -> 4263 bytes platform/icons/src/general/mouse_dark.png | Bin 0 -> 2292 bytes platform/icons/src/general/tbHidden.png | Bin 143 -> 978 bytes platform/icons/src/general/tbHidden@2x.png | Bin 0 -> 1002 bytes .../icons/src/general/tbHidden@2x_dark.png | Bin 0 -> 1002 bytes platform/icons/src/general/tbHidden_dark.png | Bin 217 -> 978 bytes platform/icons/src/general/tbShown.png | Bin 168 -> 1004 bytes platform/icons/src/general/tbShown@2x.png | Bin 0 -> 1028 bytes .../icons/src/general/tbShown@2x_dark.png | Bin 0 -> 1028 bytes platform/icons/src/general/tbShown_dark.png | Bin 272 -> 1004 bytes 34 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 platform/icons/src/general/autohideOff@2x.png create mode 100644 platform/icons/src/general/autohideOff@2x_dark.png create mode 100644 platform/icons/src/general/autohideOffInactive@2x.png create mode 100644 platform/icons/src/general/autohideOffInactive@2x_dark.png create mode 100644 platform/icons/src/general/autohideOffInactive_dark.png create mode 100644 platform/icons/src/general/autohideOff_dark.png create mode 100644 platform/icons/src/general/balloonClose@2x.png create mode 100644 platform/icons/src/general/error@2x.png create mode 100644 platform/icons/src/general/floating@2x.png create mode 100644 platform/icons/src/general/floating@2x_dark.png create mode 100644 platform/icons/src/general/floating_dark.png create mode 100644 platform/icons/src/general/help_small@2x.png create mode 100644 platform/icons/src/general/ijLogo@2x.png create mode 100644 platform/icons/src/general/information@2x.png create mode 100644 platform/icons/src/general/inspectionInProgress@2x.png create mode 100644 platform/icons/src/general/mouse@2x.png create mode 100644 platform/icons/src/general/mouse@2x_dark.png create mode 100644 platform/icons/src/general/mouse_dark.png create mode 100644 platform/icons/src/general/tbHidden@2x.png create mode 100644 platform/icons/src/general/tbHidden@2x_dark.png create mode 100644 platform/icons/src/general/tbShown@2x.png create mode 100644 platform/icons/src/general/tbShown@2x_dark.png diff --git a/platform/icons/src/general/autohideOff.png b/platform/icons/src/general/autohideOff.png index 3f4f45d262c68e79eff8ead6749e02e722fcebe1..7ec50e54c70fe018ee511d015348b2f10df58c75 100644 GIT binary patch literal 1188 zcmaJ>Z)h839KIx5*A)|HVQ4Da*NYZ6OzvNf_0GmznoHJR7^uAVLo!@`9jv54k~KRP?mzjr8p4NXxuS9V9uNw+TB5X-3M1Ox?L zo`OXvtBskj-~fh&p4Libw=5m!6;n^hJ|^Mm7Gh)AK-#lpWg5C*0#0d03jh7{OE}Qf z6h6jEq-14bMH`y6;ppseNtvBiI2BL72nIYJ3Fy$3fu~muhxbzWwl0s>{xN}rZHPOa z!XKC_OCum_+7Pe_Hm;CV5**xnv(FzqRV;y8{VX@aKX2oZN0hAVqg{B*LTs5TZ9k&{->~0YFLmcLdUGx z3c9$-m>+3!WR(4ArbVhqmF8#1{<5l???J#1xJM z5}Ky+Ts}wT`o$zm59TQ<$8anfgQS=db2O6`vn{S@Dm5J%Zi}lvt!nEZQ$PD4%>%Z=~b%dJ7U+#7-+U)i{G*GkKsH;~m z-uMy20?~q)DS0<1Hn+CYA+EVs{OkVx+h@l1-Kq(9_pfXUbJ1r$ow=Rw=nHoIwCC1d zVJ^J58k)h6&%br`n`*V%d+zMnjnMaB3j_a3YEe9`RhUF1%BY%KO+a^(8ja{9yu%`nTMB{p=guiBG2b4~~sgz)(jTYo>f zf1L^HzhR%e*1T(g$o#_LZZBZtI&vVr_20mQ>6ucB!xh%{*et2Wg%FX`KNa^~q vqy+wWWGQNKwP$ZM7EVj&UtjODn^*|Lev#h4()~u+e>V!bVe!J?EA#&VIgE)F delta 548 zcmZ3&xrt?hWIZzj1B1r2yN?+d82JKxLR^&$1OEU24OqZFN3@CA+T8{u}(c;$*0ZslmK6&$<y;cfEnk#wnSm#%G^>I?c5AXi#N%B0~zpp{%v{E--d(x|x+M hTYK~6w+HR@dl@a33sf#^)<^{T%hT1*Wt~$(699lq<`n<{ diff --git a/platform/icons/src/general/autohideOff@2x.png b/platform/icons/src/general/autohideOff@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4d4718721a9584f546d7e12972963e5662bc7d98 GIT binary patch literal 1433 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m=!ZaB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxR5#hc&_u!9QqR!T z(8R(}N5ROz&{*HVSl`fC*U-qyz|zXlQ~?TIxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7KMf<|~|UP^v> zu_jo#udkJ7UU5lcUUI6Zi>(sS0KLr26e|})V>2gXb8}N8CpSYwS7S>jHv=aVM{^@n zQxgL-Q!|)em;B_?+|;}hnBEkGUJIOhK`9}(0BEyIYEfocYKmJ?ey#%8$5xrR-C~N< zJgD9j+-@<$saGH97=2K@BE>UI2$*<4On9mVa^UGcH4m8Bi-4*6?uXxv3=B+so-U3d z6}Rq8v-Xg2lxWC*UppyV=*Y1!fvwv(GDJ@}KNXPX)#!MU+2kf9g7_GMe#u|>50tue%0*zoV2mRc<01ASCgJEEH51;S5ByD zF1>kfM&v{GpZ@9*#q-;p7S4>(yY6h;UlQvTZ1u9#YHr@sna3}1=3Yn*+rjbI$?Lt_ zMAwOGC6@$yzwpkKcyez_Ug3?cMj2Z!C8qF~2AS?Xe&zYjdk5b4-Cdd+xa@j!$pkm~ zmrJxg;wOI7zY;$8#=KPv!q+PFW?#A;t0D4j=N*nr^>5CKx0|gz4p#eCY5z!*J(A@5 zGc(iPM6;SnynvNENx}2t5@G9qxtr?QCe1LqkQbhza+z<5-HsOfvX-=ztjH#>w>F!# zwkU0`%_@#vCcaDWGI#9syD~NJ{+|53o`IPm-0T0c{syBiP+{rm>gTe~DWM4fFn$jD literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/autohideOff@2x_dark.png b/platform/icons/src/general/autohideOff@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..42cbd504a2e843126f49d166bb5da8ed1039628b GIT binary patch literal 1353 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m=!ZaB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxR5#hc&_u!9QqR!T z(8R(}N5ROz&{*HVSl`fC*U-qyz|zXlQ~?TIxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7KMf<|~|UP^v> zu_jo#udkJ7UU5lcUUI6Zi>(sS0KLr26e|~3OJf%cb8}N8CpSYwS7S>UI2$*<4On9mVa^UGcH4m8Bi-4*66)*QA1_s7`o-U3d z6}RqO^VV<)lsNEFGSVZ*!)%*ZM6|}{pnKdaIbA*P@d^iunVo9$a1-+Ns`Q=2YbveH zeV%t(N@Aj;XBVsKKll4q;o{quCQ+b zkME)tR?F{}HI-&eI-m9W)P`=sn1?2wCTh)F8thgdEal{R9JhPNcEJOt=N`F)K4G!` z^jCBBLBpT^>4D1P71sNn^s}Zct@OzvKgxhqNW}~T!!6gCRd<(@tFPrUr z<=llAfm;{J1Yfyv&wI^+5Vac@*Xruremzn2$*e`vFOF}y!y#io?^CLT&8;I+w{N#4 z&wS7yV#6Q$hT~|_I=8KF&rUh*b~jKi$Ch9BnAXP@@inIuR$hqFn)jnK>6v5Dbf3kS z6E@AT^O#$4Z1>~^Q)d*eQS{$`?hV`9BQpE9?vyiTkL{n?yzY2iT+P3~v%ha=U}oU| W);?FHYu_SJ;pXY;=d#Wzp$PzR@#|s$ literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/autohideOffInactive.png b/platform/icons/src/general/autohideOffInactive.png index c8657a08694e86791affe9ab7d4bb32eb3740337..f60866f8cc49961aa920c4d3af150ade2b160110 100644 GIT binary patch literal 1172 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%!-*I5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s0;1ij|wGfsv!3iL0rRlbfNTtFfhliIaVL91WY_2COp*wIq-C!ng>kmMZi>jGT!jSqwuj?hnvjEQ_r0^p}}#b^Zm}8In&>e6z#a~z%oIVO#UkgyjKdoeSd#{nS-73g=ex3 z+vFzfd85jfr006Z?c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxR5#hc&_u!9QqR!T z(8R(}N5ROz&{*HVSl`fC*U-qyz|zXlQ~?TIxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7KMf<|~|UP^v> zu_jo#udkJ7UU5lcUUI6Zi>(sS0KLr26e~j~3rlB5b0UI2$*<4On9mVa^UGcH4m8Bi-4*6FkiwK1_mY`PZ!6K zid%Q4o%WV?lxetoHm|H%;fvDMXnxD9TvZyb2FKj}ZI=Xic`sz=cdZgQxPPHY)oWLg zFKTkRCj$kiPWv{YEh?i}dx_I4*OeU}!k=%{DR17Smwm_m(L!eVnKzHu{5<=oEKTI} zCaZOuSIAzEG1)!oWXhpE_u2Iy*yfm58_YhtO~r|or-CcAow5rVCiCX{_N=RSH0kS#kE%`ynU&R4n%tKFev`6%okC z{I=aLHUFW6--DeVDs}&NOj0RnnSN4FWzvt71ceWM@(#~@R1|AimIt=frIh{D;jHc8 vQtGbB%HDlOHwTR0ym|2X{`@`vISm+^_WggFHHjk@R8)Gp`njxgN@xNAg3uQ# literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/autohideOffInactive@2x_dark.png b/platform/icons/src/general/autohideOffInactive@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..ca7f23e983605ab98de6f7aa6608149e127d3f4f GIT binary patch literal 1359 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m=!ZaB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxR5#hc&_u!9QqR!T z(8R(}N5ROz&{*HVSl`fC*U-qyz|zXlQ~?TIxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7KMf<|~|UP^v> zu_jo#udkJ7UU5lcUUI6Zi>(sS0KLr26e}Yq6GsClS4&ePX9Gh+S7S>{Hw$Mc6LTXI z3s*}66Bn3Xm;B_?+|;}hnBEkGUPqjIK`9}(0BEyIYEfocYKmJ?ey#%8$5xrR-C~Z@ zJgD9j+-|YJsaGH97=2K@BE>UI2$*<4On9mVa^UGcH4m8Bi-4)xKJL$L1_s6>o-U3d z6}Rq8JFD#yC~@rliEzzS<+OA|ZTUn+P5I=An;McqVq%k8r|fq;b*^u3&aw?^@q(Eg zN8d~dJly6Hq_pn&)#BG>vn0RYGcFhN`}?Zo`I*0GtDjlQGhR07t=Yz;e17ePS4WZz z_3y7|ew-ltCRJLZ*R41xkzquKs`1wOe;HF=)SI|a5ihzD?49jFsqxh=pch;`Wk)(ZAq$tB+tg54uH z(+-O7U=?gro4iG8%WlDI#*J*t*RjoMjGMq@9=SxV+2qIl3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s0;1iWM+qjm(_P+)Ry}4GaxkjV(>gU0jWgOkGUO zot)f^%wc+6@{>z*Q}aq-dQ;$f%?)ts1*L@C0-((2wsUu+CtUu)*-;%C5z$joS*h!=jnP!PxUleUQzk>xb_J&B6<$n+ z)&lh`SwA?pY+yd|uW=nm>|!>7}+0s4^(7$y85}Sb4q9e0OaY9B>(^b literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/autohideOff_dark.png b/platform/icons/src/general/autohideOff_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..aa66d91c60a2b0b1734a7ca23d3d2aa208870243 GIT binary patch literal 1196 zcmaJ>eP|nH9KIxLTFW{Lor<#2w^yi>ncQ7Iy57;4rn$rhdo^T%)*-f++?(cT@80X( z)m&;I%MhG@48;#73S%&kIW`xD{-xN-hFEmUurL_NBoc>qY*Z(Rj>h-8rt=Tu!QK18 z^E|(=hkGqK@l03e(DPf$;BE>7(7_X&hm`xDFVM`OUbI=4CI4i3m^3JErB#@;L zIT;jaL5sq?Jhr66gG&?X?9yD8mB{eZVA$fYfC5bsSjxO=a8`)i)aCHrzNSd92{GqF z&G;$WPceQE_ac3kVpx`?XdmVCc`(9b6jf8SJgU*(RN$eJ)n(0;kqT@@ zF@qM(5Q#IrUxK1-%c{m!n{dM@OVlXFOWP$ifr9Y=P(|5B8)gbV$oD^mjdW3iR0;X7 zcGTKNN?k|4b1jhLN8b4IN^j-IYv-qbugvGbiLS-AiDSQw-1_s6wQFycN~IsBKQB4t z6VBa#yDv{y<-5*WY3A^PbN$zHV3Z~vGj#$G1YpFR5!(YdE$vEA*i zb@BAOJ>7FZjk8H%|J6X{qJLlRVtw_UV?sj{E}(J(o5B literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/balloonClose.png b/platform/icons/src/general/balloonClose.png index 9c4275ccaff38e27c9650d79587b473581e0e735..aa4edd0ae465e8964647cbb86b53f8db6614d77b 100644 GIT binary patch literal 2154 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 WU|+GcCAv0#?}$$Bj@9;|Y5xZ9kU~8G literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/error@2x.png b/platform/icons/src/general/error@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..462854d894804ae8253d14522876e60ff0990feb GIT binary patch literal 1824 zcmaJ?X;c$u6b+!V$i9`$I>ac5WSPVm5)+mzK&)X`a06m8kO0ZV$;fUMA}9)i3%Jmu z9I6ONMG+N&ss(BVrL+|hsSDJK!a+8v;)3l&Mf;<4&YAg^bMJlkz3+Wza)JWxAO%fvz&PNJwgaDyJ91Dd&Vrj~zR)~$m z={d{8BG3rYN|ppxki=RHDOsVy*f<>9D_JF$#6u{s5sH;7Irx!=D|kRI<>15VB8o`G zgJg35R0Il54G5E@#!Hw|yq71yPG(^O3J4Vg$%+J}nw8AKzt?49bL}=654?w<@f`dI zQxT#dfCnQGKqt|O5(>B!U@%D_9bD=Gx&u@SNF!5dWROM#sVoYU1=4|!4<3t#NMl$b zeBY0;uoVX{Ls1orOioHlA|=sCFcM1!nM@{`LM2nFL<~VxrzlZzGEu2sFs;Cc)DlFl zLgla$&?<^I!kbYJ9&`F31%>L9tWy24OjyCl$zl~5BvG^}O#?-u|A#6RpU`SF1p4gv zKZVs{DJqB@0;%E6hy**hm<8HUDi#lc#3+n}!EnNK6@z3j3ae$X3gGbo*KoN~3MZ)- zzlV!NETK}3ij@*b$mifO0g_xUWzlIKRQ@s#3Z2TMgP?%Mq*1wiE>pncQbCG!kR}r{nWMC;#1#4O03xttgF#sLOym`3Wa>1u;iYh@b*BfVDn>BPn8*2 zMYeozYcm2scxyPv%-k%laa5ekm?(46Ts!Bg4}K}~uo%_s&Pk>EPU$rsie?v-Y&%e$ z3CzCmX5i-Vg<2@7A=6MlrM3G0Q1RiH#VODG+o@&pCb6llX^N9Y@7$>LhQzyp?+AYw zmFjJp6Py=h;blSF8MyP{&XLGDYki|$S&golbS`!LL8loPwbrQ0Ro5=N{N%0ndUu9K zp4j(x%Z`?LEkjX$SE2R%T<5kdne~dnLGRq3GEB0@w;Qj@nizB&B3M?{Tz;^lngpC) zaCH9mtHc%x=~@wk?o(IKS}q<;Jqk3}bg_LR*JQL;EH)J8J?h-l@@UHZsk4CO6jQ2D zZ2LQ9H*(g^b)->BY<%^OD7!KDE)%rXyZrsUE*BU3dq?~x-TD%~>J9Zy^K2StTgl~T zn?$>xa0fli)(fm7Ds+#Z+mO~T+=1Hfkz6m5&?p)D1{GCf)@RuIWo5%U^Sv%O=C#$G zG9FkV(zcf z`cJ(mv{@oKd_Fak(8qjjSXdMxo^a^-O}EB)U5A_Jo7R2ASkzjX<(RQLz}&Umj@y2# zyxzkseN`S0=vxy1*s!P5<^<7yR;Aq@LH=8l${eP-LqKe+^?sM)fB{mZ{>o-lRLjjEuC01fP&j*gt-LqUY=9Al=b|y-Dn@g+1+wSFihgU2*Nz0$FF)um7DQ~0RFmw+5 zmb*cZ&l)Rj;Wms7o47uIz^LB!bI>JKgV{ZUf^}Bem4C&_?duAb=S<%I+B`0>`$=P& zZNL6VJzQ8C)8y6HZHj(j41^38<+jytaWg7_v($yo8=&9EJs)=)r`rd!-<*XQh2PD) zsk$Ff<3#W~miZ$7HfvYw*j~=_h;6+Z|Tc(#qNfkjfaR4oM5BG7eRBQU0vgVGUoba6EkG zp*MTEEO64nhn{X=k`!Ox)I+q>IN6;^Z#ni2*}Yj=0AzM#rpsN literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/floating.png b/platform/icons/src/general/floating.png index 9d9581050c6278c59ea9f2a22be3a0886173f51a..5ee3f199997e3e9007feb60b46a93dbd2994423a 100644 GIT binary patch literal 1029 zcmaJ=&ui0Q7!D4kOgDuchPy0HWlXU7(Jt!}mbEoWx583tS6q)vlW%Ra5T?c7E4O59SiRys*aE=GEAeHszE|4`fRqJ2~XfBgPa*e|cUfGGhVu6YK&xaC+F$`xe~=m>gc2v<8* zEY=}{ejU1`ER*AlmSe((f35}BG%@e^NOug7S0oAx(3WM2DNg2uDK*C@C$k)cRdTp-R z(~GM1aWAYbf2)X zy*dBlm~nP&Y-{}f!@KG0GqH-H>(R&eMrX9liOJ~4AeYH(e0_D})X7`J%+J`~gUo*9 z_3qBj&ZRGd3HKX&2wH{rv~s|DrJg{7_E0!K!w literal 492 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh3?wzC-F*zCUIqAsxc>kDAIJm(AOpfiBjH>) z1Fje-0uclo03x2g{B-#Gmm@d6K7Rgj@5OhIo_~Du;$#2f19LZ?+i>LJlNX=X9Ju@V z#mA;;n>QbSvhnDnCoexuSaPs&>ZT{pKQv6)xM0i0ttX%DyY&9hwaZez4zqHKQy6({ZNy`p*&)+kD^M#H}5eI=zlqw1G3uf>&Q}oj?_YM@W_t*0k zW!Ld?Q48nh(Xz4^ety*hsA{^Wi(^PdTP^C4&HTJq_<-C?mPdj{&2BM z-&WZqL)tg&#ShJTmE@M4-Mm$g|e)^AYXQ8@nbNWoD>rZh|`@n4d z>+V}Yuf=;den{P6q#QEB_?{|~u2MGtsZn{`uwAJQ(fZ|)$-vKjYT~xQ-%PH3` tc;F&8RkVQZ)Xe6iS!?CGO=j6R<-g4rJ@isw%MVasd%F6$taD0e0szJ<`bYo( diff --git a/platform/icons/src/general/floating@2x.png b/platform/icons/src/general/floating@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..e7b51cbc1a748545838e4fb389ea13141a3541b9 GIT binary patch literal 1054 zcmaJ=TWHfz7>=tB85<4-ofj}mVK`Wuq-os}mX)q)UB!&q6;}|((&Ti_w&Y~V*_sXK zgCNc~nR^kDfeH>$5q#Lg@CLpJUcd(*h9F)*1Yvs-h6?kfTdNP&z{$Drec%86|M}0w zzTRUEbqDGQf@nzfNNGGD^2W|u{I?t4&*N!7N@P(#%%h@W10tru93WGMG7Qo{(Wb_q zgHD3*HS3uy%E~7M6&gXs!vtN!!fb-*jJlShjsisHz_4zL)avqMiqtic8i>e@Y{fxA z@0qqi|8#FgogP(rjf!@Wovwfd41g5UHO5Rwa7C)5E8w+vOjBeDf<{GZ(^OXOBjeBp zWF!~~s0+xZ|HVZ$A48yR9)j%GNTH=1%xbt zri;a5u*e0WJxsGa&(lnZ4ut|35pbqVq__do@s|}O;Hb84Asw2er>NxM1QIFibTb9R zs>qtoR+(_YXjidlHpqA>m4UMSf2d(p&<;w2KYsry>|~}aK&OENCu|j8T;A`6vV^z| z6a?)Igk$9@_7xz4P61kEJWd`N&`k{%oz@aumW7n*AjMQcN)jn75Y%-|;6qY(I2KMu zxT7(aO>jIT#S=-kn@c8nE))ruxe`<-3}B)%SF3O%OjWMe35JCuOTgAAftIwPL6$NW z^y*%us(M>ot*V!BqAHihW@ztT|GMY$5pEuDS?OB5sq{TCakJaFtG`Yk|A}A3<&+f5 zxGT9|8yiudxNVQ`+S9eAOFOO(<#N>Q^^wo77NQH|YwL|K!P)sNQGZv?2HM)%ZZ7Y7 z{iLa;rl$UI*BRo$K6>z7`?s|2pRc{}aBl8Ron8N^xH|Z(km5!@ES|ryclW^Q7gxAj zdG|+SR$V_?m=tG;w?Yg0-n@9*cj}`%la1aZM I-9zVo1Fkt#N&o-= literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/floating@2x_dark.png b/platform/icons/src/general/floating@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..64874e19a2abd9e4fdc41d36bd80a66e5ca3db7e GIT binary patch literal 1039 zcmaJ=O-$2Z7%m|Yg8}@D1Tj#{1tMG9bp_Tim$42RaRkN^mY5j2_G2s1ezpBzh2tOs z7h(uE;>CC|1oeRNz`?)7_;XPsCYq=hV-z2ZFq1t`TG6jd7k%q-|zhv2l~%f zSDmUN2%;yW9T%H-1eF_ygM|Rl)7SI5aNL!oGEy4CvIb8v-onx9Ja}YG{r}j-Hq61_Inty%Q#FtZb<$Ckl5i6FDeQDV1Q=r?xL~v`88qu=oRkW{X!QS3O)H`;6axo-|0!(6rwu^IfCVQ_8DHFJvlGe?LMD(9 zG~*CX6skCoh6q||Xpo^0*)pu^3d~roIe0WGM05*Dx(p(spTYueRaJx_!-d%p=jFNf zAj^h1Uk~3NYUhKUVuz0j2l)b5gz}^YbX4Ff2VA}+*Xab!z>!5@s#8GeF`-80G8WX* zUOXlB@?52~7p^3i#%5^eUjMr1!VzvBXIbo8yealQ&~dYyxU1KNniu#*%tgdt+?nzxMFwy{i?gBM{OH*T+7etgGW{8k?xu<>h06zP7L1+wbPKy3@?-t@+fQ z)`g{|?+sHoH;(qrKHlBk`E~Xwn;0BqlN&ec?;39&4IW-xb7iyHu`BDfJ1ySL#=g~; sALbu?skqeiwstN4yz|?|k3?A|ab%_8RnL>#C!8l53HOV)x<|5q0NYAYQ~&?~ literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/floating_dark.png b/platform/icons/src/general/floating_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..78450e5e759313241f9e89cefd93cce3a3991bd1 GIT binary patch literal 1016 zcmaJ=&ui0A91q*v=5WKy4i3S$)IkNCmo&?^gw@eDtt~8LbcGdBFil?9uq7`hZ#L^; z>JGw$A>Idq2zn5~i-&p8lb{E|UkLjHyoxY~2XVf1ZRf!nczHkgd_LdL_xrwYbAImP z;K0ZL!!U#SoLZpsP&oQ~>HkbF_MT3sNTx&3s-ml4R@`VuN2-CVo&22C?e z_o!7Yk&-s67})0Y5W@wwOW6!FJrlUPv5W{Pqb18pu-{(1WPxQS*hNX>H8+i_R<7=$ zh5B64s4p9`$XsV>mgEaOKkT@x3 z@WMEllsQ2X#;1hyAkGUS5Tm%cq$E%(}FRl^^L%B-YLps4;5#yCs z73Zs%V84o8kWPc>qUD&l=AUc8HBHGoKG7Wm<<$gB1vtwxmC1BgNJ&$wBu*p+AtTD_ zq&lU_88H=)t73Md#Z|GfY9oiVxaJWz(~%o?g6-1CD)OxB$jo}!291mrtFxC>N4+N3 z?Cd4okqfCA7~bn&_uM+7%@Z!$T}wCZzDEvic8_-TSA7f87h&hsWHHz+|2jCB>6UM9 z-kN>YW$f+mZ$uwFfgD#clOK9|$HvCie~$my+gnLJ|9)bYRg|5(XCHMXBPa3Bjf39< zm+uS@4@aUy+oKQf9lHXe(Z{z>Z>{%y`qKUE_|EHkVf$^)Vf*@d=JUsqOYi#bN5Z$5 M&&;V$Q&%_s08)BEMF0Q* literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/help_small.png b/platform/icons/src/general/help_small.png index 6c04835138fa869edd4c1af4bd3800cd007b499f..5f418a165e803893e0ac4469845fd0cfb64094d4 100644 GIT binary patch literal 1189 zcmaJ>ZD`zN98c{ib~@dJeON!(m|2|IyC+Z5w7uB#dY4??iPx3u(cVO1x#VdtT=Qb` zbeHx+>)b>){8EPCWI6_dpXMeT__EH{VYhX|9fD}NtSq7v zhSHBxNYRE~oTd4_KDL?U1ytk9k@V7j6gX4Z5?viGk6L$5(_ zKFr)rDwFJ@CCfpy5EKF`3!CVcP!I~RsTDTT91D5C@&NJy$cb!7gaW<(FeI9z^@%CD zV?7o*g_#`2wg^C>PzVXWq$UXCd@GFc(H6cX%6G8M&1|g9l`VD9KqfA8wR>E-BG-3u@ZCUaMHtE9VlesJG75D(4cb$OR-B;Lr76b1q*I^Z45h*OJ4A?~zH&?hse+ zliqrQqN?f=ay0FIpIu&EjZ`pYqdg~t-M{6#n z=$;oJ&7YcR{PybWV`HBlfA{FY0|$@J9p428t~(>O>iIo0)0d~d+V;it)b+_LU*bdW zx1Y<; z`X#HNq2lBf@6Q__*U#N>Un*t0FTVjAL~Lx=vYIy6`|Ir^KOfS1&R+egSeyr=E6Xbv z$M+AmC2DJbYwEc4a61^U;yx*rN{e+Le0K80G3vetsmC|upMU}9mpOL8EZ z=JaI!{rh+QpWnaV{rdSUkt72QGde0++1aK71N6rCZ$C`-HKm*-$_p^S%Fdq8!p{C5 zXtV3luI$&?)G*RCCF&)&uF^|sT|ja|f}7676w2`b|3`dk7>9ml0thew)Vozq?n}|P Q00000NkvXXt^-0~f;sSqQvd(} diff --git a/platform/icons/src/general/help_small@2x.png b/platform/icons/src/general/help_small@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a879dc2c378627805206194fcc766f77b0d2249e GIT binary patch literal 1542 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 LWkOz^e{}jk9W2A= literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/information.png b/platform/icons/src/general/information.png index af48de9608645053a799d595a02a28ebe9ba12d7..4d3783491c28cdfbb61ed2cfc1335aa9e3eb4d7c 100644 GIT binary patch literal 1295 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m=!ZaB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxR5#hc&_u!9QqR!T z(8R(}N5ROz&{*HVSl`fC*U-qyz|zXlQ~?TIxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7KMf<|~|UP^v> zu_jo#udkJ7UU5lcUUI6Zi>(sS0KLr26f08~14j!JS0__rGbcksS7Qr9M-w+oXJ>O4 zQ*#4H7e|<0m;B_?+|;}hnBEkGUT2(oK`9}(0BEyIYEfocYKmJ?ey#%8$5xrR-C~K; zJgD9j+-`BisaGH97=2K@BE>UI2$*<4On9mVa^UGcH4m8Bi-4&*y?o|21_s6!PZ!6K zid#p5cl#Z75ZF^J$Fhh+kdakEabg=&lBUOrMT-|Ih-?XHs_0;|Yu0yo!u^T4rHSpL zI%}7Ph{m&z~6d?0e; z^b(=fE?;CXx~yQj-r#%Z?9FE@8ttE%p382%IcJ~A++>4A^>hmvn2{NC| zSh@JnHF2H|FYnt_9q*Lj@Hg8vEnCGzj%#&qxTvgQglI`i+L4AYxtGn31v9^@$&NgF zdiU}P#`W8RdyQ8_^jREPDBc{p=8W&EjGa!d{F{}R-_$N-6Wfrxdr@23CDR#i!sHGq z)%L{y>e%uoJNZ3R=?$wE@pT_wIh=Q&Yq5&AT#@(R`|Tg28yFeV#r9wQ6Ja6?Dxy4H L{an^LB{Ts5Rd~yx delta 406 zcmV;H0crk^3e*FTNPhu#NklMfd*0tRM^q6`9DYz(PZDqsv^gTz2`Ks8%|m>rt|>3^cU90qd2JPhA|{{`bm z@4taDj1Q6ns?i6kO~VKSAc&IS=VJKw>knLD$*KDofd*3Z`ty${AagRh0Y*%Wj0|6Y zA`EEt(+AVln=T@v4X6eP46(U@;oI*&Fa;>!E0U}JLDJ1{YzCbB@b#AkJ1aA$0Z6X; z2@DHpv|<>r{D0&3pBB9T*)RPZYKq<@|sIcJg zzyD|c{QdV8gh6bO7*Ng(ITeBcD?EnA(07*qoM6N<$g7^l# AnE(I) diff --git a/platform/icons/src/general/information@2x.png b/platform/icons/src/general/information@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7f757fa394022a63f3d067422da04a980e2abd53 GIT binary patch literal 1866 zcmaJ?X;2eq7!Dc%QK+Ef1nRM@BB+qf=73~PP|Siv4QdD)qbMO+NQ7i_Y?=^{f(K&9 z1056IAKxjErJN&3Bk8#)xZy?u-#l?_M~)>V4*_diN6ED;FZoK(2HB z*E#oWkdUmnqr+#{jC>&nhW=J_S;_b7f3+?f&5hmKl0;Jud?@&Mz|s|0 z-a4i^VXqCV7XMmWaN=bQ3JhH0<(8$LbEeFAN8Qu9tjZ|D2(x*e97RdamjH|93O zpvP|EltY>Q*7n(%864_9aJByu;+Npa}Df8u0 z>wJ$b4V%yoaloPUCW&eGUSewCwKoUUH`wuPH8F0+!hHkmj*O+bcLoe|*R@QqG9)@P zo}d1pw9apnY49uR=8}}gt3l(9J8IfcdEvbk*sJVlJaPteV<@Vl@Y<5sQTZpFPlXV^ z(ye%L^k8#)z_>JiK(pvZdFeXUAeuEI>P~02GqO;s?%a;C*^$B(%6LC+QN05;gub*> z>bjZ^yIp?YF23^nvAj^)f}D=Dc?T9GwE3<&c1Tkye=ExWerA=$_wWs*k>k41T7rvVYAz-!b)wEWcsbc`o(cv-U0T z*&=RIv!O4HU*GJV(Nz0D=Hc)=X1hP=di6wa|IMKxp0)2PX2Gw#-Dp8KcNJr;0)u^5 z!S`3Beg(A?+OP2n<%6N-_=#X z;1JNxl30%ywPqJzslsNpJn~>AeIX9oy*Wjr? z7n#VM&QlhTK3ly&wu*A=T4Cpaj@oKNz&3in#&UIfQ0wdcQ6GVvswr(g!)!^VGxr?a z;v-$6b}W*QwI^kqni@RP+r6=Uw{Y0`;kzfyhPc&>#b@_`x9W%M;i2oP_Mq78KkYtO zgNVAc7@?fYxla~T@D`f^KZZGxj>iqrhI=pskbymZnz^+(&0 zvbE6YeTs(l9l6V&hOB9#z2CThlx3mEgNkX#G#l?<$L`l>ecDbRU8*-sJvX2E23*KE zEWGRI@nlT!5Nb*vag4ivu|&vRl`XpOwoa(z;P%t`l>b;&;k{$a^_?Y#M7 fXYh;oOgGBf+~k)7$LBS>{%)e^IJ9(f((=Cnwe#g_ literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/inspectionInProgress.png b/platform/icons/src/general/inspectionInProgress.png index a3dec2b95f40ff2fabc620fa1013ae2d4ee1e305..34d4875e14d4b72243d5bca19623d401e6b620d1 100644 GIT binary patch literal 1117 zcmaJ=S!mQi7)}qg)(anmwu+7^cu;q9?1q}SYmJ+(yI{()U9k@erpas@Ycgpvb<;wz z^~DwxL=Z$DJRd9`pn@RYAcBY@g5XgU1fk$V!2?mmbyB<42iL%44!-aEzyF_qMl)@j z=hrsWQWP~mol>%7o*RssS>!)wzMvog__ad`w+$` zs%nLq>%blA7D-1|SPL*=-*O0>qGBz+qv<^mgHG6G+HrdF#vK}%Mx5RzsI2NFV7HkX zaAEsETTUP7(M5x9*#Kg`LCbMs_OrtmNkR+a2EdY`%hsn*Y7|k3q925>g3|`jX@|!O1MzN z$ju?NyHv$YH^Rv4Mh-|M!0K(LZJ>g;W(uyVQrh;gX6rDm#AzZBHcdlH2r|n?Wlo4h z1&(Wth)F)OiI;`uRyoSaqEO;0Nbj?tjZ0kP50@{?4LZScNMr@N<{oGyU1Wi&j3u+I z7cp5@Z<=eA_rjLtGQFvFK9lgCB0cT>d*w3nO#lgWrdA#`gnzeq;;n`z)^`eanzfwoqLFyOI&qJ zTy{uVb30CHFGFB*f0O_J|9FL$eTtlgk)pW2$-BbKzQoPP%+%Q2;o02c86hpRZ}}Gh z000VfQchCc-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxR5#hc&_u!9QqR!T z(8R(}N5ROz&{*HVSl`fC*U-qyz|zXlQ~?TIxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7KMf<|~|UP^v> zu_jo#udkJ7UU5lcUUI6Zi>(sS0KLr26e|~VGXqygCudV*6H`M&S7QrjBWG7*7ZXDR zX9E{tG{E$_ACe|Cr4ApZKaM*&hU%(axNY_ z@4D5)g@dzHv14~s_xX;MS2Cua|ET=7UOv3??2UxR?gh;D?`pr#`&{2%e17kypEZ7F ziA9?fe}8Y8+AjX5&R%w1lkEd0{R6xT%wHVhnr1IJRFl=}l=!x1<$}p)-#5w4u1~$+ z@^<&Nb2DzvOSw0>bL`4bp4Dr` zV;FC*Iam8ZZpr~|l~0*#gB$`{AKL9$9<5g`)bzL zhZQz;JpY$R+-E&hxb(q+?42=nmJ&R5oUKl3txk?sbNM_~gj#;x$}tn-U^y})M(=p~ z=9_D8=6q{36L}!MbVAut%@5ZS4Cb6mF`5;jlNO{kb;;d4;k9AjY|V^1HcUg&Py?GZXmGUX3e#ObI__7v(r&grG#v^H+Ne)EJ5t+{^j zE;-Y))(F{k>RhS+t+BACsBDLOOTM{OZ?OjB{rBI~yIogb)#`Iw9N04JZeBdw!SC$7 znP#)MWaq6Fde@MBH!oba)1{@x?ti7#+%EQ~MLRp<){8GJo`2r`g&g0zWD6NF0pq0Y z8@}J>X0qm<*Ra5C@y}-^R^M&q_|uJM?l_s^R59=UqPxGgM!o%$VPeI&Km7sY552t# zt6RjkF|WI#{6|3rt*5J> J%Q~loCIBWREcE~Y literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/mouse.png b/platform/icons/src/general/mouse.png index 4a131be9256fd860ba0a8340d0e8cfb082c04221..4a07a796641fb70ff6f97fc36800ab71af6eb76f 100644 GIT binary patch literal 2288 zcmaJ@dsI^S7Dml{poy;vO)t_^Y6%<=5RzOVI8th8l$Mnu9F>%ZoMRAWO)92E-BQys zwH&=_R5nd&t+AU~&iE)Td)YKq&wVZAELTdE~!-9r6QScgBJggKbKm=1HivuxSi68-t00p9L zDQ%!X0%7JM=10L%p&@jkOo9^_F*ub(ZeSx2{sAhvK$rx=m^d&&EM;H^8yc|~v50|< zB!?10<$++LI9RO!*QmqzLUodmCc*}+!1$}^h5!-}7GPA8WGO^fF|eQG(hYm#H6Dxk z41tpv*gr)@h4L_gG6jesj0Lcd+(g`#=K*mfz zSVK02D4rg{4w}woI5Dt^Ff6Cz@k*rkk)}Zvy5+w4_&@X|d(6mto%kV0J91q|Kc!|VV*Jm^Y zM}U9H_$nIWZj!)DEJxl#xgNQK}GSNs<@@Nc>FKm{m(WeUDb zmORrvUZM<^L5VUsCNL1=87Y>EWJ<`(=j}3Ffmkbn#cxGkqy64uwKB zr1vvQX8}}N5RJ+q`vNQyiOI%Jb46b%dz$O_f4O*r7`(Bs|I_E0E5q;@w_m2#aQHI! zpwuwz3d2+$2B6Ch98f^0tTS zQ2PROnAw@*W6t(SR`Ztf@Y=Xt{d>mBJ*%_RbHXcZxgklOPF@={QPCB_X$5z0QK%E8 z>l@E+zq5GpXr*g(@z6PH0|~kebt*fx4lTe$fJI~ev3b^-Eyp9x7)LFglsmTpAA6C0 zuQ?AAy?AyTj|%pi_?z#@&q2HbXD_R+vN*dM(70WFzk2e~KS!5V>iOuid82I18teFE z@hRQys+2Pveeubns}YML+aQj#P0I;9-olMwkO=8EHcqn&GL0^Ub@?|BkHEk zqc?uELGjiv6TX=6fZTRz2F(|;nmeKt6_;vfKQQ&TusmTu|N3V0l(vSNCvi7a zz7IV_kYr#-%JYW>_)YZ#*FxYR4ucbuu0SP%Ph+mi*kqrxLfyASW?oyjR$ ze&6)EH@%Lxq-W^0o*$2oeTKVESzLJc1zPb(wNB@>QnK~%4}I z)cKiX#E2i=D$u?VZKqvaV-n8Kbl|6eQ<_4vtR~msjp6gp5ww?^8s;vSl`OV@o%IRT z{w{EM;}z)U$dbxdDB#Wgiw}=pUwv&OccG=0?h8+sxyWwZStrO**Te9?y;LVu8n3uJ&J?+sqet_e@=S#*V zE~gH*|E}B9)w?OJu;~=@&aHtqGo*VWkLu-r=#qBe$&-W8!+To?9<58Xxw7;{*tTVs zS4&WO%5U}aGu!=infG}|ulhM2Vt@1V8E31Wd-ocOwF3p46S||gT#x>oP3nSGTJGFO zCJxs+^P`)gVwM)CBH3(>dTAT)UNQ3PB5OB5s$hpNr=7JN?CEN73fa?Ciz~cfPjL*Y zq6$EV4a23EU9)x`%YJHq)3yd-Rq6fOo}Gkbxyi$JdcFDy&2t*D`CWB3!ud^lwX~`y z{2~F}6?Qkxom+CMO<7dsIypD_-*%5`(is)pftFDVz~@LE?q{cnd-WH}$0mxsqb6=w zQOmCFXC`kcg7z<{R(mr?ZYa}UU`A1W;cLT-P@e)6e7DN3m3y4yH#~PF&M*A*wS%#%^`t1He&4pt?x5;AWR>$B2>n`Pr zi|19}=XxsWPv*gt>VBW|B3AO+$C?SAZD{oY$9k;=?-#q+BIN!Ba^`8Q$%p^A`qq>* zz#_C|s)JQQkbXQf)65}da-UZ}s^i@PJU6n=@@0QV9KJPwj@vy!)%e9Z?u{7*z3D}( zH=ocfDLNU9DAdLPvPGM`=Pt*v_~zr8ZpSrGW15-G5vI?p*A3P5WIvrcQajw(7sh;Q zLscyut;;C8>aAu}SrbyIspoa=G4rc5P8x!x-R-7DU8Q>X`<1h@j`zX{@XqMqM>Jvg zNC)b%2lXv7;i2R!Z&ttP6;Lj-O1o!C$IQs+M^;Bd zw2|xco`*enNZPpPPRi0%XYY5L(uZ7!$dn00x~p}HwVK;G#fOpFYqAx&QxWQuEdi!B Y2ydTXQli?N>x};(TuvCfh83IsUkE3ts{jB1 delta 1941 zcmV;G2Wt565yuaZBn<>-K}|sb0I$e51&ZmBAt!$aSxH1eR9J=WmseX+T9 z;JSrtvzeXmyvZ%`JZtOR za0!3bHg*2XkB)VwBQhcHpVIi;+QCDrxkJxl4hOwdcHpTLfJE zWN;5i;^gL^2%bk2EO`N+^)21s>X0E_=YAUFTVn%l}&iw*aLxQ6w>9tqUrT8 z8rlYtmH!NeR-XM@CZfNd3&0+@ilbF&S&wkp)afDXG_&(r>>C)TFn1yGK_Z zA4F^K1l}qa&@(!ZuE80+?wiJ|o(VK}j-a@r1$q{4Q(pntiX`yzzk^H0qQ9MVUNPY> znb~^6!ch!+mtdsimO@FBw|0N@A;07W8fb-`!?PH8zlxE$4;Yz07PW_FH@N=($rS=w zL^r*61TjvL8-XmN7~00dqAvhW9#VMv-NtDu9b+B`V8!=`opTWQ?qTo`Pef{N3HA?E zSlRl7(S=QnEpKCd^&=+Mb~&;3IQ6k-4CLJuL5%$l(b_#mi8%nFSEPSR(^&X-4nXJ@ z23M->(*RmV{MRN{Zm@L<1kWv$t9=i@Sh$I!(cL$K-Gk4V-S~tl()-PQ%xoQCmc-gq z8+#ng*wQwJ=Z+yL5^Ou#dnaitMo~mtp=<6k$N|{!{Jf?q5L|^0KrI9hZ%7x^fW+2$6AF zc}nY~B?6h$ogAADVyq4#Vdeg{GmvT+6^= zDi3JtTJy<5LSDrvpY& zR0ZFlc)0sS(+TGVZ6kj73GfwD!FEPgF$xQxVSRn`3;@fC4}-&)pI?QN5|Nc-?{Ov6 zw=0oN)~>49fD5~MJS>B z!T7{17kc{T@_;4dI;#fq3g(c^8GA`GO}>~ z;u!>?e#O{P#UNNDI=Tk2wzJ12;4=BbELDM$s-S;wdL3P(OK9txK~3ubTxc=s*Q{61 zy^?)PL~Cg;3WN#y!dLwSLDsz;K)0a#_a7sl@}j2c4f>{*Fh|#g1(~Lec}OU3=wu@2l(DHeELp9x_)AmZm@& zl>vPznN|?B*;ylS4TatfA=Gtk)-D+EHO^eg{;12wydAdh0vgaiSVmTS7p(7eHGB(P zUH4WGnb(@Of$bjMBloCu*Zy_QM#&a)?v?C3u|K$O?zG0FO#`qfeD8Msh<^S*CVv9_ bY=Hj&th>)9iEm(o00000NkvXXu0mjfSfIq@ diff --git a/platform/icons/src/general/mouse@2x.png b/platform/icons/src/general/mouse@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4abe2c8aa15456b3a5452bb0a7c0a9c3782ccc87 GIT binary patch literal 4264 zcmaJ_c{r5q+nzD@Wsu79QqvF;X2wpoF_y86WvFb$m>CSlj4>Ew%~BCXq{tS9vXrE< z3?h{+uTqh15Grpm8D52N>R0dg{qcUk=Qy6{zVGWe&+9s`<$3;i&N@5VhzZLH0{{Rq zTeKyXyPE&F1^Kzp8dBIKcaf!Axzk-K{`4pujR-&zD1JnUEg2U;#1e6Y=&)x*V*mhj zfaK;*cgHvw;VEQI+z*T_OrXbgF>nkO zMGPdNV`xOz7)LjJOfcS%05vm(7&DBx4#-404#FUZgoYb2OrSsg8gchO%rGeACxjks z0{xFDcZ@RxMWGQPx|+HgcsN1_qHm~)&_(DNAk-mRaD+Att_?$IYaq0Y;D$yBUC6Hs z%8f=N_#0s@t$)Sho=l*DbUM`t28)V{(u~s9q|gFj2tz|d7+edcrKQ0|XoN?H(s2xp z&~U}y9xRFBcp8aHCs9HnKRn|6C=qlMC|Bu!QXo??n139HhW{!Qw`4E|jtWC)!eM0c zkGy`O!|7P!|H}ARbhukIl?cNU!zmFoJhvbIioeO++Wq%HKY&~{MwS$O1eq90x3x5Z zaxIz!62VB<8ih2_N5FNpb*&HxD{Tuy3kxfKeM@UyB+5WfU;j7PHZ+`$3&j(Eb4mYj z;nx3^YlNZ^adZmJjY0|e-96_(3Y`)jNTEVdD2VEDQYe8E6@KVPWq%1J(nyg+f;Ejo zhWspz5$RvTBX#sFtn~Esx#10dN=N7$S{v$H>FOXXw6&3z&|h4_zoh+(Yw-VaVO%k= zAAS8leg19Y4$qJ6KU2#+{4@8&Q0}nPxKqs(^1*Z8GzD8rq#I-Glb1;52`ky+*AK@> zd7wHv2R-+rm8=!jOdG_7Yn}ZnRm+3_`<=Siw*lAAw3J|}Tf%?=H(C244cG-I22 z$N9*LwkT(Zyn-s#QqtKZ=)H;9q5h4no&KWO(B_udsLvB8&?d`KL$Utb3*UFl0xH)} z%0D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 literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/mouse@2x_dark.png b/platform/icons/src/general/mouse@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..a753e349e0ab82e06b65c86adce83c1cdf1806de GIT binary patch literal 4263 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 aVa#AzCwgMOMb=uN76wmOKbLh*2~7Z(=__df diff --git a/platform/icons/src/general/tbHidden@2x.png b/platform/icons/src/general/tbHidden@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..25d4326480eaef6a79263732cfca15ce3e01db73 GIT binary patch literal 1002 zcmaJ=&ui2`7)`CLrBb0FqEcZ@K@_|BwcWNEH@4d(Ya^!A?LrqsZ8n*9Lz_%YX5Do0 zP%MZ-3;qY9Uc`e3uO38%f@i&`h}R;B2R#aPvfbT!a1Bi62k*V_ecycZU~cx(K>x{p zhG7Pb8LdcXkc_?*{YQ<)FFKtddYR1QB~rIS#N-`ZLBQ~=WmH6#vv%tp$}vpuX}44+ zW%CNOvBy~nhKs#`vKb~f83&fVf(WRfW!G2OAFp1sz;zUMA!`a|prWcf(+JUgW42^B zR&3c}Coh6r45@&Jhy`MA)sJATuuWY^*U2%@f+mElDD0l8vN;D-93qhAvT0ioN5Qzv ziCJ-ULL32-AZBMRd9B}^&MP~&Nbnt2@O9YmTx0NQ&=j%xvm2y?6o0Dx-rb#iJ9Xg9y`I#F zP$-p-Uf-yEe2F$U&L4cZKDzb&4xD(;99zt>;hSf@g;T<}^{a(0n8T09 tKHu-}*&ck9+WBG(4JpIhgI_PC`UGa@$-s^JHT`+=`V4(mdojIu_YbePH@W}- literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/tbHidden@2x_dark.png b/platform/icons/src/general/tbHidden@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..e6358ef43cb9dc2498013fe821eb228fbb1a6b7c GIT binary patch literal 1002 zcmaJ=PiWIn9L}87F_|zB(J|qffhex|*QQ;cjk9Z77cgV%D(gv?CU0xpl9wf~HY*;6 zf+$Sz>On-jh=SnR!w_NM#fzR4(c=)ri$`I;bZzIs8hCks_`dJ={eJKF?#<3z8X6oK zWEf^hn^sG72GJOZ(SOiv{-Vc=s|aY0v5ZQ{u-4b!p)AAnpR&sp zQqeC%6FZy{VYtxoD4Sujlc8srD~Nz9TDDz<{rP%}1-7NI3$iZgULMu#>86k7n=@sz zxngE4cJczqhL8$4h!`MrR^0%G3ft0!bR8Y@ENDT>@V|T zCX?X>iI=1}MZ|-3ml$E(4aPbODhf>B_K1yL5Gfi}Tqg=ko$jUJcwJdHXqSl=j1LWu z7datHsRPvY|3e+8iw;N$?fd))xuw4r`g0n5Su0zcYh~b(@Qx%p9aJFqhNmA44R3aryc}WxtiK$dk$mOJB zK~<-6nPj2ERk2xjkV`sTYoD9$$&EU}@n~cf`SuND6@Bc0R>sio?Iqb$ug$f3dy#u` zd1{7_?)9&G?i|tPiI&~2rJHWwBbPS2PrLf~w};p1i@2t#xpMfa`g?bG^6kX~r|pqbf82x5LZ7*1IgDJ>LHs9qdX6${-=KALV5n$~TyZ5NudZWp>056vdCyP-`cCbK5( zMJcGLAl5(OLGk86JP5scEqL)4s0bdsco6GkySw$^8ko!n&-1*``_4O$N-K-QgBJ!F zh8Zp{8D%<;q~r7{`oH+&(4y0MQmB$uTqm&=A|~(P8UjVnYM?T*obB5m&na#1vO_l@F7`pHXw`6wXe@Pll!6!ZWc{d9CR#9-6`c^yNZo z2B!D=*FATSX!E4YUf0r1ukVphn?0mm{qV%^FZ4w$7L9x*`BeLLcsQ52a_^+^>gJor z6RZ3C`=jg6ejZ%@dUr4$IKyB4cy4*L6_>648Co){{X>b|vkqiSq zVspVivb_LIS;-_OMu?@9WF~l02HNgUrWrdKDb3CR0R{k9l@dLn9xg?u00000NkvXX Hu0mjfi%C5z diff --git a/platform/icons/src/general/tbShown.png b/platform/icons/src/general/tbShown.png index b9689ea10b13e29463d5945482513c6fc877a25f..367d9bcfe9a524e581b0e3214b2c62b4928175d7 100644 GIT binary patch literal 1004 zcmaJ=PiWIn9L^XU+i)N|O)tJ>3JPoTlC)bBR=2KcZNbdZ71kYurpenHw&ca+ZA~Z4 z>19qlD2NEVi0H+Gham_m$k2n+i&w>iH@$iApa)^TbZzIs8hCks_`dJ={eJKFwq~Z! z_4gg`V;H7CmsRt0J{pdmZu&p*V_&D!F_JElS-e21x`&vgiOUG&Y<&^sk#5#5?V)jo z=^U~OMN-txD+abXJ;ZQES$kr!lH=Ap=oVuT_he$63z5OMtBrh)^P!36si?1EGZoSw5B6IcB+b-1P}ImaiuW1yUxV5tCSS*9`up(JPIWK2wnf{>Py z(NP$WLMao4qcEBln_LweD>iaSlWQJwr`mGEPOx1XSw)_;ip-3MZBWlxvD$lyx7BNK z&Gug8wp^Z?;lq3V>zC^lkKR2fZJhzx8W<@@4P!N4?)J-*|ZUYS$)flrQeSnH;+RxMMr};aTr?$NI^^ zFJtl7rP7ho?!eB4+*a4Uj+=L$Z+srvdz-aZyL%w>b93Oq)|Ks#;rq*_r`0D@rE7lx DCo?`I delta 152 zcmaFEzJhUrL_G^L0|Ud`yN`l^lth3}h-*l6lw37RF*cY z5vYc(B*-tAfx*jn=`y~K_gX*^OHUWa5RT|%ffgpVjbBU@G`v#;f{PiOR1^;D+_-VW zLQ-3q_lU<~t=4wN%}x!BJQ9u18XT3F&qy*XsFoG{{NQ*?2hbD-Pgg&ebxsLQ0LsES A0{{R3 diff --git a/platform/icons/src/general/tbShown@2x.png b/platform/icons/src/general/tbShown@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..758f1289bb91f8040c956f8fe8b4fb295ec188a6 GIT binary patch literal 1028 zcmaJ=&ui0A9M9&QV>l5MWJB09h2e0`udXbK>*kuYu3+Zu3hQOiGi;OfRI#GnXQEGI$#+mab#9A6F+bVFAr^KhG`K?8zU6ZAn+d2Jpj$b%rx#G?ks zkAn$`;p6PV!%W_stH)D}if-Yg~$}C%{RG3PP zLEZ|>OOnKL0xJknf{6N62kSx9@gpq-75au}x!6Ju2o?1rD&quAGCeqg?Y3ndzgZ?y zFgDO#mS?!|NG+hI{U2)EZM2WG@G#$h3j4XL3)w96QQ0#{!K#vF;c!qb6t~z*v?kixRI$Vv>&wioo-!STZ${ z6k{=7oJfs}QY_u#s>mqY(7`RPdB_zyaziKBE{Uu{&$ literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/tbShown@2x_dark.png b/platform/icons/src/general/tbShown@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..87c38cc7c8c110dbebec89bcb64a95c198b7ed6e GIT binary patch literal 1028 zcmaJ=&ui0A9M9&QV>l5MWkXm@VK`j#tE)}Iy16B-E0|fk%6bu+CU0xlk{6R#oAzQ= zP=pGC{sCTgP+=!M4K`#j^rkRDMMUr-Uc7i5%$Kh1JXizCd+(di=kxvf9;D|k4fGH7 z69h4knpHA*C4;xG7k|BK^*3GyQ6h)t;UX$)E+D22SO8?o(w0C5Xh!A6TQEToht8VW z9LlMeB^_F{7GP-Kaxj}9CZ>Ex)0Y7v3t-8#y!A`Ba0xJa1eC03NUDA{}{?9DY6rHqnn`ogC;RYb^<7^Yk<)8z;a z-6e(-MUi27hUdc=5%wxJ()_UPg<1*<@O0O7kO^%vP}B;rgyIyAbUy{lY0KJPvrM>P zjITKiN3%gnEugCYA8J``w1+a_Al`opd)bNum<;e>$<=Y=7DIt6N0MEjA?RiyTxnG? zU4#gFMd*;SOrBdXZ3C9Q(FR;qrIhU<&DKFmiBnjBHcdkkI58&6$yk(^d5%j&L{{Jh zf#%I!|vj#zV&cz1K)^BN}103p9{NtdsAB%yGQPI z^^URI&#%4sF?3SXwEEriJ&$U`Prml7u8zL^K6=a>?6vy7b#HI+r|VLFr|YBpdSvL+ zEAx$VdpPqfq1HZpd9MgRYgdop-?KZ1uiP(Pubt_xhb9N!tv?ooYO)^MC?7qZC)S^y U$e&8@ZU*-cHZLuIdNcG}0RZ!SXGTDZ0Lf8HzTQ^|ZvR&vZ2%Al&-OwfzlW8}t zP^uSg@!&y3=|ziPL_7#0s35H#?9H=y@TeybUOWhOvfW)hxCSQk!+Y<0-#6cE&P<)} z?K#oIFifwW)ADpa8jr3{`ak*Oz@*c0k}Z;1JWr}-fS7R`ml4oia{=X%X|G<{MhOeTElUobW z?AlbpT3fVan;ks|Mk0j@xQLh_a+kbNi85?WSE1|pm}fx^LKZXZp{b%V15_L!AaPRC z65tR>%N&&8&@fB@QGh94NbxY0grXwI3Y0+oV`;R&o>%hPWIYz$W!MTKzQXg>YL%;| zI2PIhprOzT9G^JY1F@o6#>*tbQm2P0xPDXC3+rW~ z1>+;r=OHJ=DK&tG@qei6Hqjx;qd$KCDI6A7eZ=Qch?fJ4Ufld(9LiVJ0GR{_1&o&( zRh+3{g2M{-fvSQtbB<@@YIwE=Hw;DhLSlLr(zOgr1vtmCm2_IlYU6NH5>*kxY)V$; z2~~osq`@IgP{jsU!`8BkJksFWO|B@kF$y@xA_a&y6G6Jn^#GwRF?$d*sn(4`^3M{05AXS2ap1gNPhsbNkl#@W5UBqE0000< KMNUMnLSTXuJz44i From 6f8c745e110e9209ecba71ac6793318547616f2f Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 22 Nov 2013 13:28:54 +0100 Subject: [PATCH 22/91] Retina for toolwindow icons --- .../src/toolwindows/toolWindowPalette@2x.png | Bin 0 -> 1768 bytes .../src/toolwindows/toolWindowProject@2x.png | Bin 0 -> 1843 bytes .../icons/src/toolwindows/toolWindowRun@2x.png | Bin 0 -> 1641 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 platform/icons/src/toolwindows/toolWindowPalette@2x.png create mode 100644 platform/icons/src/toolwindows/toolWindowProject@2x.png create mode 100644 platform/icons/src/toolwindows/toolWindowRun@2x.png diff --git a/platform/icons/src/toolwindows/toolWindowPalette@2x.png b/platform/icons/src/toolwindows/toolWindowPalette@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..bc14c3e7d6c58f1f3a6634b7fc6638df2622078c GIT binary patch literal 1768 zcmaJ?X;2eq7>=j~xvD@pbhJwZ5hceaM3P9Lgn$VWln@|_AR*a6fMi3mgn$gnH7Fy> z;aTGd)!|UUgCg}9(5e(Qf(M}Dpb-U?O9hHW$Jz}7_DAW??0&~Q&+|U-`@P@nu8l$K zEKC=hVlWsB4x7b8$Hj)%N zHz7|9X0D@@FF*v`K)MK);e`eaUL#YWYz)TJTcZ$)5+DSKfnud{2KMcxCM+NoGqB+l zE|IJ7h2o^_G$j<07Q`2&C5UKZthX27siC6+G6)d@8d;)TMb|K}le%)0LeIzL?_bdAO)CuuxK=; zSVHHq{HJ1}D+V?WK@@ZXAtfaRpF+mN%2)zOqtOUN5`jd*p$MERRgMTXIJs*1v;qrK ziIh?WB8BCEK~We3CnF3j>hx<0GR2InTs2iDv|t2{P(c9kL_RVfnGyte@GG>)AP)_xIVCH43w$g^o!sS*7gY z23y=oJa;HwdWo^^@cU!QtM2rxQ<7aKphj}Tmx;y+NoyG|z^ckdD`5Ay8hej|m0_8l zbyW`9$J(W@qn&)_V@1IoJ7S{A!Rmtk7fH1qc5WDs9{kNbUGmISZy&QKK4Q_S!jW{3 zO8fRO%g!BKeMSBlanwv?(S3_plu5D}Bo4I-`v%UMhMGTUu-UgG?;g`?J!kLzraK!r zKlaBKeWwWTF4$S;QWRPC@!D$!uJT;oqE*xbw%U;1d;BaLquXE75YMh1lE^T%f+O_G zrywDrD|K!W)y;t;gYi38*p@mCiBAeF>wZ8!TVFi$YAAZ^BQwuA^?KsFBR$r6RtXI) zP{Eqiippc1FOoJn?cEanWnom1@j-pZg|VoEX%9m5?tfX~bFRFxf&KGaJz*jRp+-@Gt6z~fXU&BKXpufcKEsd8MBpoV3<*~l|~+dbBywsq}<4Ji*INEuJvil0;R zFYE^wm{@1AwItf_g$t^WGsj(MPQeKgrB^Agr%Qf1!<*;F9G3+C?LIOTI=Xd9LP?Z- z+pS!0!D>ONx#N0nP9eiN_oWX1`P1O{I~&{7>*_nBLSIF-M{T#2?W7O%iKd o57vw$AF_X~PPVIye3)TI#6;KykPdv52@U@qj$aU~mKmM(4;lr!wEzGB literal 0 HcmV?d00001 diff --git a/platform/icons/src/toolwindows/toolWindowProject@2x.png b/platform/icons/src/toolwindows/toolWindowProject@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..658b9dcf7b80b85e9b25cf7694404ba7ed80a177 GIT binary patch literal 1843 zcmaJ?X;2eq7!E2T-~q}gch@kZL`XIp2$Bm3gmBbEijkvKWl0uDLv~}bK!{cgQWd-+ zh~Sl4Y87<^>OfIc#G?_snTkhLI)LB-DT>yMs~Z*UkJ6pl{f>E_=Y8Jyd%xL&7;(fj zJ6Agri8L)LQV>gwu9kPoWa4``deL=aaKXb9@FiF(o(-!J5?_X;AV8E7PD5f5SeCQ0 z8R3#h6X(h$33!5N5nGBWX|M%D(<)U2n?&LUYgMpRf#5(2k|sxa4>Ljj8-oPuTIJTl?*V+u;um@KOKR3@TepcYnv5RGn0X%r|D{XbNx97AjHSmd+c z{}k3pa#RQyi)gS+wUjuxR4+>?6+29gz&NIsU|7az6=Tvd9Mhy@Dj+Nj@Q#0h(McWApj^KvqCFpUGfB5ESmm5(Y9@LcTwf5iSf9gtA7t z0!*5zL{NN`EBnk19hYnA1f`0IEI`!qEJP+$V@lvd#%%fcUINF}`^1%v?}ark7bMJp zmUI2rIgf4;&10F4buFw5$xnq5tFwcDv&;zmuZh!XH6T2oCNXOnw`L*-wFOF<}t zOt7_{ZocTeOh(~O6531`+ii}K$?PMH1?QZ_A<&}HlQE%gRr)a<-z`NQn z_&{URrfU2YhjRm6+sg5~&#CiKSfdsDo*gl~ulHP1d)_&0ejPS*C+UneJKCpm73XoE zgqyK6OFLw@4>opwk?b)mv^V!Q-zV2uVO(C+Ht_yn?K-pW@OM-0bq`_JgKI-#FE`AY z)U)Qvy7(?d)o+EqRqrluo%1&9$3ypYhJ%0R@f5jv;>Y-#EuPlLW=H)J*Y900kJ)Ex zFEK(}R!qHd>nBB3rj5DHw6bfU=G!OztGgY0YmztIoep-bk~o>lqX%Zajn9AVxFN~w z$x%I}ST=2g)zYl8vNym{-h%$}6_0d4$?3*9s|qH%iE?in@7X4~)3hZjd#7z)MGbX5 zHtm)AE1~oC8E}Q;*JkHqr@uK+7t%7UKT{4459@u}&HY!wg>8ck6&LcfHs%1zjihIe zFJF3Ie-#jsxR=qi6L^te_hMtgyBljpk`-&8Z!R;A^e)+Xp!V0@yFIBbN&Bz-e#ot1 zW*x`MgO~3Lrx=j?o!bIBybn476+nl5{UhOJf4p+ddk>1~X>H`OAM)}T49bzL9nQ?n z@=NKOOMxY?O{{0@@eWl)qdh-bJfr40MSIzk3madyYxlXAgmmO^93mDt>{|JA}n zk5dmgPRJK6mbd8*ouy9^m-=P3`;R0V*+Hv-W_#}HUCYItkt^VVm$}!cy7WX3Z=@98 z-`_-CA1;}w9LgLDkGmPw6m;oz#JuiAWBpS%d}~XLv*`UF&4X6FldO(H-N?4157t+e z`uCOU`|@aegeBXD&{sU0G=6If_hympCbff`vqvdC%@o@7lX7Dt{fE2y4z|P`I_^4UOHCEs#mp^= zOu84C6TlY-O?KfP?>Ffo$M1uhi!NRzpCmO6C7-FzWcU94d}@w+Y1^W6+K%J%XUk^K z{&~}2r|<5;9ikLn*G=oP>UP(8zS-R)hH6K(2HIAfB=Jb0{ literal 0 HcmV?d00001 diff --git a/platform/icons/src/toolwindows/toolWindowRun@2x.png b/platform/icons/src/toolwindows/toolWindowRun@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7b7f4c57654688a7999a56afdf8ea8c5b056b268 GIT binary patch literal 1641 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m=!ZaB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxR5#hc&_u!9QqR!T z(8R(}N5ROz&{*HVSl`fC*U-qyz|zXlQ~?TIxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7KMf<|~|UP^v> zu_jo#udkJ7UU5lcUUI6Zi>(sS0KLr26f0*_6AMQJ17}ksOG86LS7S#*BPTaEb4No< zAk)Io5vJEAKe;qFHLnDwHwB^B1*cw6O2{n$+U$~Alv$RV;#QQOs{r<~RVHq?IN~%9 zsy79GKXs0-s18SN>tLgRQXk4Z`hTyWcK#j%m4}t5kNkW$^Xt*o&-S?)g&ta?xNyhSCD&dChs@6o z7HBQ*6VO-K*6IE^q>xvb)$Zz}j;6F`rH+twv@8{A&j zncSN5K<<=VoWKpEHUXE++T*3yJ1(-PRIg*2DA(PzaE{z5$##)#QVUkkzBf0W?|;YQ zYXvjn{XDWy^>ck@J?Htu^pm29!v--|rjpeQZo5qqU$*VLiE-e9@;jon-y^kZ4t7n$?7XQ>G;6pwnow7DlTYn`cgL(nYk7waA#)YICKb53lsm-*-HV;2@K ziLnq6no?Trqoye>EOle&EAQUsbHz8jr+kp(`BL0;AyISHTHBDPVs1}E8#i|yKJs6E z;?GB$m9BpeRr`OUxn)zc+)5Q`ai!afXSVEXe6%d=r}b6uwGB2Nn$s_(_zRy|aGFc= zNOFJ;gKLsTin-#{G?t4Cdqcgp^L9x`J)0jgDT Date: Fri, 22 Nov 2013 16:47:44 +0400 Subject: [PATCH 23/91] check for disposed editor or project --- .../introduce/constant/GrInplaceConstantIntroducer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceConstantIntroducer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceConstantIntroducer.java index ec1671495604..2eac1e3fb26e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceConstantIntroducer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceConstantIntroducer.java @@ -175,8 +175,10 @@ public class GrInplaceConstantIntroducer extends GrAbstractInplaceIntroducer Date: Fri, 22 Nov 2013 17:10:59 +0400 Subject: [PATCH 24/91] IDEA-116911 Speed search: wrong background in recent files --- .../src/com/intellij/ui/SimpleColoredComponent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java index 7e0d6cd78586..25bd8ba46cdc 100644 --- a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java +++ b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java @@ -632,7 +632,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible, Co final String fragment = myFragments.get(i); final int fragmentWidth = isOracleRetina ? GraphicsUtil.stringWidth(fragment, font) : metrics.stringWidth(fragment); - final Color bgColor = attributes.getBgColor(); + final Color bgColor = attributes.isSearchMatch() ? null : attributes.getBgColor(); if ((attributes.isOpaque() || isOpaque()) && bgColor != null) { g.setColor(bgColor); g.fillRect(offset, 0, fragmentWidth, getHeight()); From 9acf2ac6b3832b7aabefdd18097627fecdbe0f66 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Fri, 22 Nov 2013 18:04:28 +0400 Subject: [PATCH 25/91] IDEA-116816 Language Injection: Parameter Info: the popup is shown at the wrong place if 'Use tabs' is on --- .../hint/ShowParameterInfoContext.java | 16 ++++++++++------ .../intellij/injected/editor/EditorWindow.java | 6 +----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ShowParameterInfoContext.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ShowParameterInfoContext.java index 5f61a846d14e..14e7487cc216 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ShowParameterInfoContext.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ShowParameterInfoContext.java @@ -110,11 +110,13 @@ public class ShowParameterInfoContext implements CreateParameterInfoContext { showMethodInfo(getProject(), getEditor(), element, getHighlightedElement(), itemsToShow, offset, handler); } - private static void showParameterHint(final PsiElement element, final Editor editor, final Object[] descriptors, - final Project project, final ShowParameterInfoHandler.BestLocationPointProvider provider, + private static void showParameterHint(final PsiElement element, + final Editor editor, + final Object[] descriptors, + final Project project, @Nullable PsiElement highlighted, - final int elementStart, final ParameterInfoHandler handler - ) { + final int elementStart, + final ParameterInfoHandler handler) { if (ParameterInfoController.isAlreadyShown(editor, elementStart)) return; if (editor.isDisposed() || !editor.getComponent().isVisible()) return; @@ -129,6 +131,7 @@ public class ShowParameterInfoContext implements CreateParameterInfoContext { final LightweightHint hint = new LightweightHint(component); hint.setSelectingHint(true); final HintManagerImpl hintManager = HintManagerImpl.getInstanceImpl(); + final ShowParameterInfoHandler.BestLocationPointProvider provider = new MyBestLocationPointProvider(editor); final Pair pos = provider.getBestPointPosition(hint, element, elementStart, true, HintManager.UNDER); ApplicationManager.getApplication().invokeLater(new Runnable() { @@ -143,6 +146,8 @@ public class ShowParameterInfoContext implements CreateParameterInfoContext { hintHint.setExplicitClose(true); Editor editorToShow = editor instanceof EditorWindow ? ((EditorWindow)editor).getDelegate() : editor; + // is case of injection we need to calculate position for EditorWindow + // also we need to show the hint in the main editor because of intention bulb hintManager.showEditorHint(hint, editorToShow, pos.getFirst(), HintManager.HIDE_BY_ESCAPE | HintManager.UPDATE_BY_SCROLLING, 0, false, hintHint); new ParameterInfoController(project, editor, elementStart, hint, handler, provider); } @@ -156,8 +161,7 @@ public class ShowParameterInfoContext implements CreateParameterInfoContext { int offset, ParameterInfoHandler handler ) { - showParameterHint(list, editor, candidates, project, new MyBestLocationPointProvider(editor), - candidates.length > 1 ? highlighted: null,offset, handler); + showParameterHint(list, editor, candidates, project, candidates.length > 1 ? highlighted : null, offset, handler); } /** diff --git a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java index 9a32f8b89f0d..ce8606677f3e 100644 --- a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java +++ b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java @@ -167,12 +167,8 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx { else { int offset = lineStartOffset + column; int hostOffset = getDocument().injectedToHost(offset); - int hostLineNumber = getDocument().getDelegate().getLineNumber(hostOffset); - int hostLineStart = getDocument().getDelegate().getLineStartOffset(hostLineNumber); - - return new LogicalPosition(hostLineNumber, hostOffset - hostLineStart); + return myDelegate.offsetToLogicalPosition(hostOffset); } - } private void dispose() { From 55ad98c3c142f9808084a8e0ac33501d8620c5da Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 21 Nov 2013 19:57:54 +0400 Subject: [PATCH 26/91] [log] extract SequentialLimitedLifoExecutor from DataGetter for reuse --- .../com/intellij/vcs/log/data/DataGetter.java | 45 ++++++------- .../util/SequentialLimitedLifoExecutor.java | 64 +++++++++++++++++++ 2 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 platform/vcs-log/impl/src/com/intellij/vcs/log/util/SequentialLimitedLifoExecutor.java diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataGetter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataGetter.java index dabd64cdd4aa..ba0af62ec1b7 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataGetter.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataGetter.java @@ -4,8 +4,7 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.Consumer; -import com.intellij.util.concurrency.QueueProcessor; +import com.intellij.util.ThrowableConsumer; import com.intellij.util.containers.MultiMap; import com.intellij.util.ui.UIUtil; import com.intellij.vcs.log.Hash; @@ -14,6 +13,7 @@ import com.intellij.vcs.log.VcsShortCommitDetails; import com.intellij.vcs.log.graph.Graph; import com.intellij.vcs.log.graph.elements.Node; import com.intellij.vcs.log.graph.elements.NodeRow; +import com.intellij.vcs.log.util.SequentialLimitedLifoExecutor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -43,13 +43,13 @@ public abstract class DataGetter implements Dis @NotNull protected final VcsLogDataHolder myDataHolder; @NotNull private final Map myLogProviders; @NotNull private final VcsCommitCache myCache; + @NotNull private final SequentialLimitedLifoExecutor myLoader; /** * The sequence number of the current "loading" task. */ private long myCurrentTaskIndex = 0; - @NotNull private final QueueProcessor myLoader = new QueueProcessor(new DetailsLoadingTask()); @NotNull private final Collection myLoadingFinishedListeners = new ArrayList(); DataGetter(@NotNull VcsLogDataHolder dataHolder, @NotNull Map logProviders, @@ -58,12 +58,26 @@ public abstract class DataGetter implements Dis myLogProviders = logProviders; myCache = cache; Disposer.register(dataHolder, this); + myLoader = new SequentialLimitedLifoExecutor(this, MAX_LOADING_TASKS, + new ThrowableConsumer() { + @Override + public void consume(TaskDescriptor task) throws VcsException { + preLoadCommitData(task.nodes); + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + for (Runnable loadingFinishedListener : myLoadingFinishedListeners) { + loadingFinishedListener.run(); + } + } + }); + } + }); } @Override public void dispose() { myLoadingFinishedListeners.clear(); - myLoader.clear(); } @NotNull @@ -150,7 +164,7 @@ public abstract class DataGetter implements Dis } } TaskDescriptor task = new TaskDescriptor(nodes, taskNumber); - myLoader.addFirst(task); + myLoader.queue(task); return task; } @@ -204,25 +218,4 @@ public abstract class DataGetter implements Dis } } - private class DetailsLoadingTask implements Consumer { - - @Override - public void consume(final TaskDescriptor task) { - try { - myLoader.dismissLastTasks(MAX_LOADING_TASKS); - preLoadCommitData(task.nodes); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - for (Runnable loadingFinishedListener : myLoadingFinishedListeners) { - loadingFinishedListener.run(); - } - } - }); - } - catch (VcsException e) { - throw new RuntimeException(e); // todo - } - } - } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/util/SequentialLimitedLifoExecutor.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/util/SequentialLimitedLifoExecutor.java new file mode 100644 index 000000000000..0eb6e8562d80 --- /dev/null +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/util/SequentialLimitedLifoExecutor.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.vcs.log.util; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; +import com.intellij.util.Consumer; +import com.intellij.util.ThrowableConsumer; +import com.intellij.util.concurrency.QueueProcessor; +import org.jetbrains.annotations.NotNull; + +/** + * Queue with a limited number of tasks, and with higher priority for new tasks, than for older ones. + */ +public class SequentialLimitedLifoExecutor implements Disposable { + + private final int myMaxTasks; + @NotNull private final ThrowableConsumer myLoadProcess; + @NotNull private final QueueProcessor myLoader; + + public SequentialLimitedLifoExecutor(Disposable parentDisposable, int maxTasks, + @NotNull ThrowableConsumer loadProcess) { + myMaxTasks = maxTasks; + myLoadProcess = loadProcess; + myLoader = new QueueProcessor(new DetailsLoadingTask()); + Disposer.register(parentDisposable, this); + } + + public void queue(Task task) { + myLoader.addFirst(task); + } + + @Override + public void dispose() { + myLoader.clear(); + } + + private class DetailsLoadingTask implements Consumer { + @Override + public void consume(final Task task) { + try { + myLoader.dismissLastTasks(myMaxTasks); + myLoadProcess.consume(task); + } + catch (Throwable e) { + throw new RuntimeException(e); // todo + } + } + } + +} From fe846c1d21bb9373a8ed032770885ec69462a0f7 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 22 Nov 2013 15:48:48 +0400 Subject: [PATCH 27/91] [log] fix action's update() Use current event's presentation, not the template one. --- .../vcs-log/impl/src/com/intellij/vcs/log/ui/GoToRefAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/GoToRefAction.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/GoToRefAction.java index 4514217a25d9..12e67eb7ebf9 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/GoToRefAction.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/GoToRefAction.java @@ -61,7 +61,7 @@ public class GoToRefAction extends DumbAwareAction { @Override public void update(AnActionEvent e) { VcsLog log = e.getData(VcsLogDataKeys.VSC_LOG); - getTemplatePresentation().setEnabledAndVisible(e.getProject() != null && log != null); + e.getPresentation().setEnabledAndVisible(e.getProject() != null && log != null); } } From fd8772d48f48788bb7edc7c453f54ccfb834fdaa Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 22 Nov 2013 18:13:00 +0400 Subject: [PATCH 28/91] [log] IDEA-116470 Show "Contained in branches:" information in details * Improve RefsModel to be able to find references by indices, not hashes. * Introduce ContainingBranchesGetter: - holds a background queue to calculate the information asynchronously - calculates by walking up the graph starting from the given nodes. - saves the calculated value in the cache. - if there is already information about some node in the cache, reuse it and don't walk over this graph branch. - clear the cache from VcsLogDataHolder on smart refresh, if references have changed; and at any case during initial refresh. --- .../log/data/ContainingBranchesGetter.java | 148 ++++++++++++++++++ .../com/intellij/vcs/log/data/DataPack.java | 2 +- .../com/intellij/vcs/log/data/RefsModel.java | 32 ++-- .../vcs/log/data/VcsLogDataHolder.java | 14 +- .../vcs/log/ui/frame/DetailsPanel.java | 31 +++- .../intellij/vcs/log/ui/frame/MainFrame.java | 6 + 6 files changed, 214 insertions(+), 19 deletions(-) create mode 100644 platform/vcs-log/impl/src/com/intellij/vcs/log/data/ContainingBranchesGetter.java diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/ContainingBranchesGetter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/ContainingBranchesGetter.java new file mode 100644 index 000000000000..ddcea8986060 --- /dev/null +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/ContainingBranchesGetter.java @@ -0,0 +1,148 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.vcs.log.data; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.Condition; +import com.intellij.util.ThrowableConsumer; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.SLRUMap; +import com.intellij.vcs.log.VcsRef; +import com.intellij.vcs.log.graph.elements.Edge; +import com.intellij.vcs.log.graph.elements.Node; +import com.intellij.vcs.log.util.SequentialLimitedLifoExecutor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +/** + * Provides capabilities to asynchronously calculate "contained in branches" information. + */ +public class ContainingBranchesGetter { + + @NotNull private final SequentialLimitedLifoExecutor myTaskExecutor; + @NotNull private final Collection myLoadingFinishedListeners = new ArrayList(); + @NotNull private final SLRUMap> myCache = new SLRUMap>(1000, 1000); + + ContainingBranchesGetter(@NotNull Disposable parentDisposable) { + myTaskExecutor = new SequentialLimitedLifoExecutor(parentDisposable, 10, new ThrowableConsumer() { + @Override + public void consume(Task task) throws Throwable { + myCache.put(task.node, getContainingBranches(task.pack, task.node)); + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + for (Runnable listener : myLoadingFinishedListeners) { + listener.run(); + } + } + }); + } + }); + } + + void clearCache() { + myCache.clear(); + } + + /** + * This task will be executed each time the calculating process completes. + */ + public void addTaskCompletedListener(@NotNull Runnable runnable) { + myLoadingFinishedListeners.add(runnable); + } + + /** + * Returns the alphabetically sorted list of branches containing the specified node, if this information is ready; + * if it is not available, starts calculating in the background and returns null. + */ + @Nullable + public List requestContainingBranches(@NotNull DataPack dataPack, @NotNull Node node) { + List refs = myCache.get(node); + if (refs == null) { + myTaskExecutor.queue(new Task(dataPack, node)); + } + return refs; + } + + @NotNull + private List getContainingBranches(@NotNull DataPack dataPack, @NotNull Node node) { + RefsModel refsModel = dataPack.getRefsModel(); + Set containingBranches = ContainerUtil.newHashSet(); + + Set visitedNodes = ContainerUtil.newHashSet(); + Set nodesToCheck = ContainerUtil.newHashSet(); + nodesToCheck.add(node); + while (!nodesToCheck.isEmpty()) { + Iterator nodeIterator = nodesToCheck.iterator(); + Node nextNode = nodeIterator.next(); + nodeIterator.remove(); + + if (!visitedNodes.add(nextNode)) { + continue; + } + + for (Edge edge : nextNode.getUpEdges()) { + Node upNode = edge.getUpNode(); + // optimization: the node is contained in all branches which contain its child => no need to walk over this graph branch + List upRefs = myCache.get(upNode); + if (upRefs != null) { + containingBranches.addAll(upRefs); + } + else { + nodesToCheck.add(upNode); + } + } + + containingBranches.addAll(getBranchesPointingToThisNode(refsModel, nextNode)); + } + + return sortByName(containingBranches); + } + + @NotNull + private static Collection getBranchesPointingToThisNode(@NotNull RefsModel refsModel, @NotNull Node node) { + return ContainerUtil.filter(refsModel.refsToCommit(node.getCommitIndex()), new Condition() { + @Override + public boolean value(VcsRef ref) { + return ref.getType().isBranch(); + } + }); + } + + private static List sortByName(Collection branches) { + List branchesList = new ArrayList(branches); + ContainerUtil.sort(branchesList, new Comparator() { + @Override + public int compare(VcsRef o1, VcsRef o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + return branchesList; + } + + private static class Task { + private final DataPack pack; + private final Node node; + public Task(DataPack pack, Node node) { + this.pack = pack; + this.node = node; + } + } + +} diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPack.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPack.java index baef6132d5d5..b0b402ca71da 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPack.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPack.java @@ -52,7 +52,7 @@ public class DataPack { } }); - final RefsModel refsModel = new RefsModel(allRefs, hashGetter); + final RefsModel refsModel = new RefsModel(allRefs, indexGetter); graphModel.getFragmentManager().setUnconcealedNodeFunction(new Function() { @NotNull @Override diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/RefsModel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/RefsModel.java index 4078bbfe7965..8f79a75076a4 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/RefsModel.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/RefsModel.java @@ -1,7 +1,7 @@ package com.intellij.vcs.log.data; import com.intellij.openapi.util.Condition; -import com.intellij.util.Function; +import com.intellij.util.NotNullFunction; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import com.intellij.vcs.log.Hash; @@ -19,10 +19,11 @@ public class RefsModel { @NotNull private final Collection myBranches; @NotNull private final MultiMap myRefsToHashes; - private final Function myHashGetter; + @NotNull private final MultiMap myRefsToIndices; + @NotNull private final NotNullFunction myIndexGetter; - public RefsModel(@NotNull Collection allRefs, Function hashGetter) { - myHashGetter = hashGetter; + public RefsModel(@NotNull Collection allRefs, @NotNull NotNullFunction indexGetter) { + myIndexGetter = indexGetter; myBranches = ContainerUtil.filter(allRefs, new Condition() { @Override public boolean value(VcsRef ref) { @@ -31,6 +32,16 @@ public class RefsModel { }); myRefsToHashes = prepareRefsMap(allRefs); + myRefsToIndices = prepareRefsToIndicesMap(allRefs); + } + + @NotNull + private MultiMap prepareRefsToIndicesMap(@NotNull Collection refs) { + MultiMap map = MultiMap.create(); + for (VcsRef ref : refs) { + map.putValue(myIndexGetter.fun(ref.getCommitHash()), ref); + } + return map; } @NotNull @@ -42,8 +53,8 @@ public class RefsModel { return map; } - public boolean isBranchRef(@NotNull Hash commitHash) { - for (VcsRef ref : refsToCommit(commitHash)) { + public boolean isBranchRef(int hash) { + for (VcsRef ref : refsToCommit(hash)) { if (ref.getType().isBranch()) { return true; } @@ -59,6 +70,11 @@ public class RefsModel { return Collections.emptyList(); } + @NotNull + public Collection refsToCommit(int index) { + return myRefsToIndices.containsKey(index) ? myRefsToIndices.get(index) : Collections.emptyList(); + } + @NotNull public Collection getBranches() { return myBranches; @@ -69,8 +85,4 @@ public class RefsModel { return new ArrayList(myRefsToHashes.values()); } - public boolean isBranchRef(int hash) { - return isBranchRef(myHashGetter.fun(hash)); - } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java index 4af25dff7093..de7b48f18ef1 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java @@ -23,6 +23,7 @@ import com.intellij.openapi.progress.BackgroundTaskQueue; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vcs.VcsException; @@ -145,6 +146,7 @@ public class VcsLogDataHolder implements Disposable { private final VcsLogHashMap myHashMap; private final NotNullFunction myHashGetter; private final NotNullFunction myIndexGetter; + private final ContainingBranchesGetter myContainingBranchesGetter; public VcsLogDataHolder(@NotNull Project project, @NotNull Map logProviders, @NotNull VcsLogSettings settings) { @@ -179,6 +181,7 @@ public class VcsLogDataHolder implements Disposable { return putHash(hash); } }; + myContainingBranchesGetter = new ContainingBranchesGetter(this); } @NotNull @@ -373,8 +376,12 @@ public class VcsLogDataHolder implements Disposable { VirtualFile root = entry.getKey(); RecentCommitsInfo info = entry.getValue(); - Pair, Integer> joinResult = myLogJoiner.addCommits(myLogData.getLog(root), myLogData.getRefs(root), + Collection oldRefs = myLogData.getRefs(root); + Pair, Integer> joinResult = myLogJoiner.addCommits(myLogData.getLog(root), oldRefs, info.firstBlockCommits, info.newRefs); + if (!Comparing.haveEqualElements(oldRefs, info.newRefs)) { + myContainingBranchesGetter.clearCache(); + } List refreshedLog = joinResult.getFirst(); int newCommitsCount = joinResult.getSecond(); // the value can significantly increase if user keeps IDEA open for a long time, and frequently receives many new commits, @@ -437,6 +444,7 @@ public class VcsLogDataHolder implements Disposable { myLogData = new LogData(logsToBuild, refsByRoot, compoundLog, dataPack, false); } + myContainingBranchesGetter.clearCache(); handleOnSuccessInEdt(onSuccess, dataPack); } @@ -550,6 +558,10 @@ public class VcsLogDataHolder implements Disposable { return mySettings; } + public ContainingBranchesGetter getContainingBranchesGetter() { + return myContainingBranchesGetter; + } + private static class RecentCommitsInfo { List firstBlockCommits; Collection newRefs; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java index f93b0295fdba..47052e936b62 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java @@ -2,16 +2,19 @@ package com.intellij.vcs.log.ui.frame; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.changes.issueLinks.IssueLinkHtmlRenderer; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.BrowserHyperlinkListener; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.components.JBLoadingPanel; +import com.intellij.util.Function; import com.intellij.util.text.DateFormatUtil; import com.intellij.util.ui.UIUtil; import com.intellij.vcs.log.Hash; import com.intellij.vcs.log.VcsFullCommitDetails; import com.intellij.vcs.log.VcsRef; +import com.intellij.vcs.log.data.DataPack; import com.intellij.vcs.log.data.LoadingDetails; import com.intellij.vcs.log.data.VcsLogDataHolder; import com.intellij.vcs.log.graph.render.PrintParameters; @@ -82,21 +85,24 @@ class DetailsPanel extends JPanel implements ListSelectionListener { } else { ((CardLayout)getLayout()).show(this, STANDARD_LAYER); - Hash hash = ((AbstractVcsLogTableModel)myGraphTable.getModel()).getHashAtRow(rows[0]); + int row = rows[0]; + Hash hash = ((AbstractVcsLogTableModel)myGraphTable.getModel()).getHashAtRow(row); if (hash == null) { showMessage("No commits selected"); return; } VcsFullCommitDetails commitData = myLogDataHolder.getCommitDetailsGetter().getCommitData(hash); - if (commitData instanceof LoadingDetails) { + DataPack dataPack = myLogDataHolder.getDataPack(); + List branches = myLogDataHolder.getContainingBranchesGetter().requestContainingBranches(dataPack, dataPack.getNode(row)); + if (commitData instanceof LoadingDetails || branches == null) { myLoadingPanel.startLoading(); - myDataPanel.setData(null); + myDataPanel.setData(null, null); myRefsPanel.setRefs(Collections.emptyList()); } else { myLoadingPanel.stopLoading(); - myDataPanel.setData(commitData); + myDataPanel.setData(commitData, branches); myRefsPanel.setRefs(sortRefs(hash, commitData.getRoot())); } } @@ -123,19 +129,30 @@ class DetailsPanel extends JPanel implements ListSelectionListener { setEditable(false); myProject = project; addHyperlinkListener(new BrowserHyperlinkListener()); + setPreferredSize(new Dimension(150, 100)); } - void setData(@Nullable VcsFullCommitDetails commit) { - if (commit == null) { + void setData(@Nullable VcsFullCommitDetails commit, @Nullable List branches) { + if (commit == null || branches == null) { setText(""); } else { - String body = getHashText(commit) + "
" + getAuthorText(commit) + "

" + getMessageText(commit) + "

"; + String body = getHashText(commit) + "
" + getAuthorText(commit) + "

" + getMessageText(commit) + "

" + + "

" + getContainedBranchesText(branches) + "

"; setText("" + UIUtil.getCssFontDeclaration(UIUtil.getLabelFont()) + "" + body + ""); setCaretPosition(0); } } + private static String getContainedBranchesText(List branches) { + return "Contained in branches: " + StringUtil.join(branches, new Function() { + @Override + public String fun(VcsRef ref) { + return ref.getName(); + } + }, ", "); + } + private String getMessageText(VcsFullCommitDetails commit) { String subject = commit.getSubject(); String description = subject.length() < commit.getFullMessage().length() ? commit.getFullMessage().substring(subject.length()) : ""; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java index 008cde930488..987b797803d1 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java @@ -123,6 +123,12 @@ public class MainFrame extends JPanel implements TypeSafeDataProvider { myDetailsPanel.valueChanged(null); } }); + myLogDataHolder.getContainingBranchesGetter().addTaskCompletedListener(new Runnable() { + @Override + public void run() { + myDetailsPanel.valueChanged(null); + } + }); } public void setupDetailsSplitter(boolean state) { From 49639e870bb531b67993f7bb40f1c640b57ecc3d Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 22 Nov 2013 15:22:16 +0100 Subject: [PATCH 29/91] IDEA-116508 ("Local variable or parameter can be final" inspection use generates uncompilable code not extracting a really finalizable variable) --- .../localCanBeFinal/LocalCanBeFinal.java | 10 ++++++++++ .../inspection/localCanBeFinal/For/src/For.java | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java b/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java index 028e9b7a7e9d..8253db051060 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java @@ -231,6 +231,16 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { if (shouldBeIgnored(variable)) { iterator.remove(); } + final PsiElement parent = variable.getParent(); + if (!(parent instanceof PsiDeclarationStatement)) { + continue; + } + final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)parent; + final PsiElement[] elements = declarationStatement.getDeclaredElements(); + final PsiElement grandParent = parent.getParent(); + if (elements.length > 1 && grandParent instanceof PsiForStatement) { + iterator.remove(); // do not report when more than 1 variable declared in for loop + } } for (PsiVariable writtenVariable : writtenVariables) { diff --git a/java/java-tests/testData/inspection/localCanBeFinal/For/src/For.java b/java/java-tests/testData/inspection/localCanBeFinal/For/src/For.java index 529844bc5326..4a10521bf860 100644 --- a/java/java-tests/testData/inspection/localCanBeFinal/For/src/For.java +++ b/java/java-tests/testData/inspection/localCanBeFinal/For/src/For.java @@ -1,7 +1,8 @@ class For { void f(List list) { - for (Iterator it = list.iterator(); it.hasNext();) { // 'it' can be final but not reported + for (Iterator it = list.iterator(); it.hasNext();) { } for (int i = 0; i < 10; i++) {} + for (int i = 0, length = 10; i < length; i++) {} } } \ No newline at end of file From 425dcbb9258619014ed9854f7182a4275eb6a0a2 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Fri, 22 Nov 2013 18:43:23 +0400 Subject: [PATCH 30/91] disable rearranger grouper test: test utility and overriden methods --- .../psi/codeStyle/arrangement/JavaRearrangerGrouperTest.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerGrouperTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerGrouperTest.groovy index e30b1a8849de..e094e866573e 100644 --- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerGrouperTest.groovy +++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerGrouperTest.groovy @@ -127,7 +127,7 @@ class Sub extends Base { }''') } - void "test overriden and utility methods"() { + void "do not test overriden and utility methods"() { doTest( initial: '''\ class Base { From e1eab582734154eb624fc7e4f661d2fbdd3555ef Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 22 Nov 2013 15:53:17 +0100 Subject: [PATCH 31/91] IDEA-116071 (Field can be final inspection change) --- .../localCanBeFinal/LocalCanBeFinal.java | 86 ++++++------------- .../codeInspection/LocalCanBeFinalTest.java | 2 + .../src/messages/InspectionsBundle.properties | 2 + 3 files changed, 29 insertions(+), 61 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java b/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java index 8253db051060..d4cff693643a 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java @@ -18,6 +18,7 @@ package com.intellij.codeInspection.localCanBeFinal; import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInspection.*; +import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.psi.*; @@ -44,6 +45,8 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { public boolean REPORT_VARIABLES = true; public boolean REPORT_PARAMETERS = true; + public boolean REPORT_CATCH_PARAMETERS = true; + public boolean REPORT_FOREACH_PARAMETERS = true; private final LocalQuickFix myQuickFix; @NonNls public static final String SHORT_NAME = "LocalCanBeFinal"; @@ -148,6 +151,7 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { @Override public void visitCatchSection(PsiCatchSection section) { super.visitCatchSection(section); + if (!REPORT_CATCH_PARAMETERS) return; final PsiParameter parameter = section.getParameter(); if (PsiTreeUtil.getParentOfType(parameter, PsiClass.class) != PsiTreeUtil.getParentOfType(body, PsiClass.class)) { return; @@ -164,6 +168,7 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { @Override public void visitForeachStatement(PsiForeachStatement statement) { super.visitForeachStatement(statement); + if (!REPORT_FOREACH_PARAMETERS) return; final PsiParameter param = statement.getIterationParameter(); if (PsiTreeUtil.getParentOfType(param, PsiClass.class) != PsiTreeUtil.getParentOfType(body, PsiClass.class)) { return; @@ -219,7 +224,7 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { } }); - if (body.getParent() instanceof PsiMethod && isReportParameters()) { + if (body.getParent() instanceof PsiMethod && REPORT_PARAMETERS) { final PsiMethod method = (PsiMethod)body.getParent(); if (!(method instanceof SyntheticElement)) { // e.g. JspHolderMethod Collections.addAll(result, method.getParameterList().getParameters()); @@ -271,19 +276,21 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { private boolean shouldBeIgnored(PsiVariable psiVariable) { if (psiVariable.hasModifierProperty(PsiModifier.FINAL)) return true; - return isLocalVariable(psiVariable) ? !isReportVariables() : !isReportParameters(); - } - - private static boolean isLocalVariable(PsiVariable variable) { - if (variable instanceof PsiLocalVariable) { - return true; + if (psiVariable instanceof PsiLocalVariable) { + return !REPORT_VARIABLES; } - if (!(variable instanceof PsiParameter)) { - return false; + if (psiVariable instanceof PsiParameter) { + final PsiParameter parameter = (PsiParameter)psiVariable; + final PsiElement declarationScope = parameter.getDeclarationScope(); + if (declarationScope instanceof PsiCatchSection) { + return !REPORT_CATCH_PARAMETERS; + } + else if (declarationScope instanceof PsiForeachStatement) { + return !REPORT_FOREACH_PARAMETERS; + } + return !REPORT_PARAMETERS; } - final PsiParameter parameter = (PsiParameter)variable; - final PsiElement declarationScope = parameter.getDeclarationScope(); - return !(declarationScope instanceof PsiMethod) && !(declarationScope instanceof PsiLambdaExpression); + return true; } @Override @@ -336,55 +343,12 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { @Override public JComponent createOptionsPanel() { - return new OptionsPanel(); - } - - private boolean isReportVariables() { - return REPORT_VARIABLES; - } - - private boolean isReportParameters() { - return REPORT_PARAMETERS; - } - - private class OptionsPanel extends JPanel { - private final JCheckBox myReportVariablesCheckbox; - private final JCheckBox myReportParametersCheckbox; - - private OptionsPanel() { - super(new GridBagLayout()); - - GridBagConstraints gc = new GridBagConstraints(); - gc.weighty = 0; - gc.weightx = 1; - gc.fill = GridBagConstraints.HORIZONTAL; - gc.anchor = GridBagConstraints.NORTHWEST; - - - myReportVariablesCheckbox = new JCheckBox(InspectionsBundle.message("inspection.local.can.be.final.option")); - myReportVariablesCheckbox.setSelected(REPORT_VARIABLES); - myReportVariablesCheckbox.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - REPORT_VARIABLES = myReportVariablesCheckbox.isSelected(); - } - }); - gc.gridy = 0; - add(myReportVariablesCheckbox, gc); - - myReportParametersCheckbox = new JCheckBox(InspectionsBundle.message("inspection.local.can.be.final.option1")); - myReportParametersCheckbox.setSelected(REPORT_PARAMETERS); - myReportParametersCheckbox.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - REPORT_PARAMETERS = myReportParametersCheckbox.isSelected(); - } - }); - - gc.weighty = 1; - gc.gridy++; - add(myReportParametersCheckbox, gc); - } + final MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this); + panel.addCheckbox(InspectionsBundle.message("inspection.local.can.be.final.option"), "REPORT_VARIABLES"); + panel.addCheckbox(InspectionsBundle.message("inspection.local.can.be.final.option1"), "REPORT_PARAMETERS"); + panel.addCheckbox(InspectionsBundle.message("inspection.local.can.be.final.option2"), "REPORT_CATCH_PARAMETERS"); + panel.addCheckbox(InspectionsBundle.message("inspection.local.can.be.final.option3"), "REPORT_FOREACH_PARAMETERS"); + return panel; } @Override diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java index e29b65c31bcc..61895f6cb132 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java @@ -127,12 +127,14 @@ public class LocalCanBeFinalTest extends InspectionTestCase { public void testForeachNotReported() throws Exception { myTool.REPORT_PARAMETERS = true; myTool.REPORT_VARIABLES = false; + myTool.REPORT_FOREACH_PARAMETERS = false; doTest(); } public void testNestedForeach() throws Exception { myTool.REPORT_PARAMETERS = false; myTool.REPORT_VARIABLES = true; + myTool.REPORT_FOREACH_PARAMETERS = true; doTest(); } diff --git a/platform/platform-resources-en/src/messages/InspectionsBundle.properties b/platform/platform-resources-en/src/messages/InspectionsBundle.properties index 1387caba4afb..0665e5c4ed89 100644 --- a/platform/platform-resources-en/src/messages/InspectionsBundle.properties +++ b/platform/platform-resources-en/src/messages/InspectionsBundle.properties @@ -123,6 +123,8 @@ inspection.1.7.problem.descriptor=Usage of generified after 1.6 API which would inspection.local.can.be.final.display.name=Local variable or parameter can be final inspection.local.can.be.final.option=Report local variables inspection.local.can.be.final.option1=Report method parameters +inspection.local.can.be.final.option2=Report catch parameters +inspection.local.can.be.final.option3=Report foreach parameters inspection.can.be.local.parameter.problem.descriptor=Parameter #ref can have final modifier inspection.can.be.local.variable.problem.descriptor=Variable #ref can have final modifier From 8e82d1f945032656d597c7d170454276e7ad7cd3 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Fri, 22 Nov 2013 19:01:05 +0400 Subject: [PATCH 32/91] UpdateToRevision and CreateTag for revision implemented for mercurial (IDEA-116440) *appropriate actions added; *tag command modified (revision options provided); *common notification and repository check method moved to DvcsUtil; *related git method calls changed; *annotations added --- .../dvcs/src/com/intellij/dvcs/DvcsUtil.java | 41 +++++++++ plugins/git4idea/src/git4idea/GitUtil.java | 27 ------ .../actions/GitLogSingleCommitAction.java | 9 +- .../cherrypick/GitCherryPickAction.java | 4 +- plugins/hg4idea/src/META-INF/plugin.xml | 14 +++ .../hg4idea/action/HgCreateTagAction.java | 11 ++- .../action/HgCreateTagFromLogAction.java | 33 +++++++ .../action/HgLogSingleCommitAction.java | 91 +++++++++++++++++++ .../action/HgUpdateToFromLogAction.java | 47 ++++++++++ .../hg4idea/command/HgTagCreateCommand.java | 16 +++- 10 files changed, 254 insertions(+), 39 deletions(-) create mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagFromLogAction.java create mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/action/HgLogSingleCommitAction.java create mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToFromLogAction.java diff --git a/platform/dvcs/src/com/intellij/dvcs/DvcsUtil.java b/platform/dvcs/src/com/intellij/dvcs/DvcsUtil.java index 27a353c88ce5..9c8f1734e259 100644 --- a/platform/dvcs/src/com/intellij/dvcs/DvcsUtil.java +++ b/platform/dvcs/src/com/intellij/dvcs/DvcsUtil.java @@ -16,19 +16,31 @@ package com.intellij.dvcs; import com.intellij.dvcs.repo.Repository; +import com.intellij.dvcs.repo.RepositoryManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vcs.VcsKey; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.StatusBarWidget; import com.intellij.openapi.wm.WindowManager; import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.vcs.log.VcsLog; +import com.intellij.vcs.log.VcsLogProvider; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; +import java.util.Arrays; import java.util.Collection; +import java.util.List; /** * @author Kirill Likhodedov @@ -97,4 +109,33 @@ public class DvcsUtil { } return false; } + + /** + * Report a warning that the given root has no associated Repositories. + */ + public static void noVcsRepositoryForRoot(@NotNull Logger log, + @NotNull VirtualFile root, + @NotNull Project project, + @NotNull RepositoryManager repositoryManager, + @Nullable AbstractVcs vcs) { + if (vcs == null) { + return; + } + ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project); + List roots = Arrays.asList(vcsManager.getRootsUnderVcs(vcs)); + log.warn(String.format("Repository not found for root: %s. All roots: %s, all repositories: %s", root, roots, + repositoryManager.getRepositories())); + } + + /** + * Checks if there are hg roots in the VCS log. + */ + public static boolean logHasRootForVcs(@NotNull VcsLog log, @Nullable final VcsKey vcsKey) { + return ContainerUtil.find(log.getLogProviders(), new Condition() { + @Override + public boolean value(VcsLogProvider logProvider) { + return logProvider.getSupportedVcs().equals(vcsKey); + } + }) != null; + } } diff --git a/plugins/git4idea/src/git4idea/GitUtil.java b/plugins/git4idea/src/git4idea/GitUtil.java index b507e4a6a161..6e49379f91d0 100644 --- a/plugins/git4idea/src/git4idea/GitUtil.java +++ b/plugins/git4idea/src/git4idea/GitUtil.java @@ -23,7 +23,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; @@ -38,10 +37,7 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import com.intellij.util.Function; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; -import com.intellij.vcs.log.VcsLog; -import com.intellij.vcs.log.VcsLogProvider; import com.intellij.vcsUtil.VcsFileUtil; import com.intellij.vcsUtil.VcsUtil; import git4idea.branch.GitBranchUtil; @@ -944,27 +940,4 @@ public class GitUtil { return !output.trim().isEmpty(); } - /** - * Report a warning that the given root has no associated GitRepositories. - */ - public static void noRepositoryForRoot(@NotNull Logger log, @NotNull VirtualFile root, @NotNull Project project) { - GitRepositoryManager repositoryManager = getRepositoryManager(project); - ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project); - List roots = Arrays.asList(vcsManager.getRootsUnderVcs(GitVcs.getInstance(project))); - log.warn(String.format("Repository not found for root: %s. All roots: %s, all repositories: %s", root, roots, - repositoryManager.getRepositories())); - } - - /** - * Checks if there are Git roots in the VCS log. - */ - public static boolean logHasGitRoot(@NotNull VcsLog log) { - return ContainerUtil.find(log.getLogProviders(), new Condition() { - @Override - public boolean value(VcsLogProvider logProvider) { - return logProvider.getSupportedVcs().equals(GitVcs.getKey()); - } - }) != null; - } - } diff --git a/plugins/git4idea/src/git4idea/actions/GitLogSingleCommitAction.java b/plugins/git4idea/src/git4idea/actions/GitLogSingleCommitAction.java index 16f5a41fb2ce..39cfb2a625ad 100644 --- a/plugins/git4idea/src/git4idea/actions/GitLogSingleCommitAction.java +++ b/plugins/git4idea/src/git4idea/actions/GitLogSingleCommitAction.java @@ -15,6 +15,7 @@ */ package git4idea.actions; +import com.intellij.dvcs.DvcsUtil; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.components.ServiceManager; @@ -24,7 +25,7 @@ import com.intellij.openapi.project.Project; import com.intellij.vcs.log.VcsFullCommitDetails; import com.intellij.vcs.log.VcsLog; import com.intellij.vcs.log.VcsLogDataKeys; -import git4idea.GitUtil; +import git4idea.GitVcs; import git4idea.repo.GitRepository; import git4idea.repo.GitRepositoryManager; import org.jetbrains.annotations.NotNull; @@ -56,10 +57,10 @@ public abstract class GitLogSingleCommitAction extends DumbAwareAction { GitRepositoryManager repositoryManager = ServiceManager.getService(data.project, GitRepositoryManager.class); final GitRepository repository = repositoryManager.getRepositoryForRoot(commit.getRoot()); if (repository == null) { - GitUtil.noRepositoryForRoot(LOG, commit.getRoot(), data.project); + DvcsUtil.noVcsRepositoryForRoot(LOG, commit.getRoot(), data.project, repositoryManager, GitVcs.getInstance(data.project)); return; } - + actionPerformed(repository, commit); } @@ -83,7 +84,7 @@ public abstract class GitLogSingleCommitAction extends DumbAwareAction { } boolean isValid() { - return project != null && log != null && GitUtil.logHasGitRoot(log); + return project != null && log != null && DvcsUtil.logHasRootForVcs(log, GitVcs.getKey()); } } diff --git a/plugins/git4idea/src/git4idea/cherrypick/GitCherryPickAction.java b/plugins/git4idea/src/git4idea/cherrypick/GitCherryPickAction.java index 7d24caf30152..8547848a0ae3 100644 --- a/plugins/git4idea/src/git4idea/cherrypick/GitCherryPickAction.java +++ b/plugins/git4idea/src/git4idea/cherrypick/GitCherryPickAction.java @@ -15,6 +15,7 @@ */ package git4idea.cherrypick; +import com.intellij.dvcs.DvcsUtil; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; @@ -29,7 +30,6 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.vcs.log.*; import git4idea.GitLocalBranch; import git4idea.GitPlatformFacade; -import git4idea.GitUtil; import git4idea.GitVcs; import git4idea.commands.Git; import git4idea.config.GitVcsSettings; @@ -133,7 +133,7 @@ public class GitCherryPickAction extends DumbAwareAction { public void update(AnActionEvent e) { super.update(e); final VcsLog log = getVcsLog(e); - if (log != null && !GitUtil.logHasGitRoot(log)) { + if (log != null && !DvcsUtil.logHasRootForVcs(log, GitVcs.getKey())) { e.getPresentation().setEnabledAndVisible(false); } else { diff --git a/plugins/hg4idea/src/META-INF/plugin.xml b/plugins/hg4idea/src/META-INF/plugin.xml index 8eb193bd5fd6..049afad76350 100644 --- a/plugins/hg4idea/src/META-INF/plugin.xml +++ b/plugins/hg4idea/src/META-INF/plugin.xml @@ -75,6 +75,20 @@ + + + + + + + + + + + + + org.zmlx.hg4idea.HgVcsMessages diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java index f5635cd3f3fe..1aec1a0e56e4 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java @@ -27,13 +27,16 @@ import java.util.Collection; public class HgCreateTagAction extends HgAbstractGlobalAction { - protected void execute(@NotNull final Project project, @NotNull Collection repos, @Nullable VirtualFile selectedRepo) { + public void execute(@NotNull final Project project, + @NotNull Collection repos, + @Nullable VirtualFile selectedRepo, + @Nullable final String reference) { final HgTagDialog dialog = new HgTagDialog(project); dialog.setRoots(repos, selectedRepo); dialog.show(); if (dialog.isOK()) { try { - new HgTagCreateCommand(project, dialog.getRepository(), dialog.getTagName()).execute(new HgCommandResultHandler() { + new HgTagCreateCommand(project, dialog.getRepository(), dialog.getTagName(), reference).execute(new HgCommandResultHandler() { @Override public void process(@Nullable HgCommandResult result) { if (HgErrorUtil.hasErrorsInCommandExecution(result)) { @@ -48,4 +51,8 @@ public class HgCreateTagAction extends HgAbstractGlobalAction { } } } + + protected void execute(@NotNull final Project project, @NotNull Collection repos, @Nullable VirtualFile selectedRepo) { + execute(project, repos, selectedRepo, null); + } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagFromLogAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagFromLogAction.java new file mode 100644 index 000000000000..18a42d735046 --- /dev/null +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagFromLogAction.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.zmlx.hg4idea.action; + +import com.intellij.vcs.log.VcsFullCommitDetails; +import org.jetbrains.annotations.NotNull; +import org.zmlx.hg4idea.repo.HgRepository; + +import java.util.Arrays; + +/** + * @author Nadya Zabrodina + */ +public class HgCreateTagFromLogAction extends HgLogSingleCommitAction { + @Override + protected void actionPerformed(@NotNull HgRepository repository, @NotNull VcsFullCommitDetails commit) { + String revisionHash = commit.getHash().asString(); + new HgCreateTagAction().execute(repository.getProject(), Arrays.asList(repository.getRoot()), repository.getRoot(), revisionHash); + } +} diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgLogSingleCommitAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgLogSingleCommitAction.java new file mode 100644 index 000000000000..572c32a0cd04 --- /dev/null +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgLogSingleCommitAction.java @@ -0,0 +1,91 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.zmlx.hg4idea.action; + +import com.intellij.dvcs.DvcsUtil; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.vcs.log.VcsFullCommitDetails; +import com.intellij.vcs.log.VcsLog; +import com.intellij.vcs.log.VcsLogDataKeys; +import org.jetbrains.annotations.NotNull; +import org.zmlx.hg4idea.HgVcs; +import org.zmlx.hg4idea.repo.HgRepository; +import org.zmlx.hg4idea.repo.HgRepositoryManager; + +import java.util.List; + +/** + * @author Nadya Zabrodina + */ +public abstract class HgLogSingleCommitAction extends DumbAwareAction { + + private static final Logger LOG = Logger.getInstance(HgLogSingleCommitAction.class); + + protected abstract void actionPerformed(@NotNull HgRepository repository, @NotNull VcsFullCommitDetails commit); + + @Override + public void actionPerformed(AnActionEvent e) { + Data data = Data.collect(e); + if (!data.isValid()) { + return; + } + + List details = data.log.getSelectedDetails(); + if (details.size() != 1) { + return; + } + VcsFullCommitDetails commit = details.get(0); + + HgRepositoryManager repositoryManager = ServiceManager.getService(data.project, HgRepositoryManager.class); + final HgRepository repository = repositoryManager.getRepositoryForRoot(commit.getRoot()); + if (repository == null) { + DvcsUtil.noVcsRepositoryForRoot(LOG, commit.getRoot(), data.project, repositoryManager, HgVcs.getInstance(data.project)); + return; + } + + actionPerformed(repository, commit); + } + + @Override + public void update(AnActionEvent e) { + Data data = Data.collect(e); + boolean enabled = data.isValid() && data.log.getSelectedCommits().size() == 1; + getTemplatePresentation().setVisible(data.isValid()); + getTemplatePresentation().setEnabled(enabled); + } + + private static class Data { + Project project; + VcsLog log; + + static Data collect(AnActionEvent e) { + Data data = new Data(); + data.project = e.getData(CommonDataKeys.PROJECT); + data.log = e.getData(VcsLogDataKeys.VSC_LOG); + return data; + } + + boolean isValid() { + return project != null && log != null && DvcsUtil.logHasRootForVcs(log, HgVcs.getKey()); + } + } +} diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToFromLogAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToFromLogAction.java new file mode 100644 index 000000000000..214eb4f5170d --- /dev/null +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToFromLogAction.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.zmlx.hg4idea.action; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.vcs.log.VcsFullCommitDetails; +import org.jetbrains.annotations.NotNull; +import org.zmlx.hg4idea.HgVcs; +import org.zmlx.hg4idea.command.HgUpdateCommand; +import org.zmlx.hg4idea.execution.HgCommandResult; +import org.zmlx.hg4idea.provider.update.HgConflictResolver; +import org.zmlx.hg4idea.repo.HgRepository; +import org.zmlx.hg4idea.util.HgErrorUtil; + +/** + * @author Nadya Zabrodina + */ +public class HgUpdateToFromLogAction extends HgLogSingleCommitAction { + @Override + protected void actionPerformed(@NotNull HgRepository repository, @NotNull VcsFullCommitDetails commit) { + String revisionHash = commit.getHash().asString(); + Project project = repository.getProject(); + VirtualFile rootFile = repository.getRoot(); + HgUpdateCommand updateCommand = new HgUpdateCommand(project, rootFile); + updateCommand.setRevision(revisionHash); + HgCommandResult result = updateCommand.execute(); + new HgConflictResolver(project).resolve(rootFile); + if (HgErrorUtil.hasErrorsInCommandExecution(result)) { + new HgCommandResultNotifier(project).notifyError(result, "", "Update failed"); + } + project.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(project, null); + } +} diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTagCreateCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTagCreateCommand.java index 5c36d7dd6915..5a52f34f4b22 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTagCreateCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTagCreateCommand.java @@ -20,25 +20,33 @@ import org.zmlx.hg4idea.execution.HgCommandException; import org.zmlx.hg4idea.execution.HgCommandExecutor; import org.zmlx.hg4idea.execution.HgCommandResultHandler; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; public class HgTagCreateCommand { private final Project project; private final VirtualFile repo; private final String tagName; + private final String revisionNumberOrHash; - public HgTagCreateCommand(Project project, @NotNull VirtualFile repo, String tagName) { + public HgTagCreateCommand(Project project, @NotNull VirtualFile repo, String tagName, String revisionNumberOrHash) { this.project = project; this.repo = repo; this.tagName = tagName; + this.revisionNumberOrHash = revisionNumberOrHash; } public void execute(HgCommandResultHandler resultHandler) throws HgCommandException { if (StringUtil.isEmptyOrSpaces(tagName)) { throw new HgCommandException("tag name is empty"); } - new HgCommandExecutor(project).execute(repo, "tag", Arrays.asList(tagName), resultHandler); + List arguments = new ArrayList(); + arguments.add(tagName); + if (!StringUtil.isEmptyOrSpaces(revisionNumberOrHash)) { + arguments.add("--rev"); + arguments.add(revisionNumberOrHash); + } + new HgCommandExecutor(project).execute(repo, "tag", arguments, resultHandler); } - } From 48a004440ef2ecf5a5b83d65b9fc8de009df3a71 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Fri, 22 Nov 2013 19:12:49 +0400 Subject: [PATCH 33/91] IDEA-116862 Added Maven Dependency (via Quick Fix) added with incorrect scope add tests +review CR-IC-3321 --- .../indices/MavenArtifactSearchDialog.java | 19 +++ .../AddMavenDependencyQuickFixTest.java | 119 ++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 plugins/maven/src/test/java/org/jetbrains/idea/maven/actions/AddMavenDependencyQuickFixTest.java diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenArtifactSearchDialog.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenArtifactSearchDialog.java index d4926d66a405..c028a25becf4 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenArtifactSearchDialog.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenArtifactSearchDialog.java @@ -15,6 +15,7 @@ */ package org.jetbrains.idea.maven.indices; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Pair; @@ -35,6 +36,8 @@ import java.util.List; public class MavenArtifactSearchDialog extends DialogWrapper { private List myResult = Collections.emptyList(); + public static List ourResultForTest; + private TabbedPaneWrapper myTabbedPane; private MavenArtifactSearchPanel myArtifactsPanel; private MavenArtifactSearchPanel myClassesPanel; @@ -45,6 +48,14 @@ public class MavenArtifactSearchDialog extends DialogWrapper { @NotNull public static List searchForClass(Project project, String className) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + assert ourResultForTest != null; + + List res = ourResultForTest; + ourResultForTest = null; + return res; + } + MavenArtifactSearchDialog d = new MavenArtifactSearchDialog(project, className, true); d.show(); if (!d.isOK()) return Collections.emptyList(); @@ -54,6 +65,14 @@ public class MavenArtifactSearchDialog extends DialogWrapper { @NotNull public static List searchForArtifact(Project project, Collection managedDependencies) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + assert ourResultForTest != null; + + List res = ourResultForTest; + ourResultForTest = null; + return res; + } + MavenArtifactSearchDialog d = new MavenArtifactSearchDialog(project, "", false); d.setManagedDependencies(managedDependencies); diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/actions/AddMavenDependencyQuickFixTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/actions/AddMavenDependencyQuickFixTest.java new file mode 100644 index 000000000000..c934e6c5aa8f --- /dev/null +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/actions/AddMavenDependencyQuickFixTest.java @@ -0,0 +1,119 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.maven.actions; + +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiManager; +import org.jetbrains.idea.maven.dom.MavenDomWithIndicesTestCase; +import org.jetbrains.idea.maven.indices.MavenArtifactSearchDialog; +import org.jetbrains.idea.maven.model.MavenId; + +import java.io.IOException; +import java.util.Collections; + +/** + * @author Sergey Evdokimov + */ +public class AddMavenDependencyQuickFixTest extends MavenDomWithIndicesTestCase { + + private IntentionAction findAddMavenIntention() { + for (IntentionAction intention : myFixture.getAvailableIntentions()) { + if (intention.getText().contains("Add Maven")) { + return intention; + } + } + + return null; + } + + public void testAddDependency() throws IOException { + VirtualFile f = createProjectSubFile("src/main/java/A.java", "import org.apache.commons.io.IOUtils;\n" + + "\n" + + "public class Aaa {\n" + + "\n" + + " public void xxx() {\n" + + " IOUtils u;\n" + + " }\n" + + "\n" + + "}"); + + importProject("test" + + "project" + + "1"); + + myFixture.configureFromExistingVirtualFile(f); + + IntentionAction intentionAction = findAddMavenIntention(); + + MavenArtifactSearchDialog.ourResultForTest = Collections.singletonList(new MavenId("commons-io", "commons-io", "2.4")); + + intentionAction.invoke(myProject, myFixture.getEditor(), myFixture.getFile()); + + String pomText = PsiManager.getInstance(myProject).findFile(myProjectPom).getText(); + assert pomText.matches( + "(?s).*\\s*commons-io\\s*commons-io\\s*2.4\\s*.*"); + } + + public void testAddDependencyInTest() throws IOException { + VirtualFile f = createProjectSubFile("src/test/java/A.java", "import org.apache.commons.io.IOUtils;\n" + + "\n" + + "public class Aaa {\n" + + "\n" + + " public void xxx() {\n" + + " IOUtils u;\n" + + " }\n" + + "\n" + + "}"); + + importProject("test" + + "project" + + "1"); + + myFixture.configureFromExistingVirtualFile(f); + + IntentionAction intentionAction = findAddMavenIntention(); + + MavenArtifactSearchDialog.ourResultForTest = Collections.singletonList(new MavenId("commons-io", "commons-io", "2.4")); + + intentionAction.invoke(myProject, myFixture.getEditor(), myFixture.getFile()); + + String pomText = PsiManager.getInstance(myProject).findFile(myProjectPom).getText(); + assert pomText.matches( + "(?s).*\\s*commons-io\\s*commons-io\\s*2.4\\s*test\\s*.*"); + } + +// public void testAddDependencyStatic() throws IOException { +// VirtualFile f = createProjectSubFile("src/main/java/A.java", "import org.apache.commons.io.IOUtils;\n" + +// "\n" + +// "public class Aaa {\n" + +// "\n" + +// " public void xxx() {\n" + +// " IOUtils.closeQuietly(null);\n" + +// " }\n" + +// "\n" + +// "}"); +// +// importProject("test" + +// "project" + +// "1"); +// +// myFixture.configureFromExistingVirtualFile(f); +// +// getIntentionAtCaret("Add Maven"); +// } + +} From 29278f8022316be4dff1e096c1720d1ceab9c4fa Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 22 Nov 2013 16:11:25 +0100 Subject: [PATCH 34/91] enable softwraps for the text viewer --- .../impl/src/com/intellij/debugger/actions/ViewTextAction.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java index 780096c0ccda..9c4ec5d39bca 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java @@ -102,6 +102,7 @@ public class ViewTextAction extends BaseValueAction { editor.setVerticalScrollbarVisible(true); editor.setEmbeddedIntoDialogWrapper(true); editor.getComponent().setPreferredSize(null); + editor.getSettings().setUseSoftWraps(true); return editor; } } From 95940fac48c05523e5deb4da9b918ebde83a487e Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 22 Nov 2013 16:26:15 +0100 Subject: [PATCH 35/91] EA-52260 (AIOOBE: SearchTextField$MyModel.addElement) --- .../src/com/intellij/find/EditorSearchComponent.java | 2 +- .../platform-api/src/com/intellij/ui/SearchTextField.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java index da4024ed1147..eda7b1946ebc 100644 --- a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java +++ b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java @@ -357,7 +357,7 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data } private void setupHistoryToSearchField(SearchTextField field, String[] strings) { - field.setHistorySize(strings.length); + field.setHistorySize(20); field.setHistory(ContainerUtil.reverse(Arrays.asList(strings))); } diff --git a/platform/platform-api/src/com/intellij/ui/SearchTextField.java b/platform/platform-api/src/com/intellij/ui/SearchTextField.java index ac1b73b05ec9..c6a76b830b65 100644 --- a/platform/platform-api/src/com/intellij/ui/SearchTextField.java +++ b/platform/platform-api/src/com/intellij/ui/SearchTextField.java @@ -233,8 +233,9 @@ public class SearchTextField extends JPanel { } } - public void setHistorySize(int aHistorySize) { - myHistorySize = aHistorySize; + public void setHistorySize(int historySize) { + if (historySize <= 0) throw new IllegalArgumentException("history size must be a positive number"); + myHistorySize = historySize; } public void setHistory(List aHistory) { From 52412b3e64c46abb2c5425072f5e723130cd8915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20C=C3=A9bron?= Date: Fri, 22 Nov 2013 16:30:04 +0100 Subject: [PATCH 36/91] rebomb --- .../intellij/ui/FinderRecursivePanelSelectionUpdateTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/platform-tests/testSrc/com/intellij/ui/FinderRecursivePanelSelectionUpdateTest.java b/platform/platform-tests/testSrc/com/intellij/ui/FinderRecursivePanelSelectionUpdateTest.java index 07371bd9db40..a637db61165f 100644 --- a/platform/platform-tests/testSrc/com/intellij/ui/FinderRecursivePanelSelectionUpdateTest.java +++ b/platform/platform-tests/testSrc/com/intellij/ui/FinderRecursivePanelSelectionUpdateTest.java @@ -15,6 +15,7 @@ */ package com.intellij.ui; +import com.intellij.idea.Bombed; import com.intellij.openapi.project.Project; import com.intellij.testFramework.PlatformTestCase; import com.intellij.testFramework.SkipInHeadlessEnvironment; @@ -24,11 +25,13 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.Arrays; +import java.util.Calendar; import java.util.List; @SkipInHeadlessEnvironment public class FinderRecursivePanelSelectionUpdateTest extends PlatformTestCase { + @Bombed(year = 2014, month = Calendar.JANUARY, day = 31, user = "Yann Cebron") public void testUpdate() throws InterruptedException { StringFinderRecursivePanel panel_0 = new StringFinderRecursivePanel(getProject()) { @NotNull From d5248a116d43c3625ede5d9b3519b39cc4ed2e2a Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 22 Nov 2013 19:29:44 +0400 Subject: [PATCH 37/91] introduce current_position_() --- .../lang/parser/GeneratedParserUtilBase.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java index 10d3bdf1623c..a16ec6719eaa 100644 --- a/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java +++ b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java @@ -73,16 +73,25 @@ public class GeneratedParserUtilBase { return builder_.eof(); } + public static int current_position_(PsiBuilder builder_) { + return builder_.rawTokenIndex(); + } + public static boolean recursion_guard_(PsiBuilder builder_, int level_, String funcName_) { if (level_ > MAX_RECURSION_LEVEL) { - builder_.error("Maximum recursion level (" + MAX_RECURSION_LEVEL + ") reached in " + funcName_); + builder_.error("Maximum recursion level (" + MAX_RECURSION_LEVEL + ") reached in '" + funcName_ + "'"); return false; } return true; } + @Deprecated public static void empty_element_parsed_guard_(PsiBuilder builder_, int offset_, String funcName_) { - builder_.error("Empty element parsed in " + funcName_ +" at offset " + offset_); + empty_element_parsed_guard_(builder_, funcName_); + } + + public static void empty_element_parsed_guard_(PsiBuilder builder_, String funcName_) { + builder_.error("Empty element parsed in '" + funcName_ +"' at offset " + builder_.getCurrentOffset()); } public static boolean invalid_left_marker_guard_(PsiBuilder builder_, PsiBuilder.Marker marker_, String funcName_) { From a83276a820c00a0b0fda2216d0e7a8ad323df1c8 Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Fri, 22 Nov 2013 20:08:22 +0400 Subject: [PATCH 38/91] Connections & GestureRecognizers --- .../designer/designSurface/OperationContext.java | 9 +++++++++ .../designer/designSurface/tools/TargetingTool.java | 2 ++ 2 files changed, 11 insertions(+) diff --git a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/OperationContext.java b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/OperationContext.java index b3a423d1e4ab..f2e7d9aa3ed4 100644 --- a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/OperationContext.java +++ b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/OperationContext.java @@ -34,6 +34,7 @@ public final class OperationContext { private Object myType; private EditableArea myArea; + private RadComponent myContainer; private List myComponents; private InputEvent myInputEvent; private int myModifiers; @@ -102,6 +103,14 @@ public final class OperationContext { myArea = area; } + public RadComponent getContainer() { + return myContainer; + } + + public void setContainer(RadComponent container) { + myContainer = container; + } + public List getComponents() { return myComponents; } diff --git a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/TargetingTool.java b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/TargetingTool.java index f66b5b07f1b1..900fe2703ecb 100644 --- a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/TargetingTool.java +++ b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/TargetingTool.java @@ -155,7 +155,9 @@ public abstract class TargetingTool extends InputTool { RadLayout layout = target.getLayout(); if (layout != null) { + myContext.setContainer(target); myOperation = layout.processChildOperation(myContext); + myContext.setContainer(null); } return myOperation != null; From 8d4977aeb92d8ee09debc44a4df35474c69ff83b Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 22 Nov 2013 20:10:42 +0400 Subject: [PATCH 39/91] introduce boolean empty_element_parsed_guard_() --- .../intellij/lang/parser/GeneratedParserUtilBase.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java index a16ec6719eaa..c9b9ae264a7e 100644 --- a/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java +++ b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java @@ -87,11 +87,15 @@ public class GeneratedParserUtilBase { @Deprecated public static void empty_element_parsed_guard_(PsiBuilder builder_, int offset_, String funcName_) { - empty_element_parsed_guard_(builder_, funcName_); + builder_.error("Empty element parsed in '" + funcName_ + "' at offset " + offset_); } - public static void empty_element_parsed_guard_(PsiBuilder builder_, String funcName_) { - builder_.error("Empty element parsed in '" + funcName_ +"' at offset " + builder_.getCurrentOffset()); + public static boolean empty_element_parsed_guard_(PsiBuilder builder_, String funcName_, int prev_position_) { + if (prev_position_ == current_position_(builder_)) { + builder_.error("Empty element parsed in '" + funcName_ + "' at offset " + builder_.getCurrentOffset()); + return false; + } + return true; } public static boolean invalid_left_marker_guard_(PsiBuilder builder_, PsiBuilder.Marker marker_, String funcName_) { From 58da86dfe87255dfef5c3b83eb0d0d31b421529b Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 22 Nov 2013 14:51:20 +0100 Subject: [PATCH 40/91] don't search classes if there is dot in pattern (cherry picked from commit f231438d3d50044033963cbdb4a5b0a9d7a69cf9) --- .../src/com/intellij/ide/actions/SearchEverywhereAction.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java index 0d1c34300e42..81b51bfb03ba 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java @@ -1213,6 +1213,11 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA } private void buildClasses(String pattern, boolean includeLibraries) { + if (pattern.indexOf('.') != -1) { + //todo[kb] it's not a mistake. If we search for "*.png" or "index.xml" in SearchEverywhere + //todo[kb] we don't want to see Java classes started with Png or Xml. This approach should be reworked someday. + return; + } boolean includeLibs = includeLibraries || showAll.get(); int clsCounter = 0; final int maxCount = includeLibraries ? 5 : MAX_CLASSES; From 64636bb9ef6753b0573474e24fb04d8563df68c2 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 22 Nov 2013 17:25:08 +0100 Subject: [PATCH 41/91] fix one exception from IDEA-116497 (cherry picked from commit 1c6e2fa2aa81ba3c01c8660715e987f7b599fce1) --- .../platform-impl/src/com/intellij/ide/actions/Switcher.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java index 8696faa2b7a0..45f0da6dd5ab 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java @@ -1027,6 +1027,10 @@ public class Switcher extends AnAction implements DumbAware { public void propertyChange(PropertyChangeEvent evt) { final MyList list = getSelectedList(); final Object value = list.getSelectedValue(); + if (project.isDisposed()) { + myPopup.cancel(); + return; + } ((NameFilteringListModel)files.getModel()).refilter(); ((NameFilteringListModel)toolWindows.getModel()).refilter(); if (files.getModel().getSize() + toolWindows.getModel().getSize() == 0) { From c12b687f53bae08e210fea8f9284e54bf9522e5d Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 22 Nov 2013 17:38:59 +0100 Subject: [PATCH 42/91] IDEA-116497 UI hang during index update [r=Eugene.Zhuravlev] --- .../DefaultSymbolNavigationContributor.java | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java index fa3cd31c2546..243ecb220419 100644 --- a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java +++ b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java @@ -19,6 +19,7 @@ import com.intellij.ide.util.DefaultPsiElementCellRenderer; import com.intellij.navigation.ChooseByNameContributorEx; import com.intellij.navigation.NavigationItem; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.impl.PsiSuperMethodImplUtil; @@ -30,13 +31,11 @@ import com.intellij.util.Processor; import com.intellij.util.containers.HashSet; import com.intellij.util.indexing.FindSymbolParameters; import com.intellij.util.indexing.IdFilter; +import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; +import java.util.*; public class DefaultSymbolNavigationContributor implements ChooseByNameContributorEx { private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.gotoByName.DefaultSymbolNavigationContributor"); @@ -111,27 +110,40 @@ public class DefaultSymbolNavigationContributor implements ChooseByNameContribut IdFilter filter = parameters.getIdFilter(); PsiShortNamesCache cache = PsiShortNamesCache.getInstance(scope.getProject()); //noinspection UnusedDeclaration - boolean dummy = cache.processFieldsWithName(name, new Processor() { + final Set collectedMethods = new THashSet(); + boolean success = cache.processFieldsWithName(name, new Processor() { @Override public boolean process(PsiField field) { if (isOpenable(field)) return processor.process(field); return true; } }, scope, filter) && - cache.processMethodsWithName(name, new Processor() { - @Override - public boolean process(PsiMethod method) { - if(!method.isConstructor() && isOpenable(method) && !hasSuperMethod(method)) return processor.process(method); - return true; - } - }, scope, filter) && cache.processClassesWithName(name, new Processor() { @Override public boolean process(PsiClass aClass) { if (isOpenable(aClass)) return processor.process(aClass); return true; } + }, scope, filter) && + cache.processMethodsWithName(name, new Processor() { + @Override + public boolean process(PsiMethod method) { + if(!method.isConstructor() && isOpenable(method)) { + collectedMethods.add(method); + } + return true; + } }, scope, filter); + if (success) { + // hashSuperMethod accesses index and can not be invoked without risk of the deadlock in processMethodsWithName + Iterator iterator = collectedMethods.iterator(); + while(iterator.hasNext()) { + PsiMethod method = iterator.next(); + if (!hasSuperMethod(method) && !processor.process(method)) return; + ProgressManager.checkCanceled(); + iterator.remove(); + } + } } private static class MyComparator implements Comparator{ From fd11bd29ddd945fe69e8697bb4c0fe7c926fa70c Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Fri, 22 Nov 2013 20:55:02 +0400 Subject: [PATCH 43/91] Support for temporary and configuration-based IntelliLang injections in Python (PY-10983, PY-10721) --- .../META-INF/intellilang-python-support.xml | 2 + .../intelliLang/PyConfigurationInjector.java | 33 +++++++++++++++++ .../PyLanguageInjectionSupport.java | 35 ------------------ .../intelliLang/PyTemporaryInjector.java | 30 +++++++++++++++ .../python/codeInsight/PyInjectionUtil.java | 18 ++++++--- .../python/codeInsight/PyInjectorBase.java | 37 +++++++++++++++++++ .../regexp/PythonRegexpInjector.java | 2 +- 7 files changed, 116 insertions(+), 41 deletions(-) create mode 100644 python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyConfigurationInjector.java create mode 100644 python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyTemporaryInjector.java create mode 100644 python/src/com/jetbrains/python/codeInsight/PyInjectorBase.java diff --git a/python/IntelliLang-python/src/META-INF/intellilang-python-support.xml b/python/IntelliLang-python/src/META-INF/intellilang-python-support.xml index 2ffa9f7c2325..624d146a0378 100644 --- a/python/IntelliLang-python/src/META-INF/intellilang-python-support.xml +++ b/python/IntelliLang-python/src/META-INF/intellilang-python-support.xml @@ -7,5 +7,7 @@
+ + \ No newline at end of file diff --git a/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyConfigurationInjector.java b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyConfigurationInjector.java new file mode 100644 index 000000000000..f672f5d17ee6 --- /dev/null +++ b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyConfigurationInjector.java @@ -0,0 +1,33 @@ +package com.jetbrains.python.intelliLang; + +import com.intellij.lang.Language; +import com.intellij.psi.PsiElement; +import com.jetbrains.python.codeInsight.PyInjectorBase; +import org.intellij.plugins.intelliLang.Configuration; +import org.intellij.plugins.intelliLang.inject.InjectedLanguage; +import org.intellij.plugins.intelliLang.inject.InjectorUtils; +import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport; +import org.intellij.plugins.intelliLang.inject.config.BaseInjection; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author vlan + */ +public class PyConfigurationInjector extends PyInjectorBase { + @Nullable + @Override + public Language getInjectedLanguage(@NotNull PsiElement context) { + for (LanguageInjectionSupport support : InjectorUtils.getActiveInjectionSupports()) { + if (support instanceof PyLanguageInjectionSupport) { + final Configuration configuration = Configuration.getInstance(); + for (BaseInjection injection : configuration.getInjections(support.getId())) { + if (injection.acceptsPsiElement(context)) { + return InjectedLanguage.findLanguageById(injection.getInjectedLanguageId()); + } + } + } + } + return null; + } +} diff --git a/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyLanguageInjectionSupport.java b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyLanguageInjectionSupport.java index 5a91db5ce994..43db1f20d814 100644 --- a/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyLanguageInjectionSupport.java +++ b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyLanguageInjectionSupport.java @@ -15,22 +15,14 @@ */ package com.jetbrains.python.intelliLang; -import com.intellij.lang.Language; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiElement; import com.intellij.psi.PsiLanguageInjectionHost; import com.jetbrains.python.patterns.PythonPatterns; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.psi.PyStringLiteralExpression; import org.intellij.plugins.intelliLang.inject.AbstractLanguageInjectionSupport; -import org.intellij.plugins.intelliLang.inject.config.BaseInjection; -import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.List; - /** * @author yole */ @@ -54,33 +46,6 @@ public class PyLanguageInjectionSupport extends AbstractLanguageInjectionSupport return host instanceof PyElement; } - @Override - public boolean useDefaultInjector(PsiLanguageInjectionHost host) { - return true; - } - - @Override - public BaseInjection createInjection(Element element) { - // This is how DefaultLanguageInjector gets its injection ranges - return new BaseInjection(getId()) { - @NotNull - @Override - public List getInjectedArea(PsiElement element) { - if (element instanceof PyStringLiteralExpression) { - return ((PyStringLiteralExpression)element).getStringValueTextRanges(); - } - return super.getInjectedArea(element); - } - }; - } - - @Override - public boolean addInjectionInPlace(Language language, PsiLanguageInjectionHost psiElement) { - // XXX: Disable temporary injections via intention actions for Python elements, since TemporaryPlacesInjector cannot handle elements - // with multiple injection text ranges (PY-10691) - return true; - } - @Nullable @Override public String getHelpId() { diff --git a/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyTemporaryInjector.java b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyTemporaryInjector.java new file mode 100644 index 000000000000..d88905d623cf --- /dev/null +++ b/python/IntelliLang-python/src/com/jetbrains/python/intelliLang/PyTemporaryInjector.java @@ -0,0 +1,30 @@ +package com.jetbrains.python.intelliLang; + +import com.intellij.lang.Language; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiLanguageInjectionHost; +import com.jetbrains.python.codeInsight.PyInjectorBase; +import org.intellij.plugins.intelliLang.inject.InjectedLanguage; +import org.intellij.plugins.intelliLang.inject.TemporaryPlacesRegistry; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author vlan + */ +public class PyTemporaryInjector extends PyInjectorBase { + @Nullable + @Override + public Language getInjectedLanguage(@NotNull PsiElement context) { + final TemporaryPlacesRegistry registry = TemporaryPlacesRegistry.getInstance(context.getProject()); + if (context instanceof PsiLanguageInjectionHost) { + final PsiFile file = context.getContainingFile(); + final InjectedLanguage injectedLanguage = registry.getLanguageFor((PsiLanguageInjectionHost)context, file); + if (injectedLanguage != null) { + return injectedLanguage.getLanguage(); + } + } + return null; + } +} diff --git a/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java b/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java index d68e6c61c47f..d0a49fe810d7 100644 --- a/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java @@ -23,6 +23,7 @@ import com.jetbrains.python.psi.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.List; import static com.jetbrains.python.inspections.PyStringFormatParser.*; @@ -31,15 +32,22 @@ import static com.jetbrains.python.inspections.PyStringFormatParser.*; * @author vlan */ public class PyInjectionUtil { + public static final List> ELEMENTS_TO_INJECT_IN = + Arrays.asList(PyStringLiteralExpression.class, PyParenthesizedExpression.class, PyBinaryExpression.class, PyCallExpression.class); + private PyInjectionUtil() {} /** - * Returns true if the element is the largest expression that represents a string literal, possibly with concatenation, parentheses, - * or formatting. + * Returns the largest expression in the specified context that represents a string literal suitable for language injection, possibly + * with concatenation, parentheses, or formatting. */ - public static boolean isLargestStringLiteral(@NotNull PsiElement element) { - final PsiElement parent = element.getParent(); - return isStringLiteralPart(element) && (parent == null || !isStringLiteralPart(parent)); + @Nullable + public static PsiElement getLargestStringLiteral(@NotNull PsiElement context) { + PsiElement element = null; + for (PsiElement current = context; current != null && isStringLiteralPart(current); current = current.getParent()) { + element = current; + } + return element; } /** diff --git a/python/src/com/jetbrains/python/codeInsight/PyInjectorBase.java b/python/src/com/jetbrains/python/codeInsight/PyInjectorBase.java new file mode 100644 index 000000000000..48b62368af3d --- /dev/null +++ b/python/src/com/jetbrains/python/codeInsight/PyInjectorBase.java @@ -0,0 +1,37 @@ +package com.jetbrains.python.codeInsight; + +import com.intellij.lang.Language; +import com.intellij.lang.injection.MultiHostInjector; +import com.intellij.lang.injection.MultiHostRegistrar; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * @author vlan + */ +public abstract class PyInjectorBase implements MultiHostInjector { + @Override + public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) { + final Language language = getInjectedLanguage(context); + if (language != null) { + final PsiElement element = PyInjectionUtil.getLargestStringLiteral(context); + if (element != null) { + registrar.startInjecting(language); + PyInjectionUtil.registerStringLiteralInjection(element, registrar); + registrar.doneInjecting(); + } + } + } + + @NotNull + @Override + public List> elementsToInjectIn() { + return PyInjectionUtil.ELEMENTS_TO_INJECT_IN; + } + + @Nullable + public abstract Language getInjectedLanguage(@NotNull PsiElement context); +} diff --git a/python/src/com/jetbrains/python/codeInsight/regexp/PythonRegexpInjector.java b/python/src/com/jetbrains/python/codeInsight/regexp/PythonRegexpInjector.java index 39c9aff38410..bb23c475a576 100644 --- a/python/src/com/jetbrains/python/codeInsight/regexp/PythonRegexpInjector.java +++ b/python/src/com/jetbrains/python/codeInsight/regexp/PythonRegexpInjector.java @@ -67,7 +67,7 @@ public class PythonRegexpInjector implements MultiHostInjector { @Override public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) { final PsiElement contextParent = context.getParent(); - if (PyInjectionUtil.isLargestStringLiteral(context) && contextParent instanceof PyArgumentList) { + if (PyInjectionUtil.getLargestStringLiteral(context) == context && contextParent instanceof PyArgumentList) { final PyExpression[] args = ((PyArgumentList)contextParent).getArguments(); int index = ArrayUtil.indexOf(args, context); PyCallExpression call = PsiTreeUtil.getParentOfType(context, PyCallExpression.class); From 7a68cd1272304d648ee2e922022ef9d208697329 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 22 Nov 2013 17:52:14 +0100 Subject: [PATCH 44/91] IDEA-116929 [regression] Ant: after rewriting to DOM API create target quick fix is missing --- .../lang/ant/dom/AntResolveInspection.java | 4 + .../lang/ant/quickfix/AntCreateTargetFix.java | 93 +++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 plugins/ant/src/com/intellij/lang/ant/quickfix/AntCreateTargetFix.java diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntResolveInspection.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntResolveInspection.java index 93869991d4a1..b17f29ae11ac 100644 --- a/plugins/ant/src/com/intellij/lang/ant/dom/AntResolveInspection.java +++ b/plugins/ant/src/com/intellij/lang/ant/dom/AntResolveInspection.java @@ -21,6 +21,7 @@ import com.intellij.lang.ant.AntBundle; import com.intellij.lang.ant.AntSupport; import com.intellij.lang.ant.quickfix.AntChangeContextLocalFix; import com.intellij.lang.ant.quickfix.AntCreatePropertyFix; +import com.intellij.lang.ant.quickfix.AntCreateTargetFix; import com.intellij.lang.ant.validation.AntInspection; import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.psi.PsiFile; @@ -126,6 +127,9 @@ public class AntResolveInspection extends AntInspection { } } } + else if (ref instanceof AntDomTargetReference) { + quickFixList.add(new AntCreateTargetFix(ref.getCanonicalText())); + } holder.createProblem( domElement, diff --git a/plugins/ant/src/com/intellij/lang/ant/quickfix/AntCreateTargetFix.java b/plugins/ant/src/com/intellij/lang/ant/quickfix/AntCreateTargetFix.java new file mode 100644 index 000000000000..908769385ac1 --- /dev/null +++ b/plugins/ant/src/com/intellij/lang/ant/quickfix/AntCreateTargetFix.java @@ -0,0 +1,93 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.lang.ant.quickfix; + +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.lang.ant.AntBundle; +import com.intellij.lang.ant.dom.AntDomTarget; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.DomUtil; +import org.jetbrains.annotations.NotNull; + +public class AntCreateTargetFix implements LocalQuickFix { + private static final String TAG_NAME = "target"; + private static final String NAME_ATTR = "name"; + private final String myCanonicalText; + + public AntCreateTargetFix(String canonicalText) { + myCanonicalText = canonicalText; + } + + @NotNull + public String getName() { + return AntBundle.message("ant.create.target.intention.description", myCanonicalText); + } + + @NotNull + public String getFamilyName() { + return AntBundle.message("ant.intention.create.target.family.name"); + } + + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + final PsiElement psiElement = descriptor.getPsiElement(); + final PsiFile containingFile = psiElement.getContainingFile(); + + + Navigatable result = null; + if (containingFile instanceof XmlFile) { + final XmlFile xmlFile = (XmlFile)containingFile; + final XmlTag rootTag = xmlFile.getRootTag(); + if (rootTag != null) { + final XmlTag propTag = rootTag.createChildTag(TAG_NAME, rootTag.getNamespace(), "", false); + propTag.setAttribute(NAME_ATTR, myCanonicalText); + final DomElement contextElement = DomUtil.getDomElement(descriptor.getPsiElement()); + PsiElement generated; + if (contextElement == null) { + generated = rootTag.addSubTag(propTag, true); + } + else { + final AntDomTarget containingTarget = contextElement.getParentOfType(AntDomTarget.class, false); + final DomElement anchor = containingTarget != null ? containingTarget : contextElement; + final XmlTag tag = anchor.getXmlTag(); + if (!rootTag.equals(tag)) { + generated = tag.getParent().addBefore(propTag, tag); + } + else { + generated = rootTag.addSubTag(propTag, true); + } + } + if (generated instanceof XmlTag) { + result = new OpenFileDescriptor(project, containingFile.getVirtualFile(), ((XmlTag)generated).getValue().getTextRange().getEndOffset()); + } + if (result == null && generated instanceof Navigatable) { + result = (Navigatable)generated; + } + } + } + + if (result != null) { + result.navigate(true); + } + } +} From c5bbe866c8892923f2cd04012c81e03d2b927ae1 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 22 Nov 2013 15:33:31 +0400 Subject: [PATCH 45/91] correct test --- .../testSrc/com/intellij/psi/ClsDuplicatesTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsDuplicatesTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsDuplicatesTest.java index 2e0ee1608276..47189fb7d493 100644 --- a/java/java-tests/testSrc/com/intellij/psi/ClsDuplicatesTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/ClsDuplicatesTest.java @@ -39,7 +39,7 @@ public class ClsDuplicatesTest extends PsiTestCase { JavaRecursiveElementVisitor visitor = new JavaRecursiveElementVisitor() { @Override public void visitPackage(PsiPackage aPackage) { - System.out.println(aPackage.getQualifiedName()); +// System.out.println(aPackage.getQualifiedName()); visit(aPackage); for (PsiPackage subPackage : aPackage.getSubPackages(scope)) { @@ -65,7 +65,7 @@ public class ClsDuplicatesTest extends PsiTestCase { } super.visitClass(aClass); PsiElement parent = aClass.getParent(); - if (!(parent instanceof PsiClass)){ + if (parent instanceof PsiFile){ uniques.clear(); } } From 59858a4e87851d5e391855188525a4b12f1de370 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 22 Nov 2013 18:19:46 +0400 Subject: [PATCH 46/91] IDEA-76725 New option: "Find Usages: open in new tab" to be ON by default --- .../src/com/intellij/find/findUsages/FindUsagesManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java index 20ed2d15be6f..7047f9268dab 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -87,7 +87,7 @@ public class FindUsagesManager implements JDOMExternalizable { @NonNls private static final String VALUE_START_USAGE_AGAIN = "START_AGAIN"; private final Project myProject; private final com.intellij.usages.UsageViewManager myAnotherManager; - private boolean myToOpenInNewTab = false; + private boolean myToOpenInNewTab = true; public static class SearchData { public SmartPsiElementPointer[] myElements = null; From 3cf543e3ca37f9eaf37fa209a376482162055d70 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 22 Nov 2013 20:43:05 +0400 Subject: [PATCH 47/91] notnull --- .../com/intellij/openapi/application/BaseActionRunnable.java | 4 ++-- .../src/com/intellij/openapi/application/RunResult.java | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/platform/core-api/src/com/intellij/openapi/application/BaseActionRunnable.java b/platform/core-api/src/com/intellij/openapi/application/BaseActionRunnable.java index 212ac028a756..6bd8f05eb0c7 100644 --- a/platform/core-api/src/com/intellij/openapi/application/BaseActionRunnable.java +++ b/platform/core-api/src/com/intellij/openapi/application/BaseActionRunnable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ public abstract class BaseActionRunnable { return mySilentExecution; } - protected abstract void run(Result result) throws Throwable; + protected abstract void run(@NotNull Result result) throws Throwable; @NotNull public abstract RunResult execute(); diff --git a/platform/core-api/src/com/intellij/openapi/application/RunResult.java b/platform/core-api/src/com/intellij/openapi/application/RunResult.java index 8ff9327e9cff..85c84480a6cf 100644 --- a/platform/core-api/src/com/intellij/openapi/application/RunResult.java +++ b/platform/core-api/src/com/intellij/openapi/application/RunResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.intellij.openapi.application; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; +import org.jetbrains.annotations.NotNull; public class RunResult extends Result { @@ -28,7 +29,7 @@ public class RunResult extends Result { protected RunResult() { } - public RunResult(BaseActionRunnable action) { + public RunResult(@NotNull BaseActionRunnable action) { myActionRunnable = action; } From 67c086f0bc53dfb87331cbf1b7b4190985e7bb48 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Fri, 22 Nov 2013 21:05:44 +0400 Subject: [PATCH 48/91] Fixed SQL select IntelliLang pattern (PY-10926) --- python/IntelliLang-python/src/pyInjections.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/IntelliLang-python/src/pyInjections.xml b/python/IntelliLang-python/src/pyInjections.xml index e9ae34e1a348..a75015e02441 100644 --- a/python/IntelliLang-python/src/pyInjections.xml +++ b/python/IntelliLang-python/src/pyInjections.xml @@ -9,6 +9,6 @@ "SQL select/delete/insert/update/create" - + From f4a5f9aba64e87b21740d948c4ac6a6414fbca77 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Fri, 22 Nov 2013 21:08:41 +0400 Subject: [PATCH 49/91] Don't inject any language into percent-based Python formatting even without formatting operator (PY-10771) --- .../python/codeInsight/PyInjectionUtil.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java b/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java index d0a49fe810d7..7ce44b5531c9 100644 --- a/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java @@ -55,7 +55,7 @@ public class PyInjectionUtil { * string concatenations or formatting. */ public static void registerStringLiteralInjection(@NotNull PsiElement element, @NotNull MultiHostRegistrar registrar) { - processStringLiteral(element, registrar, "", "", Formatting.NONE); + processStringLiteral(element, registrar, "", "", Formatting.PERCENT); } private static boolean isStringLiteralPart(@NotNull PsiElement element) { @@ -108,9 +108,25 @@ public class PyInjectionUtil { final FormatStringChunk chunk = chunks.get(i); if (chunk instanceof ConstantChunk) { final int nextIndex = i + 1; - final String chunkPrefix = i == 1 && chunks.get(0) instanceof SubstitutionChunk ? missingValue : ""; - final String chunkSuffix = nextIndex < chunks.size() && - chunks.get(nextIndex) instanceof SubstitutionChunk ? missingValue : ""; + final String chunkPrefix; + if (i == 1 && chunks.get(0) instanceof SubstitutionChunk) { + chunkPrefix = missingValue; + } + else if (i == 0) { + chunkPrefix = prefix; + } else { + chunkPrefix = ""; + } + final String chunkSuffix; + if (nextIndex < chunks.size() && chunks.get(nextIndex) instanceof SubstitutionChunk) { + chunkSuffix = missingValue; + } + else if (nextIndex == chunks.size()) { + chunkSuffix = suffix; + } + else { + chunkSuffix = ""; + } final TextRange chunkRange = chunk.getTextRange().shiftRight(range.getStartOffset()); registrar.addPlace(chunkPrefix, chunkSuffix, expr, chunkRange); } From 8baba96ab13b71d9675c2e0cf732691a101ed918 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 22 Nov 2013 13:59:11 +0100 Subject: [PATCH 50/91] avoid double vfs name retrieval on initialization --- .../vfs/newvfs/impl/FileNameCache.java | 2 +- .../vfs/newvfs/impl/VirtualDirectoryImpl.java | 54 ++++++++++++--- .../vfs/newvfs/impl/VirtualFileImpl.java | 4 +- .../newvfs/impl/VirtualFileSystemEntry.java | 16 ++--- .../vfs/newvfs/persistent/FSRecords.java | 8 ++- .../newvfs/persistent/PersistentFSImpl.java | 66 +++++++++---------- 6 files changed, 87 insertions(+), 63 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FileNameCache.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FileNameCache.java index 283ec24d6884..ab9655a75c03 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FileNameCache.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FileNameCache.java @@ -79,7 +79,7 @@ public class FileNameCache { if (length == 0) return ""; if (!IOUtil.isAscii(name)) { - return name; + return new String(name); // So we don't hold whole char[] buffer of a lengthy path on JDK 6 } byte[] bytes = new byte[length]; diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java index 1906270aa400..a2e94a323d5d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java @@ -61,7 +61,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl"); public static boolean CHECK = ApplicationManager.getApplication().isUnitTestMode(); - static final VirtualDirectoryImpl NULL_VIRTUAL_FILE = new VirtualDirectoryImpl("*?;%NULL", null, LocalFileSystem.getInstance(), -42, 0) { + static final VirtualDirectoryImpl NULL_VIRTUAL_FILE = new VirtualDirectoryImpl(FileNameCache.storeName("*?;%NULL"), null, LocalFileSystem.getInstance(), -42, 0) { public String toString() { return "NULL"; } @@ -82,12 +82,12 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { */ private VirtualFileSystemEntry[] myChildren = EMPTY_ARRAY; - public VirtualDirectoryImpl(@NonNls @NotNull final String name, + public VirtualDirectoryImpl(@NonNls final int nameId, @Nullable final VirtualDirectoryImpl parent, @NotNull final NewVirtualFileSystem fs, final int id, @PersistentFS.Attributes final int attributes) { - super(name, parent, id, attributes); + super(nameId, parent, id, attributes); myFS = fs; } @@ -141,8 +141,38 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } private static class AdoptedChild extends VirtualFileImpl { + private final String myName; + private AdoptedChild(String name) { - super(name, NULL_VIRTUAL_FILE, -42, -1); + super(-1, NULL_VIRTUAL_FILE, -42, -1); + myName = name; + } + + @NotNull + @Override + public String getName() { + return myName; + } + + @Override + public void setNewName(@NotNull String newName) { + throw new IncorrectOperationException(); + } + + @Override + public int compareNameTo(@NotNull String name, boolean ignoreCase) { + return compareNames(myName, name, ignoreCase); + } + + @Override + protected char[] appendPathOnFileSystem(int accumulatedPathLength, int[] positionRef) { + char[] chars = getParent().appendPathOnFileSystem(accumulatedPathLength + 1 + myName.length(), positionRef); + if (positionRef[0] > 0 && chars[positionRef[0] - 1] != '/') { + chars[positionRef[0]++] = '/'; + } + positionRef[0] = VirtualFileSystemEntry.copyString(chars, positionRef[0], myName); + return chars; + } } @@ -199,8 +229,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { if (id <= 0) { return null; } - String shorty = new String(name); - VirtualFileSystemEntry child = createChild(shorty, id, delegate); // So we don't hold whole char[] buffer of a lengthy path + VirtualFileSystemEntry child = createChild(FileNameCache.storeName(name), id, delegate); VirtualFileSystemEntry[] after = myChildren; if (after != array) { @@ -238,15 +267,20 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } @NotNull - public VirtualFileSystemEntry createChild(@NotNull String name, int id, @NotNull NewVirtualFileSystem delegate) { + public VirtualFileSystemEntry createChild(String name, int id, @NotNull NewVirtualFileSystem delegate) { + return createChild(FileNameCache.storeName(name), id, delegate); + } + + @NotNull + private VirtualFileSystemEntry createChild(int nameId, int id, @NotNull NewVirtualFileSystem delegate) { VirtualFileSystemEntry child; final int attributes = ourPersistence.getFileAttributes(id); if (PersistentFS.isDirectory(attributes)) { - child = new VirtualDirectoryImpl(name, this, delegate, id, attributes); + child = new VirtualDirectoryImpl(nameId, this, delegate, id, attributes); } else { - child = new VirtualFileImpl(name, this, id, attributes); + child = new VirtualFileImpl(nameId, this, id, attributes); //noinspection TestOnlyProblems assertAccessInTests(child, delegate); } @@ -543,7 +577,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { resultFile = children[i++]; } else { - resultFile = createChild(nameId.name, nameId.id, delegate); + resultFile = createChild(nameId.nameId, nameId.id, delegate); } result[delegateI++] = resultFile; } 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 995670f2ae96..33c024fc5cfe 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 @@ -39,8 +39,8 @@ import java.util.Collections; public class VirtualFileImpl extends VirtualFileSystemEntry { private Charset myCharset; - VirtualFileImpl(String name, VirtualDirectoryImpl parent, int id, @PersistentFS.Attributes final int attributes) { - super(name, parent, id, attributes); + VirtualFileImpl(int nameId, VirtualDirectoryImpl parent, int id, @PersistentFS.Attributes final int attributes) { + super(nameId, parent, id, attributes); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java index 7da918a6a75f..2d5b5195dad6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java @@ -48,7 +48,6 @@ import java.nio.charset.Charset; public abstract class VirtualFileSystemEntry extends NewVirtualFile { public static final VirtualFileSystemEntry[] EMPTY_ARRAY = new VirtualFileSystemEntry[0]; - @NonNls protected static final String FS_ROOT_FAKE_NAME = ""; protected static final PersistentFS ourPersistence = PersistentFS.getInstance(); private static final Key SYMLINK_TARGET = Key.create("local.vfs.symlink.target"); @@ -70,13 +69,10 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile { private volatile int myFlags; private volatile int myId; - public VirtualFileSystemEntry(@NotNull String name, VirtualDirectoryImpl parent, int id, @PersistentFS.Attributes int attributes) { + public VirtualFileSystemEntry(int nameId, VirtualDirectoryImpl parent, int id, @PersistentFS.Attributes int attributes) { myParent = parent; myId = id; - - if (name != FS_ROOT_FAKE_NAME) { - storeName(name); - } + myNameId = nameId; if (parent != null && parent != VirtualDirectoryImpl.NULL_VIRTUAL_FILE) { setFlagInt(IS_SYMLINK_FLAG, PersistentFS.isSymLink(attributes)); @@ -90,10 +86,6 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile { setModificationStamp(LocalTimeCounter.currentTime()); } - private void storeName(@NotNull String name) { - myNameId = FileNameCache.storeName(name.replace('\\', '/')); // note: on Unix-style FS names may contain backslashes - } - private void updateLinkStatus() { boolean isSymLink = is(VFileProperty.SYMLINK); if (isSymLink) { @@ -113,7 +105,7 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile { return FileNameCache.compareNameTo(myNameId, name, ignoreCase); } - static int compareNames(@NotNull String name1, @NotNull String name2, boolean ignoreCase) { + protected static int compareNames(@NotNull String name1, @NotNull String name2, boolean ignoreCase) { return compareNames(name1, name2, ignoreCase, 0); } @@ -350,7 +342,7 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile { } myParent.removeChild(this); - storeName(newName); + myNameId = FileNameCache.storeName(newName); myParent.addChild(this); } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java index bd6691fb1601..c1c7cd6371fb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java @@ -29,6 +29,7 @@ import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.openapi.util.io.ByteSequence; import com.intellij.openapi.util.io.FileAttributes; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.newvfs.impl.FileNameCache; import com.intellij.util.ArrayUtil; import com.intellij.util.SystemProperties; import com.intellij.util.containers.ConcurrentHashMap; @@ -879,9 +880,11 @@ public class FSRecords implements Forceable { public static final NameId[] EMPTY_ARRAY = new NameId[0]; public final int id; public final String name; + public final int nameId; - public NameId(int id, @NotNull String name) { + public NameId(int id, int nameId, @NotNull String name) { this.id = id; + this.nameId = nameId; this.name = name; } @@ -904,7 +907,8 @@ public class FSRecords implements Forceable { for (int i = 0; i < count; i++) { int id = DataInputOutputUtil.readINT(input); id = id >= 0 ? id + parentId : -id; - result[i] = new NameId(id, getName(id)); + int nameId = getNameId(id); + result[i] = new NameId(id, nameId, FileNameCache.getVFileName(nameId)); } input.close(); return result; diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java index ec39e360282b..00087b175916 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java @@ -27,6 +27,7 @@ import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.newvfs.*; import com.intellij.openapi.vfs.newvfs.events.*; import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile; +import com.intellij.openapi.vfs.newvfs.impl.FileNameCache; import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl; import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry; import com.intellij.util.*; @@ -173,43 +174,26 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone return current; } - THashMap result = new THashMap(); - if (current.length == 0) { - for (String name : delegateNames) { - result.put(name, new FSRecords.NameId(-1, name)); - } - } - else { - for (FSRecords.NameId nameId : current) { - result.put(nameId.name, nameId); - } - for (String name : delegateNames) { - if (!result.containsKey(name)) { - result.put(name, new FSRecords.NameId(-1, name)); - } - } + Set toAdd = ContainerUtil.newHashSet(delegateNames); + for (FSRecords.NameId nameId : current) { + toAdd.remove(nameId.name); } - final TIntArrayList childrenIds = new TIntArrayList(result.size()); - final List nameIds = ContainerUtil.newArrayListWithExpectedSize(result.size()); - result.forEachValue(new TObjectProcedure() { - @Override - public boolean execute(FSRecords.NameId nameId) { - if (nameId.id < 0) { - FakeVirtualFile child = new FakeVirtualFile(file, nameId.name); - FileAttributes attributes = fs.getAttributes(child); - if (attributes != null) { - int childId = createAndFillRecord(fs, child, id, attributes); - nameId = new FSRecords.NameId(childId, nameId.name); - } - } - if (nameId.id > 0) { - childrenIds.add(nameId.id); - nameIds.add(nameId); - } - return true; + final TIntArrayList childrenIds = new TIntArrayList(current.length + toAdd.size()); + final List nameIds = ContainerUtil.newArrayListWithExpectedSize(current.length + toAdd.size()); + for (FSRecords.NameId nameId : current) { + childrenIds.add(nameId.id); + nameIds.add(nameId); + } + for (String newName : toAdd) { + FakeVirtualFile child = new FakeVirtualFile(file, newName); + FileAttributes attributes = fs.getAttributes(child); + if (attributes != null) { + int childId = createAndFillRecord(fs, child, id, attributes); + childrenIds.add(childId); + nameIds.add(new FSRecords.NameId(childId, FileNameCache.storeName(newName), newName)); } - }); + } FSRecords.updateList(id, childrenIds.toNativeArray()); setChildrenCached(id); @@ -1291,16 +1275,26 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone private abstract static class AbstractRoot extends VirtualDirectoryImpl { protected AbstractRoot(@NotNull NewVirtualFileSystem fs, int id) { - super(FS_ROOT_FAKE_NAME, null, fs, id, 0); + super(-1, null, fs, id, 0); } @NotNull @Override public abstract String getName(); + @Override + public int compareNameTo(@NotNull String name, boolean ignoreCase) { + return VirtualFileSystemEntry.compareNames(getName(), name, ignoreCase); + } + @Override protected abstract char[] appendPathOnFileSystem(int accumulatedPathLength, int[] positionRef); + @Override + public void setNewName(@NotNull String newName) { + throw new IncorrectOperationException(); + } + @Override public final void setParent(@NotNull VirtualFile newParent) { throw new IncorrectOperationException(); @@ -1315,7 +1309,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone @NotNull @Override public String getName() { - return FS_ROOT_FAKE_NAME; + return ""; } @SuppressWarnings("NonSynchronizedMethodOverridesSynchronizedMethod") From badc25d4447d11513db9011df592081a4ab616d6 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 22 Nov 2013 18:06:34 +0100 Subject: [PATCH 51/91] trying to make sense of p4 timeout in tests --- .../execution/process/CapturingProcessHandler.java | 14 +++++++++++++- .../testFramework/vcs/TestClientRunner.java | 6 ++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/platform/platform-api/src/com/intellij/execution/process/CapturingProcessHandler.java b/platform/platform-api/src/com/intellij/execution/process/CapturingProcessHandler.java index 0cea7ab1525e..d76817b98f97 100644 --- a/platform/platform-api/src/com/intellij/execution/process/CapturingProcessHandler.java +++ b/platform/platform-api/src/com/intellij/execution/process/CapturingProcessHandler.java @@ -66,6 +66,16 @@ public class CapturingProcessHandler extends OSProcessHandler { * @param timeoutInMilliseconds non-positive means infinity */ public ProcessOutput runProcess(int timeoutInMilliseconds) { + return runProcess(timeoutInMilliseconds, true); + } + + /** + * Starts process with specified timeout + * + * @param timeoutInMilliseconds non-positive means infinity + * @param destroyOnTimeout whether to kill the process after timeout passes + */ + public ProcessOutput runProcess(int timeoutInMilliseconds, boolean destroyOnTimeout) { if (timeoutInMilliseconds <= 0) { return runProcess(); } @@ -75,7 +85,9 @@ public class CapturingProcessHandler extends OSProcessHandler { myOutput.setExitCode(getProcess().exitValue()); } else { - destroyProcess(); + if (destroyOnTimeout) { + destroyProcess(); + } myOutput.setTimeout(); } return myOutput; diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/vcs/TestClientRunner.java b/platform/testFramework/testSrc/com/intellij/testFramework/vcs/TestClientRunner.java index 88985a81797b..65851dcc1f5a 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/vcs/TestClientRunner.java +++ b/platform/testFramework/testSrc/com/intellij/testFramework/vcs/TestClientRunner.java @@ -93,7 +93,7 @@ public class TestClientRunner { } final CapturingProcessHandler handler = new CapturingProcessHandler(clientProcess, CharsetToolkit.getDefaultSystemCharset()); - final ProcessOutput result = handler.runProcess(100*1000); + final ProcessOutput result = handler.runProcess(100*1000, false); if (myTraceClient || result.isTimeout()) { LOG.debug("*** result: " + result.getExitCode()); final String out = result.getStdout().trim(); @@ -107,7 +107,9 @@ public class TestClientRunner { } if (result.isTimeout()) { - throw new RuntimeException("Timeout waiting for VCS client to finish execution:\n" + EnvironmentUtil.getProcessList()); + String processList = EnvironmentUtil.getProcessList(); + handler.destroyProcess(); + throw new RuntimeException("Timeout waiting for VCS client to finish execution:\n" + processList); } return result; } From c7a040805f212b55866976e4ab20d00418a9f4e7 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 22 Nov 2013 18:16:21 +0100 Subject: [PATCH 52/91] get rid of psi/doc inconsistency before reparse by not relying on TextBlock information --- .../psi/impl/DocumentCommitProcessor.java | 73 +++---------------- 1 file changed, 10 insertions(+), 63 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java index dd3deece51a6..4eeb7527b908 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java +++ b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java @@ -18,7 +18,6 @@ package com.intellij.psi.impl; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; @@ -26,7 +25,6 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.UnfairTextRange; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.PomManager; import com.intellij.pom.PomModel; import com.intellij.pom.event.PomModelEvent; @@ -41,15 +39,12 @@ import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.psi.impl.source.text.DiffLog; import com.intellij.psi.impl.source.tree.FileElement; import com.intellij.psi.text.BlockSupport; -import com.intellij.util.FileContentUtilCore; import com.intellij.util.IncorrectOperationException; import com.intellij.util.Processor; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; - public abstract class DocumentCommitProcessor { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.DocumentCommitThread"); @@ -108,35 +103,26 @@ public abstract class DocumentCommitProcessor { @NotNull final PsiFile file, final boolean synchronously) { Document document = task.document; + if (PsiDocumentManager.getInstance(task.project).isCommitted(document)) return null; final TextBlock textBlock = TextBlock.get(file); - if (textBlock.isEmpty()) return null; final long startDocModificationTimeStamp = document.getModificationStamp(); final FileElement myTreeElementBeingReparsedSoItWontBeCollected = ((PsiFileImpl)file).calcTreeElement(); - if (textBlock.isEmpty()) return null; // if tree was just loaded above textBlock will be cleared by contentsLoaded final CharSequence chars = document.getCharsSequence(); final Boolean data = document.getUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY); if (data != null) { document.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, null); file.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, data); } - final String oldPsiText = ApplicationManager.getApplication().isInternal() && ApplicationManager.getApplication().isUnitTestMode() - ? myTreeElementBeingReparsedSoItWontBeCollected.getText() - : null; - final TextRange changedPsiRange = - getChangedPsiRange(file, textBlock.getStartOffset(), textBlock.getPsiEndOffset(), document.getTextLength()); - if (!assertBeforeCommit(document, file, textBlock, chars, oldPsiText, myTreeElementBeingReparsedSoItWontBeCollected)) { - return new Processor() { - @Override - public boolean process(Document document) { - VirtualFile vFile = FileDocumentManager.getInstance().getFile(document); - log("Recovering from assertBeforeCommit", task, synchronously, vFile, vFile != null && vFile.isValid()); - if (vFile != null && vFile.isValid()) { - FileContentUtilCore.reparseFiles(Arrays.asList(vFile)); - } - return true; - } - }; + final String oldPsiText = myTreeElementBeingReparsedSoItWontBeCollected.getText(); + int commonPrefixLength = StringUtil.commonPrefixLength(oldPsiText, chars); + final TextRange changedPsiRange; + if (commonPrefixLength == chars.length()) { + changedPsiRange = getChangedPsiRange(file, 0, 0, chars.length()); + } else { + int commonSuffixLength = StringUtil.commonSuffixLength(oldPsiText, chars); + changedPsiRange = getChangedPsiRange(file, commonPrefixLength, oldPsiText.length() - commonSuffixLength, chars.length()); } + BlockSupport blockSupport = BlockSupport.getInstance(file.getProject()); final DiffLog diffLog = blockSupport.reparseRange(file, changedPsiRange, chars, task.indicator); @@ -206,45 +192,6 @@ public abstract class DocumentCommitProcessor { } } - private static boolean assertBeforeCommit(@NotNull Document document, - @NotNull PsiFile file, - @NotNull TextBlock textBlock, - @NotNull CharSequence chars, - String oldPsiText, - @NotNull FileElement myTreeElementBeingReparsedSoItWontBeCollected) { - int startOffset = textBlock.getStartOffset(); - int psiEndOffset = textBlock.getPsiEndOffset(); - if (oldPsiText != null) { - @NonNls String msg = "PSI/document inconsistency before reparse: file=" + file + " of class " + file.getClass(); - if (startOffset >= oldPsiText.length()) { - msg += "\nstartOffset=" + oldPsiText + " while text length is " + oldPsiText.length() + "; "; - startOffset = oldPsiText.length(); - } - - String psiPrefix = oldPsiText.substring(0, startOffset); - String docPrefix = chars.subSequence(0, startOffset).toString(); - String psiSuffix = psiEndOffset > oldPsiText.length() ? "" : oldPsiText.substring(psiEndOffset); - String docSuffix = chars.subSequence(textBlock.getTextEndOffset(), chars.length()).toString(); - if (!psiPrefix.equals(docPrefix) || !psiSuffix.equals(docSuffix)) { - if (!psiPrefix.equals(docPrefix)) { - msg = msg + "\n\npsiPrefix=" + psiPrefix + "\n\ndocPrefix=" + docPrefix; - } - if (!psiSuffix.equals(docSuffix)) { - msg = msg + "\n\npsiSuffix=" + psiSuffix + "\n\ndocSuffix=" + docSuffix; - } - LOG.error(msg); - return false; - } - } - else if (document.getTextLength() - textBlock.getTextEndOffset() != - myTreeElementBeingReparsedSoItWontBeCollected.getTextLength() - psiEndOffset) { - LOG.error("PSI/document inconsistency before reparse: file=" + file); - return false; - } - - return true; - } - private void assertAfterCommit(Document document, final PsiFile file, String oldPsiText, From 85af40146299a96283b498cc65296ab4afe0cd29 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 22 Nov 2013 19:09:14 +0100 Subject: [PATCH 53/91] try to recover after finding stub in a non-stub file --- .../com/intellij/psi/impl/source/PsiFileImpl.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index 3c45de18afca..640c841feba7 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -1000,11 +1000,13 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF IElementType contentElementType = getContentElementType(); if (!(contentElementType instanceof IStubFileElementType)) { VirtualFile vFile = getVirtualFile(); - throw new AssertionError("ContentElementType: " + contentElementType + "; file: " + this + - "\n\t" + "Boolean.TRUE.equals(getUserData(BUILDING_STUB)) = " + Boolean.TRUE.equals(getUserData(BUILDING_STUB)) + - "\n\t" + "getTreeElement() = " + getTreeElement() + - "\n\t" + "vFile instanceof VirtualFileWithId = " + (vFile instanceof VirtualFileWithId) + - "\n\t" + "StubUpdatingIndex.canHaveStub(vFile) = " + StubTreeLoader.getInstance().canHaveStub(vFile)); + String message = "ContentElementType: " + contentElementType + "; file: " + this + + "\n\t" + "Boolean.TRUE.equals(getUserData(BUILDING_STUB)) = " + Boolean.TRUE.equals(getUserData(BUILDING_STUB)) + + "\n\t" + "getTreeElement() = " + getTreeElement() + + "\n\t" + "vFile instanceof VirtualFileWithId = " + (vFile instanceof VirtualFileWithId) + + "\n\t" + "StubUpdatingIndex.canHaveStub(vFile) = " + StubTreeLoader.getInstance().canHaveStub(vFile); + rebuildStub(); + throw new AssertionError(message); } StubElement currentStubTree = ((IStubFileElementType)contentElementType).getBuilder().buildStubTree(this); From c91c59322ff4b3a4944b4762ec18561b27eea510 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 22 Nov 2013 19:57:54 +0100 Subject: [PATCH 54/91] allow only string and int literals to have provided references in java --- .../psi/impl/source/tree/java/PsiLiteralExpressionImpl.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java index d14c08ed1b6d..cf099fb33304 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java @@ -382,7 +382,10 @@ public class PsiLiteralExpressionImpl @Override @NotNull public PsiReference[] getReferences() { - if (textMatches(PsiKeyword.NULL)) return PsiReference.EMPTY_ARRAY; + IElementType type = getLiteralElementType(); + if (type != JavaTokenType.STRING_LITERAL && type != JavaTokenType.INTEGER_LITERAL) { + return PsiReference.EMPTY_ARRAY; // there are references in int literals in SQL API parameters + } return PsiReferenceService.getService().getContributedReferences(this); } From 06d747d1c3651bdbe7aade24c5889779a999be50 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 22 Nov 2013 20:21:49 +0100 Subject: [PATCH 55/91] Some html contains wrong width and height for images --- .../platform-impl/src/com/intellij/ide/util/TipUIUtil.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java index 62b5a2389cbe..0e531bfc1fc9 100644 --- a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java +++ b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java @@ -91,9 +91,9 @@ public class TipUIUtil { private static void updateImages(StringBuffer text, Class providerClass) { final boolean dark = UIUtil.isUnderDarcula(); final boolean retina = UIUtil.isRetina(); - if (!dark && !retina) { - return; - } +// if (!dark && !retina) { +// return; +// } String suffix = ""; if (retina) suffix += "@2x"; From a0c7d51f0ed086ac0bc856a467882c17c01721ef Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Sat, 23 Nov 2013 00:09:47 +0400 Subject: [PATCH 56/91] WEB-9933 What should happen when creating node.js Express App as New Module? --- .../intellij/openapi/module/WebModuleBuilder.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/module/WebModuleBuilder.java b/platform/lang-impl/src/com/intellij/openapi/module/WebModuleBuilder.java index cee30d38edf2..991ae5f84cf8 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/WebModuleBuilder.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/WebModuleBuilder.java @@ -24,14 +24,12 @@ import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.platform.WebProjectGenerator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.List; /** * @author Dmitry Avdeev @@ -72,13 +70,14 @@ public class WebModuleBuilder extends ModuleBuilder { return myTemplate != null ? myTemplate.getIcon() : ICON; } + @Nullable @Override - public List commit(Project project, ModifiableModuleModel model, ModulesProvider modulesProvider) { - List modules = super.commit(project, model, modulesProvider); - if (modules != null && !modules.isEmpty() && myTemplate != null) { - doGenerate(myTemplate, modules.get(0)); + public Module commitModule(@NotNull Project project, @Nullable ModifiableModuleModel model) { + Module module = super.commitModule(project, model); + if (module != null && myTemplate != null) { + doGenerate(myTemplate, module); } - return modules; + return module; } private static void doGenerate(@NotNull WebProjectTemplate template, @NotNull Module module) { From c4e9893ac467732b7e4196123aba3b9368fc0445 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 22 Nov 2013 11:42:11 +0100 Subject: [PATCH 57/91] Cleanup (bug reference updated) --- platform/platform-api/src/com/intellij/ui/ScreenUtil.java | 2 +- platform/util/src/com/intellij/Patches.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/ScreenUtil.java b/platform/platform-api/src/com/intellij/ui/ScreenUtil.java index 00300b390604..76bb6f25e357 100644 --- a/platform/platform-api/src/com/intellij/ui/ScreenUtil.java +++ b/platform/platform-api/src/com/intellij/ui/ScreenUtil.java @@ -165,7 +165,7 @@ public class ScreenUtil { } private static Insets calcInsets(GraphicsConfiguration gc) { - if (Patches.SUN_BUG_ID_9000030 && GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices().length > 1) { + if (Patches.SUN_BUG_ID_7172665 && GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices().length > 1) { return new Insets(0, 0, 0, 0); } diff --git a/platform/util/src/com/intellij/Patches.java b/platform/util/src/com/intellij/Patches.java index 055a673ce675..40c517641ba4 100644 --- a/platform/util/src/com/intellij/Patches.java +++ b/platform/util/src/com/intellij/Patches.java @@ -113,9 +113,9 @@ public class Patches { /** * Java 7 incorrectly calculates screen insets on multi-monitor X Window configurations. - * See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=9000030. + * See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7172665. */ - public static final boolean SUN_BUG_ID_9000030 = SystemInfo.isXWindow && SystemInfo.isJavaVersionAtLeast("1.7"); + public static final boolean SUN_BUG_ID_7172665 = SystemInfo.isXWindow && SystemInfo.isJavaVersionAtLeast("1.7"); /** * On some WMs modal dialogs may show behind full screen window. From 264bf33af893144aa84291288941965ef85713d2 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 22 Nov 2013 15:42:42 +0100 Subject: [PATCH 58/91] platform: more readable diagnostic message --- platform/util/src/com/intellij/util/lang/UrlClassLoader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/util/lang/UrlClassLoader.java b/platform/util/src/com/intellij/util/lang/UrlClassLoader.java index b6f981638294..33733e5d4c08 100644 --- a/platform/util/src/com/intellij/util/lang/UrlClassLoader.java +++ b/platform/util/src/com/intellij/util/lang/UrlClassLoader.java @@ -235,7 +235,8 @@ public class UrlClassLoader extends ClassLoader { if (!new File(libPath = PathManager.getHomePath() + "/community/bin/" + platform + libFileName).exists()) { if (!new File(libPath = PathManager.getHomePath() + "/bin/" + platform + libFileName).exists()) { if (!new File(libPath = PathManager.getHomePathFor(IdeaWin32.class) + "/bin/" + libFileName).exists()) { - throw new UnsatisfiedLinkError("'" + libFileName + "' not found among " + Arrays.toString(new File(PathManager.getBinPath()).listFiles())); + File libDir = new File(PathManager.getBinPath()); + throw new UnsatisfiedLinkError("'" + libFileName + "' not found in '" + libDir + "' among " + Arrays.toString(libDir.list())); } } } From 702fee5d5646a5ffafcc86e16dd3e06e53ce09b8 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 22 Nov 2013 18:09:00 +0100 Subject: [PATCH 59/91] Cleanup (formatting) --- .../openapi/vfs/ex/temp/TempFileSystem.java | 51 +++++++++---------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java index 92e7ed73e486..8744cd293dee 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.openapi.vfs.ex.temp; import com.intellij.openapi.application.ApplicationManager; @@ -46,6 +45,7 @@ import java.util.Set; public class TempFileSystem extends LocalFileSystemBase { private final FSItem myRoot = new FSDir(null, "/"); + @SuppressWarnings("MethodOverridesStaticMethodOfSuperclass") public static TempFileSystem getInstance() { return ApplicationManager.getApplication().getComponent(TempFileSystem.class); } @@ -53,7 +53,6 @@ public class TempFileSystem extends LocalFileSystemBase { @NotNull @Override protected String extractRootPath(@NotNull final String path) { - //return path.startsWith("/") ? "/" : ""; return "/"; } @@ -66,6 +65,7 @@ public class TempFileSystem extends LocalFileSystemBase { private FSItem convert(VirtualFile file) { final VirtualFile parentFile = file.getParent(); if (parentFile == null) return myRoot; + FSItem parentItem = convert(parentFile); if (parentItem == null || !parentItem.isDirectory()) { return null; @@ -74,15 +74,9 @@ public class TempFileSystem extends LocalFileSystemBase { return parentItem.findChild(file.getName()); } - @Override - public VirtualFile copyFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final VirtualFile newParent, @NotNull final String copyName) - throws IOException { - return VfsUtilCore.copyFile(requestor, file, newParent, copyName); - } - @Override @NotNull - public VirtualFile createChildDirectory(final Object requestor, @NotNull final VirtualFile parent, @NotNull final String dir) throws IOException { + public VirtualFile createChildDirectory(Object requestor, @NotNull VirtualFile parent, @NotNull String dir) throws IOException { final FSItem fsItem = convert(parent); assert fsItem != null && fsItem.isDirectory(); @@ -95,27 +89,34 @@ public class TempFileSystem extends LocalFileSystemBase { throw new IOException("Directory already contains a file named " + dir); } - return new FakeVirtualFile(parent, dir); } @Override - public VirtualFile createChildFile(final Object requestor, @NotNull final VirtualFile parent, @NotNull final String file) throws IOException { + public VirtualFile createChildFile(Object requestor, @NotNull VirtualFile parent, @NotNull String file) throws IOException { final FSItem fsItem = convert(parent); if (fsItem == null) { FSRecords.invalidateCaches(); throw new IllegalStateException("cannot find parent directory: " + parent.getPath()); } - assert fsItem.isDirectory(): "parent is not a directory: " + parent.getPath(); + assert fsItem.isDirectory() : "parent is not a directory: " + parent.getPath(); final FSDir fsDir = (FSDir)fsItem; - assert fsDir.findChild(file) == null: "File " + file + " already exists in " + parent.getPath(); + assert fsDir.findChild(file) == null : "File " + file + " already exists in " + parent.getPath(); fsDir.addChild(new FSFile(fsDir, file)); return new FakeVirtualFile(parent, file); } + @Override + public VirtualFile copyFile(Object requestor, + @NotNull VirtualFile file, + @NotNull VirtualFile newParent, + @NotNull String copyName) throws IOException { + return VfsUtilCore.copyFile(requestor, file, newParent, copyName); + } + @Override public void deleteFile(final Object requestor, @NotNull final VirtualFile file) throws IOException { final FSItem fsItem = convert(file); @@ -129,23 +130,22 @@ public class TempFileSystem extends LocalFileSystemBase { @Override public void moveFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final VirtualFile newParent) throws IOException { final FSItem fsItem = convert(file); - assert fsItem != null: "failed to move file " + file.getPath(); + assert fsItem != null : "failed to move file " + file.getPath(); final FSItem newParentItem = convert(newParent); - assert newParentItem != null && newParentItem.isDirectory(): "failed to find move target " + file.getPath(); - FSDir newDir = (FSDir) newParentItem; + assert newParentItem != null && newParentItem.isDirectory() : "failed to find move target " + file.getPath(); + FSDir newDir = (FSDir)newParentItem; if (newDir.findChild(file.getName()) != null) { throw new IOException("Directory already contains a file named " + file.getName()); } fsItem.getParent().removeChild(fsItem); - ((FSDir) newParentItem).addChild(fsItem); + ((FSDir)newParentItem).addChild(fsItem); } @Override public void renameFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final String newName) throws IOException { final FSItem fsItem = convert(file); assert fsItem != null; - fsItem.setName(newName); } @@ -165,7 +165,6 @@ public class TempFileSystem extends LocalFileSystemBase { public String[] list(@NotNull final VirtualFile file) { final FSItem fsItem = convert(file); assert fsItem != null; - return fsItem.list(); } @@ -177,8 +176,7 @@ public class TempFileSystem extends LocalFileSystemBase { @Override public long getTimeStamp(@NotNull final VirtualFile file) { final FSItem fsItem = convert(file); - assert fsItem != null: "cannot find item for path " + file.getPath(); - + assert fsItem != null : "cannot find item for path " + file.getPath(); return fsItem.myTimestamp; } @@ -186,7 +184,6 @@ public class TempFileSystem extends LocalFileSystemBase { public void setTimeStamp(@NotNull final VirtualFile file, final long timeStamp) { final FSItem fsItem = convert(file); assert fsItem != null; - fsItem.myTimestamp = timeStamp > 0 ? timeStamp : LocalTimeCounter.currentTime(); } @@ -194,7 +191,6 @@ public class TempFileSystem extends LocalFileSystemBase { public boolean isWritable(@NotNull final VirtualFile file) { final FSItem fsItem = convert(file); assert fsItem != null; - return fsItem.myWritable; } @@ -202,7 +198,6 @@ public class TempFileSystem extends LocalFileSystemBase { public void setWritable(@NotNull final VirtualFile file, final boolean writableFlag) throws IOException { final FSItem fsItem = convert(file); assert fsItem != null; - fsItem.myWritable = writableFlag; } @@ -211,9 +206,7 @@ public class TempFileSystem extends LocalFileSystemBase { public byte[] contentsToByteArray(@NotNull final VirtualFile file) throws IOException { final FSItem fsItem = convert(file); if (fsItem == null) throw new FileNotFoundException("Cannot find temp for " + file.getPath()); - assert fsItem instanceof FSFile; - return ((FSFile)fsItem).myContent; } @@ -225,8 +218,10 @@ public class TempFileSystem extends LocalFileSystemBase { @Override @NotNull - public OutputStream getOutputStream(@NotNull final VirtualFile file, final Object requestor, final long modStamp, final long timeStamp) - throws IOException { + public OutputStream getOutputStream(@NotNull final VirtualFile file, + final Object requestor, + final long modStamp, + final long timeStamp) throws IOException { return new ByteArrayOutputStream() { @Override public void close() throws IOException { From 5cde14bf7bd9069fd208c727e38315d9ba4d46e1 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 22 Nov 2013 22:01:20 +0100 Subject: [PATCH 60/91] platform: partial refresh fixed Before, parts of the VFS tree (below or near some point) may remain dirty indefinitely after aborted refresh at that point --- .../vfs/newvfs/persistent/RefreshWorker.java | 42 +++++++++++---- .../openapi/vfs/local/FileWatcherTest.java | 6 +++ .../vfs/local/LocalFileSystemTest.java | 51 ++++++++++++++++++- 3 files changed, 89 insertions(+), 10 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java index 6dfe3082fd57..ad9a978134af 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.vfs.newvfs.persistent; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; @@ -29,6 +30,7 @@ import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem; import com.intellij.openapi.vfs.newvfs.events.*; import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile; import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.OpenTHashSet; import com.intellij.util.containers.Queue; @@ -36,8 +38,12 @@ import com.intellij.util.text.FilePathHashingStrategy; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; import static com.intellij.openapi.diagnostic.LogUtil.debug; import static com.intellij.util.containers.ContainerUtil.newTroveSet; @@ -97,14 +103,14 @@ public class RefreshWorker { TObjectHashingStrategy strategy = FilePathHashingStrategy.create(fs.isCaseSensitive()); while (!myRefreshQueue.isEmpty()) { - checkCancelled(); - Pair pair = myRefreshQueue.pullFirst(); NewVirtualFile file = pair.first; boolean fileDirty = file.isDirty(); debug(LOG, "file=%s dirty=%b", file, fileDirty); if (!fileDirty) continue; + checkCancelled(file); + FileAttributes attributes = pair.second != null ? pair.second : fs.getAttributes(file); if (attributes == null) { scheduleDeletion(file); @@ -139,7 +145,7 @@ public class RefreshWorker { } for (String name : newNames) { - checkCancelled(); + checkCancelled(file); FileAttributes childAttributes = fs.getAttributes(new FakeVirtualFile(file, name)); if (childAttributes != null) { scheduleCreation(file, name, childAttributes.isDirectory(), false); @@ -150,7 +156,7 @@ public class RefreshWorker { } for (VirtualFile child : file.getChildren()) { - checkCancelled(); + checkCancelled(file); if (!deletedNames.contains(child.getName())) { FileAttributes childAttributes = fs.getAttributes(child); if (childAttributes != null) { @@ -173,7 +179,7 @@ public class RefreshWorker { debug(LOG, "cached=%s actual=%s", cachedChildren, actualNames); for (VirtualFile child : cachedChildren) { - checkCancelled(); + checkCancelled(file); FileAttributes childAttributes = fs.getAttributes(child); if (childAttributes != null) { checkAndScheduleChildRefresh(file, child, childAttributes); @@ -187,7 +193,7 @@ public class RefreshWorker { List names = dir.getSuspiciousNames(); debug(LOG, "suspicious=%s", names); for (String name : names) { - checkCancelled(); + checkCancelled(file); if (name.isEmpty()) continue; VirtualFile fake = new FakeVirtualFile(file, name); @@ -250,12 +256,22 @@ public class RefreshWorker { private static class RefreshCancelledException extends RuntimeException { } - private void checkCancelled() { - if (myCancelled) { + private void checkCancelled(@NotNull NewVirtualFile stopAt) { + if (myCancelled || ourCancellingCondition != null && ourCancellingCondition.fun(stopAt)) { + forceMarkDirty(stopAt); + while (!myRefreshQueue.isEmpty()) { + NewVirtualFile next = myRefreshQueue.pullFirst().first; + forceMarkDirty(next); + } throw new RefreshCancelledException(); } } + private static void forceMarkDirty(NewVirtualFile file) { + file.markClean(); // otherwise consequent markDirty() won't have any effect + file.markDirty(); + } + private void checkAndScheduleChildRefresh(@NotNull VirtualFile parent, @NotNull VirtualFile child, @NotNull FileAttributes childAttributes) { @@ -307,4 +323,12 @@ public class RefreshWorker { myEvents.add(new VFileDeleteEvent(null, file, true)); } } + + private static Function ourCancellingCondition = null; + + @TestOnly + public static void setCancellingCondition(@Nullable Function condition) { + assert ApplicationManager.getApplication().isUnitTestMode(); + ourCancellingCondition = condition; + } } diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java index 6947c92c1e07..f15f19d26ac8 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java @@ -685,6 +685,12 @@ public class FileWatcherTest extends PlatformLangTestCase { LocalFileSystemTest.doTestPartialRefresh(top); } + public void testInterruptedRefresh() throws Exception { + // tests the same scenario with an active file watcher (prevents explicit marking of refreshed paths) + File top = createTestDir("top"); + LocalFileSystemTest.doTestInterruptedRefresh(top); + } + public void testUnicodePaths() throws Exception { if (!SystemInfo.isUnix || SystemInfo.isMac) { System.err.println("Ignored: well-defined FS required"); diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java index e53f4007022e..37122a77b349 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java @@ -32,8 +32,10 @@ import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl; import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry; import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS; import com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl; +import com.intellij.openapi.vfs.newvfs.persistent.RefreshWorker; import com.intellij.testFramework.PlatformLangTestCase; import com.intellij.testFramework.PlatformTestUtil; +import com.intellij.util.Function; import com.intellij.util.messages.MessageBusConnection; import org.jetbrains.annotations.NotNull; @@ -471,7 +473,7 @@ public class LocalFileSystemTest extends PlatformLangTestCase { doTestPartialRefresh(top); } - public static void doTestPartialRefresh(File top) throws IOException { + public static void doTestPartialRefresh(@NotNull File top) throws IOException { File sub = IoTestUtil.createTestDir(top, "sub"); File file = IoTestUtil.createTestFile(top, "sub.txt"); LocalFileSystem lfs = LocalFileSystem.getInstance(); @@ -541,4 +543,51 @@ public class LocalFileSystemTest extends PlatformLangTestCase { assertTrue(vLink.isValid()); assertTrue(vLink.isDirectory()); } + + public void testInterruptedRefresh() throws Exception { + File top = createTempDirectory(false); + doTestInterruptedRefresh(top); + } + + public static void doTestInterruptedRefresh(@NotNull File top) throws Exception { + File sub = IoTestUtil.createTestDir(top, "sub"); + File subSub = IoTestUtil.createTestDir(sub, "sub_sub"); + File file1 = IoTestUtil.createTestFile(sub, "sub_file_to_stop_at"); + File file2 = IoTestUtil.createTestFile(subSub, "sub_sub_file"); + LocalFileSystem lfs = LocalFileSystem.getInstance(); + NewVirtualFile topDir = (NewVirtualFile)lfs.refreshAndFindFileByIoFile(top); + assertNotNull(topDir); + NewVirtualFile subFile1 = (NewVirtualFile)lfs.refreshAndFindFileByIoFile(file1); + assertNotNull(subFile1); + NewVirtualFile subFile2 = (NewVirtualFile)lfs.refreshAndFindFileByIoFile(file2); + assertNotNull(subFile2); + topDir.refresh(false, true); + assertFalse(topDir.isDirty()); + assertFalse(subFile1.isDirty()); + assertFalse(subFile2.isDirty()); + + try { + subFile1.markDirty(); + subFile2.markDirty(); + RefreshWorker.setCancellingCondition(new Function() { + @Override + public Boolean fun(VirtualFile file) { + return "sub_file_to_stop_at".equals(file.getName()); + } + }); + topDir.refresh(false, true); + // should remain dirty after aborted refresh + assertTrue(subFile1.isDirty()); + assertTrue(subFile2.isDirty()); + + RefreshWorker.setCancellingCondition(null); + topDir.refresh(false, true); + assertFalse(topDir.isDirty()); + assertFalse(subFile1.isDirty()); + assertFalse(subFile2.isDirty()); + } + finally { + RefreshWorker.setCancellingCondition(null); + } + } } From 2199afd989c988c0497621b369d9c40349d66ca8 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 23 Nov 2013 09:25:30 +0100 Subject: [PATCH 61/91] IDEA-116838 Make iteration order in com.intellij.util.containers.hash.LinkedHashMap consistent with java.util.LinkedHashMap's --- .../util/containers/hash/LinkedHashMap.java | 4 +-- .../containers/hash/LinkedHashMapTest.java | 26 ++++++++++++++----- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/platform/util/src/com/intellij/util/containers/hash/LinkedHashMap.java b/platform/util/src/com/intellij/util/containers/hash/LinkedHashMap.java index d50bc4e63e7f..7843297816de 100644 --- a/platform/util/src/com/intellij/util/containers/hash/LinkedHashMap.java +++ b/platform/util/src/com/intellij/util/containers/hash/LinkedHashMap.java @@ -310,7 +310,7 @@ public class LinkedHashMap extends AbstractMap implements Map private abstract class LinkedHashIterator implements Iterator { - private LinkedHashMap.Entry e = top; + private LinkedHashMap.Entry e = back; private LinkedHashMap.Entry last; @Override @@ -329,7 +329,7 @@ public class LinkedHashMap extends AbstractMap implements Map protected LinkedHashMap.Entry nextEntry() { final LinkedHashMap.Entry result = last = e; - e = result.next; + e = result.previous; return result; } } diff --git a/platform/util/testSrc/com/intellij/util/containers/hash/LinkedHashMapTest.java b/platform/util/testSrc/com/intellij/util/containers/hash/LinkedHashMapTest.java index a1791cdb71f2..8f3ee0331ebb 100644 --- a/platform/util/testSrc/com/intellij/util/containers/hash/LinkedHashMapTest.java +++ b/platform/util/testSrc/com/intellij/util/containers/hash/LinkedHashMapTest.java @@ -87,9 +87,9 @@ public class LinkedHashMapTest { for (int i = 0; i < 10000; ++i) { tested.put(i, Integer.toString(i)); } - int i = 10000; + int i = 0; for (Integer key : tested.keySet()) { - assertEquals(--i, key.intValue()); + assertEquals(i++, key.intValue()); } } @@ -109,7 +109,7 @@ public class LinkedHashMapTest { assertEquals(5000, tested.size()); it = tested.keySet().iterator(); - for (int i = 9999; i > 0; i -= 2) { + for (int i = 1; i <= 9999; i += 2) { Assert.assertTrue(it.hasNext()); assertEquals(i, it.next().intValue()); } @@ -180,16 +180,28 @@ public class LinkedHashMapTest { } @Test - public void iteration() { - ///todo[nik] it iterates in reversed order, may be it is a bug? + public void valuesIteration() { Map map = new LinkedHashMap(); map.put(1, "a"); map.put(2, "b"); map.put(3, "c"); Iterator iterator = map.values().iterator(); - assertEquals("c", iterator.next()); - assertEquals("b", iterator.next()); assertEquals("a", iterator.next()); + assertEquals("b", iterator.next()); + assertEquals("c", iterator.next()); + assertFalse(iterator.hasNext()); + } + + @Test + public void accessOrderValuesIteration() { + Map map = new LinkedHashMap(0, true); + map.put(1, "a"); + map.put(2, "b"); + map.put(3, "c"); + Iterator iterator = map.values().iterator(); + assertEquals("a", iterator.next()); + assertEquals("b", iterator.next()); + assertEquals("c", iterator.next()); assertFalse(iterator.hasNext()); } From 1db583689685f515ca4dff9f0d3dad4a1a24275f Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 23 Nov 2013 09:47:03 +0100 Subject: [PATCH 62/91] CharArrayUtil should not return array that's longer than CharSequence --- .../util/src/com/intellij/util/text/CharArrayUtil.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/platform/util/src/com/intellij/util/text/CharArrayUtil.java b/platform/util/src/com/intellij/util/text/CharArrayUtil.java index 3889596df481..718a842ea731 100644 --- a/platform/util/src/com/intellij/util/text/CharArrayUtil.java +++ b/platform/util/src/com/intellij/util/text/CharArrayUtil.java @@ -137,11 +137,10 @@ public class CharArrayUtil { if (seq instanceof CharBuffer) { final CharBuffer buffer = (CharBuffer)seq; if (buffer.hasArray() && !buffer.isReadOnly() && buffer.arrayOffset() == 0) { - return buffer.array(); - // final char[] bufArray = buffer.array(); - // return larger array. Clients may use seq.length() to calculate correct processing range. - // if (bufArray.length == seq.length()) - // return bufArray; + char[] array = buffer.array(); + if (buffer.length() == array.length) { + return array; + } } char[] chars = new char[seq.length()]; From 51f20ecbab08ea532a5280a5903fa45b671f1d29 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Sat, 23 Nov 2013 15:33:44 +0400 Subject: [PATCH 63/91] IDEA-116628 No nulls in type parameters --- .../MissingReturnInspection.java | 62 +++++++++++- .../plugins/groovy/gpp/GppTypeConverter.java | 17 ++-- .../GroovyExpectedTypesProvider.java | 28 +----- .../groovy/lang/psi/impl/GrClosureType.java | 33 +++---- .../lang/psi/impl/GrLiteralClassType.java | 34 ++++--- .../groovy/lang/psi/impl/GrMapType.java | 10 +- .../groovy/lang/psi/impl/GrRangeType.java | 18 +++- .../groovy/lang/psi/impl/GrSpreadType.java | 78 --------------- .../groovy/lang/psi/impl/GrTupleType.java | 20 ++-- .../statements/expressions/TypesUtil.java | 9 ++ .../DefaultCallExpressionTypeCalculator.java | 13 +-- .../groovy/lang/GppFunctionalTest.groovy | 35 ------- .../lang/LiteralConstructorUsagesTest.groovy | 94 +------------------ .../codeBlock/emptyList.java | 2 +- .../codeBlock/emptyMap.java | 2 +- .../file/dynamicMethodsAccess.java | 2 +- .../file/reflectedMethodWithEllipsis.java | 2 +- 17 files changed, 149 insertions(+), 310 deletions(-) delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrSpreadType.java diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.java index fc23c014df46..31a97407fd13 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.java @@ -16,6 +16,7 @@ package org.jetbrains.plugins.groovy.codeInspection.noReturnMethod; import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; @@ -29,16 +30,26 @@ import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementVisitor; +import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.MaybeReturnInstruction; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ThrowingInstruction; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * @author ven @@ -67,7 +78,7 @@ public class MissingReturnInspection extends GroovySuppressableInspectionTool { public static ReturnStatus getReturnStatus(PsiElement subject) { if (subject instanceof GrClosableBlock) { - final PsiType inferredReturnType = GroovyExpectedTypesProvider.getExpectedClosureReturnType((GrClosableBlock)subject); + final PsiType inferredReturnType = getExpectedClosureReturnType((GrClosableBlock)subject); if (inferredReturnType instanceof PsiClassType) { PsiClass resolved = ((PsiClassType)inferredReturnType).resolve(); if (resolved != null && !(resolved instanceof PsiTypeParameter)) return mustReturnValue; @@ -83,6 +94,55 @@ public class MissingReturnInspection extends GroovySuppressableInspectionTool { } } + @Nullable + public static PsiType getExpectedClosureReturnType(GrClosableBlock closure) { + List expectedReturnTypes = new ArrayList(); + + PsiElement parent = closure.getParent(); + if (parent instanceof GrArgumentList && parent.getParent() instanceof GrMethodCall || parent instanceof GrMethodCall) { + GrMethodCall call = (GrMethodCall)(parent instanceof GrArgumentList ? parent.getParent() : parent); + + GroovyResolveResult[] variants = call.getCallVariants(null); + + for (GroovyResolveResult variant : variants) { + Map> map = + GrClosureSignatureUtil.mapArgumentsToParameters(variant, closure, true, true, call.getNamedArguments(), call.getExpressionArguments(), call.getClosureArguments()); + + if (map != null) { + Pair pair = map.get(closure); + if (pair == null) continue; + + PsiParameter parameter = pair.getFirst(); + + PsiType type = parameter.getType(); + if (TypesUtil.isPsiClassTypeToClosure(type)) { + PsiType[] parameters = ((PsiClassType)type).getParameters(); + if (parameters.length == 1) { + expectedReturnTypes.add(parameters[0]); + } + } + } + } + } + else { + final Set expectedTypes = GroovyExpectedTypesProvider.getDefaultExpectedTypes(closure); + + for (PsiType expectedType : expectedTypes) { + if (TypesUtil.isPsiClassTypeToClosure(expectedType)) { + PsiType[] parameters = ((PsiClassType)expectedType).getParameters(); + if (parameters.length == 1) { + expectedReturnTypes.add(parameters[0]); + } + } + } + } + + for (PsiType type : expectedReturnTypes) { + if (PsiType.VOID.equals(type)) return PsiType.VOID; + } + return TypesUtil.getLeastUpperBoundNullable(expectedReturnTypes, closure.getManager()); + } + @NotNull public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder problemsHolder, boolean onTheFly) { return new GroovyPsiElementVisitor(new GroovyElementVisitor() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java index 7c8714897b5b..0b4e639a0035 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java @@ -73,10 +73,13 @@ public class GppTypeConverter extends GrTypeConverter { final PsiType expectedComponent = PsiUtil.extractIterableTypeParameter(lType, false); if (expectedComponent != null && isMethodCallConversion(context)) { - PsiType tupleComponent = tupleType.getParameters()[0]; - if (tupleComponent != null && - TypesUtil.isAssignable(expectedComponent, tupleComponent, context) && hasDefaultConstructor(lType)) { - return true; + PsiType[] parameters = tupleType.getParameters(); + if (parameters.length == 1) { + PsiType tupleComponent = parameters[0]; + if (tupleComponent != null && + TypesUtil.isAssignable(expectedComponent, tupleComponent, context) && hasDefaultConstructor(lType)) { + return true; + } } } @@ -88,10 +91,10 @@ public class GppTypeConverter extends GrTypeConverter { final PsiType lKeyType = PsiUtil.substituteTypeParameter(lType, CommonClassNames.JAVA_UTIL_MAP, 0, false); final PsiType lValueType = PsiUtil.substituteTypeParameter(lType, CommonClassNames.JAVA_UTIL_MAP, 1, false); final PsiType[] parameters = ((GrMapType)rType).getParameters(); - if (lKeyType != null && lValueType != null && + if (parameters.length == 2 && lKeyType != null && lValueType != null && parameters[0] != null && parameters[1] != null && - (!TypesUtil.isAssignable(lKeyType, parameters[0], context) || !TypesUtil - .isAssignable(lValueType, parameters[1], context))) { + (!TypesUtil.isAssignable(lKeyType, parameters[0], context) || + !TypesUtil.isAssignable(lValueType, parameters[1], context))) { return null; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java index d03a7101861e..f3779a15910a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java @@ -105,32 +105,6 @@ public class GroovyExpectedTypesProvider { return result; } - @Nullable - public static PsiType getExpectedClosureReturnType(GrClosableBlock closure) { - final Set expectedTypes = getDefaultExpectedTypes(closure); - - List expectedReturnTypes = new ArrayList(); - for (PsiType expectedType : expectedTypes) { - if (!(expectedType instanceof PsiClassType)) return null; - - final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)expectedType).resolveGenerics(); - final PsiClass resolved = resolveResult.getElement(); - if (resolved == null || !(GroovyCommonClassNames.GROOVY_LANG_CLOSURE.equals(resolved.getQualifiedName()))) return null; - - final PsiTypeParameter[] typeParameters = resolved.getTypeParameters(); - if (typeParameters.length != 1) return null; - - final PsiTypeParameter expected = typeParameters[0]; - final PsiType expectedReturnType = resolveResult.getSubstitutor().substitute(expected); - if (expectedReturnType == PsiType.VOID || expectedReturnType == null) return null; - - expectedReturnTypes.add(expectedReturnType); - } - - return TypesUtil.getLeastUpperBoundNullable(expectedReturnTypes, closure.getManager()); -} - - private static class MyCalculator extends GroovyElementVisitor { private TypeConstraint[] myResult; private final GrExpression myExpression; @@ -214,7 +188,7 @@ public class GroovyExpectedTypesProvider { final GrExpression[] expressionArgs = argumentList == null ? GrExpression.EMPTY_ARRAY : argumentList.getExpressionArguments(); try { final Map> map = - GrClosureSignatureUtil.mapArgumentsToParameters(variant, methodCall, true, true, namedArgs, expressionArgs, closureArgs); + GrClosureSignatureUtil.mapArgumentsToParameters(variant, methodCall, true, false, namedArgs, expressionArgs, closureArgs); addConstraintsFromMap(constraints, map); } catch (RuntimeException e) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java index 04db42793f7f..6d59dd8adc28 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java @@ -39,7 +39,7 @@ import java.util.List; * @author ven */ public class GrClosureType extends GrLiteralClassType { - private final @NotNull GrSignature mySignature; + private final GrSignature mySignature; private PsiType[] myTypeArgs = null; private GrClosureType(@NotNull LanguageLevel languageLevel, @@ -52,21 +52,22 @@ public class GrClosureType extends GrLiteralClassType { if (!shouldInferTypeParameters) myTypeArgs = PsiType.EMPTY_ARRAY; } + private GrClosureType(@NotNull LanguageLevel level, + @NotNull GlobalSearchScope scope, + @NotNull JavaPsiFacade facade, + @NotNull GrSignature signature, + @NotNull PsiType[] typeArgs) { + super(level, scope, facade); + + mySignature = signature; + myTypeArgs = typeArgs; + } + @NotNull public String getClassName() { return "Closure"; } - @Override - public int getParameterCount() { - if (myTypeArgs != null) { - return myTypeArgs.length; - } - - final PsiClass psiClass = resolve(); - return psiClass != null && psiClass.getTypeParameters().length == 1 ? 1 : 0; - } - @NotNull public PsiType[] getParameters() { if (myTypeArgs == null) { @@ -79,7 +80,7 @@ public class GrClosureType extends GrLiteralClassType { final PsiClass psiClass = resolve(); if (psiClass != null && psiClass.getTypeParameters().length == 1) { final PsiType type = GrClosureSignatureUtil.getReturnType(mySignature); - if (type == PsiType.NULL) { + if (type == PsiType.NULL || type == null) { return new PsiType[]{null}; } else { @@ -129,9 +130,7 @@ public class GrClosureType extends GrLiteralClassType { @NotNull public PsiClassType setLanguageLevel(@NotNull final LanguageLevel languageLevel) { - final GrClosureType result = create(mySignature, myScope, myFacade, languageLevel, true); - result.myTypeArgs = this.myTypeArgs; - return result; + return new GrClosureType(languageLevel, myScope, myFacade, mySignature, myTypeArgs); } public static GrClosureType create(GroovyResolveResult[] results, GroovyPsiElement context) { @@ -187,9 +186,7 @@ public class GrClosureType extends GrLiteralClassType { public PsiType curry(@NotNull PsiType[] args, int position, @NotNull GroovyPsiElement context) { final GrSignature newSignature = mySignature.curry(args, position, context); if (newSignature == null) return null; - final GrClosureType result = create(newSignature, myScope, myFacade, myLanguageLevel, true); - result.myTypeArgs = this.myTypeArgs; - return result; + return new GrClosureType(myLanguageLevel, myScope, myFacade, newSignature, myTypeArgs); } @NotNull diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrLiteralClassType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrLiteralClassType.java index 55c8d34e9594..3595f8d70dc5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrLiteralClassType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrLiteralClassType.java @@ -46,20 +46,7 @@ public abstract class GrLiteralClassType extends PsiClassType { @NotNull public ClassResolveResult resolveGenerics() { final PsiClass myBaseClass = resolve(); - final PsiSubstitutor substitutor; - if (myBaseClass != null) { - final PsiType[] typeArgs = getParameters(); - final PsiTypeParameter[] typeParams = myBaseClass.getTypeParameters(); - if (typeParams.length == typeArgs.length) { - substitutor = PsiSubstitutor.EMPTY.putAll(myBaseClass, typeArgs); - } - else { - substitutor = PsiSubstitutor.EMPTY; - } - } - else { - substitutor = PsiSubstitutor.EMPTY; - } + final PsiSubstitutor substitutor = inferSubstitutor(myBaseClass); return new ClassResolveResult() { @@ -94,6 +81,23 @@ public abstract class GrLiteralClassType extends PsiClassType { }; } + @NotNull + private PsiSubstitutor inferSubstitutor(@Nullable PsiClass myBaseClass) { + if (myBaseClass != null) { + final PsiType[] typeArgs = getParameters(); + final PsiTypeParameter[] typeParams = myBaseClass.getTypeParameters(); + if (typeParams.length == typeArgs.length) { + return PsiSubstitutor.EMPTY.putAll(myBaseClass, typeArgs); + } + else { + return PsiSubstitutor.EMPTY.putAll(myBaseClass, new PsiType[typeParams.length]); + } + } + else { + return PsiSubstitutor.EMPTY; + } + } + @Override @NotNull public abstract String getClassName() ; @@ -161,7 +165,7 @@ public abstract class GrLiteralClassType extends PsiClassType { } @NotNull - protected PsiType getLeastUpperBound(PsiType[] psiTypes) { + protected PsiType getLeastUpperBound(PsiType... psiTypes) { PsiType result = null; final PsiManager manager = getPsiManager(); for (final PsiType other : psiTypes) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMapType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMapType.java index 69f11760cb8d..3387f988057e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMapType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMapType.java @@ -37,8 +37,6 @@ import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames. * @author peter */ public class GrMapType extends GrLiteralClassType { - private static final PsiType[] RAW_PARAMETERS = new PsiType[]{null, null}; - private final Map myStringEntries; private final List> myOtherEntries; private final String myJavaClassName; @@ -83,12 +81,6 @@ public class GrMapType extends GrLiteralClassType { } } - @NotNull - @Override - public PsiClassType rawType() { - return new GrMapType(myFacade, getResolveScope(), Collections.emptyMap(), Collections.>emptyList(), getLanguageLevel()); - } - @NotNull @Override protected String getJavaClassName() { @@ -136,7 +128,7 @@ public class GrMapType extends GrLiteralClassType { final PsiType[] keyTypes = getAllKeyTypes(); final PsiType[] valueTypes = getAllValueTypes(); if (keyTypes.length == 0 && valueTypes.length == 0) { - return RAW_PARAMETERS; + return EMPTY_ARRAY; } return new PsiType[]{getLeastUpperBound(keyTypes), getLeastUpperBound(valueTypes)}; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrRangeType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrRangeType.java index bdd93682e691..ed887fff4c8c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrRangeType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrRangeType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl; import com.intellij.openapi.util.text.StringUtil; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiClass; import com.intellij.psi.PsiClassType; import com.intellij.psi.PsiType; import com.intellij.psi.search.GlobalSearchScope; @@ -38,6 +39,8 @@ public class GrRangeType extends GrLiteralClassType { private final PsiType myIterationType; private final String myQualifiedName; + private final PsiType[] myParameters; + public GrRangeType(LanguageLevel languageLevel, GlobalSearchScope scope, JavaPsiFacade facade, @@ -53,6 +56,8 @@ public class GrRangeType extends GrLiteralClassType { else { myQualifiedName = GroovyCommonClassNames.GROOVY_LANG_OBJECT_RANGE; } + + myParameters = inferParameters(); } public GrRangeType(GlobalSearchScope scope, JavaPsiFacade facade, @Nullable PsiType left, @Nullable PsiType right) { @@ -74,7 +79,16 @@ public class GrRangeType extends GrLiteralClassType { @NotNull @Override public PsiType[] getParameters() { - return PsiType.EMPTY_ARRAY; + return myParameters; + } + + private PsiType[] inferParameters() { + if (myIterationType == null) return EMPTY_ARRAY; + + PsiClass resolved = resolve(); + if (resolved == null || resolved.getTypeParameters().length == 0) return EMPTY_ARRAY; + + return new PsiType[]{myIterationType}; } @NotNull diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrSpreadType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrSpreadType.java deleted file mode 100644 index 99b1556901de..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrSpreadType.java +++ /dev/null @@ -1,78 +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 org.jetbrains.plugins.groovy.lang.psi.impl; - -import com.intellij.openapi.project.Project; -import com.intellij.pom.java.LanguageLevel; -import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiClassType; -import com.intellij.psi.PsiType; -import com.intellij.psi.search.GlobalSearchScope; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; - -/** - * @author Max Medvedev - */ -public class GrSpreadType extends GrLiteralClassType { - - private PsiType myType; - - public GrSpreadType(PsiType original, PsiType containerType, GlobalSearchScope scope) { - this(original, containerType, LanguageLevel.JDK_1_5, scope, JavaPsiFacade.getInstance(scope.getProject())); - } - - public GrSpreadType(PsiType original, PsiType containerType, LanguageLevel languageLevel, GlobalSearchScope scope, JavaPsiFacade facade) { - super(languageLevel, scope, facade); - - final Project project = facade.getProject(); - myType = TypesUtil.createSimilarCollection(containerType, project, original); - } - - @NotNull - @Override - protected String getJavaClassName() { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @NotNull - @Override - public String getClassName() { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @NotNull - @Override - public PsiType[] getParameters() { - return new PsiType[0]; //To change body of implemented methods use File | Settings | File Templates. - } - - @NotNull - @Override - public PsiClassType setLanguageLevel(@NotNull LanguageLevel languageLevel) { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public String getInternalCanonicalText() { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public boolean isValid() { - return false; //To change body of implemented methods use File | Settings | File Templates. - } -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrTupleType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrTupleType.java index 0be4a6698d82..9d1b305d0a8b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrTupleType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrTupleType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,8 +31,8 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt * @author ven */ public class GrTupleType extends GrLiteralClassType { - private static final PsiType[] RAW_PARAMETERS = new PsiType[]{null}; private final PsiType[] myComponentTypes; + private final PsiType[] myParameters; public GrTupleType(PsiType[] componentTypes, JavaPsiFacade facade, GlobalSearchScope scope) { this(componentTypes, facade, scope,LanguageLevel.JDK_1_5); @@ -40,6 +40,8 @@ public class GrTupleType extends GrLiteralClassType { public GrTupleType(PsiType[] componentTypes, JavaPsiFacade facade, GlobalSearchScope scope,LanguageLevel languageLevel) { super(languageLevel, scope, facade); myComponentTypes = componentTypes; + + myParameters = inferParameters(); } @NotNull @@ -48,12 +50,6 @@ public class GrTupleType extends GrLiteralClassType { return CommonClassNames.JAVA_UTIL_ARRAY_LIST; } - @NotNull - @Override - public PsiClassType rawType() { - return new GrTupleType(RAW_PARAMETERS, myFacade, getResolveScope(), getLanguageLevel()); - } - @NotNull public String getClassName() { return StringUtil.getShortName(getJavaClassName()); @@ -61,9 +57,13 @@ public class GrTupleType extends GrLiteralClassType { @NotNull public PsiType[] getParameters() { - if (myComponentTypes.length == 0) return RAW_PARAMETERS; + return myParameters; + } + + private PsiType[] inferParameters() { + if (myComponentTypes.length == 0) return PsiType.EMPTY_ARRAY; final PsiType leastUpperBound = getLeastUpperBound(myComponentTypes); - if (leastUpperBound == PsiType.NULL) return RAW_PARAMETERS; + if (leastUpperBound == PsiType.NULL) return EMPTY_ARRAY; return new PsiType[]{leastUpperBound}; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java index b3955eece999..ad3219cf8810 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java @@ -913,4 +913,13 @@ public class TypesUtil { if (!changed) return null; return JavaPsiFacade.getElementFactory(project).createType(element, parameters); } + + public static boolean isPsiClassTypeToClosure(PsiType type) { + if (!(type instanceof PsiClassType)) return false; + + final PsiClass psiClass = ((PsiClassType)type).resolve(); + if (psiClass == null) return false; + + return GROOVY_LANG_CLOSURE.equals(psiClass.getQualifiedName()); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java index 7c6c7b97b250..b8d1dedd7c79 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -109,7 +109,7 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal if (type instanceof GrClosureType) { returnType = GrClosureSignatureUtil.getReturnType(((GrClosureType)type).getSignature(), callExpression); } - else if (isPsiClassTypeToClosure(type)) { + else if (TypesUtil.isPsiClassTypeToClosure(type)) { assert type instanceof PsiClassType; final PsiType[] parameters = ((PsiClassType)type).getParameters(); if (parameters.length == 1) { @@ -131,15 +131,6 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal } - private static boolean isPsiClassTypeToClosure(PsiType type) { - if (!(type instanceof PsiClassType)) return false; - - final PsiClass psiClass = ((PsiClassType)type).resolve(); - if (psiClass == null) return false; - - return GroovyCommonClassNames.GROOVY_LANG_CLOSURE.equals(psiClass.getQualifiedName()); - } - private static final Set CLOSURE_METHODS = new HashSet(); static { CLOSURE_METHODS.add("call"); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy index 3287b7613d56..39e4703016ca 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy @@ -405,41 +405,6 @@ class Point { assertEquals 1, multiResolveReference().size() } - public void testGotoSuperConstructorFromLiteralOnsets() throws Exception { - PsiClass point = myFixture.addClass(""" -class Point { - Point() {} - Point(int y) {} -}""") - - configureGppScript "Point p = [super: 2]" - assertEquals point.constructors[1], resolveReference() - - configureGppScript "Point p = [2]" - assertEquals point.constructors[1], resolveReference() - - configureGppScript "Point p = []" - assertEquals point.constructors[0], resolveReference() - - configureGppScript "Point p = [:]" - assertEquals point.constructors[0], resolveReference() - - configureGppScript "Point p = [239, 42]" - assertEquals 2, multiResolveReference().size() - - configureGppScript """ -def foo(Point p) {} -foo([2, 3]) -""" - assertEquals 2, multiResolveReference().size() - - configureGppScript """ -def foo(Point... p) {} -foo(['super':[2, 3]]) -""" - assertEquals 2, multiResolveReference().size() - } - public void testGotoClassFromLiteralOnsetsWhenNoConstructorsPresent() throws Exception { PsiClass point = myFixture.addClass(""" class Point { }""") configureGppScript "Point p = [super: 2]" diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/LiteralConstructorUsagesTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/LiteralConstructorUsagesTest.groovy index d24fa7de36b5..f56c2cb87bd4 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/LiteralConstructorUsagesTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/LiteralConstructorUsagesTest.groovy @@ -42,7 +42,7 @@ class LiteralConstructorUsagesTest extends LightGroovyTestCase { myFixture.addFileToProject "a.gpp", "Foo x = []" assertOneElement(ReferencesSearch.search(foo.constructors[0]).findAll()) } - + public void testList_ReturnValue() throws Exception { def foo = myFixture.addClass("""class Foo { Foo() {} @@ -97,98 +97,6 @@ Foo untyped() { [] } assertEquals(2, ReferencesSearch.search(foo.constructors[0]).findAll().size()) } - public void testList_GppMethodCall() throws Exception { - //------------------------declarations - def foo = myFixture.addClass(""" - package z; - class Foo { - public Foo() {} - } - """) - - myFixture.addClass(""" - package z; - public class Bar { - public static void giveMeFoo(int a, Foo f) {} - } -""") - myFixture.addFileToProject("Decl.groovy", "static def giveMeFooAsWell(z.Foo f) {}") - - //----------------------usages - myFixture.addFileToProject "a.gpp", "z.Bar.giveMeFoo(2, []) //usage" - myFixture.addFileToProject "b.groovy", """ - @Typed package aa; - z.Bar.giveMeFoo(3, []) //usage - """ - myFixture.addFileToProject "c.groovy", """ - @Typed def someMethod() { - z.Bar.giveMeFoo 4, [] //usage - Decl.giveMeFooAsWell([]) //usage - } - z.Bar.giveMeFoo 5, [] //non-typed context - Decl.giveMeFooAsWell([]) - """ - myFixture.addFileToProject "invalid.gpp", "z.Bar.giveMeFoo 42, 239, []" - myFixture.addFileToProject "nonGpp.groovy", "z.Bar.giveMeFoo(6, [])" - assertEquals(4, ReferencesSearch.search(foo.constructors[0]).findAll().size()) - } - - public void testList_GppConstructorCallWithSeveralParameters() throws Exception { - def foo = myFixture.addClass(""" - class Foo { - Foo() {} - } - """) - - myFixture.addClass(""" - class Bar { - Bar(Foo f1, Foo f2, Foo f3) {} - } - """) - myFixture.addFileToProject "a.gpp", "new Bar([],[],[])" - assertEquals(3, ReferencesSearch.search(foo.constructors[0]).findAll().size()) - } - - public void testMap_GppOverloads() throws Exception { - def foo = myFixture.addClass(""" - class Foo { - Foo() {} - Foo(int a) {} - } - """) - - myFixture.addClass(""" - class Bar { - static void foo(Foo f1, Foo f2) {} - } - """) - myFixture.addFileToProject "a.gpp", "Bar.foo([:], [super:2])" - assertEquals(1, ReferencesSearch.search(foo.constructors[0]).findAll().size()) - assertEquals(1, ReferencesSearch.search(foo.constructors[1]).findAll().size()) - } - - public void testGppCallVarargs() throws Exception { - def foo = myFixture.addClass(""" - class Foo { - Foo() {} - Foo(int a) {} - } - """) - - myFixture.addClass(""" - class Bar { - static void foo(Foo f1, Foo f2) {} - static void doo(int a, Foo f1, Foo f2) {} - } - """) - myFixture.addFileToProject "a.gpp", """ - Bar.foo([:], [super:2]) - Bar.doo 3, [:], [super:2] - """ - assertEquals(2, ReferencesSearch.search(foo.constructors[0]).findAll().size()) - assertEquals(2, ReferencesSearch.search(foo.constructors[1]).findAll().size()) - } - public void testOverloadedConstructorUsages() throws Exception { def foo = myFixture.addClass(""" class Foo { diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/emptyList.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/emptyList.java index f1283b852258..8f64cd13364f 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/emptyList.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/emptyList.java @@ -1,3 +1,3 @@ -java.util.ArrayList list = new java.util.ArrayList(); +java.util.ArrayList list = new java.util.ArrayList(); java.lang.Integer[] arr = new java.lang.Integer[0]; java.util.List strings = new java.util.ArrayList(); diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/emptyMap.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/emptyMap.java index ea2a48f2aa2e..75eabcd8e91c 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/emptyMap.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/emptyMap.java @@ -1,2 +1,2 @@ -java.util.Map map = new java.util.Map(); +java.util.Map map = new java.util.Map(); print(map.get(1)); diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/dynamicMethodsAccess.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/dynamicMethodsAccess.java index 61cfcc94699b..6a5310f384ae 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/dynamicMethodsAccess.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/dynamicMethodsAccess.java @@ -8,7 +8,7 @@ java.lang.String s = "a"; org.codehaus.groovy.runtime.DefaultGroovyMethods.invokeMethod(s, "bar", new java.lang.Object[]{4}); org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, org.codehaus.groovy.runtime.DefaultGroovyMethods.invokeMethod(s, "bar", new java.lang.Object[]{5})); -return org.codehaus.groovy.runtime.DefaultGroovyMethods.invokeMethod(s, "anme", new java.util.ArrayList()); +return org.codehaus.groovy.runtime.DefaultGroovyMethods.invokeMethod(s, "anme", new java.util.ArrayList()); } } diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/reflectedMethodWithEllipsis.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/reflectedMethodWithEllipsis.java index 3abffed415d8..6ae1849b2f89 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/reflectedMethodWithEllipsis.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/reflectedMethodWithEllipsis.java @@ -2,7 +2,7 @@ public class MyClass { public void foo(java.util.Map args, java.lang.String a, java.lang.String... b) {} public void foo(java.lang.String a, java.lang.String... b) { -foo(new java.util.LinkedHashMap(), a, b); +foo(new java.util.LinkedHashMap(), a, b); } } From bd9bfa8e5dd1bfa6e72ba9ee62f53f9435ae4b70 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Sat, 23 Nov 2013 15:58:23 +0400 Subject: [PATCH 64/91] fix testdata --- .../plugins/groovy/lang/formatter/FormatterTest.groovy | 2 +- .../{GDocAfterImports2.test => groovyDocAfterImports2.test} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename plugins/groovy/testdata/groovy/formatter/{GDocAfterImports2.test => groovyDocAfterImports2.test} (100%) diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy index 544bbd46ed66..f31fa1461810 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy @@ -763,7 +763,7 @@ def foo() { } void testGDocAfterImports() { doTest() } - void testGDocAfterImports2() { doTest() } + void testGroovyDocAfterImports2() { doTest() } void testRegexExpressions() { doTest() } diff --git a/plugins/groovy/testdata/groovy/formatter/GDocAfterImports2.test b/plugins/groovy/testdata/groovy/formatter/groovyDocAfterImports2.test similarity index 100% rename from plugins/groovy/testdata/groovy/formatter/GDocAfterImports2.test rename to plugins/groovy/testdata/groovy/formatter/groovyDocAfterImports2.test From 49939da2c01e697a211e22da4427cb721631b84e Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 23 Nov 2013 14:50:40 +0100 Subject: [PATCH 65/91] align RootIndex.isProjectExcludeRoot with DirectoryIndexImpl --- .../roots/impl/DirectoryIndexTest.java | 48 +++++++++++++++++++ .../roots/impl/DirectoryIndexImpl.java | 5 -- .../openapi/roots/impl/RootIndex.java | 23 +++++++-- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java index dbdbb5aff9b9..3641d9dc06f4 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java +++ b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java @@ -413,6 +413,9 @@ public class DirectoryIndexTest extends IdeaTestCase { checkInfoNull(module2TestOutput); assertFalse(myIndex.isProjectExcludeRoot(excluded)); + assertTrue(myIndex.isProjectExcludeRoot(projectOutput)); + assertTrue(myIndex.isProjectExcludeRoot(module2Output)); + assertFalse(myIndex.isProjectExcludeRoot(module2TestOutput)); excluded.delete(this); projectOutput.delete(this); @@ -426,14 +429,34 @@ public class DirectoryIndexTest extends IdeaTestCase { VirtualFile file = e.getFile(); checkInfoNull(file); created.add(file); + + String fileName = e.getFileName(); + if (fileName.equals("projectOutput")) { + //todo fix and uncomment +// assertTrue(myIndex.isProjectExcludeRoot(file)); + } + if (fileName.equals("module2Output")) { + //todo fix and uncomment +// assertTrue(myIndex.isProjectExcludeRoot(file)); + } + if (fileName.equals("module2TestOutput")) { + assertFalse(myIndex.isProjectExcludeRoot(file)); + } } }; VirtualFileManager.getInstance().addVirtualFileListener(l, getTestRootDisposable()); + excluded = myModule1Dir.createChildDirectory(this, excluded.getName()); assertFalse(myIndex.isProjectExcludeRoot(excluded)); + projectOutput = myModule1Dir.createChildDirectory(this, projectOutput.getName()); + assertTrue(myIndex.isProjectExcludeRoot(projectOutput)); + module2Output = myModule1Dir.createChildDirectory(this, module2Output.getName()); + assertTrue(myIndex.isProjectExcludeRoot(module2Output)); + module2TestOutput = myModule2Dir.createChildDirectory(this, module2TestOutput.getName()); + assertFalse(myIndex.isProjectExcludeRoot(module2TestOutput)); checkInfoNull(excluded); checkInfoNull(projectOutput); @@ -443,6 +466,9 @@ public class DirectoryIndexTest extends IdeaTestCase { assertEquals(created.toString(), 4, created.size()); assertFalse(myIndex.isProjectExcludeRoot(excluded)); + assertTrue(myIndex.isProjectExcludeRoot(projectOutput)); + assertTrue(myIndex.isProjectExcludeRoot(module2Output)); + assertFalse(myIndex.isProjectExcludeRoot(module2TestOutput)); } public void testExcludesShouldBeRecognizedRightOnRefresh() throws Exception { @@ -539,6 +565,28 @@ public class DirectoryIndexTest extends IdeaTestCase { assertTrue(myIndex.isProjectExcludeRoot(myOutputDir)); assertTrue(myIndex.isProjectExcludeRoot(myModule1OutputDir)); assertTrue(fileIndex.isIgnored(myModule1OutputDir)); + + PsiTestUtil.setCompilerOutputPath(myModule, moduleOutputUrl, true); + PsiTestUtil.setCompilerOutputPath(myModule2, moduleOutputUrl, false); + PsiTestUtil.setCompilerOutputPath(myModule2, moduleOutputUrl, true); + PsiTestUtil.setCompilerOutputPath(myModule3, moduleOutputUrl, false); + PsiTestUtil.setCompilerOutputPath(myModule3, moduleOutputUrl, true); + + // now no module inherits project output dir, but it still should be project-excluded + assertTrue(myIndex.isProjectExcludeRoot(myOutputDir)); + + // project output inside module content shouldn't be projectExcludeRoot + VirtualFile projectOutputUnderContent = myModule1Dir.createChildDirectory(this, "projectOutputUnderContent"); + getCompilerProjectExtension().setCompilerOutputUrl(projectOutputUnderContent.getUrl()); + fireRootsChanged(); + + assertFalse(myIndex.isProjectExcludeRoot(myOutputDir)); + //todo uncomment assertFalse(myIndex.isProjectExcludeRoot(projectOutputUnderContent)); + + projectOutputUnderContent.delete(this); + projectOutputUnderContent = myModule1Dir.createChildDirectory(this, "projectOutputUnderContent"); + assertFalse(myIndex.isProjectExcludeRoot(myOutputDir)); + //todo uncomment assertFalse(myIndex.isProjectExcludeRoot(projectOutputUnderContent)); } private void checkInfo(VirtualFile dir, diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java index 8c2948ffce22..ab711d4c4852 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java @@ -657,15 +657,10 @@ public class DirectoryIndexImpl extends DirectoryIndex { return getRootIndex().isProjectExcludeRoot(dir); } - - //noinspection UnnecessaryLocalVariable boolean standardResult = myState.myProjectExcludeRoots.contains(((NewVirtualFile)dir).getId()); -/* todo RootIndex rootIndex = getRootIndex(); Boolean riResult = rootIndex != null ? rootIndex.isProjectExcludeRoot(dir) : null; return assertConsistentResult(dir, riResult, standardResult); -*/ - return standardResult; } private VirtualFile findFileById(int dir) { diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java index 7bc634152925..cc01c67973d4 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java @@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.impl.libraries.LibraryEx; import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; @@ -32,6 +33,7 @@ import com.intellij.openapi.vfs.newvfs.events.VFileEvent; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import gnu.trove.TObjectIntHashMap; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.java.JavaSourceRootType; @@ -44,6 +46,7 @@ class RootIndex { private static final DirectoryInfo NULL_INFO = DirectoryInfo.createNew(); private final Set myProjectExcludedRoots = ContainerUtil.newHashSet(); + private final Set myModuleExcludedRoots = ContainerUtil.newHashSet(); private final Set myLibraryExcludedRoots = ContainerUtil.newHashSet(); private final Map myRoots = ContainerUtil.newTroveMap(); private final Map> myPackagePrefixRoots = ContainerUtil.newHashMap(); @@ -71,7 +74,13 @@ class RootIndex { for (ContentEntry contentEntry : contentEntries) { // Init excluded roots - Collections.addAll(myProjectExcludedRoots, contentEntry.getExcludeFolderFiles()); + VirtualFile[] excluded = contentEntry.getExcludeFolderFiles(); + for (VirtualFile excludeRoot : excluded) { + if (!FileUtil.startsWith(excludeRoot.getUrl(), contentEntry.getUrl())) { + myProjectExcludedRoots.add(excludeRoot); + } + myModuleExcludedRoots.add(excludeRoot); + } // Init module sources SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); @@ -157,7 +166,9 @@ class RootIndex { } for (DirectoryIndexExcludePolicy policy : Extensions.getExtensions(DirectoryIndexExcludePolicy.EP_NAME, project)) { - Collections.addAll(myProjectExcludedRoots, policy.getExcludeRootsForProject()); + VirtualFile[] excludeRoots = policy.getExcludeRootsForProject(); + Collections.addAll(myModuleExcludedRoots, excludeRoots); + Collections.addAll(myProjectExcludedRoots, excludeRoots); } // fill ordered entries @@ -224,7 +235,10 @@ class RootIndex { } public void checkConsistency() { - for (VirtualFile file : myProjectExcludedRoots) { + for (VirtualFile file : myLibraryExcludedRoots) { + assert file.exists() : file.getPath() + " does not exist"; + } + for (VirtualFile file : myModuleExcludedRoots) { assert file.exists() : file.getPath() + " does not exist"; } for (VirtualFile file : myLibraryExcludedRoots) { @@ -346,7 +360,7 @@ class RootIndex { } private boolean isAnyExcludeRoot(VirtualFile root) { - return myProjectExcludedRoots.contains(root) || myLibraryExcludedRoots.contains(root); + return myModuleExcludedRoots.contains(root) || myLibraryExcludedRoots.contains(root); } public boolean isProjectExcludeRoot(@NotNull final VirtualFile dir) { @@ -390,6 +404,7 @@ class RootIndex { return result; } + @Contract("_,null->false") private boolean isValidPackageDirectory(boolean includeLibrarySources, @Nullable VirtualFile file) { if (file != null) { DirectoryInfo info = getInfoForDirectory(file); From 538fcaf0415db69de88075563ce3c3b570d454bc Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 23 Nov 2013 18:24:47 +0400 Subject: [PATCH 66/91] [log] Don't hide "Go to ref" action when focus is not in the log Set target component for the log's ActionToolbar to MainFrame, to make the Log instance available in the DataContext. --- .../impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java index 987b797803d1..aa179ed7a183 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java @@ -215,7 +215,9 @@ public class MainFrame extends JPanel implements TypeSafeDataProvider { mainGroup.add(myFilterUi.getFilterActionComponents()); mainGroup.addSeparator(); mainGroup.add(toolbarGroup); - return ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, mainGroup, true).getComponent(); + ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, mainGroup, true); + toolbar.setTargetComponent(this); + return toolbar.getComponent(); } public JComponent getMainComponent() { From 4d1e0c06de79f3d09e449cec14804f8978780155 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 23 Nov 2013 18:38:33 +0400 Subject: [PATCH 67/91] [log] No need in "Copy Hash" action on the toolbar --- platform/vcs-log/impl/src/META-INF/vcs-log.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/vcs-log/impl/src/META-INF/vcs-log.xml b/platform/vcs-log/impl/src/META-INF/vcs-log.xml index 3c0749b0b2c6..befbb4aa8ef4 100644 --- a/platform/vcs-log/impl/src/META-INF/vcs-log.xml +++ b/platform/vcs-log/impl/src/META-INF/vcs-log.xml @@ -24,7 +24,6 @@ icon="AllIcons.General.Gear" text="Quick Settings" description="Quick Settings" /> - From 73ae4b2888f44523cc2863e9f1fa23e62bce43c1 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 23 Nov 2013 18:41:18 +0400 Subject: [PATCH 68/91] [log] More clear name for "Go To Ref" action --- platform/vcs-log/impl/src/META-INF/vcs-log.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vcs-log/impl/src/META-INF/vcs-log.xml b/platform/vcs-log/impl/src/META-INF/vcs-log.xml index befbb4aa8ef4..5e014d560553 100644 --- a/platform/vcs-log/impl/src/META-INF/vcs-log.xml +++ b/platform/vcs-log/impl/src/META-INF/vcs-log.xml @@ -19,7 +19,7 @@ icon="AllIcons.Actions.Copy" text="Copy Hash" description="Copy hash value of the selected commit to clipboard" /> + text="Go To Hash/Branch/Tag" description="Specify hash or name of a branch or a tag to navigate to the commit it points"/> From 7ad802c48c56ed414419be70251eaea2d3564a76 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 23 Nov 2013 18:46:21 +0400 Subject: [PATCH 69/91] [log] Show details panel by default (as it were in the old log) --- .../impl/src/com/intellij/vcs/log/data/VcsLogUiProperties.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiProperties.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiProperties.java index 1d7f197e703f..be746e6b30e8 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiProperties.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiProperties.java @@ -41,7 +41,7 @@ public class VcsLogUiProperties implements PersistentStateComponent RECENTLY_FILTERED_USERS = new ArrayDeque(); } From cff1db6c5d39bac4d2c18b214b43e310b323cb7d Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 23 Nov 2013 15:57:16 +0100 Subject: [PATCH 70/91] enable by default --- .../TypeParameterHidesVisibleTypeInspectionBase.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/TypeParameterHidesVisibleTypeInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/TypeParameterHidesVisibleTypeInspectionBase.java index 61a865296c10..8f7e6f7e3059 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/TypeParameterHidesVisibleTypeInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/TypeParameterHidesVisibleTypeInspectionBase.java @@ -35,6 +35,11 @@ public class TypeParameterHidesVisibleTypeInspectionBase extends BaseInspection return true; } + @Override + public boolean isEnabledByDefault() { + return true; + } + @Override @NotNull public String buildErrorString(Object... infos) { From 662f63c42466889b3887afe20c988e7ae949d912 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 23 Nov 2013 21:18:59 +0400 Subject: [PATCH 71/91] [log] Don't display "Loading..." immediately, let a 300ms delay For instance, "Containing branches" information is calculated frequently, but fast => blinking "Loading..." doesn't look good. --- .../impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java index 47052e936b62..b37092e0e95f 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java @@ -1,6 +1,7 @@ package com.intellij.vcs.log.ui.frame; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.util.ProgressWindow; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.changes.issueLinks.IssueLinkHtmlRenderer; @@ -64,7 +65,7 @@ class DetailsPanel extends JPanel implements ListSelectionListener { content.add(myDataPanel); content.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); - myLoadingPanel = new JBLoadingPanel(new BorderLayout(), logDataHolder); + myLoadingPanel = new JBLoadingPanel(new BorderLayout(), logDataHolder, ProgressWindow.DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS); myLoadingPanel.add(ScrollPaneFactory.createScrollPane(content)); add(myLoadingPanel, STANDARD_LAYER); From 307f3013a52b96fb980cd4500695b2e851cf8032 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 23 Nov 2013 21:26:29 +0400 Subject: [PATCH 72/91] [log] Fix possible race conditions in "Containing branches" * For the sake of simplicity allow a single loading-finished-listener; Ensure it is accessed only from the EDT. * Recreate the cache (instead of clearing) on refresh. Make the field volatile; make all other operations with the cache appear in the EDT. * Store the cache instance in Task, and put the calculated node information into the stored cache instance instead of myCache, to make sure that if log refresh happens during containing branches calculation, the result of the calculation will be put into the obsolete cache instance. * Clear the queue on log refresh (this not important, but those tasks would operate on the obsolete DataPack anyway). * Notify the listener after clearing the cache, to re-query information about the commit user was staying during the log refresh. --- .../log/data/ContainingBranchesGetter.java | 54 ++++++++++++++----- .../intellij/vcs/log/ui/frame/MainFrame.java | 2 +- .../util/SequentialLimitedLifoExecutor.java | 6 ++- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/ContainingBranchesGetter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/ContainingBranchesGetter.java index ddcea8986060..5db2212553f7 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/ContainingBranchesGetter.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/ContainingBranchesGetter.java @@ -17,6 +17,7 @@ package com.intellij.vcs.log.data; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Condition; import com.intellij.util.ThrowableConsumer; import com.intellij.util.containers.ContainerUtil; @@ -28,28 +29,33 @@ import com.intellij.vcs.log.util.SequentialLimitedLifoExecutor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.awt.*; import java.util.*; +import java.util.List; /** * Provides capabilities to asynchronously calculate "contained in branches" information. */ public class ContainingBranchesGetter { + private static final Logger LOG = Logger.getInstance(ContainingBranchesGetter.class); + @NotNull private final SequentialLimitedLifoExecutor myTaskExecutor; - @NotNull private final Collection myLoadingFinishedListeners = new ArrayList(); - @NotNull private final SLRUMap> myCache = new SLRUMap>(1000, 1000); + @NotNull private volatile SLRUMap> myCache = createCache(); + @Nullable private Runnable myLoadingFinishedListener; // access only from EDT ContainingBranchesGetter(@NotNull Disposable parentDisposable) { myTaskExecutor = new SequentialLimitedLifoExecutor(parentDisposable, 10, new ThrowableConsumer() { @Override - public void consume(Task task) throws Throwable { - myCache.put(task.node, getContainingBranches(task.pack, task.node)); + public void consume(final Task task) throws Throwable { + final List branches = getContainingBranches(task.pack, task.node); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - for (Runnable listener : myLoadingFinishedListeners) { - listener.run(); - } + // if cache is cleared (because of log refresh) during this task execution, + // this will put obsolete value into the old instance we don't care anymore + task.cache.put(task.node, branches); + notifyListener(); } }); } @@ -57,14 +63,30 @@ public class ContainingBranchesGetter { } void clearCache() { - myCache.clear(); + myCache = createCache(); + myTaskExecutor.clear(); + // re-request containing branches information for the commit user (possibly) currently stays on + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + notifyListener(); + } + }); } /** * This task will be executed each time the calculating process completes. */ - public void addTaskCompletedListener(@NotNull Runnable runnable) { - myLoadingFinishedListeners.add(runnable); + public void setTaskCompletedListener(@NotNull Runnable runnable) { + LOG.assertTrue(EventQueue.isDispatchThread()); + myLoadingFinishedListener = runnable; + } + + private void notifyListener() { + LOG.assertTrue(EventQueue.isDispatchThread()); + if (myLoadingFinishedListener != null) { + myLoadingFinishedListener.run(); + } } /** @@ -75,11 +97,16 @@ public class ContainingBranchesGetter { public List requestContainingBranches(@NotNull DataPack dataPack, @NotNull Node node) { List refs = myCache.get(node); if (refs == null) { - myTaskExecutor.queue(new Task(dataPack, node)); + myTaskExecutor.queue(new Task(dataPack, node, myCache)); } return refs; } + @NotNull + private static SLRUMap> createCache() { + return new SLRUMap>(1000, 1000); + } + @NotNull private List getContainingBranches(@NotNull DataPack dataPack, @NotNull Node node) { RefsModel refsModel = dataPack.getRefsModel(); @@ -139,9 +166,12 @@ public class ContainingBranchesGetter { private static class Task { private final DataPack pack; private final Node node; - public Task(DataPack pack, Node node) { + private final SLRUMap> cache; + + public Task(DataPack pack, Node node, SLRUMap> cache) { this.pack = pack; this.node = node; + this.cache = cache; } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java index aa179ed7a183..04a3e3e47682 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java @@ -123,7 +123,7 @@ public class MainFrame extends JPanel implements TypeSafeDataProvider { myDetailsPanel.valueChanged(null); } }); - myLogDataHolder.getContainingBranchesGetter().addTaskCompletedListener(new Runnable() { + myLogDataHolder.getContainingBranchesGetter().setTaskCompletedListener(new Runnable() { @Override public void run() { myDetailsPanel.valueChanged(null); diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/util/SequentialLimitedLifoExecutor.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/util/SequentialLimitedLifoExecutor.java index 0eb6e8562d80..d0eeea575980 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/util/SequentialLimitedLifoExecutor.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/util/SequentialLimitedLifoExecutor.java @@ -43,9 +43,13 @@ public class SequentialLimitedLifoExecutor implements Disposable { myLoader.addFirst(task); } + public void clear() { + myLoader.clear(); + } + @Override public void dispose() { - myLoader.clear(); + clear(); } private class DetailsLoadingTask implements Consumer { From 030c5f3f39c1bdd1e341fc9041111c735bc29afc Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Sun, 24 Nov 2013 03:35:54 +0400 Subject: [PATCH 73/91] IDEA-102449 Mac OS + JDK 1.7: dialog sheets go to background if focus is moved from IDEA and then back --- .../com/intellij/ui/mac/MacMessagesImpl.java | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/mac/MacMessagesImpl.java b/platform/platform-impl/src/com/intellij/ui/mac/MacMessagesImpl.java index cafcffd6a0ff..db65c46fb15d 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/MacMessagesImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/MacMessagesImpl.java @@ -24,10 +24,12 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.impl.ModalityHelper; +import com.intellij.ui.mac.foundation.Foundation; import com.intellij.ui.mac.foundation.ID; import com.intellij.ui.mac.foundation.MacUtil; import com.intellij.util.ui.UIUtil; import com.sun.jna.Callback; +import com.sun.jna.Pointer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -200,6 +202,19 @@ public class MacMessagesImpl extends MacMessages { private MacMessagesImpl() {} + private static final Callback windowDidBecomeMainCallback = new Callback() { + public void callback(ID self, + ID nsNotification) + { + synchronized (lock) { + if (!windowFromId.keySet().contains(self.longValue())) { + return; + } + } + invoke(self, "oldWindowDidBecomeMain:", nsNotification); + } + }; + static { if (SystemInfo.isMac) { final ID delegateClass = allocateObjcClassPair(getObjcClass("NSObject"), "NSAlertDelegate_"); @@ -213,6 +228,19 @@ public class MacMessagesImpl extends MacMessages { throw new RuntimeException("Unable to add method to objective-c delegate class!"); } registerObjcClassPair(delegateClass); + + if (SystemInfo.isJavaVersionAtLeast("1.7")) { + + ID awtWindow = Foundation.getObjcClass("AWTWindow"); + + Pointer windowWillEnterFullScreenMethod = Foundation.createSelector("windowDidBecomeMain:"); + ID originalWindowWillEnterFullScreen = Foundation.class_replaceMethod(awtWindow, windowWillEnterFullScreenMethod, + windowDidBecomeMainCallback, "v@::@"); + + Foundation.addMethodByID(awtWindow, Foundation.createSelector("oldWindowDidBecomeMain:"), + originalWindowWillEnterFullScreen, "v@::@"); + + } } } @@ -327,8 +355,9 @@ public class MacMessagesImpl extends MacMessages { } private static void startModal(final Window w, ID windowId) { + long windowPtr = windowId.longValue(); synchronized (lock) { - windowFromId.put(windowId.longValue(), w); + windowFromId.put(windowPtr, w); if (blockedDocumentRoots.keySet().contains(w)) { blockedDocumentRoots.put(w, blockedDocumentRoots.get(w) + 1); } else { @@ -337,6 +366,9 @@ public class MacMessagesImpl extends MacMessages { } pumpEventsDocumentExclusively(w); + synchronized (lock) { + windowFromId.remove(windowPtr); + } } private enum COMMON_DIALOG_PARAM_TYPE { @@ -717,9 +749,9 @@ public class MacMessagesImpl extends MacMessages { _window = _window.getOwner(); //At least our frame should have a title } - + while (Registry.is("skip.untitled.windows.for.mac.messages") && _window != null && _window instanceof JDialog && !((JDialog)_window).isModal()) { - _window = _window.getOwner(); + _window = _window.getOwner(); } return _window; From 332b443f8e9548b51d545ca59c11743a97345707 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Sun, 24 Nov 2013 10:23:12 +0100 Subject: [PATCH 74/91] Do not initialize docks in test mode --- .../intellij/openapi/wm/impl/SystemDock.java | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/SystemDock.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/SystemDock.java index d04caaa7cdbc..b57e538a4387 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/SystemDock.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/SystemDock.java @@ -26,20 +26,28 @@ import com.intellij.ui.win.WinDockDelegate; * @author Denis Fokin */ public class SystemDock { - - private static Delegate delegate; + private static final Delegate ourDelegate; static { - if (SystemInfo.isMac) { - delegate = MacDockDelegate.getInstance(); - } else if (SystemInfo.isWin7OrNewer && Registry.is("windows.jumplist") && !ApplicationManager.getApplication().isUnitTestMode()) { - delegate = WinDockDelegate.getInstance(); + Delegate delegate = null; + + Application app = ApplicationManager.getApplication(); + if (app != null && !app.isUnitTestMode()) { + if (SystemInfo.isMac) { + delegate = MacDockDelegate.getInstance(); + } + else if (SystemInfo.isWin7OrNewer && Registry.is("windows.jumplist")) { + delegate = WinDockDelegate.getInstance(); + } } + + ourDelegate = delegate; } - public static void updateMenu () { - if (delegate == null) return; - delegate.updateRecentProjectsMenu(); + public static void updateMenu() { + if (ourDelegate != null) { + ourDelegate.updateRecentProjectsMenu(); + } } public interface Delegate { From 3bb3524cb1a3be3c3131d0c7dc2c726968e6669f Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 24 Nov 2013 15:32:18 +0400 Subject: [PATCH 75/91] [log] Refactor: move ref painter & drawRefs & calc refs padding to the common parent class --- .../ui/render/AbstractPaddingCellRender.java | 17 ++++++++++++++++- .../vcs/log/ui/render/CommitCellRender.java | 10 ++++------ .../log/ui/render/GraphCommitCellRender.java | 8 +++----- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java index 9f1cf5a85f17..c1c9e1e7daf4 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java @@ -3,22 +3,28 @@ package com.intellij.vcs.log.ui.render; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.changes.issueLinks.IssueLinkRenderer; import com.intellij.ui.ColoredTableCellRenderer; +import com.intellij.vcs.log.VcsRef; import com.intellij.vcs.log.graph.render.GraphCommitCell; import com.intellij.vcs.log.printmodel.SpecialPrintElement; +import com.intellij.vcs.log.ui.VcsLogColorManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; +import java.awt.font.FontRenderContext; +import java.util.Collection; public abstract class AbstractPaddingCellRender extends ColoredTableCellRenderer { public static final Color MARKED_BACKGROUND = new Color(200, 255, 250); + @NotNull protected final RefPainter myRefPainter; @NotNull private final IssueLinkRenderer myIssueLinkRenderer; @Nullable private Object myValue; - protected AbstractPaddingCellRender(@NotNull Project project) { + protected AbstractPaddingCellRender(@NotNull Project project, VcsLogColorManager colorManager) { + myRefPainter = new RefPainter(colorManager, false); myIssueLinkRenderer = new IssueLinkRenderer(project, this); } @@ -58,4 +64,13 @@ public abstract class AbstractPaddingCellRender extends ColoredTableCellRenderer super.paint(g); additionPaint(g, myValue); } + + protected void drawRefs(Graphics2D g2, Collection refs, int padding) { + myRefPainter.draw(g2, refs, padding, -1); + } + + protected int calcRefsPadding(@NotNull Collection refs, @NotNull FontRenderContext fontContext) { + return myRefPainter.padding(refs, fontContext); + } + } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/CommitCellRender.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/CommitCellRender.java index 7547655c8759..20acf85a0cb7 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/CommitCellRender.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/CommitCellRender.java @@ -14,11 +14,8 @@ import java.awt.font.FontRenderContext; */ public class CommitCellRender extends AbstractPaddingCellRender { - @NotNull private final RefPainter refPainter; - public CommitCellRender(@NotNull VcsLogColorManager colorManager, Project project) { - super(project); - refPainter = new RefPainter(colorManager, false); + super(project, colorManager); } @Override @@ -26,7 +23,7 @@ public class CommitCellRender extends AbstractPaddingCellRender { CommitCell cell = getAssertCommitCell(value); FontRenderContext fontContext = ((Graphics2D)table.getGraphics()).getFontRenderContext(); - return refPainter.padding(cell.getRefsToThisCommit(), fontContext); + return calcRefsPadding(cell.getRefsToThisCommit(), fontContext); } private static CommitCell getAssertCommitCell(Object value) { @@ -48,6 +45,7 @@ public class CommitCellRender extends AbstractPaddingCellRender { protected void additionPaint(Graphics g, Object value) { CommitCell cell = getAssertCommitCell(value); Graphics2D g2 = (Graphics2D)g; - refPainter.draw(g2, cell.getRefsToThisCommit(), 0, -1); + drawRefs(g2, cell.getRefsToThisCommit(), 0); } + } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRender.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRender.java index 130c3c49af7e..02783cfbfc34 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRender.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRender.java @@ -41,14 +41,12 @@ public class GraphCommitCellRender extends AbstractPaddingCellRender { @NotNull private final GraphCellPainter graphPainter; @NotNull private final VcsLogDataHolder myDataHolder; - @NotNull private final RefPainter refPainter; public GraphCommitCellRender(@NotNull GraphCellPainter graphPainter, @NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogColorManager colorManager) { - super(logDataHolder.getProject()); + super(logDataHolder.getProject(), colorManager); this.graphPainter = graphPainter; myDataHolder = logDataHolder; - refPainter = new RefPainter(colorManager, false); } @Override @@ -60,7 +58,7 @@ public class GraphCommitCellRender extends AbstractPaddingCellRender { } FontRenderContext fontContext = ((Graphics2D)table.getGraphics()).getFontRenderContext(); - int refPadding = refPainter.padding(cell.getRefsToThisCommit(), fontContext); + int refPadding = calcRefsPadding(cell.getRefsToThisCommit(), fontContext); int countCells = cell.getPrintCell().countCell(); int graphPadding = countCells * WIDTH_NODE; @@ -99,7 +97,7 @@ public class GraphCommitCellRender extends AbstractPaddingCellRender { VirtualFile root = refs.iterator().next().getRoot(); // all refs are from the same commit => they have the same root refs = myDataHolder.getLogProvider(root).getReferenceManager().sort(refs); } - refPainter.draw(g2, refs, padding, -1); // TODO think how to behave if there are too many refs here (even if tags are collapsed) + drawRefs(g2, refs, padding); UIUtil.drawImage(g, image, 0, 0, null); } From 9f24b72775d8383cb9e92749130f9cc284409442 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 24 Nov 2013 17:21:17 +0400 Subject: [PATCH 76/91] [log] IDEA-116950 Don't display all tags if there are too many of them * Adjust RefPainter so that it calculates padding for Strings instead of refs (using the same sizes as in drawLabel). * When drawing refs, substitute tags (if there are more than 1 of them) with "first tag + N more" label. --- .../ui/render/AbstractPaddingCellRender.java | 47 ++++++++++++++-- .../vcs/log/ui/render/CommitCellRender.java | 5 +- .../log/ui/render/GraphCommitCellRender.java | 4 +- .../vcs/log/ui/render/RefPainter.java | 56 +++++++++++++++---- 4 files changed, 90 insertions(+), 22 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java index c1c9e1e7daf4..3cc9e716086e 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java @@ -1,8 +1,10 @@ package com.intellij.vcs.log.ui.render; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.vcs.changes.issueLinks.IssueLinkRenderer; import com.intellij.ui.ColoredTableCellRenderer; +import com.intellij.util.containers.ContainerUtil; import com.intellij.vcs.log.VcsRef; import com.intellij.vcs.log.graph.render.GraphCommitCell; import com.intellij.vcs.log.printmodel.SpecialPrintElement; @@ -12,8 +14,9 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.awt.font.FontRenderContext; import java.util.Collection; +import java.util.List; +import java.util.Map; public abstract class AbstractPaddingCellRender extends ColoredTableCellRenderer { @@ -65,12 +68,46 @@ public abstract class AbstractPaddingCellRender extends ColoredTableCellRenderer additionPaint(g, myValue); } - protected void drawRefs(Graphics2D g2, Collection refs, int padding) { - myRefPainter.draw(g2, refs, padding, -1); + protected void drawRefs(@NotNull Graphics2D g2, @NotNull Collection refs, int padding) { + myRefPainter.drawLabels(g2, collectLabelsForRefs(refs), padding); } - protected int calcRefsPadding(@NotNull Collection refs, @NotNull FontRenderContext fontContext) { - return myRefPainter.padding(refs, fontContext); + @NotNull + private static Map collectLabelsForRefs(@NotNull Collection refs) { + List branches = getBranches(refs); + Collection tags = ContainerUtil.subtract(refs, branches); + return getLabelsForRefs(branches, tags); } + protected int calcRefsPadding(@NotNull Collection refs, @NotNull Graphics2D g2) { + return myRefPainter.padding(collectLabelsForRefs(refs).keySet(), g2); + } + + @NotNull + private static Map getLabelsForRefs(@NotNull List branches, @NotNull Collection tags) { + Map labels = ContainerUtil.newLinkedHashMap(); + for (VcsRef branch : branches) { + labels.put(branch.getName(), branch.getType().getBackgroundColor()); + } + if (!tags.isEmpty()) { + VcsRef firstTag = tags.iterator().next(); + Color color = firstTag.getType().getBackgroundColor(); + if (tags.size() > 1) { + labels.put(firstTag.getName() + " + " + tags.size() + " more", color); + } + else { + labels.put(firstTag.getName(), color); + } + } + return labels; + } + + private static List getBranches(Collection refs) { + return ContainerUtil.filter(refs, new Condition() { + @Override + public boolean value(VcsRef ref) { + return ref.getType().isBranch(); + } + }); + } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/CommitCellRender.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/CommitCellRender.java index 20acf85a0cb7..702af3f1a667 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/CommitCellRender.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/CommitCellRender.java @@ -7,7 +7,6 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.awt.font.FontRenderContext; /** * @author erokhins @@ -21,9 +20,7 @@ public class CommitCellRender extends AbstractPaddingCellRender { @Override protected int getLeftPadding(JTable table, Object value) { CommitCell cell = getAssertCommitCell(value); - - FontRenderContext fontContext = ((Graphics2D)table.getGraphics()).getFontRenderContext(); - return calcRefsPadding(cell.getRefsToThisCommit(), fontContext); + return calcRefsPadding(cell.getRefsToThisCommit(), (Graphics2D)table.getGraphics()); } private static CommitCell getAssertCommitCell(Object value) { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRender.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRender.java index 02783cfbfc34..0752ce3ebdbc 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRender.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRender.java @@ -27,7 +27,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.awt.font.FontRenderContext; import java.awt.image.BufferedImage; import java.util.Collection; @@ -57,8 +56,7 @@ public class GraphCommitCellRender extends AbstractPaddingCellRender { return 0; } - FontRenderContext fontContext = ((Graphics2D)table.getGraphics()).getFontRenderContext(); - int refPadding = calcRefsPadding(cell.getRefsToThisCommit(), fontContext); + int refPadding = calcRefsPadding(cell.getRefsToThisCommit(), (Graphics2D)table.getGraphics()); int countCells = cell.getPrintCell().countCell(); int graphPadding = countCells * WIDTH_NODE; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/RefPainter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/RefPainter.java index ae52d3f84230..004a9eda8c17 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/RefPainter.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/RefPainter.java @@ -4,6 +4,7 @@ import com.intellij.ui.JBColor; import com.intellij.vcs.log.VcsRef; import com.intellij.vcs.log.ui.VcsLogColorManager; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.awt.*; import java.awt.font.FontRenderContext; @@ -21,6 +22,7 @@ public class RefPainter { private static final int RECTANGLE_X_PADDING = 4; private static final int RECTANGLE_Y_PADDING = 3; private static final int REF_PADDING = 13; + private static final int LABEL_PADDING = 3; private static final int FLAG_WIDTH = 8; private static final int FLAG_PADDING = 8; @@ -40,7 +42,11 @@ public class RefPainter { } private double paddingStr(@NotNull String str, @NotNull FontRenderContext renderContext) { - return DEFAULT_FONT.getStringBounds(str, renderContext).getWidth() + REF_PADDING + flagWidth(); + return getStringWidth(str, renderContext) + REF_PADDING + flagWidth(); + } + + private static double getStringWidth(@NotNull String str, @NotNull FontRenderContext renderContext) { + return DEFAULT_FONT.getStringBounds(str, renderContext).getWidth(); } private int flagWidth() { @@ -79,12 +85,16 @@ public class RefPainter { g2.drawPolygon(polygon); } - public int padding(@NotNull Collection refs, @NotNull FontRenderContext renderContext) { - float p = 0; - for (VcsRef ref : refs) { - p += paddingStr(ref.getName(), renderContext); + public int padding(@NotNull Collection refs, @NotNull Graphics2D g2) { + int p = 0; + for (String ref : refs) { + XAndWidth xAndWidth = getXAndWidth(ref, 0, g2.getFontMetrics(DEFAULT_FONT)); + p += xAndWidth.x + xAndWidth.width + LABEL_PADDING; } - return Math.round(p); + if (p > 0) { // additional padding after all references looks better + p += LABEL_PADDING; + } + return p; } public Map draw(@NotNull Graphics2D g2, @NotNull Collection refs, int startPadding, int maxWidth) { @@ -109,12 +119,28 @@ public class RefPainter { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } - public Rectangle drawLabel(@NotNull Graphics2D g2, @NotNull String label, int paddingX, @NotNull Color bgColor, Color rootIndicatorColor) { + public void drawLabels(@NotNull Graphics2D g2, @NotNull Map labels, int startPadding) { + int padding = startPadding; + for (Map.Entry entry : labels.entrySet()) { + Rectangle rectangle = drawLabel(g2, entry.getKey(), padding, entry.getValue(), null); + padding += rectangle.width + LABEL_PADDING; + } + } + + private XAndWidth getXAndWidth(String label, int paddingX, FontMetrics metrics) { + int x = paddingX + REF_PADDING / 2 - RECTANGLE_X_PADDING; + int width = metrics.stringWidth(label) + 2 * RECTANGLE_X_PADDING + flagWidth(); + return new XAndWidth(x, width); + } + + public Rectangle drawLabel(@NotNull Graphics2D g2, @NotNull String label, int paddingX, @NotNull Color bgColor, + @Nullable Color rootIndicatorColor) { setupGraphics(g2); FontMetrics metrics = g2.getFontMetrics(); - int x = paddingX + REF_PADDING / 2 - RECTANGLE_X_PADDING; + XAndWidth xAndWidth = getXAndWidth(label, paddingX, metrics); + int x = xAndWidth.x; + int width = xAndWidth.width; int y = RECTANGLE_Y_PADDING; - int width = metrics.stringWidth(label) + 2 * RECTANGLE_X_PADDING + flagWidth(); int height = HEIGHT_CELL - 2 * RECTANGLE_Y_PADDING; RoundRectangle2D rectangle2D = new RoundRectangle2D.Double(x, y, width, height, ROUND_RADIUS, ROUND_RADIUS); @@ -127,11 +153,21 @@ public class RefPainter { g2.setColor(JBColor.BLACK); drawText(g2, label, paddingX + flagWidth()); - if (myColorManager.isMultipleRoots() && myDrawMultiRepoIndicator) { + if (rootIndicatorColor != null && myColorManager.isMultipleRoots() && myDrawMultiRepoIndicator) { drawRootIndicator(g2, paddingX, y, height, rootIndicatorColor); } return new Rectangle(x, y, width, height); } + private static class XAndWidth { + private final int x; + private final int width; + + private XAndWidth(int x, int width) { + this.x = x; + this.width = width; + } + } + } From 49a033ae3c15fdfb282625dbeb96e833ef6c8c78 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 24 Nov 2013 18:29:07 +0400 Subject: [PATCH 77/91] [log] IDEA-116950 Draw just "tag +" instead of "tag + 5 more" --- .../intellij/vcs/log/ui/render/AbstractPaddingCellRender.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java index 3cc9e716086e..d75ca1d6624f 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java @@ -93,7 +93,7 @@ public abstract class AbstractPaddingCellRender extends ColoredTableCellRenderer VcsRef firstTag = tags.iterator().next(); Color color = firstTag.getType().getBackgroundColor(); if (tags.size() > 1) { - labels.put(firstTag.getName() + " + " + tags.size() + " more", color); + labels.put(firstTag.getName() + " +", color); } else { labels.put(firstTag.getName(), color); From 79ef03327958ab8a06c66dca8e5c9ef5cd8931b8 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Sun, 24 Nov 2013 16:57:02 +0100 Subject: [PATCH 78/91] do not auto-switch current suspend context if a new thread with suspenPolicy=thread hits a breakpoint (IDEA-116160) --- .../debugger/actions/SetValueAction.java | 6 ++- .../debugger/engine/DebugProcessEvents.java | 10 ++--- .../debugger/impl/DebuggerSession.java | 44 ++++++++++++++++++- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/SetValueAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/SetValueAction.java index 04f9dcb991bd..8adff3f3a6ff 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/SetValueAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/SetValueAction.java @@ -481,8 +481,10 @@ public class SetValueAction extends DebuggerAction { stateManager.addListener(new DebuggerContextListener() { public void changeEvent(DebuggerContextImpl newContext, int event) { - stateManager.removeListener(this); - editor.cancelEditing(); + if (event != DebuggerSession.EVENT_THREADS_REFRESH) { + stateManager.removeListener(this); + editor.cancelEditing(); + } } }); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java index d4da4d66486e..c54ab3b7c0e2 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java @@ -22,6 +22,7 @@ import com.intellij.debugger.engine.events.DebuggerCommandImpl; import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.engine.requests.LocatableEventRequestor; import com.intellij.debugger.engine.requests.MethodReturnValueWatcher; +import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; import com.intellij.debugger.jdi.VirtualMachineProxyImpl; import com.intellij.debugger.requests.Requestor; @@ -39,7 +40,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.registry.Registry; import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.sun.jdi.InternalException; import com.sun.jdi.ThreadReference; @@ -182,7 +182,7 @@ public class DebugProcessEvents extends DebugProcessImpl { getManagerThread().invokeAndWait(new DebuggerCommandImpl() { protected void action() throws Exception { - if (eventSet.suspendPolicy() == EventRequest.SUSPEND_ALL && !enableBreakpointsDuringEvaluation()) { + if (eventSet.suspendPolicy() == EventRequest.SUSPEND_ALL && !DebuggerSession.enableBreakpointsDuringEvaluation()) { // check if there is already one request with policy SUSPEND_ALL for (SuspendContextImpl context : getSuspendManager().getEventContexts()) { if (context.getSuspendPolicy() == EventRequest.SUSPEND_ALL) { @@ -420,7 +420,7 @@ public class DebugProcessEvents extends DebugProcessImpl { final SuspendManager suspendManager = getSuspendManager(); SuspendContextImpl evaluatingContext = SuspendManagerUtil.getEvaluatingContext(suspendManager, getSuspendContext().getThread()); - if (evaluatingContext != null && !enableBreakpointsDuringEvaluation()) { + if (evaluatingContext != null && !DebuggerSession.enableBreakpointsDuringEvaluation()) { // is inside evaluation, so ignore any breakpoints suspendManager.voteResume(suspendContext); return; @@ -476,10 +476,6 @@ public class DebugProcessEvents extends DebugProcessImpl { }); } - private static boolean enableBreakpointsDuringEvaluation() { - return Registry.is("debugger.enable.breakpoints.during.evaluation"); - } - private void processDefaultEvent(SuspendContextImpl suspendContext) { preprocessEvent(suspendContext, null); getSuspendManager().voteResume(suspendContext); diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java index aa24a431dac8..19de95a585d3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java @@ -21,6 +21,7 @@ import com.intellij.debugger.engine.*; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationListener; import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.jdi.StackFrameProxy; import com.intellij.debugger.engine.requests.RequestManagerImpl; import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; @@ -43,9 +44,11 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.registry.Registry; import com.intellij.psi.PsiCompiledElement; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; @@ -284,7 +287,12 @@ public class DebuggerSession implements AbstractDebuggerSession { public void resume() { final SuspendContextImpl suspendContext = getSuspendContext(); if(suspendContext != null) { - mySteppingThroughThreads.clear(); + if (suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_ALL) { + mySteppingThroughThreads.clear(); + } + else { + mySteppingThroughThreads.remove(suspendContext.getThread()); + } resetIgnoreStepFiltersFlag(); resumeAction(myDebugProcess.createResumeCommand(suspendContext), EVENT_RESUME); } @@ -408,6 +416,15 @@ public class DebuggerSession implements AbstractDebuggerSession { LOG.debug("paused"); } + if (!shouldSetAsActiveContext(suspendContext)) { + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void run() { + getContextManager().fireStateChanged(getContextManager().getContext(), EVENT_THREADS_REFRESH); + } + }); + return; + } + ThreadReferenceProxyImpl currentThread = suspendContext.getThread(); final StackFrameContext positionContext; @@ -503,9 +520,10 @@ public class DebuggerSession implements AbstractDebuggerSession { else if (sourceMissing) { // adjust position to be position of the breakpoint in order to show the real originator of the event position = breakpointPosition; + final StackFrameProxy frameProxy = positionContext.getFrameProxy(); String className; try { - className = positionContext.getFrameProxy().location().declaringType().name(); + className = frameProxy != null? frameProxy.location().declaringType().name() : ""; } catch (EvaluateException e) { className = ""; @@ -527,6 +545,23 @@ public class DebuggerSession implements AbstractDebuggerSession { }); } + private boolean shouldSetAsActiveContext(final SuspendContextImpl suspendContext) { + final ThreadReferenceProxyImpl newThread = suspendContext.getThread(); + if (newThread == null || suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_ALL || isSteppingThrough(newThread)) { + return true; + } + final SuspendContextImpl currentSuspendContext = getContextManager().getContext().getSuspendContext(); + if (currentSuspendContext == null) { + return true; + } + if (enableBreakpointsDuringEvaluation()) { + final ThreadReferenceProxyImpl currentThread = currentSuspendContext.getThread(); + return currentThread == null || Comparing.equal(currentThread.getThreadReference(), newThread.getThreadReference()); + } + return false; + } + + public void resumed(final SuspendContextImpl suspendContext) { final SuspendContextImpl currentContext = getProcess().getSuspendManager().getPausedContext(); DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { @@ -626,4 +661,9 @@ public class DebuggerSession implements AbstractDebuggerSession { }); } } + + public static boolean enableBreakpointsDuringEvaluation() { + return Registry.is("debugger.enable.breakpoints.during.evaluation"); + } + } From 85253bd2a281b708e5d74a81d360780b96aa51bc Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Sun, 24 Nov 2013 20:23:30 +0400 Subject: [PATCH 79/91] introduce multi-token nextTokenIs() --- .../lang/parser/GeneratedParserUtilBase.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java index c9b9ae264a7e..d18bf4c5dff7 100644 --- a/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java +++ b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java @@ -173,6 +173,33 @@ public class GeneratedParserUtilBase { return builder_.getTokenType() == token; } + public static boolean nextTokenIsFast(PsiBuilder builder_, IElementType... tokens) { + IElementType tokenType = builder_.getTokenType(); + for (IElementType token : tokens) { + if (token == tokenType) return true; + } + return false; + } + + public static boolean nextTokenIs(PsiBuilder builder_, String frameName, IElementType... tokens) { + ErrorState state = ErrorState.get(builder_); + if (state.completionState != null) return true; + boolean track = !state.suppressErrors && state.predicateCount < 2 && state.predicateSign; + if (!track) return nextTokenIsFast(builder_, tokens); + boolean useFrameName = StringUtil.isNotEmpty(frameName); + IElementType tokenType = builder_.getTokenType(); + if (tokenType == null) return false; + boolean result = false; + for (IElementType token : tokens) { + if (!useFrameName) addVariant(builder_, state, token); + result |= tokenType == token; + } + if (useFrameName) { + addVariantInner(state, builder_.getCurrentOffset(), frameName); + } + return result; + } + public static boolean nextTokenIs(PsiBuilder builder_, IElementType token) { return nextTokenIsInner(builder_, token, false); } @@ -187,6 +214,7 @@ public class GeneratedParserUtilBase { return token == tokenType; } + @Deprecated public static boolean replaceVariants(PsiBuilder builder_, int variantCount, String frameName) { ErrorState state = ErrorState.get(builder_); if (!state.suppressErrors && state.predicateCount < 2 && state.predicateSign) { From bcd648e2e1d72958cd26b271d65b6f987847a9f0 Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 24 Nov 2013 19:03:43 +0100 Subject: [PATCH 80/91] update CharArrayUtil.fromSequence doc, use it instead of fromSequenceStrict --- .../intellij/openapi/editor/impl/CharArray.java | 3 +-- .../com/intellij/psi/impl/source/PsiFileImpl.java | 2 +- .../psi/impl/source/LightPsiFileImpl.java | 2 +- .../src/com/intellij/util/text/CharArrayUtil.java | 15 +++++++++------ 4 files changed, 12 insertions(+), 10 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 be82de1e06bd..62dc9d961071 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 @@ -19,7 +19,6 @@ import com.intellij.diagnostic.Dumpable; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.ArrayUtil; import com.intellij.util.LocalTimeCounter; import com.intellij.util.text.CharArrayCharSequence; import com.intellij.util.text.CharArrayUtil; @@ -468,7 +467,7 @@ abstract class CharArray implements CharSequenceBackedByArray, Dumpable { try { flushDeferredChanged(); if (myOriginalSequence != null && myArray == null) { - myArray = array = ArrayUtil.realloc(CharArrayUtil.fromSequence(myOriginalSequence), myOriginalSequence.length()); + myArray = array = CharArrayUtil.fromSequence(myOriginalSequence); myStringRef = null; } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index 640c841feba7..7c046953b4a7 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -617,7 +617,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF @Override @NotNull public char[] textToCharArray() { - return CharArrayUtil.fromSequenceStrict(getViewProvider().getContents()); + return CharArrayUtil.fromSequence(getViewProvider().getContents()); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/LightPsiFileImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/LightPsiFileImpl.java index de7c965e89cf..7d25327c607e 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/LightPsiFileImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/LightPsiFileImpl.java @@ -258,7 +258,7 @@ public abstract class LightPsiFileImpl extends PsiElementBase implements PsiFile @Override @NotNull public char[] textToCharArray() { - return CharArrayUtil.fromSequenceStrict(getViewProvider().getContents()); + return CharArrayUtil.fromSequence(getViewProvider().getContents()); } @Override diff --git a/platform/util/src/com/intellij/util/text/CharArrayUtil.java b/platform/util/src/com/intellij/util/text/CharArrayUtil.java index 718a842ea731..24025774263b 100644 --- a/platform/util/src/com/intellij/util/text/CharArrayUtil.java +++ b/platform/util/src/com/intellij/util/text/CharArrayUtil.java @@ -99,13 +99,12 @@ public class CharArrayUtil { } } + /** + * @deprecated use {@link #fromSequence(CharSequence)} + */ @NotNull public static char[] fromSequenceStrict(@NotNull CharSequence seq) { - char[] chars = fromSequence(seq); - if (seq.length() == chars.length) return chars; - char[] strictChars = new char[seq.length()]; - System.arraycopy(chars, 0, strictChars, 0, seq.length()); - return strictChars; + return fromSequence(seq); } @Nullable @@ -126,7 +125,6 @@ public class CharArrayUtil { /** * @return the underlying char[] array if any, or the new chara array if not - * NOTE RETURNED ARRAY LENGTH MAY HAVE BE DIFFERENT FROM THE seq.length() */ @NotNull public static char[] fromSequence(@NotNull CharSequence seq) { @@ -155,6 +153,11 @@ public class CharArrayUtil { ((StringBuffer)seq).getChars(0, seq.length(), chars, 0); return chars; } + if (seq instanceof StringBuilder) { + char[] chars = new char[seq.length()]; + ((StringBuilder)seq).getChars(0, seq.length(), chars, 0); + return chars; + } if (seq instanceof String) { char[] chars = new char[seq.length()]; From 2d366e602c7fcdca4abde2c979f5fc122ce80ecf Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Sun, 24 Nov 2013 13:28:08 +0100 Subject: [PATCH 81/91] Cleanup (formatting) --- .../FileProcessingCompilerAdapterTask.java | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java index f3bb520aa61e..8ed8e88e30d0 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import com.intellij.openapi.compiler.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.LocalFileSystem; @@ -32,14 +33,14 @@ import java.util.ArrayList; import java.util.List; /** - * This is an adapter for running any FileProcessingCompiler as a compiler task - * + * This is an adapter for running any FileProcessingCompiler as a compiler task. * * @author Eugene Zhuravlev * Date: 9/5/12 */ -public class FileProcessingCompilerAdapterTask implements CompileTask{ +public class FileProcessingCompilerAdapterTask implements CompileTask { private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.FileProcessingCompilerAdapterTask"); + private final FileProcessingCompiler myCompiler; public FileProcessingCompilerAdapterTask(FileProcessingCompiler compiler) { @@ -56,15 +57,15 @@ public class FileProcessingCompilerAdapterTask implements CompileTask{ if (!CompilerWorkspaceConfiguration.getInstance(project).useOutOfProcessBuild()) { return true; } + try { final FileProcessingCompiler.ProcessingItem[] items = myCompiler.getProcessingItems(context); if (items.length == 0) { return true; } + final List toProcess = new ArrayList(); final Ref ex = new Ref(null); - - final FileProcessingCompilerStateCache cache = getCache(context); final boolean isMake = context.isMake(); DumbService.getInstance(project).runReadActionInSmartMode(new Runnable() { @@ -76,7 +77,7 @@ public class FileProcessingCompilerAdapterTask implements CompileTask{ if (isMake && cache.getTimestamp(url) == file.getTimeStamp()) { final ValidityState state = cache.getExtState(url); final ValidityState itemState = item.getValidityState(); - if (state != null ? state.equalsTo(itemState) : itemState == null) { + if (Comparing.equal(state, itemState)) { continue; } } @@ -89,16 +90,17 @@ public class FileProcessingCompilerAdapterTask implements CompileTask{ } }); - if (ex.get() != null) { - throw ex.get(); + IOException exception = ex.get(); + if (exception != null) { + throw exception; } if (toProcess.isEmpty()) { return true; } - final FileProcessingCompiler.ProcessingItem[] processed = myCompiler.process(context, toProcess.toArray(new FileProcessingCompiler.ProcessingItem[toProcess.size()])); - + final FileProcessingCompiler.ProcessingItem[] array = toProcess.toArray(new FileProcessingCompiler.ProcessingItem[toProcess.size()]); + final FileProcessingCompiler.ProcessingItem[] processed = myCompiler.process(context, array); if (processed.length == 0) { return true; } From 768f1de36fd585721ab4cc5c83ecad7844f759a7 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Sun, 24 Nov 2013 18:04:05 +0100 Subject: [PATCH 82/91] IDEA-115275 (bundle compiler migrated from VFS to plain files) - fixes stale timestamps problem - eliminates the case of loading module output into VFS --- .../com/intellij/openapi/util/io/FileUtil.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index 9895f2cb1d29..da515f2d982f 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -1419,4 +1419,21 @@ public class FileUtil extends FileUtilRt { final String name = file.getName(); return StringUtil.endsWithIgnoreCase(name, ".jar") || StringUtil.endsWithIgnoreCase(name, ".zip"); } + + public static boolean visitFiles(@NotNull File root, @NotNull Processor processor) { + if (!processor.process(root)) { + return false; + } + + File[] children = root.listFiles(); + if (children != null) { + for (File child : children) { + if (!visitFiles(child, processor)) { + return false; + } + } + } + + return true; + } } From 07385a6ebe5a2e01e6ba9c8d0cb7b15c9a13f65d Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Mon, 25 Nov 2013 09:27:53 +0400 Subject: [PATCH 83/91] get rid of invoke later --- .../constant/GrInplaceConstantIntroducer.java | 42 ++++++++----------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceConstantIntroducer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceConstantIntroducer.java index 2eac1e3fb26e..a23723a42ebe 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceConstantIntroducer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceConstantIntroducer.java @@ -15,7 +15,6 @@ */ package org.jetbrains.plugins.groovy.refactoring.introduce.constant; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.psi.*; import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.introduce.inplace.OccurrencesChooser; @@ -171,31 +170,24 @@ public class GrInplaceConstantIntroducer extends GrAbstractInplaceIntroducer Date: Mon, 25 Nov 2013 12:15:28 +0400 Subject: [PATCH 84/91] IDEA-108838 Wrong code when introducing variable in injection --- .../com/intellij/codeInsight/template/TemplateBuilderImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/TemplateBuilderImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/template/TemplateBuilderImpl.java index 29125be518ed..26d46527065b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/TemplateBuilderImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/TemplateBuilderImpl.java @@ -115,7 +115,8 @@ public class TemplateBuilderImpl implements TemplateBuilder { } public void replaceElement(PsiElement element, TextRange textRange, String primaryVariableName, String otherVariableName, boolean alwaysStopAt) { - final RangeMarker key = myDocument.createRangeMarker(textRange.shiftRight(element.getTextRange().getStartOffset())); + final TextRange elementTextRange = InjectedLanguageManager.getInstance(element.getProject()).injectedToHost(element, element.getTextRange()); + final RangeMarker key = myDocument.createRangeMarker(textRange.shiftRight(elementTextRange.getStartOffset())); myAlwaysStopAtMap.put(key, alwaysStopAt ? Boolean.TRUE : Boolean.FALSE); myVariableNamesMap.put(key, primaryVariableName); myVariableExpressions.put(key, otherVariableName); From 7c80f38656a1fdaba78d26a4c752fa772cc45fbb Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 25 Nov 2013 10:44:25 +0100 Subject: [PATCH 85/91] IDEA-116910 (Invalid "unnecessary explicit numeric cast" warning) --- .../CastThatLosesPrecisionInspection.java | 34 ++-------- ...ecessaryExplicitNumericCastInspection.java | 67 ++++++++----------- .../src/com/siyeh/ig/psiutils/TypeUtils.java | 21 ++++++ .../UnnecessaryExplicitNumericCast.java | 10 +++ .../expected.xml | 7 ++ 5 files changed, 69 insertions(+), 70 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/CastThatLosesPrecisionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/CastThatLosesPrecisionInspection.java index d45abb156159..01829b05d6cb 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/CastThatLosesPrecisionInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/CastThatLosesPrecisionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,29 +24,13 @@ import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.ExpressionUtils; import com.siyeh.ig.psiutils.MethodUtils; +import com.siyeh.ig.psiutils.TypeUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; -import java.util.HashMap; -import java.util.Map; public class CastThatLosesPrecisionInspection extends BaseInspection { - /** - * @noinspection StaticCollection - */ - private static final Map typePrecisions = new HashMap(7); - - static { - typePrecisions.put(PsiType.BYTE, 1); - typePrecisions.put(PsiType.CHAR, 2); - typePrecisions.put(PsiType.SHORT, 2); - typePrecisions.put(PsiType.INT, 3); - typePrecisions.put(PsiType.LONG, 4); - typePrecisions.put(PsiType.FLOAT, 5); - typePrecisions.put(PsiType.DOUBLE, 6); - } - @SuppressWarnings({"PublicField"}) public boolean ignoreIntegerCharCasts = false; @@ -81,8 +65,7 @@ public class CastThatLosesPrecisionInspection extends BaseInspection { return new CastThatLosesPrecisionVisitor(); } - private class CastThatLosesPrecisionVisitor - extends BaseInspectionVisitor { + private class CastThatLosesPrecisionVisitor extends BaseInspectionVisitor { @Override public void visitTypeCastExpression(@NotNull PsiTypeCastExpression expression) { @@ -95,10 +78,7 @@ public class CastThatLosesPrecisionInspection extends BaseInspection { return; } final PsiType operandType = operand.getType(); - if (!ClassUtils.isPrimitiveNumericType(operandType)) { - return; - } - if (hasLowerPrecision(operandType, castType)) { + if (!ClassUtils.isPrimitiveNumericType(operandType) || !TypeUtils.isNarrowingConversion(operandType, castType)) { return; } if (ignoreIntegerCharCasts) { @@ -129,12 +109,6 @@ public class CastThatLosesPrecisionInspection extends BaseInspection { registerError(castTypeElement, operandType); } - private boolean hasLowerPrecision(PsiType operandType, PsiType castType) { - final Integer operandPrecision = typePrecisions.get(operandType); - final Integer castPrecision = typePrecisions.get(castType); - return operandPrecision.intValue() <= castPrecision.intValue(); - } - private boolean valueIsContainableInType(Number value, PsiType type) { final long longValue = value.longValue(); final double doubleValue = value.doubleValue(); diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java index f7eeccffb09d..a850823e8624 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java @@ -28,6 +28,7 @@ import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.ExpectedTypeUtils; import com.siyeh.ig.psiutils.ExpressionUtils; +import com.siyeh.ig.psiutils.TypeUtils; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -158,17 +159,21 @@ public class UnnecessaryExplicitNumericCastInspection extends BaseInspection { final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)parent; final IElementType tokenType = polyadicExpression.getOperationTokenType(); if (binaryPromotionOperators.contains(tokenType)) { + if (TypeUtils.isNarrowingConversion(operandType, castType)) { + return true; + } if (PsiType.INT.equals(castType)) { return PsiType.LONG.equals(operandType) || PsiType.FLOAT.equals(operandType) || PsiType.DOUBLE.equals(operandType); } if (PsiType.LONG.equals(castType) || PsiType.FLOAT.equals(castType) || PsiType.DOUBLE.equals(castType)) { final PsiExpression[] operands = polyadicExpression.getOperands(); for (PsiExpression operand1 : operands) { - if (!PsiTreeUtil.isAncestor(operand1, expression, false)) { - final PsiType type = operand1.getType(); - if (castType.equals(type)) { - return false; - } + if (PsiTreeUtil.isAncestor(operand1, expression, false)) { + continue; + } + final PsiType type = operand1.getType(); + if (castType.equals(type)) { + return false; } } } @@ -283,49 +288,31 @@ public class UnnecessaryExplicitNumericCastInspection extends BaseInspection { static boolean isLegalAssignmentConversion(PsiExpression expression, PsiType assignmentType) { // JLS 5.2 Assignment Conversion - final PsiType operandType = expression.getType(); if (isLegalWideningConversion(expression, assignmentType)) { return true; } - else if (PsiType.SHORT.equals(assignmentType)) { - if (PsiType.INT.equals(operandType)) { - final Object constant = ExpressionUtils.computeConstantExpression(expression); - if (!(constant instanceof Integer)) { - return false; - } - final int i = ((Integer)constant).intValue(); - if (i >= Short.MIN_VALUE && i <= Short.MAX_VALUE) { - // narrowing - return true; - } - } + if (PsiType.SHORT.equals(assignmentType)) { + return canValueBeContained(expression, Short.MIN_VALUE, Short.MAX_VALUE); } else if (PsiType.CHAR.equals(assignmentType)) { - if (PsiType.INT.equals(operandType)) { - final Object constant = ExpressionUtils.computeConstantExpression(expression); - if (!(constant instanceof Integer)) { - return false; - } - final int i = ((Integer)constant).intValue(); - if (i >= Character.MIN_VALUE && i <= Character.MAX_VALUE) { - // narrowing - return true; - } - } + return canValueBeContained(expression, Character.MIN_VALUE, Character.MAX_VALUE); } else if (PsiType.BYTE.equals(assignmentType)) { - if (PsiType.INT.equals(operandType)) { - final Object constant = ExpressionUtils.computeConstantExpression(expression); - if (!(constant instanceof Integer)) { - return false; - } - final int i = ((Integer)constant).intValue(); - if (i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE) { - // narrowing - return true; - } - } + return canValueBeContained(expression, Byte.MIN_VALUE, Byte.MAX_VALUE); } return false; } + + private static boolean canValueBeContained(PsiExpression expression, int lowerBound, int upperBound) { + final PsiType expressionType = expression.getType(); + if (!PsiType.INT.equals(expressionType)) { + return false; + } + final Object constant = ExpressionUtils.computeConstantExpression(expression); + if (!(constant instanceof Integer)) { + return false; + } + final int i = ((Integer)constant).intValue(); + return i >= lowerBound && i <= upperBound; + } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TypeUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TypeUtils.java index 34110a4cc702..51a650461481 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TypeUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TypeUtils.java @@ -23,8 +23,23 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.HashMap; +import java.util.Map; + public class TypeUtils { + private static final Map typePrecisions = new HashMap(7); + + static { + typePrecisions.put(PsiType.BYTE, 1); + typePrecisions.put(PsiType.CHAR, 2); + typePrecisions.put(PsiType.SHORT, 2); + typePrecisions.put(PsiType.INT, 3); + typePrecisions.put(PsiType.LONG, 4); + typePrecisions.put(PsiType.FLOAT, 5); + typePrecisions.put(PsiType.DOUBLE, 6); + } + private TypeUtils() {} public static boolean typeEquals(@NonNls @NotNull String typeName, @Nullable PsiType targetType) { @@ -50,6 +65,12 @@ public class TypeUtils { return getType(CommonClassNames.JAVA_LANG_STRING, context); } + public static boolean isNarrowingConversion(PsiType operandType, PsiType castType) { + final Integer operandPrecision = typePrecisions.get(operandType); + final Integer castPrecision = typePrecisions.get(castType); + return operandPrecision.intValue() > castPrecision.intValue(); + } + public static boolean isJavaLangObject(@Nullable PsiType targetType) { return typeEquals(CommonClassNames.JAVA_LANG_OBJECT, targetType); } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/UnnecessaryExplicitNumericCast.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/UnnecessaryExplicitNumericCast.java index 9468de1baf32..26cc95afef11 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/UnnecessaryExplicitNumericCast.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/UnnecessaryExplicitNumericCast.java @@ -53,4 +53,14 @@ public class UnnecessaryExplicitNumericCast { float x = 2; target((int) x); // this line complains: 'x' unnecessarily cast to 'int' } + + void a(float angleFromTo) { + float f = (float) Math.cos(0.5) * 1.0f; // necessary + final long l = (long) i() * 9L; + float angle2 = angleFromTo + (float) (Math.PI / 2); + } + + int i() { + return 10; + } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/expected.xml index 19f2cadeff52..1e24f7ab3d58 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/expected.xml +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/unnecessary_explicit_numeric_cast/expected.xml @@ -100,4 +100,11 @@ Unnecessary explicit numeric cast ''b'' unnecessarily cast to <code>int</code> #loc + + + UnnecessaryExplicitNumericCast.java + 59 + Unnecessary explicit numeric cast + 'i()' unnecessarily cast to <code>long</code> #loc + \ No newline at end of file From 495fddcaa42fd1652b96e733028f8573a9a7401a Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 22 Nov 2013 20:15:26 +0400 Subject: [PATCH 86/91] added quick-fix to delete all unused libraries (IDEA-99885) --- .../BaseLibrariesConfigurable.java | 22 ++++++++++----- .../LibraryProjectStructureElement.java | 23 +++++++++++++++- .../ProjectStructureDaemonAnalyzer.java | 27 ++++++++++++------- 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java index 321cd77fe74d..711b723141c9 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java @@ -46,6 +46,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; import java.util.*; public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurable { @@ -257,14 +258,23 @@ public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurabl } public void removeLibrary(@NotNull LibraryProjectStructureElement element) { - getModelProvider().getModifiableModel().removeLibrary(element.getLibrary()); - myContext.getDaemonAnalyzer().removeElement(element); - final MyNode node = findNodeByObject(myRoot, element.getLibrary()); - if (node != null) { - removePaths(TreeUtil.getPathFromRoot(node)); - } + removeLibraries(Collections.singletonList(element)); } + public void removeLibraries(@NotNull List libraries) { + List pathsToRemove = new ArrayList(); + for (LibraryProjectStructureElement element : libraries) { + getModelProvider().getModifiableModel().removeLibrary(element.getLibrary()); + MyNode node = findNodeByObject(myRoot, element.getLibrary()); + if (node != null) { + pathsToRemove.add(TreeUtil.getPathFromRoot(node)); + } + } + myContext.getDaemonAnalyzer().removeElements(libraries); + removePaths(pathsToRemove.toArray(new TreePath[pathsToRemove.size()])); + } + + @Override protected boolean removeLibrary(final Library library) { final LibraryTable table = library.getTable(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java index 930cb514a80a..1fc3dbd66162 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java @@ -41,6 +41,7 @@ import org.jetbrains.annotations.NotNull; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -148,7 +149,7 @@ public class LibraryProjectStructureElement extends ProjectStructureElement { @Override public ProjectStructureProblemDescription createUnusedElementWarning() { - final List fixes = Arrays.asList(new AddLibraryToDependenciesFix(), new RemoveLibraryFix()); + final List fixes = Arrays.asList(new AddLibraryToDependenciesFix(), new RemoveLibraryFix(), new RemoveAllUnusedLibrariesFix()); return new ProjectStructureProblemDescription("Library '" + StringUtil.escapeXml(myLibrary.getName()) + "'" + " is not used", null, createPlace(), ProjectStructureProblemType.unused("unused-library"), ProjectStructureProblemDescription.ProblemLevel.PROJECT, fixes, false); @@ -225,4 +226,24 @@ public class LibraryProjectStructureElement extends ProjectStructureElement { BaseLibrariesConfigurable.getInstance(myContext.getProject(), myLibrary.getTable().getTableLevel()).removeLibrary(LibraryProjectStructureElement.this); } } + + private class RemoveAllUnusedLibrariesFix extends ConfigurationErrorQuickFix { + private RemoveAllUnusedLibrariesFix() { + super("Remove All Unused Libraries"); + } + + @Override + public void performFix() { + BaseLibrariesConfigurable configurable = BaseLibrariesConfigurable.getInstance(myContext.getProject(), LibraryTablesRegistrar.PROJECT_LEVEL); + Library[] libraries = configurable.getModelProvider().getModifiableModel().getLibraries(); + List toRemove = new ArrayList(); + for (Library library : libraries) { + LibraryProjectStructureElement libraryElement = new LibraryProjectStructureElement(myContext, library); + if (myContext.getDaemonAnalyzer().getUsages(libraryElement).isEmpty()) { + toRemove.add(libraryElement); + } + } + configurable.removeLibraries(toRemove); + } + } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java index 91183b9b5655..8b551b0f38f9 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java @@ -141,21 +141,28 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { } public void removeElement(ProjectStructureElement element) { - myElementWithNotCalculatedUsages.remove(element); - myElementsToShowWarningIfUnused.remove(element); - myWarningsAboutUnused.remove(element); - myProblemHolders.remove(element); - final Collection usages = mySourceElement2Usages.removeAll(element); - if (usages != null) { - for (ProjectStructureElementUsage usage : usages) { - myProblemHolders.remove(usage.getContainingElement()); + removeElements(Collections.singletonList(element)); + } + + public void removeElements(@NotNull List elements) { + myElementWithNotCalculatedUsages.removeAll(elements); + myElementsToShowWarningIfUnused.removeAll(elements); + for (ProjectStructureElement element : elements) { + myWarningsAboutUnused.remove(element); + myProblemHolders.remove(element); + final Collection usages = mySourceElement2Usages.removeAll(element); + if (usages != null) { + for (ProjectStructureElementUsage usage : usages) { + myProblemHolders.remove(usage.getContainingElement()); + } } + removeUsagesInElement(element); + myDispatcher.getMulticaster().problemsChanged(element); } - removeUsagesInElement(element); - myDispatcher.getMulticaster().problemsChanged(element); reportUnusedElements(); } + private void reportUnusedElements() { if (!myElementWithNotCalculatedUsages.isEmpty()) return; From dfee10f094e2155699767a14034bc136f168f083 Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 25 Nov 2013 13:49:00 +0400 Subject: [PATCH 87/91] error reporting in 'Project Structure' dialog: merge UI updates (IDEA-116808, IDEA-110799) --- .../ProjectStructureDaemonAnalyzer.java | 128 ++++++++++++------ 1 file changed, 90 insertions(+), 38 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java index 8b551b0f38f9..97ed5b0da733 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java @@ -7,13 +7,13 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.MultiValuesMap; +import com.intellij.util.Alarm; import com.intellij.util.EventDispatcher; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; @@ -29,6 +29,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { private final Set myElementsToShowWarningIfUnused = new HashSet(); private final Map myWarningsAboutUnused = new HashMap(); private final MergingUpdateQueue myAnalyzerQueue; + private final MergingUpdateQueue myResultsUpdateQueue; private final EventDispatcher myDispatcher = EventDispatcher.create(ProjectStructureDaemonAnalyzerListener.class); private final AtomicBoolean myStopped = new AtomicBoolean(false); private final ProjectConfigurationProblems myProjectConfigurationProblems; @@ -36,7 +37,9 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { public ProjectStructureDaemonAnalyzer(StructureConfigurableContext context) { Disposer.register(context, this); myProjectConfigurationProblems = new ProjectConfigurationProblems(this, context); - myAnalyzerQueue = new MergingUpdateQueue("Project Structure Daemon Analyzer", 300, false, null, this, null, false); + myAnalyzerQueue = new MergingUpdateQueue("Project Structure Daemon Analyzer", 300, false, null, this, null, Alarm.ThreadToUse.POOLED_THREAD); + myResultsUpdateQueue = new MergingUpdateQueue("Project Structure Analysis Results Updater", 300, false, MergingUpdateQueue.ANY_COMPONENT, + this, null, Alarm.ThreadToUse.SWING_THREAD); } private void doUpdate(final ProjectStructureElement element, final boolean check, final boolean collectUsages) { @@ -63,21 +66,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { ProjectStructureValidator.check(element, problemsHolder); } }.execute(); - invokeLater(new Runnable() { - @Override - public void run() { - if (myStopped.get()) return; - - if (LOG.isDebugEnabled()) { - LOG.debug("updating problems for " + element); - } - final ProjectStructureProblemDescription warning = myWarningsAboutUnused.get(element); - if (warning != null) - problemsHolder.registerProblem(warning); - myProblemHolders.put(element, problemsHolder); - myDispatcher.getMulticaster().problemsChanged(element); - } - }); + myResultsUpdateQueue.queue(new ProblemsComputedUpdate(element, problemsHolder)); } private void doCollectUsages(final ProjectStructureElement element) { @@ -92,18 +81,9 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { result.setResult(getUsagesInElement(element)); } }.execute().getResultObject(); - - invokeLater(new Runnable() { - @Override - public void run() { - if (myStopped.get() || usages == null) return; - - if (LOG.isDebugEnabled()) { - LOG.debug("updating usages for " + element); - } - updateUsages(element, usages); - } - }); + if (usages != null) { + myResultsUpdateQueue.queue(new UsagesCollectedUpdate(element, usages)); + } } private static List getUsagesInElement(final ProjectStructureElement element) { @@ -116,11 +96,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { addUsage(usage); } myElementWithNotCalculatedUsages.remove(element); - reportUnusedElements(); - } - - private static void invokeLater(Runnable runnable) { - SwingUtilities.invokeLater(runnable); + myResultsUpdateQueue.queue(new ReportUnusedElementsUpdate()); } public void queueUpdate(@NotNull final ProjectStructureElement element) { @@ -159,7 +135,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { removeUsagesInElement(element); myDispatcher.getMulticaster().problemsChanged(element); } - reportUnusedElements(); + myResultsUpdateQueue.queue(new ReportUnusedElementsUpdate()); } @@ -212,8 +188,10 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { LOG.debug("analyzer stopped"); myStopped.set(true); myAnalyzerQueue.cancelAllUpdates(); + myResultsUpdateQueue.cancelAllUpdates(); clearCaches(); myAnalyzerQueue.deactivate(); + myResultsUpdateQueue.deactivate(); } public void clearCaches() { @@ -239,6 +217,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { public void dispose() { myStopped.set(true); myAnalyzerQueue.cancelAllUpdates(); + myResultsUpdateQueue.cancelAllUpdates(); } @Nullable @@ -263,6 +242,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { public void reset() { LOG.debug("analyzer started"); myAnalyzerQueue.activate(); + myResultsUpdateQueue.activate(); myAnalyzerQueue.queue(new Update("reset") { @Override public void run() { @@ -277,9 +257,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { mySourceElement2Usages.clear(); myContainingElement2Usages.clear(); myElementWithNotCalculatedUsages.clear(); - if (myProjectConfigurationProblems != null) { - myProjectConfigurationProblems.clearProblems(); - } + myProjectConfigurationProblems.clearProblems(); } private class AnalyzeElementUpdate extends Update { @@ -319,4 +297,78 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { } } } + + private class UsagesCollectedUpdate extends Update { + private final ProjectStructureElement myElement; + private final List myUsages; + private final Object[] myEqualityObjects; + + public UsagesCollectedUpdate(ProjectStructureElement element, List usages) { + super(element); + myElement = element; + myUsages = usages; + myEqualityObjects = new Object[]{element, "usages collected"}; + } + + @NotNull + @Override + public Object[] getEqualityObjects() { + return myEqualityObjects; + } + + @Override + public void run() { + if (myStopped.get()) return; + + if (LOG.isDebugEnabled()) { + LOG.debug("updating usages for " + myElement); + } + updateUsages(myElement, myUsages); + } + } + + private class ProblemsComputedUpdate extends Update { + private final ProjectStructureElement myElement; + private final ProjectStructureProblemsHolderImpl myProblemsHolder; + private final Object[] myEqualityObjects; + + public ProblemsComputedUpdate(ProjectStructureElement element, ProjectStructureProblemsHolderImpl problemsHolder) { + super(element); + myElement = element; + myProblemsHolder = problemsHolder; + myEqualityObjects = new Object[]{element, "problems computed"}; + } + + @NotNull + @Override + public Object[] getEqualityObjects() { + return myEqualityObjects; + } + + @Override + public void run() { + if (myStopped.get()) return; + + if (LOG.isDebugEnabled()) { + LOG.debug("updating problems for " + myElement); + } + final ProjectStructureProblemDescription warning = myWarningsAboutUnused.get(myElement); + if (warning != null) { + myProblemsHolder.registerProblem(warning); + } + myProblemHolders.put(myElement, myProblemsHolder); + myDispatcher.getMulticaster().problemsChanged(myElement); + } + } + + private class ReportUnusedElementsUpdate extends Update { + private ReportUnusedElementsUpdate() { + super("unused elements"); + } + + @Override + public void run() { + reportUnusedElements(); + } + } } From 372d6c1e69d0e192514ff166ac176b6d82d9e541 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 25 Nov 2013 13:20:49 +0400 Subject: [PATCH 88/91] javadoc --- platform/lang-api/src/com/intellij/psi/LanguageInjector.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/lang-api/src/com/intellij/psi/LanguageInjector.java b/platform/lang-api/src/com/intellij/psi/LanguageInjector.java index d45e2b570791..b92f092f00c8 100644 --- a/platform/lang-api/src/com/intellij/psi/LanguageInjector.java +++ b/platform/lang-api/src/com/intellij/psi/LanguageInjector.java @@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull; * Describes logic for injecting language inside hosting PSI element. * E.g. "inject XPath language into all XML attributes named 'select' that sit inside XML tag prefixed with 'xsl:'". * @see com.intellij.psi.PsiLanguageInjectionHost + * @see com.intellij.lang.injection.MultiHostInjector */ public interface LanguageInjector { ExtensionPointName EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.languageInjector"); From 0e1c82098855ed1d416e9fa42d0ca606689f5f43 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 25 Nov 2013 13:56:24 +0400 Subject: [PATCH 89/91] IDEA-113684 Soft wraps insert additional spaces --- .../injected/editor/EditorWindow.java | 6 ++- .../intellij/codeInsight/SoftWrapTest.java | 54 +++++++++++++++++++ xml/tests/testData/softWrap/softWrap.html | 12 +++++ .../testData/softWrap/softWrap_after.html | 12 +++++ 4 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 xml/tests/src/com/intellij/codeInsight/SoftWrapTest.java create mode 100644 xml/tests/testData/softWrap/softWrap.html create mode 100644 xml/tests/testData/softWrap/softWrap_after.html diff --git a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java index ce8606677f3e..8b7da068f968 100644 --- a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java +++ b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java @@ -36,6 +36,7 @@ import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.editor.highlighter.EditorHighlighter; import com.intellij.openapi.editor.highlighter.LightHighlighterClient; import com.intellij.openapi.editor.impl.EditorImpl; +import com.intellij.openapi.editor.impl.SoftWrapModelImpl; import com.intellij.openapi.editor.impl.TextDrawingCallback; import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces; import com.intellij.openapi.editor.markup.MarkupModel; @@ -73,6 +74,7 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx { private boolean myDisposed; private final MarkupModelWindow myMarkupModelDelegate; private final FoldingModelWindow myFoldingModelWindow; + private final SoftWrapModelImpl mySoftWrapModel; public static Editor create(@NotNull final DocumentWindowImpl documentRange, @NotNull final EditorImpl editor, @NotNull final PsiFile injectedFile) { assert documentRange.isValid(); @@ -106,6 +108,8 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx { mySelectionModelDelegate = new SelectionModelWindow(myDelegate, myDocumentWindow,this); myMarkupModelDelegate = new MarkupModelWindow((MarkupModelEx)myDelegate.getMarkupModel(), myDocumentWindow); myFoldingModelWindow = new FoldingModelWindow(delegate.getFoldingModel(), documentWindow, this); + mySoftWrapModel = new SoftWrapModelImpl(this); + Disposer.register(myDocumentWindow, mySoftWrapModel); } public static void disposeInvalidEditors() { @@ -262,7 +266,7 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx { @Override @NotNull public SoftWrapModelEx getSoftWrapModel() { - return myDelegate.getSoftWrapModel(); + return mySoftWrapModel; } @Override diff --git a/xml/tests/src/com/intellij/codeInsight/SoftWrapTest.java b/xml/tests/src/com/intellij/codeInsight/SoftWrapTest.java new file mode 100644 index 000000000000..4de8e700def3 --- /dev/null +++ b/xml/tests/src/com/intellij/codeInsight/SoftWrapTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.impl.SoftWrapModelImpl; +import com.intellij.openapi.editor.impl.softwrap.mapping.SoftWrapApplianceManager; +import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase; + +/** + * @author Dmitry Avdeev + * Date: 25.11.13 + */ +public class SoftWrapTest extends LightPlatformCodeInsightFixtureTestCase { + + public void testSoftWrapInInjection() throws Exception { + + myFixture.configureByFile("softWrap.html"); + Editor editor = myFixture.getEditor(); + editor.getSettings().setUseSoftWraps(true); + ((SoftWrapModelImpl)editor.getSoftWrapModel()).getApplianceManager().setWidthProvider(new SoftWrapApplianceManager.VisibleAreaWidthProvider() { + @Override + public int getVisibleAreaWidth() { + return 600; + } + }); + + myFixture.type('j'); + myFixture.checkResultByFile("softWrap_after.html"); + } + + @Override + protected String getBasePath() { + return "/xml/tests/testData/softWrap"; + } + + @Override + protected boolean isCommunity() { + return true; + } +} diff --git a/xml/tests/testData/softWrap/softWrap.html b/xml/tests/testData/softWrap/softWrap.html new file mode 100644 index 000000000000..dfddbbf95281 --- /dev/null +++ b/xml/tests/testData/softWrap/softWrap.html @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/xml/tests/testData/softWrap/softWrap_after.html b/xml/tests/testData/softWrap/softWrap_after.html new file mode 100644 index 000000000000..7d5c77a43e9a --- /dev/null +++ b/xml/tests/testData/softWrap/softWrap_after.html @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file From 7021a46c83f2e557427b0ed3ca8f1a2ed2f84324 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Mon, 25 Nov 2013 14:32:11 +0400 Subject: [PATCH 90/91] style --- .../git4idea/src/git4idea/roots/GitIntegrationEnabler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/git4idea/src/git4idea/roots/GitIntegrationEnabler.java b/plugins/git4idea/src/git4idea/roots/GitIntegrationEnabler.java index a9e0c6ee0ad0..15c98d9c8e92 100644 --- a/plugins/git4idea/src/git4idea/roots/GitIntegrationEnabler.java +++ b/plugins/git4idea/src/git4idea/roots/GitIntegrationEnabler.java @@ -61,8 +61,8 @@ public class GitIntegrationEnabler { Collection gitRoots = ContainerUtil.filter(detectInfo.getRoots(), new Condition() { @Override public boolean value(VcsRoot root) { - AbstractVcs gitVcs = root.getVcs(); - return gitVcs != null && gitVcs.getName().equals(GitVcs.NAME); + AbstractVcs vcs = root.getVcs(); + return vcs != null && vcs.getName().equals(GitVcs.NAME); } }); Collection roots = VcsRootErrorsFinder.vcsRootsToVirtualFiles(gitRoots); From 726ffc171f7e1898d877b8fe4c9a8b2d478774f3 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Mon, 25 Nov 2013 15:24:48 +0400 Subject: [PATCH 91/91] [log] Make "show details" & "show long edges" actions dumb aware --- .../intellij/vcs/log/ui/frame/MainFrame.java | 67 +++++++++++-------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java index 04a3e3e47682..c58abbb17ff4 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java @@ -4,6 +4,7 @@ import com.intellij.icons.AllIcons; import com.intellij.ide.actions.RefreshAction; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Splitter; @@ -176,34 +177,8 @@ public class MainFrame extends JPanel implements TypeSafeDataProvider { } }; - AnAction showFullPatchAction = new ToggleAction("Show long edges", - "Show long branch edges even if commits are invisible in the current view.", - VcsLogIcons.ShowHideLongEdges) { - @Override - public boolean isSelected(AnActionEvent e) { - return !myUI.areLongEdgesHidden(); - } - - @Override - public void setSelected(AnActionEvent e, boolean state) { - myUI.setLongEdgeVisibility(state); - } - }; - - ToggleAction showDetailsAction = new ToggleAction("Show Details", "Display details panel", AllIcons.Actions.Preview) { - @Override - public boolean isSelected(AnActionEvent e) { - return !myProject.isDisposed() && myUiProperties.isShowDetails(); - } - - @Override - public void setSelected(AnActionEvent e, boolean state) { - setupDetailsSplitter(state); - if (!myProject.isDisposed()) { - myUiProperties.setShowDetails(state); - } - } - }; + AnAction showFullPatchAction = new ShowLongEdgesAction(); + AnAction showDetailsAction = new ShowDetailsAction(); refreshAction.registerShortcutOn(this); @@ -284,4 +259,40 @@ public class MainFrame extends JPanel implements TypeSafeDataProvider { } } } + + private class ShowDetailsAction extends ToggleAction implements DumbAware { + + public ShowDetailsAction() { + super("Show Details", "Display details panel", AllIcons.Actions.Preview); + } + + @Override + public boolean isSelected(AnActionEvent e) { + return !myProject.isDisposed() && myUiProperties.isShowDetails(); + } + + @Override + public void setSelected(AnActionEvent e, boolean state) { + setupDetailsSplitter(state); + if (!myProject.isDisposed()) { + myUiProperties.setShowDetails(state); + } + } + } + + private class ShowLongEdgesAction extends ToggleAction implements DumbAware { + public ShowLongEdgesAction() { + super("Show long edges", "Show long branch edges even if commits are invisible in the current view.", VcsLogIcons.ShowHideLongEdges); + } + + @Override + public boolean isSelected(AnActionEvent e) { + return !myUI.areLongEdgesHidden(); + } + + @Override + public void setSelected(AnActionEvent e, boolean state) { + myUI.setLongEdgeVisibility(state); + } + } }