From 96baacaa8625fc4f23d81b8b4352c9d376f48173 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 13 Jan 2012 14:27:48 +0400 Subject: [PATCH 01/15] test depends on the first 17 classes in annotations.jar? Really? --- .../projectView/ProjectTreeStructureTest.java | 37 +------------------ .../projectView/BaseProjectViewTestCase.java | 16 ++------ .../com/intellij/openapi/ui/Queryable.java | 18 ++++----- .../intellij/psi/impl/source/PsiFileImpl.java | 2 +- 4 files changed, 15 insertions(+), 58 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeStructureTest.java b/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeStructureTest.java index 80882a8f1fa6..6f90cad43b83 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeStructureTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeStructureTest.java @@ -7,7 +7,7 @@ public class ProjectTreeStructureTest extends BaseProjectViewTestCase { @Override protected void setUp() throws Exception { super.setUp(); - myPrintInfo = new Queryable.PrintInfo(new String[]{"className", "fileName", "fieldName", "methodName", "packageName"}); + myPrintInfo = new Queryable.PrintInfo(); } public void test1() { @@ -33,24 +33,6 @@ public class ProjectTreeStructureTest extends BaseProjectViewTestCase { " Form1.form\n" + " Form2.form\n"); - assertStructureEqual("Project\n" + - " External Libraries\n" + - " Library: < java 1.7 >\n" + - " annotations.jar\n" + - " META-INF\n" + - " MANIFEST.MF\n" + - " classpath.index\n" + - " org\n" + - " intellij\n" + - " lang\n" + - " annotations\n" + - " Identifier\n" + - " Language\n" + - " Pattern\n" + - " PrintFormat\n" + - " PrintFormatPattern\n" + - " RegExp\n"); - getProjectTreeStructure().setProviders(); assertStructureEqual(getPackageDirectory(), @@ -62,23 +44,6 @@ public class ProjectTreeStructureTest extends BaseProjectViewTestCase { " Form1.java\n" + " Form2.form\n"); - assertStructureEqual("Project\n" + - " External Libraries\n" + - " Library: < java 1.7 >\n" + - " annotations.jar\n" + - " META-INF\n" + - " MANIFEST.MF\n" + - " classpath.index\n" + - " org\n" + - " intellij\n" + - " lang\n" + - " annotations\n" + - " Identifier.class\n" + - " Language.class\n" + - " Pattern.class\n" + - " PrintFormat.class\n" + - " PrintFormatPattern.class\n" + - " RegExp.class\n"); } public void testShowClassMembers() { diff --git a/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java b/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java index 51450a22b756..46fc89441060 100644 --- a/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java +++ b/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java @@ -31,7 +31,7 @@ import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; -import com.intellij.testFramework.IdeaTestUtil; +import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.ProjectViewTestUtil; import com.intellij.testFramework.TestSourceBasedTestCase; import com.intellij.util.Function; @@ -112,10 +112,6 @@ public abstract class BaseProjectViewTestCase extends TestSourceBasedTestCase { return (AbstractProjectTreeStructure)myStructure; } - protected void assertStructureEqual(@NonNls String expected) { - assertStructureEqual(myStructure.getRootElement(), expected); - } - protected void assertStructureEqual(String expected, Comparator comparator) { assertStructureEqual(myStructure.getRootElement(), expected, 27, comparator); } @@ -123,16 +119,12 @@ public abstract class BaseProjectViewTestCase extends TestSourceBasedTestCase { private void assertStructureEqual(PsiDirectory root, String expected, int maxRowCount, AbstractTreeStructure structure) { assertNotNull(root); PsiDirectoryNode rootNode = new PsiDirectoryNode(myProject, root, (ViewSettings)structure); - assertStructureEqual(rootNode, expected, maxRowCount, IdeaTestUtil.createComparator(myPrintInfo)); - } - - private void assertStructureEqual(Object rootNode, String expected) { - assertStructureEqual(rootNode, expected, 17, IdeaTestUtil.createComparator(myPrintInfo)); + assertStructureEqual(rootNode, expected, maxRowCount, PlatformTestUtil.createComparator(myPrintInfo)); } private void assertStructureEqual(Object rootNode, String expected, int maxRowCount, Comparator comparator) { checkGetParentConsistency(rootNode); - StringBuffer actual = IdeaTestUtil.print(myStructure, rootNode, 0, comparator, maxRowCount, ' ', myPrintInfo); + StringBuffer actual = PlatformTestUtil.print(myStructure, rootNode, 0, comparator, maxRowCount, ' ', myPrintInfo); assertEquals(expected, actual.toString()); } @@ -185,7 +177,7 @@ public abstract class BaseProjectViewTestCase extends TestSourceBasedTestCase { } protected static void assertListsEqual(ListModel model, String expected) { - assertEquals(expected, IdeaTestUtil.print(model)); + assertEquals(expected, PlatformTestUtil.print(model)); } public static void checkContainsMethod(final Object rootElement, final AbstractTreeStructure structure) { diff --git a/platform/core-api/src/com/intellij/openapi/ui/Queryable.java b/platform/core-api/src/com/intellij/openapi/ui/Queryable.java index 263153ffc0e2..53d595f860ba 100644 --- a/platform/core-api/src/com/intellij/openapi/ui/Queryable.java +++ b/platform/core-api/src/com/intellij/openapi/ui/Queryable.java @@ -26,8 +26,8 @@ public interface Queryable { void putInfo(@NotNull Map info); class PrintInfo { - String[] myIdKeys; - String[] myInfoKeys; + private final String[] myIdKeys; + private final String[] myInfoKeys; public PrintInfo() { this(null, null); @@ -57,13 +57,13 @@ public interface Queryable { String id = null; - String[] names = print.myIdKeys != null ? print.myIdKeys : new String[] {"name"}; - for (String eachKey : names) { - String eachValue = map.get(eachKey); - if (eachValue != null) { - id = eachValue; - } - } + //String[] names = print.myIdKeys != null ? print.myIdKeys : new String[] {"name"}; + //for (String eachKey : names) { + // String eachValue = map.get(eachKey); + // if (eachValue != null) { + // id = eachValue; + // } + //} if (!map.isEmpty()) { id = map.values().iterator().next(); 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 5ba9126fc94b..a636bb660e28 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 @@ -1029,7 +1029,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF } @Override - public void putInfo(Map info) { + public void putInfo(@NotNull Map info) { putInfo(this, info); } From 26bf65a8fbf469aac2a5dd39c631ebf93b69e403 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 13 Jan 2012 12:21:23 +0100 Subject: [PATCH 02/15] for over array with array.length stored in variable can be foreach too --- .../migration/ForCanBeForeachInspection.java | 223 +++++++++--------- .../migration/foreach/ForCanBeForEach.java | 8 + .../igtest/migration/foreach/expected.xml | 7 + 3 files changed, 129 insertions(+), 109 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/ForCanBeForeachInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/ForCanBeForeachInspection.java index b484244e62ab..c130cc858206 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/ForCanBeForeachInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/ForCanBeForeachInspection.java @@ -498,18 +498,33 @@ public class ForCanBeForeachInspection extends BaseInspection { if (tokenType.equals(JavaTokenType.LT)) { arrayLengthExpression = (PsiReferenceExpression)ParenthesesUtils.stripParentheses(rhs); indexName = lhs.getText(); - } else if (tokenType.equals(JavaTokenType.GT)) { + } + else if (tokenType.equals(JavaTokenType.GT)) { arrayLengthExpression = (PsiReferenceExpression)ParenthesesUtils.stripParentheses(lhs); indexName = rhs.getText(); - } else { + } + else { return null; } if (arrayLengthExpression == null) { return null; } - final PsiReferenceExpression arrayReference = (PsiReferenceExpression)arrayLengthExpression.getQualifierExpression(); + PsiReferenceExpression arrayReference = (PsiReferenceExpression)arrayLengthExpression.getQualifierExpression(); if (arrayReference == null) { - return null; + final PsiElement target = arrayLengthExpression.resolve(); + if (!(target instanceof PsiVariable)) { + return null; + } + final PsiVariable variable = (PsiVariable)target; + final PsiExpression initializer = variable.getInitializer(); + if (!(initializer instanceof PsiReferenceExpression)) { + return null; + } + final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)initializer; + arrayReference = (PsiReferenceExpression)referenceExpression.getQualifierExpression(); + if (arrayReference == null) { + return null; + } } final PsiArrayType arrayType = (PsiArrayType)arrayReference.getType(); if (arrayType == null) { @@ -524,33 +539,24 @@ public class ForCanBeForeachInspection extends BaseInspection { final PsiVariable arrayVariable = (PsiVariable)target; final PsiStatement body = forStatement.getBody(); final PsiStatement firstStatement = getFirstStatement(body); - final boolean isDeclaration = - isArrayElementDeclaration(firstStatement, arrayVariable, - indexName); + final boolean isDeclaration = isArrayElementDeclaration(firstStatement, arrayVariable, indexName); final String contentVariableName; @NonNls final String finalString; final PsiStatement statementToSkip; if (isDeclaration) { - final PsiDeclarationStatement declarationStatement = - (PsiDeclarationStatement)firstStatement; + final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)firstStatement; assert declarationStatement != null; - final PsiElement[] declaredElements = - declarationStatement.getDeclaredElements(); + final PsiElement[] declaredElements = declarationStatement.getDeclaredElements(); final PsiElement declaredElement = declaredElements[0]; if (!(declaredElement instanceof PsiVariable)) { return null; } - final PsiVariable variable = - (PsiVariable)declaredElement; - if (VariableAccessUtils.variableIsAssigned(variable, - forStatement)) { - final String collectionName = - arrayReference.getReferenceName(); - contentVariableName = createNewVariableName(forStatement, - componentType, collectionName); + final PsiVariable variable = (PsiVariable)declaredElement; + if (VariableAccessUtils.variableIsAssigned(variable, forStatement)) { + final String collectionName = arrayReference.getReferenceName(); + contentVariableName = createNewVariableName(forStatement, componentType, collectionName); final Project project = forStatement.getProject(); - final CodeStyleSettings codeStyleSettings = - CodeStyleSettingsManager.getSettings(project); + final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project); if (codeStyleSettings.GENERATE_FINAL_LOCALS) { finalString = "final "; } @@ -571,13 +577,10 @@ public class ForCanBeForeachInspection extends BaseInspection { } } else { - final String collectionName = - arrayReference.getReferenceName(); - contentVariableName = createNewVariableName(forStatement, - componentType, collectionName); + final String collectionName = arrayReference.getReferenceName(); + contentVariableName = createNewVariableName(forStatement, componentType, collectionName); final Project project = forStatement.getProject(); - final CodeStyleSettings codeStyleSettings = - CodeStyleSettingsManager.getSettings(project); + final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project); if (codeStyleSettings.GENERATE_FINAL_LOCALS) { finalString = "final "; } @@ -597,8 +600,7 @@ public class ForCanBeForeachInspection extends BaseInspection { out.append(arrayName); out.append(')'); if (body != null) { - replaceArrayAccess(body, contentVariableName, arrayVariable, - indexName, statementToSkip, out); + replaceArrayAccess(body, contentVariableName, arrayVariable, indexName, statementToSkip, out); } return out.toString(); } @@ -991,7 +993,14 @@ public class ForCanBeForeachInspection extends BaseInspection { } final PsiDeclarationStatement declaration = (PsiDeclarationStatement)initialization; final PsiElement[] declaredElements = declaration.getDeclaredElements(); - if (declaredElements.length < 1) { + final PsiElement secondDeclaredElement; + if (declaredElements.length == 1) { + secondDeclaredElement = null; + } + else if (declaredElements.length == 2) { + secondDeclaredElement = declaredElements[1]; + } + else { return false; } final PsiElement declaredElement = declaredElements[0]; @@ -1012,7 +1021,7 @@ public class ForCanBeForeachInspection extends BaseInspection { return false; } final PsiExpression condition = forStatement.getCondition(); - final Holder collectionHolder = getCollectionFromSizeComparison(condition, indexVariable); + final Holder collectionHolder = getCollectionFromSizeComparison(condition, indexVariable, secondDeclaredElement); if (collectionHolder == null) { return false; } @@ -1041,10 +1050,16 @@ public class ForCanBeForeachInspection extends BaseInspection { if (!(initialization instanceof PsiDeclarationStatement)) { return false; } - final PsiDeclarationStatement declaration = - (PsiDeclarationStatement)initialization; + final PsiDeclarationStatement declaration = (PsiDeclarationStatement)initialization; final PsiElement[] declaredElements = declaration.getDeclaredElements(); - if (declaredElements.length != 1) { + final PsiElement secondDeclaredElement; + if (declaredElements.length == 1) { + secondDeclaredElement = null; + } + else if (declaredElements.length == 2) { + secondDeclaredElement = declaredElements[1]; + } + else { return false; } final PsiElement declaredElement = declaredElements[0]; @@ -1065,15 +1080,12 @@ public class ForCanBeForeachInspection extends BaseInspection { if (integer.intValue() != 0) { return false; } - //if (!isArrayLengthComparison(condition, indexVariable)) { - // return false; - //} final PsiStatement update = forStatement.getUpdate(); if (!VariableAccessUtils.variableIsIncremented(indexVariable, update)) { return false; } final PsiExpression condition = forStatement.getCondition(); - final PsiReferenceExpression arrayReference = getVariableReferenceFromCondition(condition, indexVariable); + final PsiReferenceExpression arrayReference = getVariableReferenceFromCondition(condition, indexVariable, secondDeclaredElement); if (arrayReference == null) { return false; } @@ -1083,17 +1095,10 @@ public class ForCanBeForeachInspection extends BaseInspection { } final PsiVariable arrayVariable = (PsiVariable)element; final PsiStatement body = forStatement.getBody(); - if (body == null) { - return true; - } - if (!isIndexVariableOnlyUsedAsIndex(arrayVariable, indexVariable, body)) { - return false; - } - if (VariableAccessUtils.variableIsAssigned(arrayVariable, body)) { - return false; - } - return !VariableAccessUtils.arrayContentsAreAssigned(arrayVariable, - body); + return body == null || + isIndexVariableOnlyUsedAsIndex(arrayVariable, indexVariable, body) && + !VariableAccessUtils.variableIsAssigned(arrayVariable, body) && + !VariableAccessUtils.arrayContentsAreAssigned(arrayVariable, body); } private static boolean isIndexVariableOnlyUsedAsIndex( @@ -1280,8 +1285,9 @@ public class ForCanBeForeachInspection extends BaseInspection { } @Nullable - private static PsiReferenceExpression getVariableReferenceFromCondition(PsiExpression condition, PsiVariable variable) { - System.out.println("ForCanBeForeachInspection.getVariableReferenceFromCondition(" + condition + ")"); + private static PsiReferenceExpression getVariableReferenceFromCondition(PsiExpression condition, + PsiVariable variable, + PsiElement secondDeclaredElement) { condition = ParenthesesUtils.stripParentheses(condition); if (!(condition instanceof PsiBinaryExpression)) { return null; @@ -1293,40 +1299,51 @@ public class ForCanBeForeachInspection extends BaseInspection { if (rhs == null) { return null; } - final PsiReferenceExpression referenceExpression; + PsiReferenceExpression referenceExpression; if (tokenType.equals(JavaTokenType.LT)) { - if (!VariableAccessUtils.evaluatesToVariable(lhs, variable) || !expressionIsArrayLengthLookup(rhs)) { - return null; - } - if (rhs instanceof PsiMethodCallExpression) { - final PsiMethodCallExpression expression = (PsiMethodCallExpression)rhs; - referenceExpression = expression.getMethodExpression(); - } - else if (rhs instanceof PsiReferenceExpression) { - referenceExpression = (PsiReferenceExpression)rhs; - } - else { + if (!VariableAccessUtils.evaluatesToVariable(lhs, variable) || !(rhs instanceof PsiReferenceExpression)) { return null; } + referenceExpression = (PsiReferenceExpression)rhs; } else if (tokenType.equals(JavaTokenType.GT)) { - if (!VariableAccessUtils.evaluatesToVariable(rhs, variable) || !expressionIsArrayLengthLookup(lhs)) { - return null; - } - if (lhs instanceof PsiMethodCallExpression) { - final PsiMethodCallExpression expression = (PsiMethodCallExpression)lhs; - referenceExpression = expression.getMethodExpression(); - } - else if (lhs instanceof PsiReferenceExpression) { - referenceExpression = (PsiReferenceExpression)lhs; - } - else { + if (!VariableAccessUtils.evaluatesToVariable(rhs, variable) || !(lhs instanceof PsiReferenceExpression)) { return null; } + referenceExpression = (PsiReferenceExpression)lhs; } else { return null; } + if (!expressionIsArrayLengthLookup(referenceExpression)) { + final PsiElement target = referenceExpression.resolve(); + if (secondDeclaredElement != null && !secondDeclaredElement.equals(target)) { + return null; + } + if (target instanceof PsiVariable) { + final PsiVariable maxVariable = (PsiVariable)target; + final PsiCodeBlock context = PsiTreeUtil.getParentOfType(maxVariable, PsiCodeBlock.class); + if (context == null) { + return null; + } + if (VariableAccessUtils.variableIsAssigned(maxVariable, context)) { + return null; + } + final PsiExpression expression = ParenthesesUtils.stripParentheses(maxVariable.getInitializer()); + if (!(expression instanceof PsiReferenceExpression)) { + return null; + } + referenceExpression = (PsiReferenceExpression)expression; + if (!expressionIsArrayLengthLookup(referenceExpression)) { + return null; + } + } + } + else { + if (secondDeclaredElement != null) { + return null; + } + } final PsiExpression qualifierExpression = referenceExpression.getQualifierExpression(); if (qualifierExpression instanceof PsiReferenceExpression) { return (PsiReferenceExpression)qualifierExpression; @@ -1341,27 +1358,8 @@ public class ForCanBeForeachInspection extends BaseInspection { } } - private static boolean isArrayLengthComparison(PsiExpression condition, PsiVariable variable) { - System.out.println("ForCanBeForeachInspection.isArrayLengthComparison(" + condition + ", " + variable + ")"); - condition = ParenthesesUtils.stripParentheses(condition); - if (!(condition instanceof PsiBinaryExpression)) { - return false; - } - final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)condition; - final IElementType tokenType = binaryExpression.getOperationTokenType(); - final PsiExpression lhs = binaryExpression.getLOperand(); - final PsiExpression rhs = binaryExpression.getROperand(); - if (tokenType.equals(JavaTokenType.LT)) { - return VariableAccessUtils.evaluatesToVariable(lhs, variable) && rhs != null && expressionIsArrayLengthLookup(rhs); - } - else if (tokenType.equals(JavaTokenType.GT)) { - return VariableAccessUtils.evaluatesToVariable(rhs, variable) && expressionIsArrayLengthLookup(lhs); - } - return false; - } - - private static Holder getCollectionFromSizeComparison( - PsiExpression condition, PsiVariable variable) { + @Nullable + private static Holder getCollectionFromSizeComparison(PsiExpression condition, PsiVariable variable, PsiElement secondDeclaredElement) { condition = ParenthesesUtils.stripParentheses(condition); if (!(condition instanceof PsiBinaryExpression)) { return null; @@ -1374,13 +1372,13 @@ public class ForCanBeForeachInspection extends BaseInspection { if (!VariableAccessUtils.evaluatesToVariable(lhs, variable)) { return null; } - return getCollectionFromListMethodCall(rhs, HardcodedMethodConstants.SIZE); + return getCollectionFromListMethodCall(rhs, HardcodedMethodConstants.SIZE, secondDeclaredElement); } else if (tokenType.equals(JavaTokenType.GT)) { if (!VariableAccessUtils.evaluatesToVariable(rhs, variable)) { return null; } - return getCollectionFromListMethodCall(lhs, HardcodedMethodConstants.SIZE); + return getCollectionFromListMethodCall(lhs, HardcodedMethodConstants.SIZE, secondDeclaredElement); } return null; } @@ -1407,23 +1405,31 @@ public class ForCanBeForeachInspection extends BaseInspection { CommonClassNames.JAVA_UTIL_LIST); } - private static Holder getCollectionFromListMethodCall( - PsiExpression expression, String methodName) { + @Nullable + private static Holder getCollectionFromListMethodCall(PsiExpression expression, String methodName, PsiElement secondDeclaredElement) { expression = ParenthesesUtils.stripParentheses(expression); if (expression instanceof PsiReferenceExpression) { final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression; final PsiElement target = referenceExpression.resolve(); - if (target instanceof PsiVariable) { - final PsiVariable variable = (PsiVariable)target; - final PsiCodeBlock context = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class); - if (context != null) { - if (!VariableAccessUtils.variableIsAssigned(variable, context)) { - expression = ParenthesesUtils.stripParentheses(variable.getInitializer()); - } - } + if (secondDeclaredElement != null && !secondDeclaredElement.equals(target)) { + return null; } + if (!(target instanceof PsiVariable)) { + return null; + } + final PsiVariable variable = (PsiVariable)target; + final PsiCodeBlock context = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class); + if (context == null) { + return null; + } + if (VariableAccessUtils.variableIsAssigned(variable, context)) { + return null; + } + expression = ParenthesesUtils.stripParentheses(variable.getInitializer()); + } + else if (secondDeclaredElement != null) { + return null; } - if (!(expression instanceof PsiMethodCallExpression)) { return null; } @@ -1466,7 +1472,6 @@ public class ForCanBeForeachInspection extends BaseInspection { } private static boolean expressionIsArrayLengthLookup(PsiExpression expression) { - System.out.println("ForCanBeForeachInspection.expressionIsArrayLengthLookup(" + expression + ")"); expression = ParenthesesUtils.stripParentheses(expression); if (!(expression instanceof PsiReferenceExpression)) { return false; diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach/ForCanBeForEach.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach/ForCanBeForEach.java index 4e335443e285..ceb0034f6b37 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach/ForCanBeForEach.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach/ForCanBeForEach.java @@ -258,5 +258,13 @@ public class ForCanBeForEach { public void food(int[] is) { for (int i = 0; is.length > i; i++) { } + for (int i = 0, j = 10; i < is.length; i++) { + } + } + + void foo(List l) { + for (int i = 0, j = 10; i < l.size(); i++) { + System.out.println(j); + } } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach/expected.xml index ba0d20f5e815..c544dc2bbb1f 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach/expected.xml +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach/expected.xml @@ -106,6 +106,13 @@ <code>for</code> loop replaceable with 'for each' #loc + + ForCanBeForEach.java + 252 + 'for' loop replaceable with 'for each' + <code>for</code> loop replaceable with 'for each' #loc + + ForCanBeForEach.java 259 From 63e8272a76e9fc7fe1b81354b82d7b1d4397319e Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Fri, 13 Jan 2012 15:20:06 +0400 Subject: [PATCH 03/15] IDEA-79691 Option to keep cursor on screen when scrolling with Ctrl+Up/Down --- .../editor/actions/EditorActionUtil.java | 51 ++++++++++++------- .../editor/actions/ScrollDownAction.java | 4 +- .../actions/ScrollDownAndMoveAction.java | 40 +++++++++++++++ .../editor/actions/ScrollUpAction.java | 4 +- .../editor/actions/ScrollUpAndMoveAction.java | 40 +++++++++++++++ .../src/messages/ActionsBundle.properties | 2 + .../src/idea/PlatformActions.xml | 2 + 7 files changed, 120 insertions(+), 23 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAndMoveAction.java create mode 100644 platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAndMoveAction.java diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java index de36566c2bb8..04582bc98034 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,27 +55,38 @@ public class EditorActionUtil { private EditorActionUtil() { } - public static void scrollRelatively(Editor editor, int lineShift) { + /** + * Tries to change given editor's viewport position in vertical dimension by the given number of visual lines. + * + * @param editor target editor which viewport position should be changed + * @param lineShift defines viewport position's change length + * @param moveCaret flag that identifies whether caret should be moved if its current position becomes off-screen + */ + public static void scrollRelatively(Editor editor, int lineShift, boolean moveCaret) { if (lineShift != 0) { editor.getScrollingModel().scrollVertically( editor.getScrollingModel().getVerticalScrollOffset() + lineShift * editor.getLineHeight() ); } - //Rectangle viewRectangle = editor.getScrollingModel().getVisibleArea(); - //int lineNumber = editor.getCaretModel().getVisualPosition().line; - //if (viewRectangle != null) { - // VisualPosition startPos = editor.xyToVisualPosition(new Point(0, viewRectangle.y)); - // int start = startPos.line + 1; - // VisualPosition endPos = editor.xyToVisualPosition(new Point(0, viewRectangle.y + viewRectangle.height)); - // int end = endPos.line - 2; - //if (lineNumber < start) { - // editor.getCaretModel().moveCaretRelatively(0, start - lineNumber, false, false, true); - //} - //else if (lineNumber > end) { - // editor.getCaretModel().moveCaretRelatively(0, end - lineNumber, false, false, true); - //} - //} + if (!moveCaret) { + return; + } + + Rectangle viewRectangle = editor.getScrollingModel().getVisibleArea(); + int lineNumber = editor.getCaretModel().getVisualPosition().line; + if (viewRectangle != null) { + VisualPosition startPos = editor.xyToVisualPosition(new Point(0, viewRectangle.y)); + int start = startPos.line + 1; + VisualPosition endPos = editor.xyToVisualPosition(new Point(0, viewRectangle.y + viewRectangle.height)); + int end = endPos.line - 2; + if (lineNumber < start) { + editor.getCaretModel().moveCaretRelatively(0, start - lineNumber, false, false, true); + } + else if (lineNumber > end) { + editor.getCaretModel().moveCaretRelatively(0, end - lineNumber, false, false, true); + } + } } public static void moveCaretRelativelyAndScroll(Editor editor, @@ -215,9 +226,11 @@ public class EditorActionUtil { } if (isCamel) { - if (firstIsIdentifierPart && secondIsIdentifierPart && - (Character.isLowerCase(prev) && Character.isUpperCase(current) || prev != '_' && current == '_' || - Character.isUpperCase(prev) && Character.isUpperCase(current) && Character.isLowerCase(next))) { + if (firstIsIdentifierPart + && (Character.isLowerCase(prev) && Character.isUpperCase(current) + || prev != '_' && current == '_' + || Character.isUpperCase(prev) && Character.isUpperCase(current) && Character.isLowerCase(next))) + { return true; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAction.java index 09a4b6ea7317..80990c251578 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ public class ScrollDownAction extends InactiveEditorAction { private static class Handler extends EditorActionHandler { @Override public void execute(Editor editor, DataContext dataContext) { - EditorActionUtil.scrollRelatively(editor, 1); + EditorActionUtil.scrollRelatively(editor, 1, false); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAndMoveAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAndMoveAction.java new file mode 100644 index 000000000000..29bbedfba770 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAndMoveAction.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +/** + * Moves editor viewport one visual line down. Caret is also moved one line down if it becomes off-screen + * + * @author Denis Zhdanov + * @since 1/13/12 1:22 PM + */ +public class ScrollDownAndMoveAction extends InactiveEditorAction { + + public ScrollDownAndMoveAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + @Override + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.scrollRelatively(editor, 1, true); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAction.java index 422613413f82..f2214cdfaf1f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ public class ScrollUpAction extends InactiveEditorAction { private static class Handler extends EditorActionHandler { @Override public void execute(Editor editor, DataContext dataContext) { - EditorActionUtil.scrollRelatively(editor, -1); + EditorActionUtil.scrollRelatively(editor, -1, false); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAndMoveAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAndMoveAction.java new file mode 100644 index 000000000000..919e121323dd --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAndMoveAction.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +/** + * Moves editor viewport one visual line up. Caret is also moved one line up if it becomes off-screen. + * + * @author Denis Zhdanov + * @since 1/13/12 1:21 PM + */ +public class ScrollUpAndMoveAction extends InactiveEditorAction { + + public ScrollUpAndMoveAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + @Override + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.scrollRelatively(editor, -1, true); + } + } +} diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index efc5af738f96..b32e2251622f 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -89,6 +89,8 @@ action.EditorTab.text=Tab action.EmacsStyleIndent.text=Emacs Tab action.EditorScrollUp.text=Scroll Up action.EditorScrollDown.text=Scroll Down +action.EditorScrollUpAndMove.text=Scroll Up and Move if Necessary +action.EditorScrollDownAndMove.text=Scroll Down and Move if Necessary action.EditorScrollTop.text=Scroll to Top action.EditorScrollBottom.text=Scroll to Bottom action.EditorMoveUpAndScroll.text=Move Up and Scroll diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 8f16cfe5b38d..cfe8b1fa5ef4 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -51,6 +51,8 @@ + + From 4049d02937ba2f36aa1eb24d4db85227a50a5f45 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 13 Jan 2012 12:27:57 +0100 Subject: [PATCH 04/15] install plugins in background (IDEA-23187) --- .../ide/plugins/ActionInstallPlugin.java | 77 +++++++++++++++---- .../ide/plugins/PluginManagerMain.java | 23 ++++-- 2 files changed, 80 insertions(+), 20 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java index c96d1f09a529..15b3f9a14734 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java @@ -16,15 +16,24 @@ package com.intellij.ide.plugins; import com.intellij.ide.IdeBundle; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationListener; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.application.ApplicationNamesInfo; +import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.IconLoader; import com.intellij.util.net.IOExceptionDialog; +import org.jetbrains.annotations.NotNull; +import javax.swing.event.HyperlinkEvent; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -81,7 +90,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { IdeaPluginDescriptor[] selection = getPluginTable().getSelectedObjects(); if (userConfirm(selection)) { - ArrayList list = new ArrayList(); + final ArrayList list = new ArrayList(); for (IdeaPluginDescriptor descr : selection) { PluginNode pluginNode = null; if (descr instanceof PluginNode) { @@ -99,31 +108,69 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { } } try { - if (PluginManagerMain.downloadPlugins(list, host.getPluginsModel().view)) { - for (PluginNode pluginNode : list) { - final String idString = pluginNode.getPluginId().getIdString(); - final PluginManagerUISettings pluginManagerUISettings = PluginManagerUISettings.getInstance(); - if (!pluginManagerUISettings.myInstalledPlugins.contains(idString)) { - pluginManagerUISettings.myInstalledPlugins.add(idString); + final Runnable onInstallRunnable = new Runnable() { + @Override + public void run() { + installedPluginsToModel(list); + installed.setRequireShutdown(true); + if (!installed.isDisposed()) { + getPluginTable().updateUI(); + } + else { + notifyPluginsWereInstalled(); } - pluginManagerUISettings.myOutdatedPlugins.remove(idString); } - final InstalledPluginsTableModel installedPluginsModel = (InstalledPluginsTableModel)installed.getPluginsModel(); - for (PluginNode node : list) { - installedPluginsModel.appendOrUpdateDescriptor(node); - } - installed.setRequireShutdown(true); - } + }; + PluginManagerMain.downloadPlugins(list, host.getPluginsModel().view, onInstallRunnable); } catch (IOException e1) { PluginManagerMain.LOG.error(e1); IOExceptionDialog .showErrorDialog(IdeBundle.message("action.download.and.install.plugin"), IdeBundle.message("error.plugin.download.failed")); } - getPluginTable().updateUI(); } } + private void installedPluginsToModel(ArrayList list) { + for (PluginNode pluginNode : list) { + final String idString = pluginNode.getPluginId().getIdString(); + final PluginManagerUISettings pluginManagerUISettings = PluginManagerUISettings.getInstance(); + if (!pluginManagerUISettings.myInstalledPlugins.contains(idString)) { + pluginManagerUISettings.myInstalledPlugins.add(idString); + } + pluginManagerUISettings.myOutdatedPlugins.remove(idString); + } + + final InstalledPluginsTableModel installedPluginsModel = (InstalledPluginsTableModel)installed.getPluginsModel(); + for (PluginNode node : list) { + installedPluginsModel.appendOrUpdateDescriptor(node); + } + } + + private static void notifyPluginsWereInstalled() { + final ApplicationEx app = ApplicationManagerEx.getApplicationEx(); + final boolean restartCapable = app.isRestartCapable(); + String message = ""; + message += restartCapable ? IdeBundle.message("message.idea.restart.required", ApplicationNamesInfo.getInstance().getProductName()) + : IdeBundle.message("message.idea.shutdown.required", ApplicationNamesInfo.getInstance().getProductName()); + message += "
Restart now" : "\"shutdown\">Shutdown"; + message += ""; + Notifications.Bus.notify(new Notification(IdeBundle.message("title.plugin.error"), IdeBundle.message("title.plugin.error"), + message, NotificationType.INFORMATION, new NotificationListener() { + @Override + public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { + notification.expire(); + if (restartCapable) { + app.restart(); + } + else { + app.exit(true); + } + } + })); + } + public PluginTable getPluginTable() { return host.getPluginTable(); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java index 8891bb01c92c..de9d2b33330a 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java @@ -22,9 +22,12 @@ import com.intellij.ide.ui.search.SearchUtil; import com.intellij.ide.ui.search.SearchableOptionsRegistrar; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.updateSettings.impl.PluginDownloader; @@ -99,6 +102,7 @@ public abstract class PluginManagerMain implements Disposable { protected final MyPluginsFilter myFilter = new MyPluginsFilter(); protected PluginManagerUISettings myUISettings; + private boolean myDisposed = false; public PluginManagerMain( PluginManagerUISettings uiSettings) { @@ -125,6 +129,11 @@ public abstract class PluginManagerMain implements Disposable { protected abstract JScrollPane createTable(); public void dispose() { + myDisposed = true; + } + + public boolean isDisposed() { + return myDisposed; } public void filter(String filter) { @@ -280,14 +289,18 @@ public abstract class PluginManagerMain implements Disposable { loadPluginsFromHostInBackground(); } - public static boolean downloadPlugins(final List plugins, final List allPlugins) throws IOException { + public static boolean downloadPlugins(final List plugins, final List allPlugins, final Runnable onSuccess) throws IOException { final boolean[] result = new boolean[1]; try { - ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { - public void run() { - result[0] = PluginInstaller.prepareToInstall(plugins, allPlugins); + ProgressManager.getInstance().run(new Task.Backgroundable(null, IdeBundle.message("progress.download.plugins"), true) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + if (PluginInstaller.prepareToInstall(plugins, allPlugins)) { + ApplicationManager.getApplication().invokeLater(onSuccess); + result[0] = true; + } } - }, IdeBundle.message("progress.download.plugins"), true, null); + }); } catch (RuntimeException e) { if (e.getCause() != null && e.getCause() instanceof IOException) { From 4902b2ee7c9168f87f84baca68e2aee248293f87 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 13 Jan 2012 12:33:37 +0100 Subject: [PATCH 05/15] minimum size --- .../intellij/execution/ui/ConfigurationArgumentsHelpArea.form | 1 + 1 file changed, 1 insertion(+) diff --git a/java/execution/impl/src/com/intellij/execution/ui/ConfigurationArgumentsHelpArea.form b/java/execution/impl/src/com/intellij/execution/ui/ConfigurationArgumentsHelpArea.form index f01790d3163c..a84a90ee9d06 100644 --- a/java/execution/impl/src/com/intellij/execution/ui/ConfigurationArgumentsHelpArea.form +++ b/java/execution/impl/src/com/intellij/execution/ui/ConfigurationArgumentsHelpArea.form @@ -30,6 +30,7 @@ + From e175b0faaa0d572692a467103b322650f2845b2f Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 13 Jan 2012 12:42:30 +0100 Subject: [PATCH 06/15] mnemonics/margins --- .../src/com/intellij/execution/remote/RemoteConfigurable.form | 4 ++-- .../src/messages/ExecutionBundle.properties | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/execution/impl/src/com/intellij/execution/remote/RemoteConfigurable.form b/java/execution/impl/src/com/intellij/execution/remote/RemoteConfigurable.form index 332e022e67ff..53490c2e1d3c 100644 --- a/java/execution/impl/src/com/intellij/execution/remote/RemoteConfigurable.form +++ b/java/execution/impl/src/com/intellij/execution/remote/RemoteConfigurable.form @@ -2,7 +2,7 @@
- + @@ -149,7 +149,7 @@ - + diff --git a/platform/platform-resources-en/src/messages/ExecutionBundle.properties b/platform/platform-resources-en/src/messages/ExecutionBundle.properties index 54fa6cfcbda7..3be53cf875b1 100644 --- a/platform/platform-resources-en/src/messages/ExecutionBundle.properties +++ b/platform/platform-resources-en/src/messages/ExecutionBundle.properties @@ -247,10 +247,10 @@ remote.configuration.socket.radio=Socket remote.configuration.shared.memory.address.label=Shared memory address: remote.configuration.port.label=Port: remote.configuration.host.label=Host: -remote.configuration.remote.debugging.allows.you.to.connect.idea.to.a.running.jvm.label=Remote debugging allows you to connect IDEA to a running JVM started with the following command line arguments +remote.configuration.remote.debugging.allows.you.to.connect.idea.to.a.running.jvm.label=&Remote debugging allows you to connect IDEA to a running JVM started with the following command line arguments standard.runner.description=Run selected configuration environment.variables.helper.use.arguments.label=Use the following command line arguments for running remote JVM -environment.variables.helper.use.arguments.jdk13.label=If the application runs on JDK 1.3.x or earlier, use following arguments +environment.variables.helper.use.arguments.jdk13.label=If the &application runs on JDK 1.3.x or earlier, use following arguments select.run.configuration.for.item.action.name=Select {0} save.run.configuration.for.item.action.name=Save {0} junit.runing.info.status.done.count=Done: {0} From 909a66e063e33769b3d3ca16a9e294683153c90e Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Thu, 12 Jan 2012 12:53:01 +0300 Subject: [PATCH 07/15] Make 'MvcModuleStructureSynchronizer.myModificationTracker' final. --- .../plugins/groovy/mvc/MvcModuleStructureSynchronizer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java index 04321da4d48d..f4e2b1452ea0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java @@ -60,7 +60,7 @@ public class MvcModuleStructureSynchronizer extends AbstractProjectComponent { private long myModificationCount = 0; - private ModificationTracker myModificationTracker = new ModificationTracker() { + private final ModificationTracker myModificationTracker = new ModificationTracker() { @Override public long getModificationCount() { return myModificationCount; From 38ee0058bf14ea0c8589978dccc68ba398164ac7 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 13 Jan 2012 12:56:38 +0100 Subject: [PATCH 08/15] scope view: correct select/reload order --- .../src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java index 1d93a2037c96..94ac5e24c046 100644 --- a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java @@ -428,6 +428,8 @@ public class ScopeTreeViewPanel extends JPanel implements Disposable { final boolean wasCollapsed = myTree.isCollapsed(path); final Runnable runnable = new Runnable() { public void run() { + TreeUtil.sort(rootToReload, getNodeComparator()); + treeModel.reload(rootToReload); if (!wasCollapsed) { myTree.collapsePath(path); for (TreePath treePath : treePaths) { @@ -437,8 +439,6 @@ public class ScopeTreeViewPanel extends JPanel implements Disposable { TreeUtil.selectPath(myTree, selectionPath); } } - TreeUtil.sort(rootToReload, getNodeComparator()); - treeModel.reload(rootToReload); } }; if (ApplicationManager.getApplication().isUnitTestMode()) { From 469725a8e49d8ff372d2736e1f09f58876868198 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Fri, 13 Jan 2012 15:47:26 +0300 Subject: [PATCH 09/15] IDEA-75575 (maven: don't offer to re-import after formatting pom.xml) --- .../project/MavenProjectsManagerWatcher.java | 43 +++++++++++++++++-- .../jetbrains/idea/maven/utils/MavenUtil.java | 42 ++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java index 13ce80de07a1..b280a74e7086 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java @@ -56,6 +56,7 @@ import org.jetbrains.idea.maven.utils.MavenMergingUpdateQueue; import org.jetbrains.idea.maven.utils.MavenUtil; import java.io.File; +import java.io.IOException; import java.util.*; public class MavenProjectsManagerWatcher { @@ -395,9 +396,9 @@ public class MavenProjectsManagerWatcher { filesToUpdate.removeAll(filesToRemove); scheduleUpdate(filesToUpdate, filesToRemove, false, forceImportAndResolve); } - } - clearLists(); + clearLists(); + } } private boolean areFileSetsInitialised() { @@ -426,6 +427,9 @@ public class MavenProjectsManagerWatcher { } private static abstract class MyFileChangeListenerBase implements BulkFileListener { + + private static final Key CONTENT_CRC_KEY = Key.create("MyFileChangeListenerBase"); + protected abstract boolean isRelevant(String path); protected abstract void updateFile(VirtualFile file); @@ -453,6 +457,21 @@ public class MavenProjectsManagerWatcher { deleteRecursively(moveEvent.getFile()); } } + else if (each instanceof VFileContentChangeEvent) { + VirtualFile virtualFile = each.getFile(); + if (virtualFile == null) continue; + + if (virtualFile.getLength() < 40 * 1024) { + try { + String content = VfsUtil.loadText(virtualFile); + int crc = MavenUtil.getXmlCrc(content); + virtualFile.putUserData(CONTENT_CRC_KEY, crc); + } + catch (IOException e) { + // Ignore + } + } + } } } } @@ -489,7 +508,25 @@ public class MavenProjectsManagerWatcher { } } else if (each instanceof VFileContentChangeEvent) { - updateFile(each.getFile()); + VirtualFile virtualFile = each.getFile(); + if (virtualFile == null) continue; + + Integer oldCrc = virtualFile.getUserData(CONTENT_CRC_KEY); + if (oldCrc != null) { + try { + virtualFile.putUserData(CONTENT_CRC_KEY, null); + + String content = VfsUtil.loadText(virtualFile); + int newCrc = MavenUtil.getXmlCrc(content); + + if (newCrc == oldCrc) continue; + } + catch (IOException e) { + // Ignore + } + } + + updateFile(virtualFile); } else if (each instanceof VFilePropertyChangeEvent) { if (isRenamed(each)) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java index d05fc5fa4122..23577805661f 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java @@ -19,6 +19,8 @@ import com.intellij.codeInsight.template.TemplateManager; import com.intellij.codeInsight.template.impl.TemplateImpl; import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.lexer.Lexer; +import com.intellij.lexer.XmlLexer; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; @@ -44,6 +46,8 @@ import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.xml.XmlTokenType; import com.intellij.util.Function; import com.intellij.util.SystemProperties; import com.intellij.util.containers.ContainerUtil; @@ -65,6 +69,7 @@ import java.util.concurrent.Future; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import java.util.zip.CRC32; public class MavenUtil { public static final String MAVEN_NOTIFICATION_GROUP = "Maven"; @@ -630,4 +635,41 @@ public class MavenUtil { public interface MavenTaskHandler { void waitFor(); } + + public static int getXmlCrc(@NotNull String xmlText) { + Lexer lexer = new XmlLexer(); + lexer.start(xmlText.trim()); + + CRC32 crc = new CRC32(); + + while (true) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) break; + + if (XmlTokenType.XML_REAL_WHITE_SPACE == tokenType + || XmlTokenType.XML_WHITE_SPACE == tokenType + || XmlTokenType.COMMENTS.contains(tokenType)) { + crc.update(1); + + do { + lexer.advance(); + tokenType = lexer.getTokenType(); + } + while (XmlTokenType.XML_REAL_WHITE_SPACE == tokenType + || XmlTokenType.XML_WHITE_SPACE == tokenType + || XmlTokenType.COMMENTS.contains(tokenType)); + } + else { + for (int start = lexer.getTokenStart(), end = lexer.getTokenEnd(); start < end; start++) { + char a = xmlText.charAt(start); + crc.update(a); + crc.update(a >>> 8); + } + + lexer.advance(); + } + } + + return (int)crc.getValue(); + } } From 8c9d99f553c08f9d36f7c8a7d8b2672ac2960940 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Fri, 13 Jan 2012 15:58:51 +0300 Subject: [PATCH 10/15] IDEA-75575 (maven: don't offer to re-import after formatting pom.xml) --- .../main/java/org/jetbrains/idea/maven/utils/MavenUtil.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java index 23577805661f..dc690a54622c 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java @@ -637,8 +637,9 @@ public class MavenUtil { } public static int getXmlCrc(@NotNull String xmlText) { + String trimmedText = xmlText.trim(); Lexer lexer = new XmlLexer(); - lexer.start(xmlText.trim()); + lexer.start(trimmedText); CRC32 crc = new CRC32(); @@ -661,7 +662,7 @@ public class MavenUtil { } else { for (int start = lexer.getTokenStart(), end = lexer.getTokenEnd(); start < end; start++) { - char a = xmlText.charAt(start); + char a = trimmedText.charAt(start); crc.update(a); crc.update(a >>> 8); } From 105a959dde11506ab4b213b7cff54cc047f89db5 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 13 Jan 2012 13:18:20 +0100 Subject: [PATCH 11/15] when waitUntilRefreshed is called during refresh running, wait until it finishes --- .../openapi/vcs/changes/UpdateRequestsQueue.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java index 61f3774c8550..b7adf26927d6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java @@ -52,6 +52,7 @@ public class UpdateRequestsQueue { private volatile boolean myIgnoreBackgroundOperation; private boolean myRequestSubmitted; + private boolean myRequestRunning; private final List myWaitingUpdateCompletionQueue; private final ProjectLevelVcsManager myPlVcsManager; //private final ScheduledSlowlyClosingAlarm mySharedExecutor; @@ -156,7 +157,7 @@ public class UpdateRequestsQueue { semaphore.up(); } }; - if (myRequestSubmitted && !myStopped) { + if (myRequestSubmitted || myRequestRunning) { myWaitingUpdateCompletionQueue.add(runnable); } else { @@ -169,7 +170,7 @@ public class UpdateRequestsQueue { } synchronized (myLock) { - if (!myRequestSubmitted || myStopped) { + if (!myRequestSubmitted && !myRequestRunning) { return; } } @@ -236,9 +237,10 @@ public class UpdateRequestsQueue { private class MyRunnable implements Runnable { public void run() { final List copy = new ArrayList(myWaitingUpdateCompletionQueue.size()); - try { synchronized (myLock) { + LOG.assertTrue(!myRequestRunning); + myRequestRunning = true; if (myStopped) { myRequestSubmitted = false; LOG.debug("MyRunnable: STOPPED, project: " + myProject.getName() + ", runnable: " + hashCode()); @@ -269,6 +271,7 @@ public class UpdateRequestsQueue { LOG.debug("MyRunnable: invokeD, project: " + myProject.getName() + ", runnable: " + hashCode()); } finally { synchronized (myLock) { + myRequestRunning = false; LOG.debug("MyRunnable: delete executed, project: " + myProject.getName() + ", runnable: " + hashCode()); if (! copy.isEmpty()) { myWaitingUpdateCompletionQueue.removeAll(copy); From b15a75479cf12ae560bef8b57f6daa867309d71b Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Fri, 13 Jan 2012 16:46:50 +0300 Subject: [PATCH 12/15] revert fix: IDEA-75575 (maven: don't offer to re-import after formatting pom.xml) --- .../project/MavenProjectsManagerWatcher.java | 43 ++----------------- .../jetbrains/idea/maven/utils/MavenUtil.java | 43 ------------------- 2 files changed, 3 insertions(+), 83 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java index b280a74e7086..13ce80de07a1 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java @@ -56,7 +56,6 @@ import org.jetbrains.idea.maven.utils.MavenMergingUpdateQueue; import org.jetbrains.idea.maven.utils.MavenUtil; import java.io.File; -import java.io.IOException; import java.util.*; public class MavenProjectsManagerWatcher { @@ -396,9 +395,9 @@ public class MavenProjectsManagerWatcher { filesToUpdate.removeAll(filesToRemove); scheduleUpdate(filesToUpdate, filesToRemove, false, forceImportAndResolve); } - - clearLists(); } + + clearLists(); } private boolean areFileSetsInitialised() { @@ -427,9 +426,6 @@ public class MavenProjectsManagerWatcher { } private static abstract class MyFileChangeListenerBase implements BulkFileListener { - - private static final Key CONTENT_CRC_KEY = Key.create("MyFileChangeListenerBase"); - protected abstract boolean isRelevant(String path); protected abstract void updateFile(VirtualFile file); @@ -457,21 +453,6 @@ public class MavenProjectsManagerWatcher { deleteRecursively(moveEvent.getFile()); } } - else if (each instanceof VFileContentChangeEvent) { - VirtualFile virtualFile = each.getFile(); - if (virtualFile == null) continue; - - if (virtualFile.getLength() < 40 * 1024) { - try { - String content = VfsUtil.loadText(virtualFile); - int crc = MavenUtil.getXmlCrc(content); - virtualFile.putUserData(CONTENT_CRC_KEY, crc); - } - catch (IOException e) { - // Ignore - } - } - } } } } @@ -508,25 +489,7 @@ public class MavenProjectsManagerWatcher { } } else if (each instanceof VFileContentChangeEvent) { - VirtualFile virtualFile = each.getFile(); - if (virtualFile == null) continue; - - Integer oldCrc = virtualFile.getUserData(CONTENT_CRC_KEY); - if (oldCrc != null) { - try { - virtualFile.putUserData(CONTENT_CRC_KEY, null); - - String content = VfsUtil.loadText(virtualFile); - int newCrc = MavenUtil.getXmlCrc(content); - - if (newCrc == oldCrc) continue; - } - catch (IOException e) { - // Ignore - } - } - - updateFile(virtualFile); + updateFile(each.getFile()); } else if (each instanceof VFilePropertyChangeEvent) { if (isRenamed(each)) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java index dc690a54622c..d05fc5fa4122 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java @@ -19,8 +19,6 @@ import com.intellij.codeInsight.template.TemplateManager; import com.intellij.codeInsight.template.impl.TemplateImpl; import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; -import com.intellij.lexer.Lexer; -import com.intellij.lexer.XmlLexer; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; @@ -46,8 +44,6 @@ import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.tree.IElementType; -import com.intellij.psi.xml.XmlTokenType; import com.intellij.util.Function; import com.intellij.util.SystemProperties; import com.intellij.util.containers.ContainerUtil; @@ -69,7 +65,6 @@ import java.util.concurrent.Future; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import java.util.zip.CRC32; public class MavenUtil { public static final String MAVEN_NOTIFICATION_GROUP = "Maven"; @@ -635,42 +630,4 @@ public class MavenUtil { public interface MavenTaskHandler { void waitFor(); } - - public static int getXmlCrc(@NotNull String xmlText) { - String trimmedText = xmlText.trim(); - Lexer lexer = new XmlLexer(); - lexer.start(trimmedText); - - CRC32 crc = new CRC32(); - - while (true) { - IElementType tokenType = lexer.getTokenType(); - if (tokenType == null) break; - - if (XmlTokenType.XML_REAL_WHITE_SPACE == tokenType - || XmlTokenType.XML_WHITE_SPACE == tokenType - || XmlTokenType.COMMENTS.contains(tokenType)) { - crc.update(1); - - do { - lexer.advance(); - tokenType = lexer.getTokenType(); - } - while (XmlTokenType.XML_REAL_WHITE_SPACE == tokenType - || XmlTokenType.XML_WHITE_SPACE == tokenType - || XmlTokenType.COMMENTS.contains(tokenType)); - } - else { - for (int start = lexer.getTokenStart(), end = lexer.getTokenEnd(); start < end; start++) { - char a = trimmedText.charAt(start); - crc.update(a); - crc.update(a >>> 8); - } - - lexer.advance(); - } - } - - return (int)crc.getValue(); - } } From 8e64a24077d0332517e5464b60ed7f8fa8119423 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 13 Jan 2012 13:33:43 +0100 Subject: [PATCH 13/15] quick documentation: do not check dependant module libraries for javadoc roots (IDEA-77608) --- .../src/com/intellij/lang/java/JavaDocumentationProvider.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java index 8fe14eb39185..84a92d657add 100644 --- a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java +++ b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java @@ -674,6 +674,9 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext final List orderEntries = fileIndex.getOrderEntriesForFile(virtualFile); for (OrderEntry orderEntry : orderEntries) { + if (orderEntry instanceof ModuleOrderEntry) { + continue; + } final String[] files = orderEntry.getUrls(JavadocOrderRootType.getInstance()); final List httpRoot = PlatformDocumentationUtil.getHttpRoots(files, relPath); if (httpRoot != null) return httpRoot; From 82511122520e28082efd563e75cfea7d57430631 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Fri, 13 Jan 2012 14:54:52 +0100 Subject: [PATCH 14/15] PerformanceMonitor: do not create empty dirs if not necessary --- .../src/com/intellij/diagnostic/PerformanceWatcher.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/PerformanceWatcher.java b/platform/platform-impl/src/com/intellij/diagnostic/PerformanceWatcher.java index 6922ddedeb4e..717ddecbf122 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/PerformanceWatcher.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/PerformanceWatcher.java @@ -97,7 +97,6 @@ public class PerformanceWatcher implements ApplicationComponent { myLogDir = new File(PathManager.getLogPath() + "/threadDumps-" + myDateFormat.format(new Date()) + "-" + ApplicationInfo.getInstance().getBuild().asString()); - myLogDir.mkdirs(); myCurHangLogDir = myLogDir; try { @@ -165,7 +164,6 @@ public class PerformanceWatcher implements ApplicationComponent { if (myUnresponsiveDuration == UNRESPONSIVE_THRESHOLD) { //System.out.println("EDT is not responding at " + myPrintDateFormat.format(new Date())); myCurHangLogDir = new File(myLogDir, myDateFormat.format(new Date())); - myCurHangLogDir.mkdirs(); } if (myUnresponsiveDuration >= UNRESPONSIVE_THRESHOLD) { dumpThreads(false); @@ -174,7 +172,9 @@ public class PerformanceWatcher implements ApplicationComponent { else { if (myUnresponsiveDuration >= UNRESPONSIVE_THRESHOLD) { //System.out.println("EDT was unresponsive for " + myUnresponsiveDuration + " seconds"); - myCurHangLogDir.renameTo(new File(myLogDir, getLogDirForHang())); + if (myCurHangLogDir.exists()) { + myCurHangLogDir.renameTo(new File(myLogDir, getLogDirForHang())); + } myUnresponsiveDuration = 0; myCurHangLogDir = myLogDir; @@ -199,6 +199,8 @@ public class PerformanceWatcher implements ApplicationComponent { public void dumpThreads(boolean millis) { final String suffix = millis ? "-" + String.valueOf(System.currentTimeMillis()) : ""; + myCurHangLogDir.mkdirs(); + File f = new File(myCurHangLogDir, "threadDump-" + myDateFormat.format(new Date()) + suffix + ".txt"); FileOutputStream fos; try { From 1d2514b11ce1948353708f14e403f4e89bf7ea28 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Fri, 13 Jan 2012 17:56:20 +0300 Subject: [PATCH 15/15] IDEA-68102 (maven: don't validate outputDirectory) --- .../org/jetbrains/idea/maven/dom/model/MavenDomBuild.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/MavenDomBuild.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/MavenDomBuild.java index 361d0fbcff8c..91b6a20332ec 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/MavenDomBuild.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/MavenDomBuild.java @@ -88,7 +88,7 @@ public interface MavenDomBuild extends MavenDomBuildBase { */ @NotNull @Required(value = false, nonEmpty = true) - @Convert(value = PathReferenceConverter.class, soft = false) + @Convert(value = PathReferenceConverter.class, soft = true) GenericDomValue getOutputDirectory(); /** @@ -102,7 +102,7 @@ public interface MavenDomBuild extends MavenDomBuildBase { */ @NotNull @Required(value = false, nonEmpty = true) - @Convert(value = PathReferenceConverter.class, soft = false) + @Convert(value = PathReferenceConverter.class, soft = true) GenericDomValue getTestOutputDirectory(); /**