From ea161b35d315c63aa674841eaf985ebf571c6111 Mon Sep 17 00:00:00 2001 From: Maxime Date: Sat, 2 May 2015 23:57:39 +0200 Subject: [PATCH 01/28] IDEA-139903 TaskManagement: Trello: Change 'number' placeholder in commit message --- .../src/com/intellij/tasks/trello/TrelloTask.java | 6 ++++++ .../src/com/intellij/tasks/trello/model/TrelloCard.java | 9 +++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloTask.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloTask.java index 57a28c08b95b..7f36ddd8c4dd 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloTask.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloTask.java @@ -120,4 +120,10 @@ public class TrelloTask extends Task { public TaskRepository getRepository() { return myRepository; } + + @NotNull + @Override + public String getNumber() { + return myCard.getIdShort(); + } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/model/TrelloCard.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/model/TrelloCard.java index 668ab361e25d..137c82a9fb70 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/model/TrelloCard.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/model/TrelloCard.java @@ -36,9 +36,9 @@ import static com.intellij.tasks.trello.model.TrelloLabel.LabelColor; @SuppressWarnings("UnusedDeclaration") public class TrelloCard extends TrelloModel { - public static final String REQUIRED_FIELDS = "closed,desc,idMembers,idBoard,idList,labels,name,url,dateLastActivity"; + public static final String REQUIRED_FIELDS = "closed,desc,idMembers,idBoard,idList,idShort,labels,name,url,dateLastActivity"; - private String idBoard, idList; + private String idBoard, idList, idShort; private List idMembers; private String name; @SerializedName("desc") @@ -77,6 +77,11 @@ public class TrelloCard extends TrelloModel { return idList; } + @NotNull + public String getIdShort() { + return idShort; + } + @NotNull public List getIdMembers() { return idMembers; From 96de0f83f4c87fe66612c69b8914c9fc154334b1 Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Thu, 7 May 2015 16:07:09 +0300 Subject: [PATCH 02/28] [vcs-log] fix empty Author field in table when only an email was specified IDEA-137361 --- .../intellij/vcs/log/ui/tables/GraphTableModel.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java index 476bab69af06..d76862ffb3d9 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java @@ -10,7 +10,10 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.DateFormatUtil; -import com.intellij.vcs.log.*; +import com.intellij.vcs.log.Hash; +import com.intellij.vcs.log.VcsFullCommitDetails; +import com.intellij.vcs.log.VcsRef; +import com.intellij.vcs.log.VcsShortCommitDetails; import com.intellij.vcs.log.data.LoadingDetails; import com.intellij.vcs.log.data.VcsLogDataHolder; import com.intellij.vcs.log.data.VisiblePack; @@ -157,6 +160,7 @@ public class GraphTableModel extends AbstractTableModel { /** * Requests the proper data provider to load more data from the log & recreate the model. + * * @param onLoaded will be called upon task completion on the EDT. */ public void requestToLoadMore(@NotNull Runnable onLoaded) { @@ -183,7 +187,9 @@ public class GraphTableModel extends AbstractTableModel { return ""; } else { - return data.getAuthor().getName() + (data.getAuthor().equals(data.getCommitter()) ? "" : "*"); + String authorString = data.getAuthor().getName(); + if (authorString.isEmpty()) authorString = data.getAuthor().getEmail(); + return authorString + (data.getAuthor().equals(data.getCommitter()) ? "" : "*"); } case DATE_COLUMN: if (data == null || data.getAuthorTime() < 0) { @@ -208,6 +214,7 @@ public class GraphTableModel extends AbstractTableModel { * Returns Changes for commits at selected rows.
* Rows are given in the order as they appear in the table, i. e. in reverse chronological order.
* Changes can be returned as-is, i.e. with duplicate changes for a single file. + * * @return Changes selected in all rows, or null if this data is not ready yet. */ @Nullable From d95cd6665229a79c5bb622ec2982beac433179a6 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 8 May 2015 16:36:40 +0200 Subject: [PATCH 03/28] junit sm runner: remember parents for every description to be able to restore the state and be always in sync with the initial tree (IDEA-135907) --- .../JUnitTreeByDescriptionHierarchyTest.java | 76 +++++--- .../src/com/intellij/junit4/SMTestSender.java | 162 +++++++----------- 2 files changed, 109 insertions(+), 129 deletions(-) diff --git a/plugins/junit/test/com/intellij/execution/junit/JUnitTreeByDescriptionHierarchyTest.java b/plugins/junit/test/com/intellij/execution/junit/JUnitTreeByDescriptionHierarchyTest.java index d46dff96d663..c5c051fe47bb 100644 --- a/plugins/junit/test/com/intellij/execution/junit/JUnitTreeByDescriptionHierarchyTest.java +++ b/plugins/junit/test/com/intellij/execution/junit/JUnitTreeByDescriptionHierarchyTest.java @@ -65,26 +65,25 @@ public class JUnitTreeByDescriptionHierarchyTest { "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" + - "##teamcity[testSuiteFinished name='root']\n" + - "##teamcity[testSuiteStarted name ='TestA']\n" + - "##teamcity[testSuiteStarted name ='|[0|]']\n" + + "##teamcity[testSuiteStarted name='TestA']\n" + + "##teamcity[testSuiteStarted name='|[0|]']\n" + "##teamcity[testStarted name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" + "\n" + "##teamcity[testFinished name='testName|[0|]']\n" + "##teamcity[testSuiteFinished name='|[0|]']\n" + - "##teamcity[testSuiteStarted name ='|[1|]']\n" + + "##teamcity[testSuiteStarted name='|[1|]']\n" + "##teamcity[testStarted name='testName|[1|]' locationHint='java:test://a.TestA.testName|[1|]']\n" + "\n" + "##teamcity[testFinished name='testName|[1|]']\n" + "##teamcity[testSuiteFinished name='|[1|]']\n" + "##teamcity[testSuiteFinished name='TestA']\n" + - "##teamcity[testSuiteStarted name ='TestB']\n" + - "##teamcity[testSuiteStarted name ='|[0|]']\n" + + "##teamcity[testSuiteStarted name='TestB']\n" + + "##teamcity[testSuiteStarted name='|[0|]']\n" + "##teamcity[testStarted name='testName|[0|]' locationHint='java:test://a.TestB.testName|[0|]']\n" + "\n" + "##teamcity[testFinished name='testName|[0|]']\n" + "##teamcity[testSuiteFinished name='|[0|]']\n" + - "##teamcity[testSuiteStarted name ='|[1|]']\n" + + "##teamcity[testSuiteStarted name='|[1|]']\n" + "##teamcity[testStarted name='testName|[1|]' locationHint='java:test://a.TestB.testName|[1|]']\n" + "\n" + "##teamcity[testFinished name='testName|[1|]']\n" + @@ -109,17 +108,16 @@ public class JUnitTreeByDescriptionHierarchyTest { //start "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'TestA' comment = 'a' location = 'java:suite://a.TestA']\n" + - "##teamcity[testSuiteStarted name ='|[0|]']\n" + + "##teamcity[testSuiteStarted name='|[0|]']\n" + "##teamcity[testStarted name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" + "\n" + "##teamcity[testFinished name='testName|[0|]']\n" + "##teamcity[testSuiteFinished name='|[0|]']\n" + - "##teamcity[testSuiteStarted name ='|[1|]']\n" + + "##teamcity[testSuiteStarted name='|[1|]']\n" + "##teamcity[testStarted name='testName|[1|]' locationHint='java:test://a.TestA.testName|[1|]']\n" + "\n" + "##teamcity[testFinished name='testName|[1|]']\n" + - "##teamcity[testSuiteFinished name='|[1|]']\n" + - "##teamcity[testSuiteFinished name='TestA']\n"); + "##teamcity[testSuiteFinished name='|[1|]']\n"); } @Test @@ -154,16 +152,15 @@ public class JUnitTreeByDescriptionHierarchyTest { //started "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" + - "##teamcity[testSuiteFinished name='root']\n" + - "##teamcity[testSuiteStarted name ='ASuite1']\n" + - "##teamcity[testSuiteStarted name ='ATest']\n" + + "##teamcity[testSuiteStarted name='ASuite1']\n" + + "##teamcity[testSuiteStarted name='ATest']\n" + "##teamcity[testStarted name='test1' locationHint='java:test://ATest.test1']\n" + "\n" + "##teamcity[testFinished name='test1']\n" + "##teamcity[testSuiteFinished name='ATest']\n" + "##teamcity[testSuiteFinished name='ASuite1']\n" + - "##teamcity[testSuiteStarted name ='ASuite2']\n" + - "##teamcity[testSuiteStarted name ='ATest']\n" + + "##teamcity[testSuiteStarted name='ASuite2']\n" + + "##teamcity[testSuiteStarted name='ATest']\n" + "##teamcity[testStarted name='test1' locationHint='java:test://ATest.test1']\n" + "\n" + "##teamcity[testFinished name='test1']\n" + @@ -204,8 +201,37 @@ public class JUnitTreeByDescriptionHierarchyTest { "##teamcity[rootName name = 'TestA' location = 'java:suite://TestA']\n" + "##teamcity[testStarted name='testName' locationHint='java:test://TestA.testName']\n" + "\n" + - "##teamcity[testFinished name='testName']\n" + - "##teamcity[testSuiteFinished name='TestA']\n"); + "##teamcity[testFinished name='testName']\n"); + } + + @Test + public void testParameterizedTestsUpsideDown() throws Exception { + final Description aTestClass = Description.createSuiteDescription("ATest"); + final ArrayList tests = new ArrayList(); + final Description testMethod = Description.createSuiteDescription("testName"); + aTestClass.addChild(testMethod); + for (String paramName : new String[]{"[0]", "[1]"}) { + final Description testDescription = Description.createTestDescription("ATest", "testName" + paramName); + tests.add(testDescription); + testMethod.addChild(testDescription); + } + doTest(aTestClass, tests, + "##teamcity[suiteTreeStarted name='testName' locationHint='java:suite://testName']\n" + + "##teamcity[suiteTreeNode name='testName|[0|]' locationHint='java:test://ATest.testName|[0|]']\n" + + "##teamcity[suiteTreeNode name='testName|[1|]' locationHint='java:test://ATest.testName|[1|]']\n" + + "##teamcity[suiteTreeEnded name='testName']\n", + + + "##teamcity[enteredTheMatrix]\n" + + "##teamcity[rootName name = 'ATest' location = 'java:suite://ATest']\n" + + "##teamcity[testSuiteStarted name='testName']\n" + + "##teamcity[testStarted name='testName|[0|]' locationHint='java:test://ATest.testName|[0|]']\n" + + "\n" + + "##teamcity[testFinished name='testName|[0|]']\n" + + "##teamcity[testStarted name='testName|[1|]' locationHint='java:test://ATest.testName|[1|]']\n" + + "\n" + + "##teamcity[testFinished name='testName|[1|]']\n" + + "##teamcity[testSuiteFinished name='testName']\n"); } @Test @@ -240,21 +266,20 @@ public class JUnitTreeByDescriptionHierarchyTest { //start "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" + - "##teamcity[testSuiteFinished name='root']\n" + - "##teamcity[testSuiteStarted name ='ATest']\n" + - "##teamcity[testSuiteStarted name ='|[0|]']\n" + + "##teamcity[testSuiteStarted name='ATest']\n" + + "##teamcity[testSuiteStarted name='|[0|]']\n" + "##teamcity[testStarted name='testName|[0|]' locationHint='java:test://ATest.testName|[0|]']\n" + "\n" + "##teamcity[testFinished name='testName|[0|]']\n" + "##teamcity[testSuiteFinished name='|[0|]']\n" + - "##teamcity[testSuiteStarted name ='|[1|]']\n" + + "##teamcity[testSuiteStarted name='|[1|]']\n" + "##teamcity[testStarted name='testName|[1|]' locationHint='java:test://ATest.testName|[1|]']\n" + "\n" + "##teamcity[testFinished name='testName|[1|]']\n" + "##teamcity[testSuiteFinished name='|[1|]']\n" + "##teamcity[testSuiteFinished name='ATest']\n" + - "##teamcity[testSuiteStarted name ='suite']\n" + - "##teamcity[testSuiteStarted name ='ATest']\n" + + "##teamcity[testSuiteStarted name='suite']\n" + + "##teamcity[testSuiteStarted name='ATest']\n" + "##teamcity[testStarted name='test' locationHint='java:test://ATest.test']\n" + "\n" + "##teamcity[testFinished name='test']\n" + @@ -298,7 +323,6 @@ public class JUnitTreeByDescriptionHierarchyTest { "##teamcity[rootName name = 'TestA' location = 'java:suite://TestA']\n" + "##teamcity[testStarted name='warning' locationHint='java:test://junit.framework.TestSuite$1.warning']\n" + "\n" + - "##teamcity[testFinished name='warning']\n" + - "##teamcity[testSuiteFinished name='TestA']\n"); + "##teamcity[testFinished name='warning']\n"); } } diff --git a/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java b/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java index 453a60e6fe7c..0523dd50800b 100644 --- a/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java +++ b/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java @@ -41,16 +41,14 @@ public class SMTestSender extends RunListener { public static final String EMPTY_SUITE_NAME = "junit.framework.TestSuite$1"; public static final String EMPTY_SUITE_WARNING = "warning"; - private String myCurrentSuiteName; - private String myCurrentClassName; - private String myParamName; + private List myStartedSuites = new ArrayList(); + private Map myParents = new HashMap(); + private final PrintStream myPrintStream; + private String myRootName; - private PrintStream myPrintStream = System.out; - private final Map myParents = new HashMap(); - private final Map mySuites = new HashMap(); - - - public SMTestSender() {} + public SMTestSender() { + myPrintStream = System.out; + } public SMTestSender(PrintStream printStream) { myPrintStream = printStream; @@ -62,100 +60,69 @@ public class SMTestSender extends RunListener { public void testRunStarted(Description description) throws Exception { myPrintStream.println("##teamcity[enteredTheMatrix]"); - if (myCurrentClassName != null && !myCurrentClassName.startsWith("[")) { - int lastPointIdx = myCurrentClassName.lastIndexOf('.'); - String name = myCurrentClassName; + if (myRootName != null && !myRootName.startsWith("[")) { + int lastPointIdx = myRootName.lastIndexOf('.'); + String name = myRootName; String comment = null; if (lastPointIdx >= 0) { - name = myCurrentClassName.substring(lastPointIdx + 1); - comment = myCurrentClassName.substring(0, lastPointIdx); + name = myRootName.substring(lastPointIdx + 1); + comment = myRootName.substring(0, lastPointIdx); } myPrintStream.println("##teamcity[rootName name = \'" + escapeName(name) + (comment != null ? ("\' comment = \'" + escapeName(comment)) : "") + "\'" + - " location = \'java:suite://" + escapeName(myCurrentClassName) + + " location = \'java:suite://" + escapeName(myRootName) + "\']"); - myCurrentClassName = getShortName(myCurrentClassName); + myRootName = getShortName(myRootName); } } public void testRunFinished(Result result) throws Exception { - if (myParamName != null) { - myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(myParamName) + "\']"); - } - if (myCurrentClassName != null) { - myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(myCurrentClassName) + "\']"); - } - if (myCurrentSuiteName != null) { - myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(getShortName(myCurrentSuiteName)) + "\']"); + for (int i = myStartedSuites.size() - 1; i>= 0; i--) { + Object parent = myStartedSuites.get(i); + myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName((String)parent) + "\']"); } + myStartedSuites.clear(); } public void testStarted(Description description) throws Exception { final String methodName = JUnit4ReflectionUtil.getMethodName(description); final String classFQN = JUnit4ReflectionUtil.getClassName(description); - final int paramStart = methodName.indexOf('['); - if (myParamName != null){ - myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(myParamName) + "\']"); - myParamName = null; - } - final List suites = (List)myParents.get(description); - if (suites != null && !suites.isEmpty()) { - String currentSuite = (String)suites.get(0); - List descriptors = (List)mySuites.get(currentSuite); + final List parents = (List)myParents.get(description); + if (parents != null) { - if (descriptors.isEmpty()) { - currentSuite = (String)suites.get(1); - descriptors = (List)mySuites.get(currentSuite); + List parentsHierarchy = (List)parents.remove(0); + + int idx = 0; + String currentClass; + String currentParent; + while (idx < myStartedSuites.size() && idx < parentsHierarchy.size()) { + currentClass = (String)myStartedSuites.get(idx); + currentParent = getShortName(JUnit4ReflectionUtil.getClassName((Description)parentsHierarchy.get(parentsHierarchy.size() - 1 - idx))); + if (!currentClass.equals(currentParent)) break; + idx++; } - if (!currentSuite.equals(myCurrentSuiteName)) { - finishCurrentSuite(); - myCurrentSuiteName = currentSuite; - myPrintStream.println("##teamcity[testSuiteStarted name =\'" + escapeName(getShortName(myCurrentSuiteName)) + "\']"); + for (int i = myStartedSuites.size() - 1; i >= idx; i--) { + currentClass = (String)myStartedSuites.remove(i); + myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(currentClass) + "\']"); } - descriptors.remove(description); - } - else if (myCurrentSuiteName != null){ - finishCurrentSuite(); - myCurrentSuiteName = null; - } - - String className = getShortName(classFQN); - if (!myEmptyTests.isEmpty() && isWarning(methodName, classFQN)) { - className = (String)myEmptyTests.remove(0); - } - - if (!className.equals(myCurrentClassName)) { - if (myCurrentClassName != null) { - myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(myCurrentClassName) + "\']"); - } - myCurrentClassName = className; - myPrintStream.println("##teamcity[testSuiteStarted name =\'" + escapeName(myCurrentClassName) + "\']"); - } - if (paramStart > -1) { - final String paramName = methodName.substring(paramStart, methodName.length()); - if (!paramName.equals(myParamName)) { - myParamName = paramName; - myPrintStream.println("##teamcity[testSuiteStarted name =\'" + escapeName(myParamName) + "\']"); + for (int i = idx; i < parentsHierarchy.size(); i++) { + Description parent = (Description)parentsHierarchy.get(parentsHierarchy.size() - 1 - i); + final String className = getShortName(JUnit4ReflectionUtil.getClassName(parent)); + if (!className.equals(myRootName)) { + myPrintStream.println("##teamcity[testSuiteStarted name=\'" + escapeName(className) + "\']"); + myStartedSuites.add(className); + } } } + myPrintStream.println("##teamcity[testStarted name=\'" + escapeName(methodName) + "\' " + getTestMethodLocation(methodName, classFQN) + "]"); } - private void finishCurrentSuite() { - if (myCurrentClassName != null) { - myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(myCurrentClassName) + "\']"); - myCurrentClassName = null; - } - if (myCurrentSuiteName != null) { - myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(getShortName(myCurrentSuiteName)) + "\']"); - } - } - public void testFinished(Description description) throws Exception { myPrintStream.println("\n##teamcity[testFinished name=\'" + escapeName(JUnit4ReflectionUtil.getMethodName(description)) + "\']"); } @@ -249,39 +216,29 @@ public class SMTestSender extends RunListener { return messageLength < threshold; } - private final List myEmptyTests = new ArrayList(); - - private void sendTree(Description description, Description parent, Description suiteParent) { + private void sendTree(Description description, Description parent, List currentParents) { + List pParents = new ArrayList(3); + pParents.addAll(currentParents); + if (parent != null && !myRootName.equals(JUnit4ReflectionUtil.getClassName(parent))) { + pParents.add(0, parent); + } + String className = JUnit4ReflectionUtil.getClassName(description); if (description.getChildren().isEmpty()) { final String methodName = JUnit4ReflectionUtil.getMethodName((Description)description); if (methodName != null) { - if (isWarning(methodName, className)) { - className = JUnit4ReflectionUtil.getClassName(parent); - myEmptyTests.add(getShortName(className)); - } - myPrintStream.println("##teamcity[suiteTreeNode name=\'" + escapeName(methodName) + "\' " + getTestMethodLocation(methodName, className) + "]"); - } - - if (suiteParent != null ) { - final String parentFQName = JUnit4ReflectionUtil.getClassName(suiteParent); - if (!myCurrentClassName.equals(parentFQName)) { + if (parent != null) { List parents = (List)myParents.get(description); if (parents == null) { - parents = new ArrayList(); + parents = new ArrayList(1); myParents.put(description, parents); } - if (!parents.contains(parentFQName)) { - parents.add(parentFQName); - } - - List descriptors = (List)mySuites.get(parentFQName); - if (descriptors == null) { - descriptors = new ArrayList(); - mySuites.put(parentFQName, descriptors); - } - descriptors.add(description); + parents.add(pParents); } + if (isWarning(methodName, className)) { + className = JUnit4ReflectionUtil.getClassName(parent); + } + myPrintStream.println("##teamcity[suiteTreeNode name=\'" + escapeName(methodName) + "\' " + getTestMethodLocation(methodName, className) + "]"); } return; @@ -292,8 +249,7 @@ public class SMTestSender extends RunListener { for (Iterator iterator = tests.iterator(); iterator.hasNext(); ) { final Object next = iterator.next(); final Description nextDescription = (Description)next; - final List childTests = nextDescription.getChildren(); - if ((myCurrentClassName == null || !myCurrentClassName.equals(className)) && !pass) { + if ((myRootName == null || !myRootName.equals(className)) && !pass) { pass = true; String locationHint = className; if (isParameter((Description)description)) { @@ -308,7 +264,7 @@ public class SMTestSender extends RunListener { } myPrintStream.println("##teamcity[suiteTreeStarted name=\'" + escapeName(getShortName(className)) + "\' locationHint=\'java:suite://" + escapeName(locationHint) + "\']"); } - sendTree(nextDescription, description, isParameter(description) ? null : childTests.isEmpty() && parent != null ? parent : description); + sendTree(nextDescription, description, pParents); } if (pass) { myPrintStream.println("##teamcity[suiteTreeEnded name=\'" + escapeName(getShortName(JUnit4ReflectionUtil.getClassName((Description)description))) + "\']"); @@ -329,8 +285,8 @@ public class SMTestSender extends RunListener { } public void sendTree(Description description) { - myCurrentClassName = JUnit4ReflectionUtil.getClassName((Description)description); - sendTree(description, null, null); + myRootName = JUnit4ReflectionUtil.getClassName((Description)description); + sendTree(description, null, new ArrayList()); } private static String getShortName(String fqName) { From baa93aaed9ce80e3aea2c6a73879aef62906443f Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Fri, 8 May 2015 17:45:20 +0300 Subject: [PATCH 04/28] diff: try to fallback to patience diff on FilesTooBigForDiffException - add missed check --- .../util/src/com/intellij/util/diff/PatienceIntLCS.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/util/diff/PatienceIntLCS.java b/platform/util/src/com/intellij/util/diff/PatienceIntLCS.java index 672a4b6190f5..947f144e8b3a 100644 --- a/platform/util/src/com/intellij/util/diff/PatienceIntLCS.java +++ b/platform/util/src/com/intellij/util/diff/PatienceIntLCS.java @@ -86,8 +86,12 @@ public class PatienceIntLCS { int matched = matching[0].length; assert matched > 0; + c1 = matching[0][0]; + c2 = matching[1][0]; + + checkReduction(c1, c2); PatienceIntLCS patienceDiff = - new PatienceIntLCS(myFirst, mySecond, start1, matching[0][0], start2, matching[1][0], myChanges1, myChanges2); + new PatienceIntLCS(myFirst, mySecond, start1, c1, start2, c2, myChanges1, myChanges2); patienceDiff.execute(); for (int i = 1; i < matching[0].length; i++) { From 3543124c4250a97399c087b7bd411a88080bd01b Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 8 May 2015 16:40:10 +0200 Subject: [PATCH 05/28] vcs test cases moved to vcs-impl module to avoid circular dependency between vcs-impl and testFramework --- platform/testFramework/testFramework.iml | 7 +- .../ExternalChangesDetectionVcsTest.java | 211 +++++++++++ .../committed/VcsEventsListenerTest.java | 355 ++++++++++++++++++ .../vcs/AbstractJunitVcsTestCase.java | 0 .../vcs/AbstractVcsTestCase.java | 0 5 files changed, 569 insertions(+), 4 deletions(-) create mode 100644 platform/vcs-impl/testSrc/com/intellij/openapi/vcs/changes/committed/ExternalChangesDetectionVcsTest.java create mode 100644 platform/vcs-impl/testSrc/com/intellij/openapi/vcs/changes/committed/VcsEventsListenerTest.java rename platform/{testFramework => vcs-impl}/testSrc/com/intellij/testFramework/vcs/AbstractJunitVcsTestCase.java (100%) rename platform/{testFramework => vcs-impl}/testSrc/com/intellij/testFramework/vcs/AbstractVcsTestCase.java (100%) diff --git a/platform/testFramework/testFramework.iml b/platform/testFramework/testFramework.iml index 19a4097b1f15..bb99b4dbda56 100644 --- a/platform/testFramework/testFramework.iml +++ b/platform/testFramework/testFramework.iml @@ -14,12 +14,12 @@ - + - + @@ -27,5 +27,4 @@ - - + \ No newline at end of file diff --git a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/changes/committed/ExternalChangesDetectionVcsTest.java b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/changes/committed/ExternalChangesDetectionVcsTest.java new file mode 100644 index 000000000000..ece7f752ddc7 --- /dev/null +++ b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/changes/committed/ExternalChangesDetectionVcsTest.java @@ -0,0 +1,211 @@ +package com.intellij.openapi.vcs.changes.committed; + +import com.intellij.ide.startup.impl.StartupManagerImpl; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.changes.*; +import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; +import com.intellij.testFramework.fixtures.TempDirTestFixture; +import com.intellij.testFramework.vcs.AbstractJunitVcsTestCase; +import com.intellij.util.Processor; +import com.intellij.util.ui.UIUtil; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.util.List; +import java.util.regex.Pattern; + +/** + * @author irengrig + */ +public class ExternalChangesDetectionVcsTest extends AbstractJunitVcsTestCase { + private MockAbstractVcs myVcs; + private ProjectLevelVcsManagerImpl myVcsManager; + private LocalFileSystem myLFS; + private ChangeListManager myChangeListManager; + private VcsDirtyScopeManager myVcsDirtyScopeManager; + private TempDirTestFixture myTempDirTestFixture; + private File myClientRoot; + + @Before + public void setUp() throws Exception { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + try { + final IdeaTestFixtureFactory fixtureFactory = IdeaTestFixtureFactory.getFixtureFactory(); + myTempDirTestFixture = fixtureFactory.createTempDirTestFixture(); + myTempDirTestFixture.setUp(); + + myClientRoot = new File(myTempDirTestFixture.getTempDirPath(), "clientroot"); + myClientRoot.mkdir(); + + initProject(myClientRoot, ExternalChangesDetectionVcsTest.this.getTestName()); + + ((StartupManagerImpl)StartupManager.getInstance(myProject)).runPostStartupActivities(); + + myVcs = new MockAbstractVcs(myProject); + myVcs.setChangeProvider(new MyMockChangeProvider()); + myVcsManager = (ProjectLevelVcsManagerImpl)ProjectLevelVcsManager.getInstance(myProject); + myVcsManager.registerVcs(myVcs); + myVcsManager.setDirectoryMapping("", myVcs.getName()); + + myLFS = LocalFileSystem.getInstance(); + myChangeListManager = ChangeListManager.getInstance(myProject); + ((ProjectComponent)myChangeListManager).projectOpened(); + myVcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject); + ((ProjectComponent)myVcsDirtyScopeManager).projectOpened(); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + } + + @After + public void tearDown() throws Exception { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + try { + myVcsManager.unregisterVcs(myVcs); + ((ProjectComponent)myChangeListManager).projectClosed(); + ((ProjectComponent)myVcsDirtyScopeManager).projectClosed(); + + tearDownProject(); + if (myTempDirTestFixture != null) { + myTempDirTestFixture.tearDown(); + myTempDirTestFixture = null; + } + FileUtil.delete(myClientRoot); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + } + + @Test + public void testDeletion() throws Exception { + final File f = new File(myClientRoot, "f.txt"); + f.createNewFile(); + final VirtualFile vf = myLFS.refreshAndFindFileByIoFile(f); + myChangeListManager.ensureUpToDate(false); + ((ChangeListManagerImpl) myChangeListManager).getUnversionedFiles().contains(vf); + FileUtil.delete(f); + myWorkingCopyDir.refresh(false, true); + myChangeListManager.ensureUpToDate(false); + ((ChangeListManagerImpl) myChangeListManager).getUnversionedFiles().isEmpty(); + } + + @Test + public void testGeneration() throws Exception { + for (int i = 0; i < 100; i++) { + final File f = new File(myClientRoot, "f" + i + ".txt"); + f.createNewFile(); + } + myWorkingCopyDir.refresh(false, true); + myChangeListManager.ensureUpToDate(false); + final List unversionedFiles = ((ChangeListManagerImpl)myChangeListManager).getUnversionedFiles(); + final Pattern pattern = Pattern.compile("f([0-9])+\\.txt"); + int cnt = 0; + for (VirtualFile unversionedFile : unversionedFiles) { + if (VfsUtil.isAncestor(myWorkingCopyDir, unversionedFile, true)) { + ++ cnt; + Assert.assertTrue(pattern.matcher(unversionedFile.getName()).matches()); + } + } + Assert.assertEquals(100, cnt); + } + + /*@Test + public void testMoveDir() throws Exception { + final File root = new File(myClientRoot, "was"); + root.mkdir(); + for (int i = 0; i < 10; i++) { + final File dir = new File(root, "dir" + i); + dir.mkdir(); + for (int j = 0; j < 10; j++) { + final File f = new File(dir, "f" + j + ".txt"); + f.createNewFile(); + } + } + myWorkingCopyDir.refresh(false, true); + myChangeListManager.ensureUpToDate(false); + List unversionedFiles = ((ChangeListManagerImpl)myChangeListManager).getUnversionedFiles(); + final Pattern pattern = Pattern.compile("f([0-9])+\\.txt"); + final Pattern patternDir = Pattern.compile("dir([0-9])+"); + int cnt = 0; + for (VirtualFile unversionedFile : unversionedFiles) { + if (VfsUtil.isAncestor(myWorkingCopyDir, unversionedFile, true) && (! "was".equals(unversionedFile.getName()))) { + ++ cnt; + Assert.assertTrue(pattern.matcher(unversionedFile.getName()).matches() || patternDir.matcher(unversionedFile.getName()).matches()); + } + } + Assert.assertEquals(110, cnt); + final File renamedFile = new File(myClientRoot, "newName"); + FileUtil.copyDir(root, renamedFile); + FileUtil.delete(root); + + myWorkingCopyDir.refresh(false, true); + myChangeListManager.ensureUpToDate(false); + unversionedFiles = ((ChangeListManagerImpl)myChangeListManager).getUnversionedFiles(); + + cnt = 0; + for (VirtualFile unversionedFile : unversionedFiles) { + if (VfsUtil.isAncestor(myWorkingCopyDir, unversionedFile, true) && (! "newName".equals(unversionedFile.getName()))) { + ++ cnt; + Assert.assertTrue((pattern.matcher(unversionedFile.getName()).matches() || patternDir.matcher(unversionedFile.getName()).matches())); + if (unversionedFile.getPath().indexOf("newName") == -1) { + System.out.println("wrong " + unversionedFile.getPath()); + } + } + } + Assert.assertEquals(110, cnt); + }*/ + + private static class MyMockChangeProvider implements ChangeProvider { + @Override + public void doCleanup(List files) { + } + + @Override + public void getChanges(VcsDirtyScope dirtyScope, + final ChangelistBuilder builder, + ProgressIndicator progress, + ChangeListManagerGate addGate) throws VcsException { + for (FilePath path : dirtyScope.getDirtyFiles()) { + builder.processUnversionedFile(path.getVirtualFile()); + } + final Processor processor = new Processor() { + @Override + public boolean process(final VirtualFile vf) { + builder.processUnversionedFile(vf); + return true; + } + }; + for (FilePath dir : dirtyScope.getRecursivelyDirtyDirectories()) { + VfsUtil.processFilesRecursively(dir.getVirtualFile(), processor); + } + } + + @Override + public boolean isModifiedDocumentTrackingRequired() { + return false; + } + } +} diff --git a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/changes/committed/VcsEventsListenerTest.java b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/changes/committed/VcsEventsListenerTest.java new file mode 100644 index 000000000000..f24ad1fed284 --- /dev/null +++ b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/changes/committed/VcsEventsListenerTest.java @@ -0,0 +1,355 @@ +package com.intellij.openapi.vcs.changes.committed; + +import com.intellij.ide.startup.impl.StartupManagerImpl; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vcs.*; +import com.intellij.openapi.vcs.changes.Change; +import com.intellij.openapi.vcs.changes.ChangeList; +import com.intellij.openapi.vcs.changes.ChangeListManager; +import com.intellij.openapi.vcs.checkin.CheckinEnvironment; +import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl; +import com.intellij.openapi.vcs.rollback.RollbackEnvironment; +import com.intellij.openapi.vcs.rollback.RollbackProgressListener; +import com.intellij.openapi.vcs.ui.RefreshableOnComponent; +import com.intellij.openapi.vcs.update.SequentialUpdatesContext; +import com.intellij.openapi.vcs.update.UpdateEnvironment; +import com.intellij.openapi.vcs.update.UpdateSession; +import com.intellij.openapi.vcs.update.UpdatedFiles; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.testFramework.UsefulTestCase; +import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; +import com.intellij.testFramework.fixtures.TempDirTestFixture; +import com.intellij.testFramework.vcs.AbstractJunitVcsTestCase; +import com.intellij.util.NullableFunction; +import com.intellij.util.PairConsumer; +import com.intellij.util.ui.UIUtil; +import junit.framework.Assert; +import org.jetbrains.annotations.NotNull; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * @author irengrig + * Date: 12/21/10 + * Time: 2:03 PM + */ +public class VcsEventsListenerTest extends AbstractJunitVcsTestCase { + private AbstractVcs myVcs; + private ProjectLevelVcsManagerImpl myVcsManager; + private ChangeListManager myChangeListManager; + private TempDirTestFixture myTempDirFixture; + private File myClientRoot; + + @Before + public void setUp() { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + try { + final IdeaTestFixtureFactory fixtureFactory = IdeaTestFixtureFactory.getFixtureFactory(); + myTempDirFixture = fixtureFactory.createTempDirTestFixture(); + myTempDirFixture.setUp(); + + myClientRoot = new File(myTempDirFixture.getTempDirPath(), "clientroot"); + myClientRoot.mkdir(); + + initProject(myClientRoot, VcsEventsListenerTest.this.getTestName()); + + ((StartupManagerImpl)StartupManager.getInstance(myProject)).runPostStartupActivities(); + + myChangeListManager = ChangeListManager.getInstance(myProject); + myVcs = VcsActiveEnvironmentsProxy.proxyVcs(new MyVcs(myProject, "mock")); + myVcsManager = (ProjectLevelVcsManagerImpl)ProjectLevelVcsManager.getInstance(myProject); + myVcsManager.registerVcs(myVcs); + myVcsManager.setDirectoryMapping(myWorkingCopyDir.getPath(), myVcs.getName()); + + ((ProjectComponent)myChangeListManager).projectOpened(); + } + catch (Exception e) { + tearDown(); + throw new RuntimeException(e); + } + } + }); + } + + @After + public void tearDown() { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + try { + if (myVcsManager != null && myVcs != null) { + myVcsManager.unregisterVcs(myVcs); + } + + ((ProjectComponent)myChangeListManager).projectClosed(); + tearDownProject(); + if (myTempDirFixture != null) { + myTempDirFixture.tearDown(); + myTempDirFixture = null; + } + FileUtil.delete(myClientRoot); + } + catch (Exception e) { + throw new RuntimeException(e); + } + finally { + try { + UsefulTestCase.clearFields(this); + } + catch (IllegalAccessException e) { + //noinspection ThrowFromFinallyBlock + throw new RuntimeException(e); + } + } + } + }); + } + + @Test + public void testSimpleListeningWithProxy() throws Exception { + final VcsEventsListenerManager manager = myVcsManager.getVcsEventsListenerManager(); + final List list = Arrays.asList(new VirtualFile[]{myWorkingCopyDir}); + final MyCheckinListener listener = new MyCheckinListener(list); + final Object key = manager.addCheckin(new ForwardingListener(listener)); + + myVcs.getCheckinEnvironment().scheduleUnversionedFilesForAddition(list); + + Assert.assertTrue(listener.isChecked()); + listener.assertCheckOk(); + + listener.reset(); + + manager.removeCheckin(key); + listener.reset(); + myVcs.getCheckinEnvironment().scheduleUnversionedFilesForAddition(list); + Assert.assertFalse(listener.isChecked()); + } + + @Test + public void testSimpleListeningWithoutProxy() throws Exception { + myVcsManager.setDirectoryMapping(myWorkingCopyDir.getPath(), "svn"); + + testSimpleListeningWithProxy(); + } + + private static class MyVcs extends MockAbstractVcs { + private MyVcs(Project project, String name) { + super(project, name); + } + + @Override + protected UpdateEnvironment createUpdateEnvironment() { + return new UpdateEnvironment() { + @Override + public void fillGroups(UpdatedFiles updatedFiles) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @NotNull + @Override + public UpdateSession updateDirectories(@NotNull FilePath[] contentRoots, + UpdatedFiles updatedFiles, + ProgressIndicator progressIndicator, + @NotNull Ref context) throws ProcessCanceledException { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Configurable createConfigurable(Collection files) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public boolean validateOptions(Collection roots) { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + }; + } + + @Override + protected RollbackEnvironment createRollbackEnvironment() { + return new RollbackEnvironment() { + @Override + public String getRollbackOperationName() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void rollbackChanges(List changes, + List vcsExceptions, + @NotNull RollbackProgressListener listener) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void rollbackMissingFileDeletion(List files, + List exceptions, + RollbackProgressListener listener) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void rollbackModifiedWithoutCheckout(List files, + List exceptions, + RollbackProgressListener listener) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void rollbackIfUnchanged(VirtualFile file) { + //To change body of implemented methods use File | Settings | File Templates. + } + }; + } + + @Override + protected CheckinEnvironment createCheckinEnvironment() { + return new CheckinEnvironment() { + @Override + public RefreshableOnComponent createAdditionalOptionsPanel(CheckinProjectPanel panel, + PairConsumer additionalDataConsumer) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public String getDefaultMessageFor(FilePath[] filesToCheckin) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public String getHelpId() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public String getCheckinOperationName() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public List commit(List changes, String preparedComment) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public List commit(List changes, + String preparedComment, + @NotNull NullableFunction parametersHolder, Set feedback) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public List scheduleMissingFileForDeletion(List files) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public List scheduleUnversionedFilesForAddition(List files) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public boolean keepChangeListAfterCommit(ChangeList changeList) { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public boolean isRefreshAfterCommitNeeded() { + return true; + } + }; + } + } + + private static class MyCheckinListener implements CheckinEnvironment { + private boolean myChecked; + private boolean myAssertOk; + private final List myCheckList; + + public MyCheckinListener(final List checkList) { + myCheckList = checkList; + myChecked = false; + myAssertOk = true; + } + + @Override + public RefreshableOnComponent createAdditionalOptionsPanel(CheckinProjectPanel panel, + PairConsumer additionalDataConsumer) { + return null; + } + @Override + public String getDefaultMessageFor(FilePath[] filesToCheckin) { + return null; + } + @Override + public String getHelpId() { + return null; + } + @Override + public String getCheckinOperationName() { + return null; + } + @Override + public List commit(List changes, String preparedComment) { + return null; + } + + @Override + public List commit(List changes, + String preparedComment, + @NotNull NullableFunction parametersHolder, Set feedback) { + return null; + } + + @Override + public List scheduleMissingFileForDeletion(List files) { + return null; + } + + @Override + public List scheduleUnversionedFilesForAddition(List files) { + myChecked = true; + myAssertOk = myCheckList.equals(files); + return null; + } + + @Override + public boolean keepChangeListAfterCommit(ChangeList changeList) { + return false; + } + + @Override + public boolean isRefreshAfterCommitNeeded() { + return true; + } + + public boolean isChecked() { + return myChecked; + } + + public void assertCheckOk() { + Assert.assertTrue(myAssertOk); + } + + public void reset() { + myAssertOk = true; + myChecked = false; + } + } +} diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/vcs/AbstractJunitVcsTestCase.java b/platform/vcs-impl/testSrc/com/intellij/testFramework/vcs/AbstractJunitVcsTestCase.java similarity index 100% rename from platform/testFramework/testSrc/com/intellij/testFramework/vcs/AbstractJunitVcsTestCase.java rename to platform/vcs-impl/testSrc/com/intellij/testFramework/vcs/AbstractJunitVcsTestCase.java diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/vcs/AbstractVcsTestCase.java b/platform/vcs-impl/testSrc/com/intellij/testFramework/vcs/AbstractVcsTestCase.java similarity index 100% rename from platform/testFramework/testSrc/com/intellij/testFramework/vcs/AbstractVcsTestCase.java rename to platform/vcs-impl/testSrc/com/intellij/testFramework/vcs/AbstractVcsTestCase.java From f4e1e4e5e98504ccb028573975cd2bbf30ce3339 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 8 May 2015 15:26:59 +0200 Subject: [PATCH 06/28] no dependency for util except classloader classes --- .../util/src/com/intellij/util/lang/JarMemoryLoader.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/platform/util/src/com/intellij/util/lang/JarMemoryLoader.java b/platform/util/src/com/intellij/util/lang/JarMemoryLoader.java index f012f1fc6526..497db669ba7f 100644 --- a/platform/util/src/com/intellij/util/lang/JarMemoryLoader.java +++ b/platform/util/src/com/intellij/util/lang/JarMemoryLoader.java @@ -15,9 +15,7 @@ */ package com.intellij.util.lang; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.util.containers.hash.HashMap; -import com.intellij.util.io.zip.ZipShort; +import com.intellij.openapi.util.io.FileUtilRt; import org.jetbrains.annotations.Nullable; import sun.misc.Resource; @@ -26,6 +24,7 @@ import java.io.IOException; import java.net.URL; import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -64,8 +63,8 @@ public class JarMemoryLoader { ZipEntry sizeEntry = entries.nextElement(); if (sizeEntry == null || !sizeEntry.getName().equals(SIZE_ENTRY)) return null; - byte[] bytes = FileUtil.loadBytes(zipFile.getInputStream(sizeEntry), 2); - int size = ZipShort.getValue(bytes); + byte[] bytes = FileUtilRt.loadBytes(zipFile.getInputStream(sizeEntry), 2); + int size = ((bytes[1] & 0xFF) << 8) + (bytes[0] & 0xFF); JarMemoryLoader loader = new JarMemoryLoader(); for (int i = 0; i < size && entries.hasMoreElements(); i++) { From 9e3c44b2fec06eb8d08795059b8d4f3f8641ac3f Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 8 May 2015 15:50:12 +0200 Subject: [PATCH 07/28] [optimization] we need to use cached ZipFile's in UrlClassLoader that is switched on when canLockJar = true --- .../src/com/intellij/ide/BootstrapClassLoaderUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java b/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java index 6e313990e112..9dab9c62b3a3 100644 --- a/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java +++ b/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java @@ -58,7 +58,7 @@ public class BootstrapClassLoaderUtil extends ClassUtilCore { UrlClassLoader.Builder builder = UrlClassLoader.build() .urls(filterClassPath(new ArrayList(classpath))) - .allowLock(false) + .allowLock() .usePersistentClasspathIndexForLocalClassDirectories() .useCache(); if (Boolean.valueOf(System.getProperty(PROPERTY_ALLOW_BOOTSTRAP_RESOURCES, "true"))) { From cd114b4490f6bd17b03b7e4e736bd87977fcad40 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 8 May 2015 16:54:37 +0200 Subject: [PATCH 08/28] [performance] SoftReference for ZipFile is back, also decreased dependencies slightly --- .../src/com/intellij/util/lang/JarLoader.java | 75 ++++++++++++++----- 1 file changed, 57 insertions(+), 18 deletions(-) diff --git a/platform/util/src/com/intellij/util/lang/JarLoader.java b/platform/util/src/com/intellij/util/lang/JarLoader.java index 68c0bfb5479e..17b8181c619b 100644 --- a/platform/util/src/com/intellij/util/lang/JarLoader.java +++ b/platform/util/src/com/intellij/util/lang/JarLoader.java @@ -17,11 +17,11 @@ package com.intellij.util.lang; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.util.io.URLUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import sun.misc.Resource; +import java.io.File; import java.io.IOException; import java.lang.ref.SoftReference; import java.net.URL; @@ -30,15 +30,18 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; class JarLoader extends Loader { - private final URL myURL; + private final File myCanonicalFile; + private final boolean myCanLockJar; // true implies that the zipfile will not be modified in the lifetime of the JarLoader private SoftReference myMemoryLoader; + private volatile SoftReference myZipFileSoftReference; // Used only when myCanLockJar==true - // todo drop unused parameter JarLoader(URL url, @SuppressWarnings("unused") boolean canLockJar, int index, boolean preloadJarContents) throws IOException { - super(new URL(URLUtil.JAR_PROTOCOL, "", -1, url + "!/"), index); - myURL = url; + super(new URL("jar", "", -1, url + "!/"), index); - ZipFile zipFile = new ZipFile(getFileUrl()); + myCanonicalFile = new File(FileUtil.unquote(url.getFile())).getCanonicalFile(); + myCanLockJar = canLockJar; + + ZipFile zipFile = getZipFile(); // IOException from opening is propagated to caller if zip file isn't valid, try { if (preloadJarContents) { JarMemoryLoader loader = JarMemoryLoader.load(zipFile, getBaseURL()); @@ -48,18 +51,14 @@ class JarLoader extends Loader { } } finally { - zipFile.close(); + releaseZipFile(zipFile); } } - private String getFileUrl() throws IOException { - return FileUtil.unquote(myURL.getFile()); - } - @NotNull @Override public ClasspathCache.LoaderData buildData() throws IOException { - ZipFile zipFile = new ZipFile(getFileUrl()); + ZipFile zipFile = getZipFile(); try { ClasspathCache.LoaderData loaderData = new ClasspathCache.LoaderData(); Enumeration entries = zipFile.entries(); @@ -72,21 +71,21 @@ class JarLoader extends Loader { return loaderData; } finally { - zipFile.close(); + releaseZipFile(zipFile); } } @Override @Nullable Resource getResource(String name, boolean flag) { - JarMemoryLoader loader = com.intellij.reference.SoftReference.dereference(myMemoryLoader); + JarMemoryLoader loader = myMemoryLoader != null? myMemoryLoader.get() : null; if (loader != null) { Resource resource = loader.getResource(name); if (resource != null) return resource; } try { - ZipFile zipFile = new ZipFile(getFileUrl()); + ZipFile zipFile = getZipFile(); try { ZipEntry entry = zipFile.getEntry(name); if (entry != null) { @@ -94,18 +93,58 @@ class JarLoader extends Loader { } } finally { - zipFile.close(); + releaseZipFile(zipFile); } } catch (Exception e) { - Logger.getInstance(JarLoader.class).error("url: " + myURL, e); + error("file: " + myCanonicalFile, e); } return null; } + protected void error(String message, Throwable t) { + //Logger.getLogger(JarLoader.class.getName()).log(Level.SEVERE, message, t); + Logger.getInstance(JarLoader.class).error(message, t); + } + + private void releaseZipFile(ZipFile zipFile) throws IOException { + // Closing of zip file when myCanLockJar=true happens in ZipFile.finalize + if (!myCanLockJar) { + zipFile.close(); + } + } + + @NotNull + private ZipFile getZipFile() throws IOException { + // This code is executed at least 100K times (O(number of classes needed to load)) and it takes considerable time to open ZipFile's + // such number of times so we store reference to ZipFile if we allowed to lock the file (assume it isn't changed) + if (myCanLockJar) { + SoftReference zipFileSoftReference = myZipFileSoftReference; + if(zipFileSoftReference != null) { + ZipFile existingZipFile = zipFileSoftReference.get(); + if (existingZipFile != null) return existingZipFile; + } + synchronized (ourLock) { + zipFileSoftReference = myZipFileSoftReference; + if(zipFileSoftReference != null) { + ZipFile existingZipFile = zipFileSoftReference.get(); + if (existingZipFile != null) return existingZipFile; + } + // ZipFile's native implementation (ZipFile.c, zip_util.c) has path -> file descriptor cache + ZipFile zipFile = new ZipFile(myCanonicalFile); + myZipFileSoftReference = new SoftReference(zipFile); + return zipFile; + } + } else { + return new ZipFile(myCanonicalFile); + } + } + @Override public String toString() { - return "JarLoader [" + myURL + "]"; + return "JarLoader [" + myCanonicalFile + "]"; } + + private static final Object ourLock = new Object(); } From 6a2a3c2ee934e39cb7470528654572fc4bb2a2d1 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Fri, 8 May 2015 18:12:28 +0300 Subject: [PATCH 09/28] Enable resolving to the roots of the modules for Scratch files (PY-15818) Scratch files are now located outside of the project, so foothold PSI elements in them don't allow us to find their modules. For Scratch files we explicitly add the ability to resolve to any of the modules of the project, as we did earlier for the console runner. --- python/src/com/jetbrains/python/psi/PyUtil.java | 7 +++++++ .../python/psi/resolve/QualifiedNameResolverImpl.java | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index 4d104f1c2629..dbe5c44d6bfe 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -23,6 +23,7 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.scratch.ScratchFileService; import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.lang.ASTFactory; import com.intellij.lang.ASTNode; @@ -1803,6 +1804,12 @@ public class PyUtil { return type == builtinCache.getObjectType() || type == builtinCache.getOldstyleClassobjType(); } + public static boolean isInScratchFile(@NotNull PsiElement element) { + final ScratchFileService service = ScratchFileService.getInstance(); + final PsiFile file = element.getContainingFile(); + return service != null && file != null && service.getRootType(file.getVirtualFile()) != null; + } + /** * This helper class allows to collect various information about AST nodes composing {@link PyStringLiteralExpression}. */ diff --git a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java index b073db8c6955..e0ce6f2dfc1a 100644 --- a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java +++ b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java @@ -37,6 +37,7 @@ import com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsUtil; import com.jetbrains.python.console.PydevConsoleRunner; import com.jetbrains.python.facet.PythonPathContributingFacet; import com.jetbrains.python.psi.PyFile; +import com.jetbrains.python.psi.PyUtil; import com.jetbrains.python.psi.impl.PyBuiltinCache; import com.jetbrains.python.psi.impl.PyImportResolver; import com.jetbrains.python.sdk.PySdkUtil; @@ -84,7 +85,7 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso @Override public QualifiedNameResolver fromElement(@NotNull PsiElement foothold) { myContext.setFromElement(foothold); - if (PydevConsoleRunner.isInPydevConsole(foothold)) { + if (PydevConsoleRunner.isInPydevConsole(foothold) || PyUtil.isInScratchFile(foothold)) { withAllModules(); Sdk sdk = PydevConsoleRunner.getConsoleSdk(foothold); if (sdk != null) { From b1168f8d3e656c8a28ceff905926a66c371abc60 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Fri, 8 May 2015 18:17:00 +0300 Subject: [PATCH 10/28] Fixed NPE --- python/src/com/jetbrains/python/psi/PyUtil.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index dbe5c44d6bfe..5ec8c8d0e16b 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -1807,7 +1807,11 @@ public class PyUtil { public static boolean isInScratchFile(@NotNull PsiElement element) { final ScratchFileService service = ScratchFileService.getInstance(); final PsiFile file = element.getContainingFile(); - return service != null && file != null && service.getRootType(file.getVirtualFile()) != null; + if (file != null) { + final VirtualFile virtualFile = file.getVirtualFile(); + return service != null && virtualFile != null && service.getRootType(virtualFile) != null; + } + return false; } /** From cc077fce25b0978cd440650dcda58811881842c1 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 8 May 2015 11:52:35 +0200 Subject: [PATCH 11/28] IDEA-140082 (Garbage text in "Unused declaration" batch inspection result) --- .../src/com/intellij/codeInspection/ex/HTMLComposerImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ex/HTMLComposerImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/ex/HTMLComposerImpl.java index c8a8361b020b..a00ffe6c7f4d 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/ex/HTMLComposerImpl.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/ex/HTMLComposerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -286,7 +286,6 @@ public abstract class HTMLComposerImpl extends HTMLComposer { @Override public void appendListItem(StringBuffer buf, RefElement refElement) { startListItem(buf); - buf.append(CLOSE_TAG); appendElementReference(buf, refElement, true); appendAdditionalListItemInfo(buf, refElement); doneListItem(buf); From df63f2a5aca780ede0f3501941f7816efbe047ac Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 8 May 2015 18:11:46 +0300 Subject: [PATCH 12/28] [git] IDEA-91996 Guess repository if there are no virtual files in the scope --- .../src/git4idea/actions/GitRepositoryAction.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java b/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java index 50ba95a046fb..68d5aba3f6e0 100644 --- a/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java +++ b/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java @@ -15,6 +15,7 @@ */ package git4idea.actions; +import com.intellij.dvcs.repo.Repository; import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; @@ -114,19 +115,18 @@ public abstract class GitRepositoryAction extends DumbAwareAction { if (files != null) { for (VirtualFile file : files) { GitRepositoryManager manager = GitUtil.getRepositoryManager(project); - if (manager == null) { - return false; - } - final GitRepository repositoryForFile = manager.getRepositoryForFile(file); - if (repositoryForFile != null && repositoryForFile.getState() == GitRepository.State.REBASING) { - return true; - } + if (isRebasing(manager.getRepositoryForFile(file))) return true; } } + if (isRebasing(GitBranchUtil.getCurrentRepository(project))) return true; } return false; } + private static boolean isRebasing(@Nullable GitRepository repository) { + return repository != null && repository.getState() == Repository.State.REBASING; + } + /** * Get git roots for the project. The method shows dialogs in the case when roots cannot be retrieved, so it should be called * from the event dispatch thread. From 12ae1f7872ed34d36fdf111b2b0d8dd228c3b204 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 8 May 2015 17:24:55 +0200 Subject: [PATCH 13/28] java sm locator: accept vm class names (IDEA-105556) --- .../testframework/JavaTestLocator.java | 30 ++++++++----------- .../junit/JUnitRerunFailedTestsTest.java | 19 ++++++++++++ 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocator.java b/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocator.java index d4e529772a72..ac4c581f15e9 100644 --- a/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocator.java +++ b/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocator.java @@ -22,10 +22,11 @@ import com.intellij.execution.junit2.info.MethodLocation; import com.intellij.execution.testframework.sm.runner.SMTestLocator; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiManager; import com.intellij.psi.PsiMethod; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.ClassUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -50,32 +51,27 @@ public class JavaTestLocator implements SMTestLocator { path = path.substring(0, idx); } - JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); if (SUITE_PROTOCOL.equals(protocol)) { path = StringUtil.trimEnd(path, "."); - PsiClass[] classes = javaPsiFacade.findClasses(path, scope); - if (classes.length > 0) { + PsiClass aClass = ClassUtil.findPsiClass(PsiManager.getInstance(project), path, null, true, scope); + if (aClass != null) { results = ContainerUtil.newSmartList(); - for (PsiClass aClass : classes) { - results.add(paramName != null ? PsiMemberParameterizedLocation.getParameterizedLocation(aClass, paramName) - : new PsiLocation(project, aClass)); - } + results.add(paramName != null ? PsiMemberParameterizedLocation.getParameterizedLocation(aClass, paramName) + : new PsiLocation(project, aClass)); } } else if (TEST_PROTOCOL.equals(protocol)) { String className = StringUtil.getPackageName(path); if (!StringUtil.isEmpty(className)) { String methodName = StringUtil.getShortName(path); - PsiClass[] classes = javaPsiFacade.findClasses(className, scope); - if (classes.length > 0) { + PsiClass aClass = ClassUtil.findPsiClass(PsiManager.getInstance(project), className, null, true, scope); + if (aClass != null) { results = ContainerUtil.newSmartList(); - for (PsiClass aClass : classes) { - PsiMethod[] methods = aClass.findMethodsByName(methodName, true); - if (methods.length > 0) { - for (PsiMethod method : methods) { - results.add(paramName != null ? new PsiMemberParameterizedLocation(project, method, aClass, paramName) - : MethodLocation.elementInClass(method, aClass)); - } + PsiMethod[] methods = aClass.findMethodsByName(methodName, true); + if (methods.length > 0) { + for (PsiMethod method : methods) { + results.add(paramName != null ? new PsiMemberParameterizedLocation(project, method, aClass, paramName) + : MethodLocation.elementInClass(method, aClass)); } } } diff --git a/plugins/junit/test/com/intellij/execution/junit/JUnitRerunFailedTestsTest.java b/plugins/junit/test/com/intellij/execution/junit/JUnitRerunFailedTestsTest.java index f0273b478608..4a270259d8c0 100644 --- a/plugins/junit/test/com/intellij/execution/junit/JUnitRerunFailedTestsTest.java +++ b/plugins/junit/test/com/intellij/execution/junit/JUnitRerunFailedTestsTest.java @@ -130,4 +130,23 @@ public class JUnitRerunFailedTestsTest extends LightCodeInsightFixtureTestCase }); assertNull(TestMethods.getTestPresentation(testProxy, project, searchScope)); } + + public void testInnerClass() throws Exception { + myFixture.addClass("public class TestClass {\n" + + " public static class Tests extends junit.framework.TestCase {\n" + + " public void testFoo() throws Exception {}\n" + + " }\n" + + "}"); + + final SMTestProxy testProxy = new SMTestProxy("testFoo", false, "java:test://TestClass$Tests.testFoo"); + final Project project = getProject(); + final GlobalSearchScope searchScope = GlobalSearchScope.projectScope(project); + testProxy.setLocator(JavaTestLocator.INSTANCE); + Location location = testProxy.getLocation(project, searchScope); + assertNotNull(location); + PsiElement element = location.getPsiElement(); + assertTrue(element instanceof PsiMethod); + String name = ((PsiMethod)element).getName(); + assertEquals(name, "testFoo"); + } } From 3346704a9b287e121e692220c6ecb70ebdac9864 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 8 May 2015 18:22:34 +0200 Subject: [PATCH 14/28] junit sm runner: ensure testFailed even if getMessage() throws an exception --- .../testFramework/CompositeException.java | 3 ++- .../src/com/intellij/junit4/SMTestSender.java | 21 ++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/CompositeException.java b/platform/testFramework/src/com/intellij/testFramework/CompositeException.java index 59e73bf718d4..4ec1c8b21107 100644 --- a/platform/testFramework/src/com/intellij/testFramework/CompositeException.java +++ b/platform/testFramework/src/com/intellij/testFramework/CompositeException.java @@ -130,7 +130,8 @@ public class CompositeException extends Exception { sb.append(line); line = exceptionProcessor.fun(exception); - if (!line.endsWith("\n")) line += '\n'; + if (line == null) line = "null\n"; + else if (!line.endsWith("\n")) line += '\n'; stringProcessor.process(line); sb.append(line); } diff --git a/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java b/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java index 0523dd50800b..b835081a92b3 100644 --- a/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java +++ b/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java @@ -32,6 +32,8 @@ import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.*; public class SMTestSender extends RunListener { @@ -128,13 +130,22 @@ public class SMTestSender extends RunListener { } public void testFailure(Failure failure) throws Exception { - final String failureMessage = failure.getMessage(); - final String trace = failure.getTrace(); final Map attrs = new HashMap(); attrs.put("name", JUnit4ReflectionUtil.getMethodName(failure.getDescription())); - final ComparisonFailureData notification = createExceptionNotification(failure.getException()); - ComparisonFailureData.registerSMAttributes(notification, trace, failureMessage, attrs); - myPrintStream.println(ServiceMessage.asString(ServiceMessageTypes.TEST_FAILED, attrs)); + try { + final String trace = failure.getTrace(); + final ComparisonFailureData notification = createExceptionNotification(failure.getException()); + ComparisonFailureData.registerSMAttributes(notification, trace, failure.getMessage(), attrs); + } + catch (Throwable e) { + final StringWriter stringWriter = new StringWriter(); + final PrintWriter writer = new PrintWriter(stringWriter); + e.printStackTrace(writer); + ComparisonFailureData.registerSMAttributes(null, stringWriter.toString(), e.getMessage(), attrs); + } + finally { + myPrintStream.println(ServiceMessage.asString(ServiceMessageTypes.TEST_FAILED, attrs)); + } } public void testAssumptionFailure(Failure failure) { From e2306d39759ed777f1af772d32ea4bd57c4870d5 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Fri, 8 May 2015 18:41:28 +0200 Subject: [PATCH 15/28] Save snapshot for remote profiling. --- python/helpers/profiler/prof_util.py | 8 ++++++-- python/helpers/profiler/run_profiler.py | 8 +++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/python/helpers/profiler/prof_util.py b/python/helpers/profiler/prof_util.py index ebdc5be6da62..ca7ff3cab43e 100644 --- a/python/helpers/profiler/prof_util.py +++ b/python/helpers/profiler/prof_util.py @@ -2,6 +2,7 @@ __author__ = 'traff' import threading import os +import tempfile from _prof_imports import Stats, FuncStat, Function class ProfDaemonThread(threading.Thread): @@ -16,9 +17,12 @@ class ProfDaemonThread(threading.Thread): def OnRun(self): pass -def generate_snapshot_filepath(basepath): +def generate_snapshot_filepath(basepath, local_temp_dir=False): if basepath is None: - return None + basepath = 'snapshot' + if local_temp_dir: + basepath = os.path.join(tempfile.gettempdir(), os.path.basename(basepath)) + n = 0 path = basepath + '.pstat' while os.path.exists(path): diff --git a/python/helpers/profiler/run_profiler.py b/python/helpers/profiler/run_profiler.py index 060efaa698a0..b8f707dee994 100644 --- a/python/helpers/profiler/run_profiler.py +++ b/python/helpers/profiler/run_profiler.py @@ -67,7 +67,7 @@ class Profiler(object): def process(self, message): if hasattr(message, 'save_snapshot'): - self.save_snapshot(message.id, generate_snapshot_filepath(message.save_snapshot.filepath) if not remote_run else None) + self.save_snapshot(message.id, generate_snapshot_filepath(message.save_snapshot.filepath, remote_run), remote_run) else: raise AssertionError("Unknown request %s" % dir(message)) @@ -84,7 +84,7 @@ class Profiler(object): pydev_imports.execfile(file, globals, globals) # execute the script self.stop_profiling() - self.save_snapshot(0, generate_snapshot_filepath(base_snapshot_path) if not remote_run else None) + self.save_snapshot(0, generate_snapshot_filepath(base_snapshot_path, remote_run), remote_run) def start_profiling(self): self.profiling_backend.enable() @@ -104,11 +104,13 @@ class Profiler(object): self.profiling_backend.dump_stats(filename) return filename - def save_snapshot(self, id, filename): + def save_snapshot(self, id, filename, send_stat=False): self.stop_profiling() if filename is not None: filename = self.dump_snapshot(filename) print('Snapshot saved to %s' % filename) + + if not send_stat: response = ProfilerResponse(id=id, snapshot_filepath=filename) else: response = ProfilerResponse(id=id) From c3d95ce9eda1a554f6ab2723f5defc676f3baf8d Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Tue, 10 Feb 2015 17:33:43 +0300 Subject: [PATCH 16/28] diff: split complex queue into two classes --- .../impl/CacheDiffRequestChainProcessor.java | 19 +-- .../diff/impl/DiffRequestProcessor.java | 1 + .../diff/tools/util/base/DiffViewerBase.java | 26 ++-- ...kExecutor.java => BackgroundTaskUtil.java} | 66 ++++------ .../com/intellij/diff/util/DiffTaskQueue.java | 116 ++++++++++++++++++ .../vcs/changes/CacheChangeProcessor.java | 21 ++-- 6 files changed, 174 insertions(+), 75 deletions(-) rename platform/diff-impl/src/com/intellij/diff/util/{WaitingBackgroundableTaskExecutor.java => BackgroundTaskUtil.java} (63%) create mode 100644 platform/diff-impl/src/com/intellij/diff/util/DiffTaskQueue.java diff --git a/platform/diff-impl/src/com/intellij/diff/impl/CacheDiffRequestChainProcessor.java b/platform/diff-impl/src/com/intellij/diff/impl/CacheDiffRequestChainProcessor.java index 49a400022a99..63aabc7bf446 100644 --- a/platform/diff-impl/src/com/intellij/diff/impl/CacheDiffRequestChainProcessor.java +++ b/platform/diff-impl/src/com/intellij/diff/impl/CacheDiffRequestChainProcessor.java @@ -21,9 +21,9 @@ import com.intellij.diff.chains.DiffRequestProducer; import com.intellij.diff.chains.DiffRequestProducerException; import com.intellij.diff.requests.*; import com.intellij.diff.tools.util.SoftHardCacheMap; +import com.intellij.diff.util.DiffTaskQueue; import com.intellij.diff.util.DiffUserDataKeys; import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy; -import com.intellij.diff.util.WaitingBackgroundableTaskExecutor; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -33,9 +33,11 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.util.ProgressWindow; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; import com.intellij.util.Consumer; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.Convertor; +import org.jetbrains.annotations.CalledInAwt; import org.jetbrains.annotations.CalledInBackground; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -51,7 +53,7 @@ public abstract class CacheDiffRequestChainProcessor extends DiffRequestProcesso @NotNull private final SoftHardCacheMap myRequestCache = new SoftHardCacheMap(5, 5); - @NotNull private final WaitingBackgroundableTaskExecutor myTaskExecutor = new WaitingBackgroundableTaskExecutor(); + @NotNull private final DiffTaskQueue myQueue = new DiffTaskQueue(); public CacheDiffRequestChainProcessor(@Nullable Project project, @NotNull DiffRequestChain requestChain) { super(project, requestChain); @@ -62,6 +64,7 @@ public abstract class CacheDiffRequestChainProcessor extends DiffRequestProcesso // Update // + @CalledInAwt public void updateRequest(final boolean force, @Nullable final ScrollToPolicy scrollToChangePolicy) { List requests = myRequestChain.getRequests(); int index = myRequestChain.getIndex(); @@ -78,12 +81,13 @@ public abstract class CacheDiffRequestChainProcessor extends DiffRequestProcesso return; } - myTaskExecutor.execute( - new Convertor() { + myQueue.executeAndTryWait( + new Function() { @Override - public Runnable convert(ProgressIndicator indicator) { + public Runnable fun(ProgressIndicator indicator) { final DiffRequest request = loadRequest(producer, indicator); return new Runnable() { + @CalledInAwt @Override public void run() { myRequestCache.put(producer, request); @@ -131,9 +135,10 @@ public abstract class CacheDiffRequestChainProcessor extends DiffRequestProcesso // @Override + @CalledInAwt protected void onDispose() { super.onDispose(); - myTaskExecutor.abort(); + Disposer.dispose(myQueue); myRequestCache.clear(); } diff --git a/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java b/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java index 2b6fbcb3a798..74674c4f83ab 100644 --- a/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java +++ b/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java @@ -299,6 +299,7 @@ public abstract class DiffRequestProcessor implements Disposable { protected void onAfterNavigate() { } + @CalledInAwt protected void onDispose() { } diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/base/DiffViewerBase.java b/platform/diff-impl/src/com/intellij/diff/tools/util/base/DiffViewerBase.java index 16dd6a0fd80c..8e03481e1c7a 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/util/base/DiffViewerBase.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/util/base/DiffViewerBase.java @@ -20,7 +20,7 @@ import com.intellij.diff.FrameDiffTool; import com.intellij.diff.FrameDiffTool.DiffViewer; import com.intellij.diff.requests.ContentDiffRequest; import com.intellij.diff.tools.util.DiffDataKeys; -import com.intellij.diff.util.WaitingBackgroundableTaskExecutor; +import com.intellij.diff.util.DiffTaskQueue; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataProvider; @@ -31,8 +31,7 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.util.ProgressWindow; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; -import com.intellij.util.Alarm; -import com.intellij.util.containers.Convertor; +import com.intellij.util.Function; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.*; @@ -47,9 +46,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider { @NotNull protected final DiffContext myContext; @NotNull protected final ContentDiffRequest myRequest; - @NotNull private final WaitingBackgroundableTaskExecutor myTaskExecutor = new WaitingBackgroundableTaskExecutor(); - @NotNull private final Alarm myAlarm = new Alarm(); - + @NotNull private final DiffTaskQueue myTaskExecutor = new DiffTaskQueue(); @NotNull private final AtomicBoolean myDisposed = new AtomicBoolean(false); public DiffViewerBase(@NotNull DiffContext context, @NotNull ContentDiffRequest request) { @@ -75,15 +72,11 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider { public final void dispose() { if (!myDisposed.compareAndSet(false, true)) return; - Disposer.dispose(myAlarm); - abortRediff(); - onDispose(); UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { - abortRediff(); onDisposeAwt(); } }); @@ -92,14 +85,10 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider { @CalledInAwt public final void scheduleRediff() { if (myDisposed.get()) return; - myTaskExecutor.abort(); - final int modificationStamp = myTaskExecutor.getModificationStamp(); - myAlarm.cancelAllRequests(); - myAlarm.addRequest(new Runnable() { + myTaskExecutor.abortAndSchedule(new Runnable() { @Override public void run() { - if (modificationStamp != myTaskExecutor.getModificationStamp()) return; rediff(); } }, ProgressWindow.DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS); @@ -127,10 +116,10 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider { int waitMillis = trySync || tryRediffSynchronously() ? ProgressWindow.DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS : 0; - myTaskExecutor.execute( - new Convertor() { + myTaskExecutor.executeAndTryWait( + new Function() { @Override - public Runnable convert(ProgressIndicator indicator) { + public Runnable fun(ProgressIndicator indicator) { return performRediff(indicator); } }, @@ -199,6 +188,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider { protected abstract Runnable performRediff(@NotNull ProgressIndicator indicator); protected void onDispose() { + Disposer.dispose(myTaskExecutor); } @CalledInAwt diff --git a/platform/diff-impl/src/com/intellij/diff/util/WaitingBackgroundableTaskExecutor.java b/platform/diff-impl/src/com/intellij/diff/util/BackgroundTaskUtil.java similarity index 63% rename from platform/diff-impl/src/com/intellij/diff/util/WaitingBackgroundableTaskExecutor.java rename to platform/diff-impl/src/com/intellij/diff/util/BackgroundTaskUtil.java index 3a95b5c60b9f..9cf267a06075 100644 --- a/platform/diff-impl/src/com/intellij/diff/util/WaitingBackgroundableTaskExecutor.java +++ b/platform/diff-impl/src/com/intellij/diff/util/BackgroundTaskUtil.java @@ -21,7 +21,7 @@ import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.util.EmptyRunnable; -import com.intellij.util.containers.Convertor; +import com.intellij.util.Function; import org.jetbrains.annotations.CalledInAwt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -34,59 +34,38 @@ import java.util.concurrent.atomic.AtomicReference; * Executor to perform long operations on pooled thread * Is is used to reduce blinking, in case of fast end of background task. */ -public class WaitingBackgroundableTaskExecutor { +public class BackgroundTaskUtil { private static final Runnable TOO_SLOW_OPERATION = new EmptyRunnable(); - private int myModificationStamp = 0; - @Nullable private ProgressIndicator myProgressIndicator; - @CalledInAwt - public int getModificationStamp() { - return myModificationStamp; + @NotNull + public static ProgressIndicator executeAndTryWait(@NotNull final Function backgroundTask, + @Nullable final Runnable onSlowAction, + final int waitMillis) { + return executeAndTryWait(backgroundTask, onSlowAction, waitMillis, false); } @CalledInAwt - public void abort() { - if (myProgressIndicator != null) { - myProgressIndicator.cancel(); - myProgressIndicator = null; - myModificationStamp++; - } - } - - @CalledInAwt - public void execute(@NotNull final Convertor backgroundTask, - @Nullable final Runnable onSlowAction, - final int waitMillis) { - execute(backgroundTask, onSlowAction, waitMillis, false); - } - - @CalledInAwt - public void execute(@NotNull final Convertor backgroundTask, - @Nullable final Runnable onSlowAction, - final int waitMillis, - final boolean forceEDT) { - abort(); - - myModificationStamp++; - final int modificationStamp = myModificationStamp; - + @NotNull + public static ProgressIndicator executeAndTryWait(@NotNull final Function backgroundTask, + @Nullable final Runnable onSlowAction, + final int waitMillis, + final boolean forceEDT) { final ModalityState modality = ModalityState.current(); - myProgressIndicator = new EmptyProgressIndicator() { + final ProgressIndicator indicator = new EmptyProgressIndicator() { @NotNull @Override public ModalityState getModalityState() { return modality; } }; - final ProgressIndicator indicator = myProgressIndicator; final Semaphore semaphore = new Semaphore(0); final AtomicReference resultRef = new AtomicReference(); if (forceEDT) { - Runnable result = backgroundTask.convert(indicator); - finish(result, modificationStamp, indicator); + Runnable callback = backgroundTask.fun(indicator); + finish(callback, indicator); } else { ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { @@ -95,18 +74,18 @@ public class WaitingBackgroundableTaskExecutor { ProgressManager.getInstance().executeProcessUnderProgress(new Runnable() { @Override public void run() { - final Runnable result = backgroundTask.convert(indicator); + final Runnable callback = backgroundTask.fun(indicator); if (indicator.isCanceled()) { semaphore.release(); return; } - if (!resultRef.compareAndSet(null, result)) { + if (!resultRef.compareAndSet(null, callback)) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - finish(result, modificationStamp, indicator); + finish(callback, indicator); } }, modality); } @@ -123,19 +102,20 @@ public class WaitingBackgroundableTaskExecutor { } if (!resultRef.compareAndSet(null, TOO_SLOW_OPERATION)) { // update presentation in the same thread to reduce blinking, caused by 'invokeLater' and fast background operation - finish(resultRef.get(), modificationStamp, indicator); + finish(resultRef.get(), indicator); } else { if (onSlowAction != null) onSlowAction.run(); } } + + return indicator; } @CalledInAwt - private void finish(@NotNull Runnable result, int modificationStamp, @NotNull ProgressIndicator indicator) { + private static void finish(@NotNull Runnable result, @NotNull ProgressIndicator indicator) { if (indicator.isCanceled()) return; - if (myModificationStamp != modificationStamp) return; - result.run(); + indicator.stop(); } } diff --git a/platform/diff-impl/src/com/intellij/diff/util/DiffTaskQueue.java b/platform/diff-impl/src/com/intellij/diff/util/DiffTaskQueue.java new file mode 100644 index 000000000000..96027e2a7356 --- /dev/null +++ b/platform/diff-impl/src/com/intellij/diff/util/DiffTaskQueue.java @@ -0,0 +1,116 @@ +/* + * Copyright 2000-2015 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.diff.util; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.util.Disposer; +import com.intellij.util.Alarm; +import com.intellij.util.Function; +import org.jetbrains.annotations.*; + +import java.util.concurrent.atomic.AtomicReference; + +public class DiffTaskQueue implements Disposable { + @NotNull private final Object LOCK = new Object(); + @NotNull private final Alarm myAlarm = new Alarm(); + + private boolean myDisposed; + @NotNull private final AtomicReference myProgressIndicator = new AtomicReference(); + + @CalledInAny + public void dispose() { + // if EDT is awaiting for background progress in executeAndTryWait - it holds LOCK. + // so we want to try cancel indicator before getting the lock. + cancelProgress(); + synchronized (LOCK) { + if (myDisposed) return; + myDisposed = true; + cancelProgress(); + Disposer.dispose(myAlarm); + } + } + + @CalledInAwt + public void abort() { + synchronized (LOCK) { + cancelProgress(); + myAlarm.cancelAllRequests(); + } + } + + private void cancelProgress() { + ProgressIndicator indicator = myProgressIndicator.getAndSet(null); + if (indicator != null) indicator.cancel(); + } + + @CalledInAwt + public void abortAndSchedule(@NotNull final Runnable task, int millis) { + synchronized (LOCK) { + if (myDisposed) return; + abort(); + + myAlarm.addRequest(new Runnable() { + @Override + public void run() { + synchronized (LOCK) { + if (myDisposed) return; + } + task.run(); + } + }, millis); + } + } + + @CalledInAwt + public void executeAndTryWait(@NotNull final Function backgroundTask, + @Nullable final Runnable onSlowAction, + final int waitMillis) { + executeAndTryWait(backgroundTask, onSlowAction, waitMillis, false); + } + + @CalledInAwt + public void executeAndTryWait(@NotNull final Function backgroundTask, + @Nullable final Runnable onSlowAction, + final int waitMillis, + final boolean forceEDT) { + synchronized (LOCK) { + if (myDisposed) return; + abort(); + + Function function = new Function() { + @Override + @CalledInBackground + public Runnable fun(final ProgressIndicator indicator) { + final Runnable callback = backgroundTask.fun(indicator); + return new Runnable() { + @Override + @CalledInAwt + public void run() { + synchronized (LOCK) { + if (myDisposed) return; + indicator.checkCanceled(); + } + callback.run(); + } + }; + } + }; + + myProgressIndicator.set(BackgroundTaskUtil.executeAndTryWait(function, onSlowAction, waitMillis, forceEDT)); + } + } +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CacheChangeProcessor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CacheChangeProcessor.java index 2df8cad37e62..fd0b781bd06a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CacheChangeProcessor.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CacheChangeProcessor.java @@ -19,9 +19,9 @@ import com.intellij.diff.chains.DiffRequestProducerException; import com.intellij.diff.impl.DiffRequestProcessor; import com.intellij.diff.requests.*; import com.intellij.diff.tools.util.SoftHardCacheMap; +import com.intellij.diff.util.DiffTaskQueue; import com.intellij.diff.util.DiffUserDataKeys; import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy; -import com.intellij.diff.util.WaitingBackgroundableTaskExecutor; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -31,10 +31,11 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.util.ProgressWindow; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestProducer; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.Convertor; import org.jetbrains.annotations.*; import java.util.Collections; @@ -48,7 +49,7 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor { @Nullable private Change myCurrentChange; - @NotNull private final WaitingBackgroundableTaskExecutor myTaskExecutor = new WaitingBackgroundableTaskExecutor(); + @NotNull private final DiffTaskQueue myQueue = new DiffTaskQueue(); public CacheChangeProcessor(@NotNull Project project) { super(project); @@ -74,21 +75,25 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor { // Update // + @CalledInAwt public void updateRequest(final boolean force, @Nullable final ScrollToPolicy scrollToChangePolicy) { final Change change = myCurrentChange; + DiffRequest cachedRequest = loadRequestFast(change); if (cachedRequest != null) { applyRequest(cachedRequest, force, scrollToChangePolicy); return; } - myTaskExecutor.execute( - new Convertor() { + // TODO: check if current loading change is the same as we want to load now? (and not interrupt loading) + myQueue.executeAndTryWait( + new Function() { @Override - public Runnable convert(ProgressIndicator indicator) { + public Runnable fun(ProgressIndicator indicator) { final DiffRequest request = loadRequest(change, indicator); return new Runnable() { @Override + @CalledInAwt public void run() { myRequestCache.put(change, Pair.create(change, request)); applyRequest(request, force, scrollToChangePolicy); @@ -107,6 +112,7 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor { } @Nullable + @CalledInAwt @Contract("null -> !null") protected DiffRequest loadRequestFast(@Nullable Change change) { if (change == null) return NoDiffRequest.INSTANCE; @@ -152,9 +158,10 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor { // @Override + @CalledInAwt protected void onDispose() { super.onDispose(); - myTaskExecutor.abort(); + Disposer.dispose(myQueue); myRequestCache.clear(); } From 7af9174046f024c4a8065c09d21fe8b1c675427f Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Fri, 8 May 2015 20:09:38 +0300 Subject: [PATCH 17/28] Inject Python into function annotations only if they look like type hints (PY-15810) Currently PEP 484 is still a draft and PyCharm doesn't implement ignore comments and decorators for suppressing type checking of annotations. We shouldn't inject Python into annotations that are not supposed to be type hints. --- .../PyTypingAnnotationInjector.java | 15 ++++- .../com/jetbrains/python/PyTypingTest.java | 64 +++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/PyTypingAnnotationInjector.java b/python/src/com/jetbrains/python/codeInsight/PyTypingAnnotationInjector.java index 16a7b86261b3..b460e0f03de9 100644 --- a/python/src/com/jetbrains/python/codeInsight/PyTypingAnnotationInjector.java +++ b/python/src/com/jetbrains/python/codeInsight/PyTypingAnnotationInjector.java @@ -24,16 +24,27 @@ import com.jetbrains.python.psi.PyStringLiteralExpression; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.regex.Pattern; + /** * @author vlan */ public class PyTypingAnnotationInjector extends PyInjectorBase { + public static final Pattern RE_TYPING_ANNOTATION = Pattern.compile("\\s*\\S+(\\[.*\\])?\\s*"); + @Nullable @Override public Language getInjectedLanguage(@NotNull PsiElement context) { - if (context instanceof PyStringLiteralExpression && PsiTreeUtil.getParentOfType(context, PyAnnotation.class, true) != null) { - return PyDocstringLanguageDialect.getInstance(); + if (context instanceof PyStringLiteralExpression) { + final PyStringLiteralExpression expr = (PyStringLiteralExpression)context; + if (PsiTreeUtil.getParentOfType(context, PyAnnotation.class, true) != null && isTypingAnnotation(expr.getStringValue())) { + return PyDocstringLanguageDialect.getInstance(); + } } return null; } + + private static boolean isTypingAnnotation(@NotNull String s) { + return RE_TYPING_ANNOTATION.matcher(s).matches(); + } } diff --git a/python/testSrc/com/jetbrains/python/PyTypingTest.java b/python/testSrc/com/jetbrains/python/PyTypingTest.java index 6ac1fdfd5c2e..b6126e9abeb6 100644 --- a/python/testSrc/com/jetbrains/python/PyTypingTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypingTest.java @@ -15,6 +15,15 @@ */ package com.jetbrains.python; +import com.intellij.lang.injection.InjectedLanguageManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.testFramework.LightProjectDescriptor; import com.jetbrains.python.documentation.PythonDocumentationProvider; import com.jetbrains.python.fixtures.PyTestCase; @@ -25,6 +34,8 @@ import com.jetbrains.python.psi.types.TypeEvalContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + /** * Tests for a type system based on mypy's typing module. * @@ -306,6 +317,59 @@ public class PyTypingTest extends PyTestCase { " pass\n"); } + public void testStringLiteralInjection() { + doTestInjectedText("class C:\n" + + " def foo(self, expr: 'C'):\n" + + " pass\n", + "C"); + } + + public void testStringLiteralInjectionParameterizedType() { + doTestInjectedText("from typing import Union, List\n" + + "\n" + + "class C:\n" + + " def foo(self, expr: 'Union[List[C], C]'):\n" + + " pass\n", + "Union[List[C], C]"); + } + + // PY-15810 + public void testNoStringLiteralInjectionForNonTypingStrings() { + doTestNoInjectedText("class C:\n" + + " def foo(self, expr: 'foo bar'):\n" + + " pass\n"); + } + + private void doTestNoInjectedText(@NotNull String text) { + myFixture.configureByText(PythonFileType.INSTANCE, text); + final InjectedLanguageManager languageManager = InjectedLanguageManager.getInstance(myFixture.getProject()); + final PsiLanguageInjectionHost host = languageManager.getInjectionHost(getElementAtCaret()); + assertNull(host); + } + + private void doTestInjectedText(@NotNull String text, @NotNull String expected) { + myFixture.configureByText(PythonFileType.INSTANCE, text); + final InjectedLanguageManager languageManager = InjectedLanguageManager.getInstance(myFixture.getProject()); + final PsiLanguageInjectionHost host = languageManager.getInjectionHost(getElementAtCaret()); + assertNotNull(host); + final List> files = languageManager.getInjectedPsiFiles(host); + assertNotNull(files); + assertFalse(files.isEmpty()); + final PsiElement injected = files.get(0).getFirst(); + assertEquals(expected, injected.getText()); + } + + @NotNull + private PsiElement getElementAtCaret() { + final Editor editor = myFixture.getEditor(); + final Document document = editor.getDocument(); + final PsiFile file = PsiDocumentManager.getInstance(myFixture.getProject()).getPsiFile(document); + assertNotNull(file); + final PsiElement element = file.findElementAt(myFixture.getCaretOffset()); + assertNotNull(element); + return element; + } + private void doTest(@NotNull String expectedType, @NotNull String text) { myFixture.copyDirectoryToProject("typing", ""); myFixture.configureByText(PythonFileType.INSTANCE, text); From 0f9583bcba33e59ba7fbe61a5d5eef43adf0a117 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 8 May 2015 19:20:51 +0200 Subject: [PATCH 18/28] platform: recursively invalidate VFS subtree on directory deletion/creation Fixes the issue of missed changes when a subtree is moved out and a similar one is moved on it's place. --- .../openapi/vfs/impl/local/FileWatcher.java | 4 +-- .../openapi/vfs/local/FileWatcherTest.java | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java index 7516febe596b..c5b459261fa8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -556,7 +556,7 @@ public class FileWatcher { case CREATE: case DELETE: for (String p : paths) { - myDirtyPaths.dirtyPaths.add(p); + myDirtyPaths.dirtyPathsRecursive.add(p); String parentPath = new File(p).getParent(); if (parentPath != null) { myDirtyPaths.dirtyPaths.add(parentPath); 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 8baa5a78c50f..7f52a1df5ff6 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 @@ -714,6 +714,33 @@ public class FileWatcherTest extends PlatformLangTestCase { } } + public void testDisplacementByIsomorphicTree() throws Exception { + File top = createTestDir("top"); + File up = createTestDir(top, "up"); + File middle = createTestDir(up, "middle"); + File file = createTestFile(middle, "file.txt", "original content"); + File up_copy = new File(top, "up_copy"); + FileUtil.copyDir(up, up_copy); + FileUtil.writeToFile(file, "new content"); + + VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file); + assertNotNull(vFile); + assertEquals("new content", VfsUtilCore.loadText(vFile)); + + LocalFileSystem.WatchRequest request = watch(up); + try { + myAccept = true; + FileUtil.rename(up, new File(top, "up.bak")); + FileUtil.rename(up_copy, up); + assertEvent(VFileContentChangeEvent.class, file.getPath()); + assertTrue(vFile.isValid()); + assertEquals("original content", VfsUtilCore.loadText(vFile)); + } + finally { + unwatch(request); + } + } + @NotNull private LocalFileSystem.WatchRequest watch(File watchFile) { From ad6670874f37c52f4a15f30e1ab2682bd81f40f8 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Fri, 8 May 2015 19:24:42 +0200 Subject: [PATCH 19/28] Fix 2nd and more capturing snapshot (PY-15823). --- python/helpers/profiler/yappi_profiler.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/python/helpers/profiler/yappi_profiler.py b/python/helpers/profiler/yappi_profiler.py index c1024c4b0e9d..2be2d2f74836 100644 --- a/python/helpers/profiler/yappi_profiler.py +++ b/python/helpers/profiler/yappi_profiler.py @@ -24,8 +24,7 @@ class YappiProfile(object): self.stats = yappi.convert2pstats(yappi.get_func_stats()).stats def getstats(self): - if self.stats is None: - self.create_stats() + self.create_stats() return self.stats From 10e4f33f71334e6712b56461e9782ef2bef86090 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 8 May 2015 19:28:05 +0200 Subject: [PATCH 20/28] junit: allow debug in fork mode (IDEA-121566) --- .../execution/JavaTestFrameworkRunnableState.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java b/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java index cb6c6a95c88e..00139eadb07a 100644 --- a/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java +++ b/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java @@ -16,6 +16,7 @@ package com.intellij.execution; import com.intellij.ExtensionPoints; +import com.intellij.debugger.impl.GenericDebuggerRunnerSettings; import com.intellij.execution.configurations.*; import com.intellij.execution.process.OSProcessHandler; import com.intellij.execution.process.ProcessAdapter; @@ -205,7 +206,7 @@ public abstract class JavaTestFrameworkRunnableState" + "Please specify single working directory, or change test scope to single module."); @@ -228,7 +234,7 @@ public abstract class JavaTestFrameworkRunnableStatePlease change fork mode to <none> to " + actionName.toLowerCase( Locale.ENGLISH) + "."); From 027f0aab9a2860a3ab4a96de2a362e24802d4949 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 8 May 2015 19:30:15 +0200 Subject: [PATCH 21/28] SMTestSender -> JUnit4TestListener --- .../junit/JUnitTreeByDescriptionHierarchyTest.java | 8 ++++---- .../src/com/intellij/junit4/JUnit4IdeaTestRunner.java | 6 +++--- .../junit4/{SMTestSender.java => JUnit4TestListener.java} | 6 +++--- .../src/com/intellij/junit4/JUnit4TestResultsSender.java | 4 +--- 4 files changed, 11 insertions(+), 13 deletions(-) rename plugins/junit_rt/src/com/intellij/junit4/{SMTestSender.java => JUnit4TestListener.java} (98%) diff --git a/plugins/junit/test/com/intellij/execution/junit/JUnitTreeByDescriptionHierarchyTest.java b/plugins/junit/test/com/intellij/execution/junit/JUnitTreeByDescriptionHierarchyTest.java index c5c051fe47bb..50f7dcf6db7d 100644 --- a/plugins/junit/test/com/intellij/execution/junit/JUnitTreeByDescriptionHierarchyTest.java +++ b/plugins/junit/test/com/intellij/execution/junit/JUnitTreeByDescriptionHierarchyTest.java @@ -15,7 +15,7 @@ */ package com.intellij.execution.junit; -import com.intellij.junit4.SMTestSender; +import com.intellij.junit4.JUnit4TestListener; import com.intellij.openapi.util.text.StringUtil; import junit.framework.Assert; import org.junit.Test; @@ -170,7 +170,7 @@ public class JUnitTreeByDescriptionHierarchyTest { private static void doTest(Description root, List tests, String expectedTree, String expectedStart) throws Exception { final StringBuffer buf = new StringBuffer(); - final SMTestSender sender = new SMTestSender(new PrintStream(new OutputStream() { + final JUnit4TestListener sender = new JUnit4TestListener(new PrintStream(new OutputStream() { @Override public void write(int b) throws IOException { buf.append(new String(new byte[]{(byte)b})); @@ -300,7 +300,7 @@ public class JUnitTreeByDescriptionHierarchyTest { private static void doTest(Description description, String expected) { final StringBuffer buf = new StringBuffer(); - new SMTestSender(new PrintStream(new OutputStream() { + new JUnit4TestListener(new PrintStream(new OutputStream() { @Override public void write(int b) throws IOException { buf.append(new String(new byte[]{(byte)b})); @@ -313,7 +313,7 @@ public class JUnitTreeByDescriptionHierarchyTest { @Test public void testProcessEmptyTestCase() throws Exception { final Description description = Description.createSuiteDescription("TestA"); - final Description emptyDescription = Description.createTestDescription(SMTestSender.EMPTY_SUITE_NAME, SMTestSender.EMPTY_SUITE_WARNING); + final Description emptyDescription = Description.createTestDescription(JUnit4TestListener.EMPTY_SUITE_NAME, JUnit4TestListener.EMPTY_SUITE_WARNING); description.addChild(emptyDescription); doTest(description, Collections.singletonList(emptyDescription), "##teamcity[suiteTreeNode name='warning' locationHint='java:test://TestA.warning']\n", diff --git a/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java b/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java index 4f68466cdac3..348607c84024 100644 --- a/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java +++ b/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java @@ -52,9 +52,9 @@ public class JUnit4IdeaTestRunner implements IdeaTestRunner { description = getFilteredDescription(request, description); } - if (myTestsListener instanceof SMTestSender) { + if (myTestsListener instanceof JUnit4TestListener) { if (sendTree) { - ((SMTestSender)myTestsListener).sendTree(description); + ((JUnit4TestListener)myTestsListener).sendTree(description); } sendTree = false; } else { @@ -189,7 +189,7 @@ public class JUnit4IdeaTestRunner implements IdeaTestRunner { public void setStreams(Object segmentedOut, Object segmentedErr, int lastIdx) { if (JUnitStarter.SM_RUNNER) { - myTestsListener = new SMTestSender(); + myTestsListener = new JUnit4TestListener(); } else { myRegistry = new JUnit4OutputObjectRegistry((PacketProcessor)segmentedOut, lastIdx); myTestsListener = new JUnit4TestResultsSender(myRegistry); diff --git a/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java b/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestListener.java similarity index 98% rename from plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java rename to plugins/junit_rt/src/com/intellij/junit4/JUnit4TestListener.java index b835081a92b3..ff16fed6e210 100644 --- a/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java +++ b/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestListener.java @@ -36,7 +36,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.util.*; -public class SMTestSender extends RunListener { +public class JUnit4TestListener extends RunListener { private static final String MESSAGE_LENGTH_FOR_PATTERN_MATCHING = "idea.junit.message.length.threshold"; private static final String JUNIT_FRAMEWORK_COMPARISON_NAME = ComparisonFailure.class.getName(); private static final String ORG_JUNIT_COMPARISON_NAME = "org.junit.ComparisonFailure"; @@ -48,11 +48,11 @@ public class SMTestSender extends RunListener { private final PrintStream myPrintStream; private String myRootName; - public SMTestSender() { + public JUnit4TestListener() { myPrintStream = System.out; } - public SMTestSender(PrintStream printStream) { + public JUnit4TestListener(PrintStream printStream) { myPrintStream = printStream; } diff --git a/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestResultsSender.java b/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestResultsSender.java index 1285e5abc1b5..d397acb45bea 100644 --- a/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestResultsSender.java +++ b/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestResultsSender.java @@ -29,8 +29,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class JUnit4TestResultsSender extends RunListener { private static final String JUNIT_FRAMEWORK_COMPARISON_NAME = ComparisonFailure.class.getName(); @@ -108,7 +106,7 @@ public class JUnit4TestResultsSender extends RunListener { private static PacketFactory createExceptionNotification(Throwable assertion) { if (assertion instanceof KnownException) return ((KnownException)assertion).getPacketFactory(); - final ComparisonFailureData notification = SMTestSender.createExceptionNotification(assertion); + final ComparisonFailureData notification = JUnit4TestListener.createExceptionNotification(assertion); if (notification != null) { return ComparisonDetailsExtractor.create(assertion, notification.getExpected(), notification.getActual()); } From ec559b0368887fd9f2f059b7e06d3c5ce20b3ae6 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 8 May 2015 19:40:06 +0200 Subject: [PATCH 22/28] debug in fork mode: disable socket for run --- .../com/intellij/execution/JavaTestFrameworkRunnableState.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java b/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java index 00139eadb07a..9fb6e4cf989b 100644 --- a/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java +++ b/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java @@ -206,7 +206,7 @@ public abstract class JavaTestFrameworkRunnableState Date: Fri, 8 May 2015 19:59:48 +0200 Subject: [PATCH 23/28] Cleanup (tests merged) --- .../vfs/local/SymlinkHandlingTest.java | 44 +++++++++++- .../openapi/vfs/local/SymlinkTestCase.java | 71 ------------------- 2 files changed, 43 insertions(+), 72 deletions(-) delete mode 100644 platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkTestCase.java diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkHandlingTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkHandlingTest.java index 218cc4c865d6..12aa12edd134 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkHandlingTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkHandlingTest.java @@ -21,6 +21,7 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.*; +import com.intellij.testFramework.LightPlatformTestCase; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; @@ -33,7 +34,37 @@ import java.util.Set; import static com.intellij.openapi.util.io.IoTestUtil.*; import static com.intellij.testFramework.PlatformTestUtil.assertPathsEqual; -public class SymlinkHandlingTest extends SymlinkTestCase { +public class SymlinkHandlingTest extends LightPlatformTestCase { + protected LocalFileSystem myFileSystem; + protected File myTempDir; + + @Override + protected void setUp() throws Exception { + super.setUp(); + myFileSystem = LocalFileSystem.getInstance(); + myTempDir = createTestDir("temp"); + } + + @Override + protected void tearDown() throws Exception { + try { + super.tearDown(); + } + finally { + delete(myTempDir); + } + } + + @Override + protected void runTest() throws Throwable { + if (SystemInfo.areSymLinksSupported) { + super.runTest(); + } + else { + System.err.println("Skipped: " + getName()); + } + } + public void testMissingLink() throws Exception { File missingFile = new File(myTempDir, "missing_file"); assertTrue(missingFile.getPath(), !missingFile.exists() || missingFile.delete()); @@ -362,6 +393,17 @@ public class SymlinkHandlingTest extends SymlinkTestCase { return myFileSystem.findFileByPath(ioFile.getPath()); } + protected void refresh() { + assertTrue(myTempDir.getPath(), myTempDir.isDirectory() || myTempDir.mkdirs()); + + VirtualFile tempDir = myFileSystem.refreshAndFindFileByIoFile(myTempDir); + assertNotNull(myTempDir.getPath(), tempDir); + + tempDir.getChildren(); + tempDir.refresh(false, true); + VfsUtilCore.visitChildrenRecursively(tempDir, new VirtualFileVisitor() { }); + } + private static void assertBrokenLink(@NotNull VirtualFile link) { assertTrue(link.is(VFileProperty.SYMLINK)); assertEquals(0, link.getLength()); diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkTestCase.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkTestCase.java deleted file mode 100644 index 999fa434481c..000000000000 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkTestCase.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.openapi.vfs.local; - -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.io.IoTestUtil; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtilCore; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileVisitor; -import com.intellij.testFramework.LightPlatformLangTestCase; - -import java.io.File; - -import static com.intellij.openapi.util.io.IoTestUtil.createTestDir; - -public abstract class SymlinkTestCase extends LightPlatformLangTestCase { - protected LocalFileSystem myFileSystem; - protected File myTempDir; - - @Override - protected void setUp() throws Exception { - super.setUp(); - myFileSystem = LocalFileSystem.getInstance(); - myTempDir = createTestDir("temp"); - } - - @Override - protected void tearDown() throws Exception { - try { - super.tearDown(); - } - finally { - IoTestUtil.delete(myTempDir); - } - } - - @Override - protected void runTest() throws Throwable { - if (SystemInfo.areSymLinksSupported) { - super.runTest(); - } - else { - System.err.println("Skipped: " + getName()); - } - } - - protected void refresh() { - assertTrue(myTempDir.getPath(), myTempDir.isDirectory() || myTempDir.mkdirs()); - - VirtualFile tempDir = myFileSystem.refreshAndFindFileByIoFile(myTempDir); - assertNotNull(myTempDir.getPath(), tempDir); - - tempDir.getChildren(); - tempDir.refresh(false, true); - VfsUtilCore.visitChildrenRecursively(tempDir, new VirtualFileVisitor() { }); - } -} From d026da5968aa92cacfaf13692a5bcdb88da6e00a Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 8 May 2015 20:00:34 +0200 Subject: [PATCH 24/28] Cleanup (typos) --- .../badPlugins/plugins/BadPlugin2.jar | Bin 1647 -> 1653 bytes .../intellij/application/BadPluginTest.java | 29 +++++++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/platform/platform-tests/testData/badPlugins/plugins/BadPlugin2.jar b/platform/platform-tests/testData/badPlugins/plugins/BadPlugin2.jar index 5ff3678492cef9f23518ac628797781a2a6de147..56df54520e2e0c7e697e09013fd7f701737f3feb 100644 GIT binary patch delta 871 zcmaFQ^Oc7^z?+#xgn?ml9;^67xd0|+mdP7gr6$he5@KNBU`Wf*a?(j|;}c*4s$kx@ zO_ix0tQshFV%`e38&*%`Y=KhltPBjo3^EM9t|5-Po_=on1v#bZnR$8@xjCUBoD9q! zKYT(Rfw;7Sn}Lz#1v3K!m{=R)+kM+WV6XTu`7QgTyge6+bS2Na%d%@}tWzXc>dodH ze<9Y$BGsLl|7zXk&mA}0o2%DXpFZ#2>`LPz&8P>i`t7{|Ps}B>x6Dd?zvA&>Ry2g|Y0eT|8I@RllK;r@6Jk75be1q1ybKAp z(!BX&lF_QGZ4Sp<=cJassLs8kzTW=SV`Js!gKw_w{HL7!`|rGcEFt!W1>($c2PfAr za+r{D(9G@2x$J4?{^i|2AOAU-{wIH>j6~A*6<+5WQhHr01t-n+!0*B|-Vt14?1z$~e=z*o>vuA*+8S6Q65*7}=8TN|A+*}vWY^(@z0sfp#t zYZ0NAo2^Bwo-NbZkorKZgH`l-J+{^k{WRP^lOI*UMV z%{z+sxwoHvU-&1eOaG@=QG09I&r>hTGUmwMRf@P1_P+CS#+sW9>pCOW7jm4MXqVWp zyY<53S2qjV>s^-IyU6D#q!YJ5_gc|Ow@uc6lCb2vPXMo%f+G?zEa!*~#!t|5vq}Y}?U%EOzDT^GEX2_oxcG`EA&+!aey$ z=)4=XkC(2$yzCD5y33s(`08aeqziP{{8YGG)MIlavdpgg&8kz9Vh5LA&}?M5&21xQv7tCQ`U`Wf)*GGsxV^ys0gNiyO7U?DDBo-Hgq~(}_ny{u~37|Lw n10xV`X*>x`+gQ^yDlUo%X z-;+M?-t0=_qJz>2k^1#*y3?PSXB?gyqw;>zr?=8hT=%AIef4Rvl*ztowf>(9Ki4yU zDo}dv>nQl-;H1)kJf`5ozWO&N?vS|I*w*xG3%lFQqIu`Jtm=;R2XPx-cWOmpkXzZ{FU+-i3ESmJ2*^5N*86b;FLiRsyRpMC@ga5x%$0f+f>ae&h0KQZEX>_Uw1E33&gR&yk5IZh^wX zZ3^`VlFHY-XI($jSiRVLt;(d?7V960Sn^(|yuMIYmhG|T!5+=%rJtggeXNT+?PgVV zGW^2-RliNP?P$LhxAOGaBf052R2kjQ8SG!7p8O(o-i6w?OV(dLc87c2XU_k;^*SDp z3wgKX2$b2n$(>P}c}{8PDkH@mB39}K59+Fy%cuVo50LO?=a_jfsMH#m0Nq$Y36POV zgaMekC&#d+3)TP=U0Qy=K0@>gtD?<3sHjt7kzR66VsSBC8kodE=@!{QP`X8cmy-?I X#KZ!;S=m5hEI{}LNT&iVW?%pSr6))C diff --git a/platform/platform-tests/testSrc/com/intellij/application/BadPluginTest.java b/platform/platform-tests/testSrc/com/intellij/application/BadPluginTest.java index 8c2c7f3236be..6bb618d3970f 100644 --- a/platform/platform-tests/testSrc/com/intellij/application/BadPluginTest.java +++ b/platform/platform-tests/testSrc/com/intellij/application/BadPluginTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 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.application; import com.intellij.ide.plugins.IdeaPluginDescriptor; @@ -6,7 +21,7 @@ import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.testFramework.PlatformLangTestCase; +import com.intellij.testFramework.PlatformTestCase; import com.intellij.testFramework.PlatformTestUtil; import java.io.File; @@ -15,24 +30,22 @@ import java.util.List; /** * @author Dmitry Avdeev - * Date: 1/9/13 + * @since 9.01.2013 */ -public class BadPluginTest extends PlatformLangTestCase { - - private static final String COM_YOURCOMPANY_UNIQUE_PLUGIN_ID = "com.yourcompany.unique.plugin.id"; +public class BadPluginTest extends PlatformTestCase { + private static final String COM_YOUR_COMPANY_UNIQUE_PLUGIN_ID = "com.your.company.unique.plugin.id"; public void testBadPlugin() throws Exception { - IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginId.getId(COM_YOURCOMPANY_UNIQUE_PLUGIN_ID)); + IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginId.getId(COM_YOUR_COMPANY_UNIQUE_PLUGIN_ID)); if (plugin == null) return; List disabledPlugins = new ArrayList(); PluginManagerCore.loadDisabledPlugins(PathManager.getConfigPath(), disabledPlugins); assertEquals(1, disabledPlugins.size()); - assertEquals(COM_YOURCOMPANY_UNIQUE_PLUGIN_ID, disabledPlugins.get(0)); + assertEquals(COM_YOUR_COMPANY_UNIQUE_PLUGIN_ID, disabledPlugins.get(0)); } @Override protected void setUp() throws Exception { - String path = PlatformTestUtil.getCommunityPath() + "/platform/platform-tests/testData/badPlugins"; File directory = createTempDirectory(false); FileUtil.copyDir(new File(path), directory); From 459e3574f3791ffbf9f85541eb27d81374452b94 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 8 May 2015 20:01:17 +0200 Subject: [PATCH 25/28] test framework: null checks --- .../com/intellij/testFramework/PlatformTestCase.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index d4bc09129695..670bcfd7bd43 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -458,15 +458,18 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro result.add(e); } - //cleanTheWorld(); try { - myEditorListenerTracker.checkListenersLeak(); + if (myEditorListenerTracker != null) { + myEditorListenerTracker.checkListenersLeak(); + } } catch (AssertionError error) { result.add(error); } try { - myThreadTracker.checkLeak(); + if (myThreadTracker != null) { + myThreadTracker.checkLeak(); + } } catch (AssertionError error) { result.add(error); @@ -477,9 +480,6 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro catch (Throwable error) { result.add(error); } - //if (directoryIndex != null) { - // directoryIndex.assertAncestorConsistent(); - //} } finally { myProjectManager = null; From 9f1a944f75430156a0d2feb6d22b43d549f287e9 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Fri, 8 May 2015 21:38:43 +0300 Subject: [PATCH 26/28] forked tests debugging: fixed assert on reattach --- .../src/com/intellij/debugger/engine/DebugProcessImpl.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java index 13ef8d37cd5c..3bd67509e586 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -1769,7 +1769,12 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb ApplicationManager.getApplication().assertIsDispatchThread(); //TODO: remove this requirement ((XDebugSessionImpl)getXdebugProcess().getSession()).reset(); myState.set(STATE_INITIAL); - myRequestManager.processDetached(this, false); + getManagerThread().schedule(new DebuggerCommandImpl() { + @Override + protected void action() throws Exception { + myRequestManager.processDetached(DebugProcessImpl.this, false); + } + }); myConnection = environment.getRemoteConnection(); getManagerThread().restartIfNeeded(); createVirtualMachine(environment.getSessionName(), environment.isPollConnection()); From 2f47f0caf0c556d4fcdab59bc90aaab2d82a3d22 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 8 May 2015 20:50:58 +0200 Subject: [PATCH 27/28] migration to stream api: disable for raw types (IDEA-140095) --- .../StreamApiMigrationInspection.java | 3 ++- .../beforeRawCollection.java | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeRawCollection.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java index 6f503534cb9c..b4ca43f4cc0b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java @@ -109,7 +109,8 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo } if (ExceptionUtil.getThrownCheckedExceptions(new PsiElement[] {body}).isEmpty()) { - if (isCollectCall(body, statement.getIterationParameter())) { + if (!(iteratedValueType instanceof PsiClassType && ((PsiClassType)iteratedValueType).isRaw()) && + isCollectCall(body, statement.getIterationParameter())) { holder.registerProblem(iteratedValue, "Can be replaced with collect call", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceWithCollectCallFix()); } else if (!isTrivial(body, statement.getIterationParameter())) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeRawCollection.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeRawCollection.java new file mode 100644 index 000000000000..fd51db79f84e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeRawCollection.java @@ -0,0 +1,22 @@ +// "Replace with forEach" "false" +import java.util.*; +import java.util.stream.Collectors + +class A { + public static List toTypedList1(Collection collection, Class aClass) { + if (collection.size() == 0) { + return Collections.emptyList(); + } + + List result = new ArrayList<>(collection.size()); + + for (Object obj : collection) { + result.add(aClass.cast(obj)); + } + + return result; + } + + + +} \ No newline at end of file From 7e5c05720e2abd5293981d06782c09ca06e00865 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 8 May 2015 20:57:58 +0200 Subject: [PATCH 28/28] testng: disable prepared incomplete tree (IDEA-140109) --- .../src/org/testng/IDEARemoteTestNG.java | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/plugins/testng_rt/src/org/testng/IDEARemoteTestNG.java b/plugins/testng_rt/src/org/testng/IDEARemoteTestNG.java index 3f98528cc533..6204eea43a0e 100644 --- a/plugins/testng_rt/src/org/testng/IDEARemoteTestNG.java +++ b/plugins/testng_rt/src/org/testng/IDEARemoteTestNG.java @@ -18,12 +18,8 @@ package org.testng; import jetbrains.buildServer.messages.serviceMessages.ServiceMessage; import org.testng.collections.Lists; -import org.testng.xml.XmlClass; -import org.testng.xml.XmlInclude; import org.testng.xml.XmlSuite; -import org.testng.xml.XmlTest; -import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -51,27 +47,6 @@ public class IDEARemoteTestNG extends TestNG { int testCount= 0; - for (XmlSuite suite : suites) { - System.out.println("##teamcity[suiteTreeStarted name=\'" + suite.getName() + "\' locationHint=\'java:suite://" + suite.getName() + "\']"); - final List tests = suite.getTests(); - for (XmlTest test : tests) { - for (XmlClass aClass : test.getXmlClasses()) { - final String shortName = IDEATestNGRemoteListener.getShortName(aClass.getName()); - System.out.println("##teamcity[suiteTreeStarted name=\'" + - shortName + "\' locationHint=\'java:suite://" + aClass.getName() + "\']"); - if (myParam != null) { - for (XmlInclude include : aClass.getIncludedMethods()) { - aClass.setIncludedMethods(Arrays.asList(new XmlInclude(include.getName(), Arrays.asList(Integer.parseInt(myParam)), 0))); - } - } - - System.out.println("##teamcity[suiteTreeEnded name=\'" + shortName + "\']"); - } - testCount += test.getClasses().size(); - } - System.out.println("##teamcity[suiteTreeEnded name=\'" + suite.getName() + "\']"); - } - final HashMap map = new HashMap(); map.put("count", String.valueOf(testCount)); System.out.println(ServiceMessage.asString("testCount", map));