From 228453e493bd1d407da15c695afe30f8635805c0 Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 11 Nov 2009 21:37:04 +0300 Subject: [PATCH 01/36] pull up: as refactoring processor --- .../memberPullUp/JavaPullUpHandler.java | 42 ---------------- .../memberPullUp/PullUpDialog.java | 11 +++-- .../memberPullUp/PullUpHelper.java | 49 ++++++++++++++++++- 3 files changed, 56 insertions(+), 46 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java index 8d11c60cfe46..55e137a4d9b9 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java @@ -24,12 +24,8 @@ */ package com.intellij.refactoring.memberPullUp; -import com.intellij.history.LocalHistory; -import com.intellij.history.LocalHistoryAction; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ScrollType; @@ -43,12 +39,9 @@ import com.intellij.refactoring.classMembers.MemberInfoBase; import com.intellij.refactoring.lang.ElementsHandler; import com.intellij.refactoring.ui.ConflictsDialog; import com.intellij.refactoring.util.CommonRefactoringUtil; -import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.RefactoringHierarchyUtil; import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.refactoring.util.classMembers.MemberInfoStorage; -import com.intellij.usageView.UsageViewUtil; -import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; @@ -145,44 +138,9 @@ public class JavaPullUpHandler implements RefactoringActionHandler, PullUpDialog dialog.show(); - - if (!dialog.isOK()) return; - - CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { - public void run() { - final Runnable action = new Runnable() { - public void run() { - doRefactoring(dialog); - } - }; - ApplicationManager.getApplication().runWriteAction(action); - } - }, REFACTORING_NAME, null); - } - private void doRefactoring(PullUpDialog dialog) { - LocalHistoryAction a = LocalHistory.startAction(myProject, getCommandName()); - try { - try { - PullUpHelper helper = new PullUpHelper(mySubclass, dialog.getSuperClass(), dialog.getSelectedMemberInfos(), - new DocCommentPolicy(dialog.getJavaDocPolicy())); - helper.moveMembersToBase(); - helper.moveFieldInitializations(); - } - finally { - a.finish(); - } - } - catch (IncorrectOperationException e) { - LOG.error(e); - } - } - - private String getCommandName() { - return RefactoringBundle.message("pullUp.command", UsageViewUtil.getDescriptiveName(mySubclass)); - } public boolean checkConflicts(PullUpDialog dialog) { final MemberInfo[] infos = dialog.getSelectedMemberInfos(); diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java index 5678304124bf..09db451ed8d0 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java @@ -26,8 +26,8 @@ package com.intellij.refactoring.memberPullUp; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.DialogWrapper; import com.intellij.psi.*; +import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; @@ -35,6 +35,8 @@ import com.intellij.refactoring.classMembers.MemberInfoChange; import com.intellij.refactoring.ui.ClassCellRenderer; import com.intellij.refactoring.ui.DocCommentPanel; import com.intellij.refactoring.ui.MemberSelectionPanel; +import com.intellij.refactoring.ui.RefactoringDialog; +import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.RefactoringHierarchyUtil; import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier; import com.intellij.refactoring.util.classMembers.MemberInfo; @@ -51,7 +53,7 @@ import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.List; -public class PullUpDialog extends DialogWrapper { +public class PullUpDialog extends RefactoringDialog { private final Callback myCallback; private MemberSelectionPanel myMemberSelectionPanel; private MyMemberInfoModel myMemberInfoModel; @@ -174,9 +176,12 @@ public class PullUpDialog extends DialogWrapper { }*/ } - protected void doOKAction() { + protected void doAction() { if (!myCallback.checkConflicts(this)) return; JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC = myJavaDocPanel.getPolicy(); + + invokeRefactoring(new PullUpHelper(myClass, getSuperClass(), getSelectedMemberInfos(), + new DocCommentPolicy(getJavaDocPolicy()))); close(OK_EXIT_CODE); } diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java index 4ff800d044f8..3706299c6fec 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java @@ -40,21 +40,28 @@ import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.MethodSignatureUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.listeners.JavaRefactoringListenerManager; import com.intellij.refactoring.listeners.impl.JavaRefactoringListenerManagerImpl; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor; import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.VisibilityUtil; import com.intellij.util.containers.HashMap; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; -public class PullUpHelper { +public class PullUpHelper extends BaseRefactoringProcessor{ private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.memberPullUp.PullUpHelper"); private final PsiClass mySourceClass; private final PsiClass myTargetSuperClass; @@ -67,6 +74,7 @@ public class PullUpHelper { public PullUpHelper(PsiClass sourceClass, PsiClass targetSuperClass, MemberInfo[] membersToMove, DocCommentPolicy javaDocPolicy) { + super(sourceClass.getProject()); mySourceClass = sourceClass; myTargetSuperClass = targetSuperClass; myMembersToMove = membersToMove; @@ -75,6 +83,27 @@ public class PullUpHelper { myManager = mySourceClass.getManager(); } + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { + return new PullUpUsageViewDescriptor(); + } + + @NotNull + protected UsageInfo[] findUsages() { + return new UsageInfo[0]; + } + + protected void refreshElements(PsiElement[] elements) { + } + + protected void performRefactoring(UsageInfo[] usages) { + moveMembersToBase(); + moveFieldInitializations(); + } + + protected String getCommandName() { + return RefactoringBundle.message("pullUp.command", UsageViewUtil.getDescriptiveName(mySourceClass)); + } + public void moveMembersToBase() throws IncorrectOperationException { final HashSet movedMembers = new HashSet(); @@ -743,4 +772,22 @@ public class PullUpHelper { return false; } + private class PullUpUsageViewDescriptor implements UsageViewDescriptor { + public String getProcessedElementsHeader() { + return "Pull up members from"; + } + + @NotNull + public PsiElement[] getElements() { + return new PsiElement[]{mySourceClass}; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return "Class to pull up members to \"" + RefactoringUIUtil.getDescription(myTargetSuperClass, true) + "\""; + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return null; + } + } } From 7903035c6daa06747ae9e3ce2c2c256b66f0e24f Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 11 Nov 2009 21:37:16 +0300 Subject: [PATCH 02/36] pull up: as refactoring processor --- .../testSrc/com/intellij/refactoring/PullUpTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java index 1d75d59410eb..956fd609bc99 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java @@ -91,8 +91,7 @@ public class PullUpTest extends LightCodeInsightTestCase { }; JavaRefactoringListenerManager.getInstance(getProject()).addMoveMembersListener(listener); final PullUpHelper helper = new PullUpHelper(sourceClass, targetClass, infos, new DocCommentPolicy(DocCommentPolicy.ASIS)); - helper.moveMembersToBase(); - helper.moveFieldInitializations(); + helper.run(); JavaRefactoringListenerManager.getInstance(getProject()).removeMoveMembersListener(listener); assertEquals(countMoved[0], membersToFind.length); checkResultByFile(BASE_PATH + getTestName(false) + "_after.java"); From d9831b2c91d3ee91f6cb5b80eb808c138b1ef0cd Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 12 Nov 2009 13:31:01 +0300 Subject: [PATCH 03/36] rerun failed tests: get logs from initial configuration (IDEADEV-41329) --- .../AbstractRerunFailedTestsAction.java | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/java/execution/impl/src/com/intellij/execution/actions/AbstractRerunFailedTestsAction.java b/java/execution/impl/src/com/intellij/execution/actions/AbstractRerunFailedTestsAction.java index efacb799f4c2..038df8e86aec 100644 --- a/java/execution/impl/src/com/intellij/execution/actions/AbstractRerunFailedTestsAction.java +++ b/java/execution/impl/src/com/intellij/execution/actions/AbstractRerunFailedTestsAction.java @@ -44,6 +44,7 @@ import com.intellij.openapi.util.WriteExternalException; import org.jdom.Element; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.List; public class AbstractRerunFailedTestsAction extends AnAction { @@ -122,18 +123,16 @@ public class AbstractRerunFailedTestsAction extends AnAction { return null; } - protected static abstract class MyRunProfile implements ModuleRunProfile, RunConfiguration { - private final RunConfiguration myConfiguration; + protected static abstract class MyRunProfile extends RunConfigurationBase implements ModuleRunProfile{ + private final RunConfigurationBase myConfiguration; - public MyRunProfile(RunConfiguration configuration) { + public MyRunProfile(RunConfigurationBase configuration) { + super(configuration.getProject(), configuration.getFactory(), ActionsBundle.message("action.RerunFailedTests.text")); myConfiguration = configuration; } public void clear() { } - public String getName() { - return ActionsBundle.message("action.RerunFailedTests.text"); - } public void checkConfiguration() throws RuntimeConfigurationException {} @@ -146,22 +145,10 @@ public class AbstractRerunFailedTestsAction extends AnAction { myConfiguration.writeExternal(element); } - public ConfigurationFactory getFactory() { - return myConfiguration.getFactory(); - } - - public void setName(final String name) { - myConfiguration.setName(name); - } - public SettingsEditor getConfigurationEditor() { return myConfiguration.getConfigurationEditor(); } - public Project getProject() { - return myConfiguration.getProject(); - } - @NotNull public ConfigurationType getType() { return myConfiguration.getType(); @@ -183,6 +170,20 @@ public class AbstractRerunFailedTestsAction extends AnAction { return myConfiguration.getUniqueID(); } + public LogFileOptions getOptionsForPredefinedLogFile(PredefinedLogFile predefinedLogFile) { + return myConfiguration.getOptionsForPredefinedLogFile(predefinedLogFile); + } + public ArrayList getPredefinedLogFiles() { + return myConfiguration.getPredefinedLogFiles(); + } + + public ArrayList getAllLogFiles() { + return myConfiguration.getAllLogFiles(); + } + + public ArrayList getLogFiles() { + return myConfiguration.getLogFiles(); + } } } \ No newline at end of file From 11373491d27e65ea028b9752a2c7c42b4ed52af0 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 12 Nov 2009 16:29:05 +0300 Subject: [PATCH 04/36] inline superclass: process default/implicit constructors (IDEADEV-41326) --- .../InlineSuperClassRefactoringProcessor.java | 50 +++++++++++++++++-- .../CopyDefaultConstructorUsageInfo.java | 47 +++++++++++++++++ .../usageInfo/InlineSuperCallUsageInfo.java | 13 ++++- .../after/Test.java | 6 +++ .../before/Super.java | 5 ++ .../before/Test.java | 5 ++ .../multipleConstructors/after/Test.java | 3 +- .../after/Test.java | 6 +++ .../before/Super.java | 5 ++ .../before/Test.java | 3 ++ .../superConstructorWithParam/after/Test.java | 6 ++- .../refactoring/InlineSuperClassTest.java | 8 +++ 12 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/CopyDefaultConstructorUsageInfo.java create mode 100644 java/java-tests/testData/refactoring/inlineSuperClass/childConstructorImplicitlyCallsSuper/after/Test.java create mode 100644 java/java-tests/testData/refactoring/inlineSuperClass/childConstructorImplicitlyCallsSuper/before/Super.java create mode 100644 java/java-tests/testData/refactoring/inlineSuperClass/childConstructorImplicitlyCallsSuper/before/Test.java create mode 100644 java/java-tests/testData/refactoring/inlineSuperClass/noChildConstructorCallsSuperDefault/after/Test.java create mode 100644 java/java-tests/testData/refactoring/inlineSuperClass/noChildConstructorCallsSuperDefault/before/Super.java create mode 100644 java/java-tests/testData/refactoring/inlineSuperClass/noChildConstructorCallsSuperDefault/before/Test.java diff --git a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java index 7c34cf7e9974..fe69892a9ca7 100644 --- a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java @@ -34,13 +34,13 @@ import com.intellij.refactoring.memberPushDown.PushDownProcessor; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.FixableUsageInfo; import com.intellij.refactoring.util.FixableUsagesRefactoringProcessor; +import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.refactoring.util.classMembers.MemberInfoStorage; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; import com.intellij.util.IncorrectOperationException; -import com.intellij.util.Processor; -import com.intellij.util.containers.HashMap; +import com.intellij.util.Processor;import com.intellij.util.containers.HashMap; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; @@ -79,6 +79,7 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); final PsiElementFactory elementFactory = facade.getElementFactory(); final PsiResolveHelper resolveHelper = facade.getResolveHelper(); + ReferencesSearch.search(mySuperClass).forEach(new Processor() { public boolean process(final PsiReference reference) { final PsiElement element = reference.getElement(); @@ -134,12 +135,14 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori for (PsiReference reference : ReferencesSearch.search(member, member.getUseScope(), true)) { final PsiElement element = reference.getElement(); if (element instanceof PsiReferenceExpression && - ((PsiReferenceExpression)element).getQualifierExpression() instanceof PsiSuperExpression && PsiTreeUtil.isAncestor( - targetClass, element, false)) { + ((PsiReferenceExpression)element).getQualifierExpression() instanceof PsiSuperExpression && + PsiTreeUtil.isAncestor(targetClass, element, false)) { usages.add(new RemoveQualifierUsageInfo((PsiReferenceExpression)element)); } } } + + final PsiMethod[] superConstructors = mySuperClass.getConstructors(); for (PsiMethod constructor : targetClass.getConstructors()) { final PsiCodeBlock constrBody = constructor.getBody(); LOG.assertTrue(constrBody != null); @@ -154,11 +157,30 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori final PsiMethod superConstructor = ((PsiMethodCallExpression)expression).resolveMethod(); if (superConstructor != null && superConstructor.getBody() != null) { usages.add(new InlineSuperCallUsageInfo((PsiMethodCallExpression)expression)); + continue; } } } } } + + //insert implicit call to super + for (PsiMethod superConstructor : superConstructors) { + if (superConstructor.getParameterList().getParametersCount() == 0) { + final PsiExpression expression = JavaPsiFacade.getElementFactory(myProject).createExpressionFromText("super()", constructor); + usages.add(new InlineSuperCallUsageInfo((PsiMethodCallExpression)expression, constrBody)); + } + } + } + + if (targetClass.getConstructors().length == 0) { + //copy default constructor + for (PsiMethod superConstructor : superConstructors) { + if (superConstructor.getParameterList().getParametersCount() == 0) { + usages.add(new CopyDefaultConstructorUsageInfo(targetClass, superConstructor)); + break; + } + } } } } @@ -191,7 +213,25 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori } }.run(); replaceInnerTypeUsages(); - super.performRefactoring(usages); + + RefactoringUtil.sortDepthFirstRightLeftOrder(usages); + for (UsageInfo usageInfo : usages) { + if (!(usageInfo instanceof ReplaceExtendsListUsageInfo)) { + try { + ((FixableUsageInfo)usageInfo).fixUsage(); + } + catch (IncorrectOperationException e) { + LOG.info(e); + } + } + } + + //postpone broken hierarchy + for (UsageInfo usage : usages) { + if (usage instanceof ReplaceExtendsListUsageInfo) { + ((ReplaceExtendsListUsageInfo)usage).fixUsage(); + } + } try { mySuperClass.delete(); } diff --git a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/CopyDefaultConstructorUsageInfo.java b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/CopyDefaultConstructorUsageInfo.java new file mode 100644 index 000000000000..dff42d11468d --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/CopyDefaultConstructorUsageInfo.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2009 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. + */ + +/* + * User: anna + * Date: 27-Aug-2008 + */ +package com.intellij.refactoring.inlineSuperClass.usageInfo; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiCodeBlock; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.util.FixableUsageInfo; +import com.intellij.util.IncorrectOperationException; + +public class CopyDefaultConstructorUsageInfo extends FixableUsageInfo{ + private final PsiClass myTargetClass; + private final PsiMethod myConstructor; + + + public CopyDefaultConstructorUsageInfo(PsiClass targetClass, PsiMethod constructor) { + super(targetClass); + myTargetClass = targetClass; + myConstructor = constructor; + } + + public void fixUsage() throws IncorrectOperationException { + final PsiCodeBlock body = myConstructor.getBody(); + assert body != null; + if (body.getFirstBodyElement() != null) { //do not copy empty constructor + myTargetClass.add(myConstructor.copy()); + } + } +} \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/InlineSuperCallUsageInfo.java b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/InlineSuperCallUsageInfo.java index f3137b27672c..1115aefe8cb6 100644 --- a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/InlineSuperCallUsageInfo.java +++ b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/InlineSuperCallUsageInfo.java @@ -34,14 +34,25 @@ import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; public class InlineSuperCallUsageInfo extends FixableUsageInfo { + private PsiCodeBlock myConstrBody; public InlineSuperCallUsageInfo(PsiMethodCallExpression methodCallExpression) { super(methodCallExpression); } + public InlineSuperCallUsageInfo(PsiMethodCallExpression methodCallExpression, PsiCodeBlock constrBody) { + super(methodCallExpression); + myConstrBody = constrBody; + } + @Override public void fixUsage() throws IncorrectOperationException { - final PsiElement element = getElement(); + PsiElement element = getElement(); + if (element != null && myConstrBody != null) { + assert !element.isPhysical(); + final PsiStatement statement = JavaPsiFacade.getElementFactory(getProject()).createStatementFromText("super();", myConstrBody); + element = ((PsiExpressionStatement)myConstrBody.addBefore(statement, myConstrBody.getFirstBodyElement())).getExpression(); + } if (element instanceof PsiMethodCallExpression) { PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)element).getMethodExpression(); final PsiMethod superConstructor = (PsiMethod)methodExpression.resolve(); diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/childConstructorImplicitlyCallsSuper/after/Test.java b/java/java-tests/testData/refactoring/inlineSuperClass/childConstructorImplicitlyCallsSuper/after/Test.java new file mode 100644 index 000000000000..2373b7cf2919 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineSuperClass/childConstructorImplicitlyCallsSuper/after/Test.java @@ -0,0 +1,6 @@ +class Test { + Test() { + System.out.println("Super"); + System.out.println("Test"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/childConstructorImplicitlyCallsSuper/before/Super.java b/java/java-tests/testData/refactoring/inlineSuperClass/childConstructorImplicitlyCallsSuper/before/Super.java new file mode 100644 index 000000000000..b72e7b53d7fb --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineSuperClass/childConstructorImplicitlyCallsSuper/before/Super.java @@ -0,0 +1,5 @@ +class Super { + Super() { + System.out.println("Super"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/childConstructorImplicitlyCallsSuper/before/Test.java b/java/java-tests/testData/refactoring/inlineSuperClass/childConstructorImplicitlyCallsSuper/before/Test.java new file mode 100644 index 000000000000..27b95120df33 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineSuperClass/childConstructorImplicitlyCallsSuper/before/Test.java @@ -0,0 +1,5 @@ +class Test extends Super{ + Test() { + System.out.println("Test"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/multipleConstructors/after/Test.java b/java/java-tests/testData/refactoring/inlineSuperClass/multipleConstructors/after/Test.java index bfc7012bf28a..798a7f2e7f99 100644 --- a/java/java-tests/testData/refactoring/inlineSuperClass/multipleConstructors/after/Test.java +++ b/java/java-tests/testData/refactoring/inlineSuperClass/multipleConstructors/after/Test.java @@ -1,5 +1,6 @@ class Test { - Test(String s){super(s);} + Test(String s){ + } void foo() { Test s = new Test(""); diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/noChildConstructorCallsSuperDefault/after/Test.java b/java/java-tests/testData/refactoring/inlineSuperClass/noChildConstructorCallsSuperDefault/after/Test.java new file mode 100644 index 000000000000..20fc1a5c93e1 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineSuperClass/noChildConstructorCallsSuperDefault/after/Test.java @@ -0,0 +1,6 @@ +class Test { + + Test() { + System.out.println(""); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/noChildConstructorCallsSuperDefault/before/Super.java b/java/java-tests/testData/refactoring/inlineSuperClass/noChildConstructorCallsSuperDefault/before/Super.java new file mode 100644 index 000000000000..f92c6de3cf6b --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineSuperClass/noChildConstructorCallsSuperDefault/before/Super.java @@ -0,0 +1,5 @@ +class Super { + Super() { + System.out.println(""); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/noChildConstructorCallsSuperDefault/before/Test.java b/java/java-tests/testData/refactoring/inlineSuperClass/noChildConstructorCallsSuperDefault/before/Test.java new file mode 100644 index 000000000000..87dc25bd8bbc --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineSuperClass/noChildConstructorCallsSuperDefault/before/Test.java @@ -0,0 +1,3 @@ +class Test extends Super{ + +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/superConstructorWithParam/after/Test.java b/java/java-tests/testData/refactoring/inlineSuperClass/superConstructorWithParam/after/Test.java index df4758f7b040..cd4bab30bcba 100644 --- a/java/java-tests/testData/refactoring/inlineSuperClass/superConstructorWithParam/after/Test.java +++ b/java/java-tests/testData/refactoring/inlineSuperClass/superConstructorWithParam/after/Test.java @@ -2,8 +2,10 @@ class Test { String s; Test(String s){ - super(s); - System.out.println("hello"); + if (s != null) { + this.s = s; + } + System.out.println("hello"); } void foo() { diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java index 7c72ef08f403..e44006ef5ff3 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java @@ -147,6 +147,14 @@ public class InlineSuperClassTest extends MultiFileTestCase { doTest(); } + public void testChildConstructorImplicitlyCallsSuper() throws Exception { + doTest(); + } + + public void testNoChildConstructorCallsSuperDefault() throws Exception { + doTest(); + } + public void testMultipleSubclasses() throws Exception { doTest(new PerformAction() { public void performAction(final VirtualFile rootDir, final VirtualFile rootAfter) throws Exception { From 1d1e4ba7fa8d53ba7685cf0af66a9fa64b2d3aaf Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 12 Nov 2009 17:12:35 +0300 Subject: [PATCH 05/36] encapsulate fields: do not invoke refactoring on empty set of fields --- .../encapsulateFields/EncapsulateFieldsDialog.java | 5 +++++ .../encapsulateFields/EncapsulateFieldsHandler.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java index cee5a2a4fd7a..4431cb52cebc 100644 --- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java @@ -457,6 +457,11 @@ public String getAccessorsVisibility() { return; } + if (getCheckedRows().length == 0) { + CommonRefactoringUtil.showErrorMessage(REFACTORING_NAME, "Nothing found to encapsulate", HelpID.ENCAPSULATE_FIELDS, myProject); + return; + } + invokeRefactoring(new EncapsulateFieldsProcessor(myProject, this)); JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance(); settings.ENCAPSULATE_FIELDS_USE_ACCESSORS_WHEN_ACCESSIBLE = myCbUseAccessorsWhenAccessible.isSelected(); diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java index fa2a1433fb10..925c63147d85 100644 --- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java @@ -106,6 +106,11 @@ public class EncapsulateFieldsHandler implements RefactoringActionHandler { } LOG.assertTrue(aClass != null); + final PsiField[] fields = aClass.getFields(); + if (fields.length == 0) { + CommonRefactoringUtil.showErrorHint(project, PlatformDataKeys.EDITOR.getData(dataContext), "Class has no fields to encapsulate", REFACTORING_NAME, HelpID.ENCAPSULATE_FIELDS); + return; + } if (aClass.isInterface()) { String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("encapsulate.fields.refactoring.cannot.be.applied.to.interface")); From 15a71e3b667d5b8c660ed980aef0dd1f4ea92b84 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 12 Nov 2009 17:19:49 +0300 Subject: [PATCH 06/36] NPE --- .../EncapsulateFieldsProcessor.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java index 4a4f2d29f087..c5ef1894fb82 100644 --- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java @@ -79,8 +79,11 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor { protected boolean preprocessUsages(Ref refUsages) { final MultiMap conflicts = new MultiMap(); - checkExistingMethods(myDescriptor.getGetterPrototypes(), conflicts, true); - checkExistingMethods(myDescriptor.getSetterPrototypes(), conflicts, false); + final PsiMethod[] getterPrototypes = myDescriptor.getGetterPrototypes(); + final PsiMethod[] setterPrototypes = myDescriptor.getSetterPrototypes(); + + checkExistingMethods(getterPrototypes, conflicts, true); + checkExistingMethods(setterPrototypes, conflicts, false); final Collection classes = ClassInheritorsSearch.search(myClass).findAll(); for (int i = 0; i < myFields.length; i++) { final PsiField field = myFields[i]; @@ -88,11 +91,11 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor { final Set getters = new HashSet(); for (PsiClass aClass : classes) { - final PsiMethod getterOverrider = aClass.findMethodBySignature(myDescriptor.getGetterPrototypes()[i], false); + final PsiMethod getterOverrider = getterPrototypes != null ? aClass.findMethodBySignature(getterPrototypes[i], false) : null; if (getterOverrider != null) { getters.add(getterOverrider); } - final PsiMethod setterOverrider = aClass.findMethodBySignature(myDescriptor.getSetterPrototypes()[i], false); + final PsiMethod setterOverrider = setterPrototypes != null ? aClass.findMethodBySignature(setterPrototypes[i], false) : null; if (setterOverrider != null) { setters.add(setterOverrider); } @@ -534,7 +537,7 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor { else { return null; } - if(containingClass.isInheritor(myClass, false)) { + if(containingClass != null && containingClass.isInheritor(myClass, false)) { final PsiExpression newMethodExpression = factory.createExpressionFromText("super." + targetMethod.getName(), context); methodCall.getMethodExpression().replace(newMethodExpression); From 370ea04931a4d1d85f6a6fda6097a0d054b71c51 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 12 Nov 2009 18:24:40 +0300 Subject: [PATCH 07/36] AIOOBE (17122) --- .../usageInfo/ReplaceConstructorWithSettersChainInfo.java | 2 +- .../replaceConstructorWithBuilder/varargs/after/Test.java | 1 + .../replaceConstructorWithBuilder/varargs/before/Test.java | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/usageInfo/ReplaceConstructorWithSettersChainInfo.java b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/usageInfo/ReplaceConstructorWithSettersChainInfo.java index 7a149f1221e6..0510863beb37 100644 --- a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/usageInfo/ReplaceConstructorWithSettersChainInfo.java +++ b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/usageInfo/ReplaceConstructorWithSettersChainInfo.java @@ -54,7 +54,7 @@ public class ReplaceConstructorWithSettersChainInfo extends FixableUsageInfo { final PsiParameter[] parameters = constructor.getParameterList().getParameters(); final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(constructor.getProject()); - for (int i = 0; i < constructor.getParameterList().getParametersCount(); i++) { + for (int i = 0; i < Math.min(constructor.getParameterList().getParametersCount(), args.length); i++) { String arg = args[i].getText(); if (parameters[i].isVarArgs()) { for(int ia = i + 1; ia < args.length; ia++) { diff --git a/java/java-tests/testData/refactoring/replaceConstructorWithBuilder/varargs/after/Test.java b/java/java-tests/testData/refactoring/replaceConstructorWithBuilder/varargs/after/Test.java index 9efc7ff4b230..4486a59bb548 100644 --- a/java/java-tests/testData/refactoring/replaceConstructorWithBuilder/varargs/after/Test.java +++ b/java/java-tests/testData/refactoring/replaceConstructorWithBuilder/varargs/after/Test.java @@ -3,5 +3,6 @@ public class Test { void foo(){} public static void main(String[] args){ new Builder().setI(1, 2, 3).createTest().foo(); + new Builder().createTest().foo(); } } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/replaceConstructorWithBuilder/varargs/before/Test.java b/java/java-tests/testData/refactoring/replaceConstructorWithBuilder/varargs/before/Test.java index be0ebb461b02..47e68a521d78 100644 --- a/java/java-tests/testData/refactoring/replaceConstructorWithBuilder/varargs/before/Test.java +++ b/java/java-tests/testData/refactoring/replaceConstructorWithBuilder/varargs/before/Test.java @@ -3,5 +3,6 @@ public class Test { void foo(){} public static void main(String[] args){ new Test(1, 2, 3).foo(); + new Test().foo(); } } \ No newline at end of file From 6cd7e105c79ebdb33162a5dc4453fc87d9974823 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 12 Nov 2009 18:49:08 +0300 Subject: [PATCH 08/36] replace constructor with builder: fill initial package; request focus to corresponding components --- .../ReplaceConstructorWithBuilderDialog.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java index 09e3d1e6368d..d041fdad3ddb 100644 --- a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java @@ -26,6 +26,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.RefactoringBundle; @@ -108,6 +109,8 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog { final ActionListener enableDisableListener = new ActionListener() { public void actionPerformed(final ActionEvent e) { setEnabled(myCreateBuilderClassRadioButton.isSelected()); + IdeFocusManager.getInstance(myProject).requestFocus( + myCreateBuilderClassRadioButton.isSelected() ? myNewClassName : myExistentClassTF.getChildComponent(), true); validateButtons(); } }; @@ -209,7 +212,7 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog { }; myPackageTextField = - new PackageNameReferenceEditorCombo("", myProject, RECENT_KEYS, RefactoringBundle.message("choose.destination.package")); + new PackageNameReferenceEditorCombo(((PsiJavaFile)myConstructors[0].getContainingFile()).getPackageName(), myProject, RECENT_KEYS, RefactoringBundle.message("choose.destination.package")); myPackageTextField.getChildComponent().getDocument().addDocumentListener(adapter); @@ -307,7 +310,7 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog { case PARAM: return "Parameter"; case FIELD: - return "Fieled Name"; + return "Field Name"; case SETTER: return "Setter Name"; case DEFAULT_VALUE: From d35a81bae3cfa770df1c5ddf9c4ab7202414542e Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 12 Nov 2009 19:33:05 +0300 Subject: [PATCH 09/36] invoke translating compilers per-module chunk --- .../intellij/compiler/impl/CompileDriver.java | 170 +++++++++----- .../AnnotationProcessingCompiler.java | 4 +- .../javaCompiler/BackendCompilerWrapper.java | 219 ++++++------------ .../DummyTranslatingCompiler.java | 3 +- .../impl/javaCompiler/JavaCompiler.java | 7 +- .../resourceCompiler/ResourceCompiler.java | 19 +- .../intellij/compiler/make/CacheUtils.java | 77 +++++- .../compiler/make/DependencyCache.java | 15 +- .../compiler/make/StorageClassId.java | 46 ---- .../compiler/make/StorageFieldId.java | 47 ---- .../compiler/make/StorageMethodId.java | 54 ----- .../openapi/compiler/TranslatingCompiler.java | 9 +- .../groovy/compiler/GroovyCompilerBase.java | 64 ++--- .../generator/GroovycStubGenerator.java | 5 +- .../make/Form2ByteCodeCompiler.java | 2 +- 15 files changed, 327 insertions(+), 414 deletions(-) delete mode 100644 java/compiler/impl/src/com/intellij/compiler/make/StorageClassId.java delete mode 100644 java/compiler/impl/src/com/intellij/compiler/make/StorageFieldId.java delete mode 100644 java/compiler/impl/src/com/intellij/compiler/make/StorageMethodId.java diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index ace9d8dac9c7..38a99a7acbd2 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -25,6 +25,7 @@ import com.intellij.CommonBundle; import com.intellij.analysis.AnalysisScope; import com.intellij.compiler.*; import com.intellij.compiler.make.CacheCorruptedException; +import com.intellij.compiler.make.CacheUtils; import com.intellij.compiler.make.DependencyCache; import com.intellij.compiler.progress.CompilerTask; import com.intellij.diagnostic.IdeErrorsDialog; @@ -47,6 +48,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; @@ -840,67 +842,121 @@ public class CompileDriver { final TranslatingCompiler[] translators = compilerManager.getCompilers(TranslatingCompiler.class, myCompilerFilter); - final Set generatedTypes = new HashSet(); - VirtualFile[] snapshot = null; + final List> sortedChunks = Collections.unmodifiableList(ApplicationManager.getApplication().runReadAction(new Computable>>() { + public List> compute() { + final ModuleManager moduleManager = ModuleManager.getInstance(myProject); + return ModuleCompilerUtil.getSortedModuleChunks(myProject, Arrays.asList(moduleManager.getModules())); + } + })); - final TranslatorsOutputSink sink = new TranslatorsOutputSink(context, translators); try { - for (int currentCompiler = 0, translatorsLength = translators.length; currentCompiler < translatorsLength; currentCompiler++) { - sink.setCurrentCompilerIndex(currentCompiler); - final TranslatingCompiler translator = translators[currentCompiler]; - if (context.getProgressIndicator().isCanceled()) { - throw new ExitException(ExitStatus.CANCELLED); - } - - DumbService.getInstance(myProject).waitForSmartMode(); - - if (snapshot == null || ContainerUtil.intersects(generatedTypes, compilerManager.getRegisteredInputTypes(translator))) { - // rescan snapshot if previously generated files can influence the input of this compiler - snapshot = ApplicationManager.getApplication().runReadAction(new Computable() { - public VirtualFile[] compute() { - return context.getCompileScope().getFiles(null, true); - } - }); - } - - final CompileContextEx _context; - if (translator instanceof IntermediateOutputCompiler) { - // wrap compile context so that output goes into intermediate directories - final IntermediateOutputCompiler _translator = (IntermediateOutputCompiler)translator; - _context = new CompileContextExProxy(context) { - public VirtualFile getModuleOutputDirectory(final Module module) { - return getGenerationOutputDir(_translator, module, false); + VirtualFile[] snapshot = null; + final Map, Collection> chunkMap = new HashMap, Collection>(); + int total = 0; + int processed = 0; + for (final Chunk currentChunk : sortedChunks) { + final TranslatorsOutputSink sink = new TranslatorsOutputSink(context, translators); + final Set generatedTypes = new HashSet(); + Collection chunkFiles = chunkMap.get(currentChunk); + try { + for (int currentCompiler = 0, translatorsLength = translators.length; currentCompiler < translatorsLength; currentCompiler++) { + sink.setCurrentCompilerIndex(currentCompiler); + final TranslatingCompiler compiler = translators[currentCompiler]; + if (context.getProgressIndicator().isCanceled()) { + throw new ExitException(ExitStatus.CANCELLED); } - public VirtualFile getModuleOutputDirectoryForTests(final Module module) { - return getGenerationOutputDir(_translator, module, true); + DumbService.getInstance(myProject).waitForSmartMode(); + + if (snapshot == null || ContainerUtil.intersects(generatedTypes, compilerManager.getRegisteredInputTypes(compiler))) { + // rescan snapshot if previously generated files may influence the input of this compiler + snapshot = ApplicationManager.getApplication().runReadAction(new Computable() { + public VirtualFile[] compute() { + return context.getCompileScope().getFiles(null, true); + } + }); + final Map> moduleToFilesMap = CompilerUtil.buildModuleToFilesMap(context, snapshot); + for (Chunk moduleChunk : sortedChunks) { + List files = Collections.emptyList(); + for (Module module : moduleChunk.getNodes()) { + final List moduleFiles = moduleToFilesMap.get(module); + if (moduleFiles != null) { + files = ContainerUtil.concat(files, moduleFiles); + } + } + chunkMap.put(moduleChunk, files); + } + total = snapshot.length * translatorsLength; + chunkFiles = chunkMap.get(currentChunk); } - }; - } - else { - _context = context; - } - final boolean compiledSomething = - compileSources(_context, translators, currentCompiler, snapshot, forceCompile, isRebuild, trackDependencies, onlyCheckStatus, sink); - if (compiledSomething) { - generatedTypes.addAll(compilerManager.getRegisteredOutputTypes(translator)); - } + final CompileContextEx _context; + if (compiler instanceof IntermediateOutputCompiler) { + // wrap compile context so that output goes into intermediate directories + final IntermediateOutputCompiler _compiler = (IntermediateOutputCompiler)compiler; + _context = new CompileContextExProxy(context) { + public VirtualFile getModuleOutputDirectory(final Module module) { + return getGenerationOutputDir(_compiler, module, false); + } - if (_context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { - throw new ExitException(ExitStatus.ERRORS); - } + public VirtualFile getModuleOutputDirectoryForTests(final Module module) { + return getGenerationOutputDir(_compiler, module, true); + } + }; + } + else { + _context = context; + } + final boolean compiledSomething = + compileSources(_context, currentChunk, compiler, chunkFiles, forceCompile, isRebuild, trackDependencies, onlyCheckStatus, sink); - didSomething |= compiledSomething; + processed += chunkFiles.size(); + _context.getProgressIndicator().setFraction(((double)processed) / total); + + if (compiledSomething) { + generatedTypes.addAll(compilerManager.getRegisteredOutputTypes(compiler)); + } + + if (_context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + throw new ExitException(ExitStatus.ERRORS); + } + + didSomething |= compiledSomething; + } + } + finally { + if (context.getMessageCount(CompilerMessageCategory.ERROR) == 0) { + // perform update only if there were no errors, so it is guaranteed that the file was processd by all neccesary compilers + sink.flushPostponedItems(); + } + } } } + catch (ProcessCanceledException e) { + ProgressManager.getInstance().executeNonCancelableSection(new Runnable() { + public void run() { + try { + final Collection deps = CacheUtils.findDependentFiles(context, Collections.emptySet(), null, null); + if (deps.size() > 0) { + TranslatingCompilerFilesMonitor.getInstance().update(context, null, Collections.emptyList(), deps.toArray(new VirtualFile[deps.size()])); + } + } + catch (IOException ignored) { + LOG.info(ignored); + } + catch (CacheCorruptedException ignored) { + LOG.info(ignored); + } + } + }); + throw e; + } finally { - if (context.getMessageCount(CompilerMessageCategory.ERROR) == 0) { - // perform update only if there were no errors, so it is guaranteed that the file was processd by all neccesary compilers - sink.flushPostponedItems(); - } dropDependencyCache(context); + if (didSomething) { + TranslatingCompilerFilesMonitor.getInstance().updateOutputRootsLayout(myProject); + } } return didSomething; } @@ -1353,15 +1409,13 @@ public class CompileDriver { }; } - private boolean compileSources(final CompileContextEx context, TranslatingCompiler[] compilers, int currentCompiler, final VirtualFile[] sources, + private boolean compileSources(final CompileContextEx context, final Chunk moduleChunk, final TranslatingCompiler compiler, final Collection srcSnapshot, final boolean forceCompile, final boolean isRebuild, final boolean trackDependencies, final boolean onlyCheckStatus, TranslatingCompiler.OutputSink sink) throws ExitException { - final TranslatingCompiler compiler = compilers[currentCompiler]; - final Set toCompile = new HashSet(); final List> toDelete = new ArrayList>(); context.getProgressIndicator().pushState(); @@ -1372,13 +1426,13 @@ public class CompileDriver { public void run() { TranslatingCompilerFilesMonitor.getInstance().collectFiles( - context, compiler, Arrays.asList(sources).iterator(), forceCompile, isRebuild, toCompile, toDelete + context, compiler, srcSnapshot.iterator(), forceCompile, isRebuild, toCompile, toDelete ); if (trackDependencies && !toCompile.isEmpty()) { // should add dependent files + // todo: drop this? final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); final PsiManager psiManager = PsiManager.getInstance(myProject); - final VirtualFile[] filesToCompile = toCompile.toArray(new VirtualFile[toCompile.size()]); - for (final VirtualFile file : filesToCompile) { + for (final VirtualFile file : toCompile.toArray(new VirtualFile[toCompile.size()])) { if (fileTypeManager.getFileTypeByFile(file) == StdFileTypes.JAVA) { final PsiFile psiFile = psiManager.findFile(file); if (psiFile != null) { @@ -1414,9 +1468,9 @@ public class CompileDriver { context.requestRebuildNextTime(e.getMessage()); } } - + if ((wereFilesDeleted[0] || !toCompile.isEmpty()) && context.getMessageCount(CompilerMessageCategory.ERROR) == 0) { - compiler.compile(context, toCompile.toArray(new VirtualFile[toCompile.size()]), sink); + compiler.compile(context, moduleChunk, toCompile.toArray(new VirtualFile[toCompile.size()]), sink); } } finally { @@ -1729,7 +1783,6 @@ public class CompileDriver { return true; } - // todo: add validation for module chunks: all modules that form a chunk must have the same JDK private boolean validateCompilerConfiguration(final CompileScope scope, boolean checkOutputAndSourceIntersection) { final Module[] scopeModules = scope.getAffectedModules()/*ModuleManager.getInstance(myProject).getModules()*/; final List modulesWithoutOutputPathSpecified = new ArrayList(); @@ -2188,9 +2241,6 @@ public class CompileDriver { LOG.info(e); myContext.requestRebuildNextTime(e.getMessage()); } - finally { - filesMonitor.updateOutputRootsLayout(myContext.getProject()); - } } } } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessingCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessingCompiler.java index 70407ba1eb40..c8fa49fc14cb 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessingCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessingCompiler.java @@ -34,6 +34,7 @@ import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Chunk; import org.jetbrains.annotations.NotNull; import java.io.DataInput; @@ -90,7 +91,8 @@ public class AnnotationProcessingCompiler implements SourceProcessingCompiler{ private void compile(final CompileContext context, final VirtualFile[] files) { final JavacCompiler javacCompiler = getBackEndCompiler(); final boolean processorMode = javacCompiler.setAnnotationProcessorMode(true); - final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(myProject, Arrays.asList(files), (CompileContextEx)context, javacCompiler, DummySink.INSTANCE); + final Chunk dummyChunk = new Chunk(Collections.emptySet()); // TODO! + final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(dummyChunk, myProject, Arrays.asList(files), (CompileContextEx)context, javacCompiler, DummySink.INSTANCE); try { wrapper.compile(); } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java index b9586b133bec..137b51e7d445 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java @@ -51,12 +51,13 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Chunk; +import com.intellij.util.Function; import com.intellij.util.cls.ClsFormatException; -import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; import gnu.trove.TIntHashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; @@ -78,6 +79,7 @@ public class BackendCompilerWrapper { private final CompileContextEx myCompileContext; private final List myFilesToCompile; private final TranslatingCompiler.OutputSink mySink; + private final Chunk myChunk; private final Project myProject; private final Set myFilesToRecompile; private final Map myModuleToTempDirMap = new THashMap(); @@ -88,10 +90,11 @@ public class BackendCompilerWrapper { public final Map> myFileNameToSourceMap= new THashMap>(); - public BackendCompilerWrapper(@NotNull final Project project, + public BackendCompilerWrapper(Chunk chunk, @NotNull final Project project, @NotNull List filesToCompile, @NotNull CompileContextEx compileContext, @NotNull BackendCompiler compiler, TranslatingCompiler.OutputSink sink) { + myChunk = chunk; myProject = project; myCompiler = compiler; myCompileContext = compileContext; @@ -102,7 +105,7 @@ public class BackendCompilerWrapper { mySuccesfullyCompiledJavaFiles = new HashSet(filesToCompile.size()); } - public List compile() throws CompilerException, CacheCorruptedException { + public void compile() throws CompilerException, CacheCorruptedException { Application application = ApplicationManager.getApplication(); final Set allDependent = new HashSet(); COMPILE: @@ -112,13 +115,12 @@ public class BackendCompilerWrapper { saveTestData(); } - final Map> moduleToFilesMap = CompilerUtil.buildModuleToFilesMap(myCompileContext, myFilesToCompile); - compileModules(moduleToFilesMap); + compileModules(buildModuleToFilesMap(myFilesToCompile)); } Collection dependentFiles; do { - dependentFiles = findDependentFiles(); + dependentFiles = CacheUtils.findDependentFiles(myCompileContext, mySuccesfullyCompiledJavaFiles, myCompiler.getDependencyProcessor(), DEPENDENCY_FILTER); if (!dependentFiles.isEmpty()) { myFilesToRecompile.addAll(dependentFiles); @@ -130,9 +132,8 @@ public class BackendCompilerWrapper { if (filesInScope.isEmpty()) { break; } - final Map> moduleToFilesMap = CompilerUtil.buildModuleToFilesMap(myCompileContext, filesInScope); myCompileContext.getDependencyCache().clearTraverseRoots(); - compileModules(moduleToFilesMap); + compileModules(buildModuleToFilesMap(filesInScope)); } } while (!dependentFiles.isEmpty() && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0); @@ -154,26 +155,24 @@ public class BackendCompilerWrapper { myModuleToTempDirMap.clear(); } - if (myCompileContext.getProgressIndicator().isCanceled()) { - myFilesToRecompile.clear(); - // when cancelled pretend nothing was compiled and next compile will compile everything from the scratch - return Collections.emptyList(); - } - // do not update caches if cancelled because there is a chance that they will be incomplete if (CompilerConfiguration.MAKE_ENABLED) { - ProgressIndicator indicator = myCompileContext.getProgressIndicator(); - final DependencyCache cache = myCompileContext.getDependencyCache(); + if (!myCompileContext.getProgressIndicator().isCanceled()) { + // when cancelled pretend nothing was compiled and next compile will compile everything from the scratch + final ProgressIndicator indicator = myCompileContext.getProgressIndicator(); + final DependencyCache cache = myCompileContext.getDependencyCache(); - indicator.setText(CompilerBundle.message("progress.updating.caches")); - indicator.setText2(""); + indicator.pushState(); + indicator.setText(CompilerBundle.message("progress.updating.caches")); + indicator.setText2(""); - cache.update(indicator); + cache.update(); - indicator.setText(CompilerBundle.message("progress.saving.caches")); - cache.resetState(); + indicator.setText(CompilerBundle.message("progress.saving.caches")); + cache.resetState(); - indicator.setText(""); + indicator.popState(); + } } myFilesToRecompile.removeAll(mySuccesfullyCompiledJavaFiles); @@ -184,13 +183,19 @@ public class BackendCompilerWrapper { if (myFilesToRecompile.size() > 0 || outputs.size() > 0) { mySink.add(null, outputs, myFilesToRecompile.toArray(new VirtualFile[myFilesToRecompile.size()])); } - return null; + } + + private Map> buildModuleToFilesMap(final List filesToCompile) { + if (myChunk.getNodes().size() == 1) { + return Collections.singletonMap(myChunk.getNodes().iterator().next(), Collections.unmodifiableList(filesToCompile)); + } + return CompilerUtil.buildModuleToFilesMap(myCompileContext, filesToCompile); } // package-info.java hack private List processPackageInfoFiles() { if (myFilesToRecompile.isEmpty()) { - return Collections.EMPTY_LIST; + return Collections.emptyList(); } final List outputs = new ArrayList(); ApplicationManager.getApplication().runReadAction(new Runnable() { @@ -215,13 +220,16 @@ public class BackendCompilerWrapper { return outputs; } - private List getFilesInScope(final Collection dependentFiles) { - final List filesInScope = new ArrayList(dependentFiles.size()); + private List getFilesInScope(final Collection files) { + final List filesInScope = new ArrayList(files.size()); ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { - for (VirtualFile dependentFile : dependentFiles) { - if (myCompileContext.getCompileScope().belongs(dependentFile.getUrl())) { - filesInScope.add(dependentFile); + for (VirtualFile file : files) { + if (myCompileContext.getCompileScope().belongs(file.getUrl())) { + final Module module = myCompileContext.getModuleByFile(file); + if (myChunk.getNodes().contains(module)) { + filesInScope.add(file); + } } } } @@ -230,25 +238,21 @@ public class BackendCompilerWrapper { } private void compileModules(final Map> moduleToFilesMap) throws CompilerException { - final List chunks = getModuleChunks(moduleToFilesMap); - List files = ContainerUtil.concat(moduleToFilesMap.values()); myProcessedFilesCount = 0; - myTotalFilesToCompile = files.size(); + //myTotalFilesToCompile = 0; + //for (List list : moduleToFilesMap.values()) { + // myTotalFilesToCompile += list.size(); + //} - for (final ModuleChunk chunk : chunks) { - try { - boolean success = compileChunk(chunk); - if (!success) { - return; - } - } - catch (IOException e) { - throw new CompilerException(e.getMessage(), e); - } + try { + compileChunk(new ModuleChunk(myCompileContext, myChunk, moduleToFilesMap)); + } + catch (IOException e) { + throw new CompilerException(e.getMessage(), e); } } - private boolean compileChunk(ModuleChunk chunk) throws IOException { + private void compileChunk(ModuleChunk chunk) throws IOException { runTransformingCompilers(chunk); setPresentableNameFor(chunk); @@ -259,9 +263,6 @@ public class BackendCompilerWrapper { try { for (final OutputDir outputDir : outs) { doCompile(chunk, outputDir.getPath(), outputDir.getKind()); - if (myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) { - return false; - } } } finally { @@ -269,8 +270,6 @@ public class BackendCompilerWrapper { FileUtil.asyncDelete(fileToDelete); } } - - return true; } @@ -295,6 +294,7 @@ public class BackendCompilerWrapper { }); } + @Nullable private File getOutputDirsToCompileTo(ModuleChunk chunk, final List pairs) throws IOException { File fileToDelete = null; if (chunk.getModuleCount() == 1) { // optimization @@ -333,19 +333,6 @@ public class BackendCompilerWrapper { return fileToDelete; } - private List getModuleChunks(final Map> moduleToFilesMap) { - final List modules = new ArrayList(moduleToFilesMap.keySet()); - final List> chunks = ApplicationManager.getApplication().runReadAction(new Computable>>() { - public List> compute() { - return ModuleCompilerUtil.getSortedModuleChunks(myProject, modules); - } - }); - final List moduleChunks = new ArrayList(chunks.size()); - for (final Chunk chunk : chunks) { - moduleChunks.add(new ModuleChunk(myCompileContext, chunk, moduleToFilesMap)); - } - return moduleChunks; - } private boolean shouldCompileTestsSeparately(Module module) { final String moduleTestOutputDirectory = getTestsOutputDir(module); @@ -368,77 +355,18 @@ public class BackendCompilerWrapper { private final TIntHashSet myProcessedNames = new TIntHashSet(); private final Set myProcessedFiles = new HashSet(); + private final Function>, Pair>> DEPENDENCY_FILTER = new Function>, Pair>>() { + public Pair> fun(Pair> deps) { + final TIntHashSet currentDeps = new TIntHashSet(deps.getFirst()); + currentDeps.removeAll(myProcessedNames.toArray()); + myProcessedNames.addAll(deps.getFirst()); - private Collection findDependentFiles() throws CacheCorruptedException { - if (!CompilerConfiguration.MAKE_ENABLED) { - return Collections.emptyList(); + final Set depFiles = new HashSet(deps.getSecond()); + depFiles.removeAll(myProcessedFiles); + myProcessedFiles.addAll(deps.getSecond()); + return new Pair>(currentDeps.toArray(), depFiles); } - myCompileContext.getProgressIndicator().setText(CompilerBundle.message("progress.checking.dependencies")); - - final DependencyCache dependencyCache = myCompileContext.getDependencyCache(); - - final long start = System.currentTimeMillis(); - - final Pair> deps = - dependencyCache.findDependentClasses(myCompileContext, myProject, mySuccesfullyCompiledJavaFiles, myCompiler.getDependencyProcessor()); - - final TIntHashSet currentDeps = new TIntHashSet(deps.getFirst()); - currentDeps.removeAll(myProcessedNames.toArray()); - final int[] depQNames = currentDeps.toArray(); - myProcessedNames.addAll(deps.getFirst()); - - final Set depFiles = new HashSet(deps.getSecond()); - depFiles.removeAll(myProcessedFiles); - myProcessedFiles.addAll(deps.getSecond()); - - final Set dependentFiles = new HashSet(); - final CacheCorruptedException[] _ex = {null}; - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - try { - CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(myProject); - SourceFileFinder sourceFileFinder = new SourceFileFinder(myProject, myCompileContext); - final Cache cache = dependencyCache.getCache(); - for (final int infoQName : depQNames) { - final String qualifiedName = dependencyCache.resolve(infoQName); - final String sourceFileName = cache.getSourceFileName(infoQName); - final VirtualFile file = sourceFileFinder.findSourceFile(qualifiedName, sourceFileName); - if (file != null) { - if (!compilerConfiguration.isExcludedFromCompilation(file)) { - dependentFiles.add(file); - if (ApplicationManager.getApplication().isUnitTestMode()) { - LOG.assertTrue(file.isValid()); - CompilerManagerImpl.addRecompiledPath(file.getPath()); - } - } - } - else { - LOG.info("No source file for " + dependencyCache.resolve(infoQName) + " found; source file name=" + sourceFileName); - } - } - for (final VirtualFile file : depFiles) { - if (!compilerConfiguration.isExcludedFromCompilation(file)) { - dependentFiles.add(file); - if (ApplicationManager.getApplication().isUnitTestMode()) { - LOG.assertTrue(file.isValid()); - CompilerManagerImpl.addRecompiledPath(file.getPath()); - } - } - } - } - catch (CacheCorruptedException e) { - _ex[0] = e; - } - } - }); - if (_ex[0] != null) { - throw _ex[0]; - } - myCompileContext.getProgressIndicator().setText(CompilerBundle.message("progress.found.dependent.files", dependentFiles.size())); - - CompilerUtil.logDuration("Finding dependencies", System.currentTimeMillis() - start); - return dependentFiles; - } + }; private final Object lock = new Object(); @@ -736,11 +664,11 @@ public class BackendCompilerWrapper { return compiledWithErrors; } - private void buildOutputItemsList(final String outputDir, Module module, VirtualFile from, - final FileTypeManager typeManager, - final Set compiledWithErrors, - final VirtualFile sourceRoot, - final String packagePrefix, final List filesToRefresh, final Map> results) throws CacheCorruptedException { + private void buildOutputItemsList(final String outputDir, Module module, VirtualFile from, + final FileTypeManager typeManager, + final Set compiledWithErrors, + final VirtualFile sourceRoot, + final String packagePrefix, final List filesToRefresh, final Map> results) throws CacheCorruptedException { final Ref exRef = new Ref(null); final ModuleFileIndex fileIndex = ModuleRootManager.getInstance(module).getFileIndex(); final ContentIterator contentIterator = new ContentIterator() { @@ -777,8 +705,9 @@ public class BackendCompilerWrapper { } }.iterateContent(from); } - if (exRef.get() != null) { - throw exRef.get(); + final CacheCorruptedException exc = exRef.get(); + if (exc != null) { + throw exc; } } @@ -843,6 +772,7 @@ public class BackendCompilerWrapper { } } + @Nullable private Pair moveToRealLocation(String tempOutputDir, String pathToClass, VirtualFile sourceFile, final List filesToRefresh) { final Module module = myCompileContext.getModuleByFile(sourceFile); if (module == null) { @@ -873,11 +803,9 @@ public class BackendCompilerWrapper { boolean success = fromFile.renameTo(toFile); if (!success) { // assuming cause of the fail: intermediate dirs do not exist - final File parentFile = toFile.getParentFile(); - if (parentFile != null) { - parentFile.mkdirs(); - success = fromFile.renameTo(toFile); // retry after making non-existent dirs - } + FileUtil.createParentDirs(toFile); + // retry after making non-existent dirs + success = fromFile.renameTo(toFile); } if (!success) { // failed to move the file: e.g. because source and destination reside on different mountpoints. try { @@ -921,9 +849,8 @@ public class BackendCompilerWrapper { return out; } - private int myProcessedFilesCount = 0; - private int myTotalFilesToCompile = 0; - private int myClassesCount = 0; + private volatile int myProcessedFilesCount = 0; + private volatile int myClassesCount = 0; private volatile String myModuleName = null; private void sourceFileProcessed() { @@ -941,7 +868,7 @@ public class BackendCompilerWrapper { msg = CompilerBundle.message("statistics.files.classes", myProcessedFilesCount, myClassesCount); } myCompileContext.getProgressIndicator().setText2(msg); - myCompileContext.getProgressIndicator().setFraction(1.0* myProcessedFilesCount /myTotalFilesToCompile); + //myCompileContext.getProgressIndicator().setFraction(1.0* myProcessedFilesCount /myTotalFilesToCompile); } private class ClassParsingThread implements Runnable { diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummyTranslatingCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummyTranslatingCompiler.java index 2d0dae2da064..573b7e02323d 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummyTranslatingCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummyTranslatingCompiler.java @@ -21,6 +21,7 @@ import com.intellij.openapi.compiler.*; import com.intellij.openapi.module.Module; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Chunk; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -40,7 +41,7 @@ public class DummyTranslatingCompiler implements TranslatingCompiler, Intermedia return file.getName().endsWith(FILETYPE_EXTENSION); } - public void compile(final CompileContext context, final VirtualFile[] files, OutputSink sink) { + public void compile(final CompileContext context, Chunk moduleChunk, final VirtualFile[] files, OutputSink sink) { final List filesToRefresh = new ArrayList(); final Map> outputs = new HashMap>(); ApplicationManager.getApplication().runReadAction(new Runnable() { diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java index 3f910231e624..60043afb6524 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java @@ -30,8 +30,10 @@ import com.intellij.openapi.compiler.ex.CompileContextEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Chunk; import org.jetbrains.annotations.NotNull; import java.util.Arrays; @@ -54,10 +56,9 @@ public class JavaCompiler implements TranslatingCompiler { return FILE_TYPE_MANAGER.getFileTypeByFile(file).equals(StdFileTypes.JAVA); } - public void compile(CompileContext context, VirtualFile[] files, OutputSink sink) { + public void compile(CompileContext context, Chunk moduleChunk, VirtualFile[] files, OutputSink sink) { final BackendCompiler backEndCompiler = getBackEndCompiler(); - final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(myProject, Arrays.asList(files), (CompileContextEx)context, backEndCompiler, - sink); + final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(moduleChunk, myProject, Arrays.asList(files), (CompileContextEx)context, backEndCompiler, sink); try { wrapper.compile(); } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java index f2bac34c2ebb..468618c3b296 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java @@ -39,6 +39,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.Chunk; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -70,12 +71,13 @@ public class ResourceCompiler implements TranslatingCompiler { return !StdFileTypes.JAVA.equals(FILE_TYPE_MANAGER.getFileTypeByFile(file)) && myConfiguration.isResourceFile(file); } - public void compile(final CompileContext context, final VirtualFile[] files, OutputSink sink) { + public void compile(final CompileContext context, Chunk moduleChunk, final VirtualFile[] files, OutputSink sink) { context.getProgressIndicator().pushState(); context.getProgressIndicator().setText(CompilerBundle.message("progress.copying.resources")); final Map> processed = new HashMap>(); final LinkedList copyCommands = new LinkedList(); + final Module singleChunkModule = moduleChunk.getNodes().size() == 1? moduleChunk.getNodes().iterator().next() : null; final long start = System.currentTimeMillis(); ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { @@ -84,7 +86,7 @@ public class ResourceCompiler implements TranslatingCompiler { if (context.getProgressIndicator().isCanceled()) { break; } - final Module module = context.getModuleByFile(file); + final Module module = singleChunkModule != null? singleChunkModule : context.getModuleByFile(file); if (module == null) { continue; // looks like file invalidated } @@ -94,17 +96,20 @@ public class ResourceCompiler implements TranslatingCompiler { } final String sourcePath = file.getPath(); final String relativePath = VfsUtil.getRelativePath(file, fileRoot, '/'); - final String outputPath = CompilerPaths.getModuleOutputPath(module, ((CompileContextEx)context).isInTestSourceContent(file)); - if (outputPath == null) { + final boolean inTests = ((CompileContextEx)context).isInTestSourceContent(file); + final VirtualFile outputDir = inTests? context.getModuleOutputDirectoryForTests(module) : context.getModuleOutputDirectory(module); + if (outputDir == null) { continue; } + final String outputPath = outputDir.getPath(); + final String packagePrefix = fileIndex.getPackageNameByDirectory(fileRoot); final String targetPath; if (packagePrefix != null && packagePrefix.length() > 0) { - targetPath = outputPath+"/"+packagePrefix.replace('.', '/')+"/"+relativePath; + targetPath = outputPath + "/" + packagePrefix.replace('.', '/') + "/" + relativePath; } else { - targetPath = outputPath+"/"+relativePath; + targetPath = outputPath + "/" + relativePath; } if (sourcePath.equals(targetPath)) { addToMap(processed, outputPath, new MyOutputItem(targetPath, file)); @@ -126,7 +131,7 @@ public class ResourceCompiler implements TranslatingCompiler { if (context.getProgressIndicator().isCanceled()) { break; } - context.getProgressIndicator().setFraction((idx++) * 1.0 / total); + //context.getProgressIndicator().setFraction((idx++) * 1.0 / total); context.getProgressIndicator().setText2("Copying " + command.getFromPath() + "..."); try { rootsToRefresh.add(command.getOutputPath()); diff --git a/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java b/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java index 7405710468a8..f0faf4e19683 100644 --- a/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java +++ b/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java @@ -15,16 +15,26 @@ */ package com.intellij.compiler.make; +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.CompilerManagerImpl; import com.intellij.compiler.SymbolTable; import com.intellij.compiler.classParsing.MethodInfo; +import com.intellij.compiler.impl.CompilerUtil; +import com.intellij.compiler.impl.javaCompiler.DependencyProcessor; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.CompilerBundle; +import com.intellij.openapi.compiler.ex.CompileContextEx; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtil; +import com.intellij.util.Function; import com.intellij.util.StringBuilderSpinAllocator; import gnu.trove.TIntHashSet; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; +import java.util.*; /** * @author Eugene Zhuravlev @@ -116,4 +126,69 @@ public class CacheUtils { } return true; } + + public static Collection findDependentFiles(final CompileContextEx context, final Set succesfullyCompiledJavaFiles, + final @Nullable DependencyProcessor additionalDependencyProcessor, + final @Nullable Function>, Pair>> filter) throws CacheCorruptedException { + if (!CompilerConfiguration.MAKE_ENABLED) { + return Collections.emptyList(); + } + context.getProgressIndicator().setText(CompilerBundle.message("progress.checking.dependencies")); + + final DependencyCache dependencyCache = context.getDependencyCache(); + + final long start = System.currentTimeMillis(); + + final Pair> deps = + dependencyCache.findDependentClasses(context, context.getProject(), succesfullyCompiledJavaFiles, additionalDependencyProcessor); + final Pair> filteredDeps = filter != null? filter.fun(deps) : deps; + + final Set dependentFiles = new HashSet(); + final CacheCorruptedException[] _ex = {null}; + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + try { + CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(context.getProject()); + SourceFileFinder sourceFileFinder = new SourceFileFinder(context.getProject(), context); + final Cache cache = dependencyCache.getCache(); + for (final int infoQName : filteredDeps.getFirst()) { + final String qualifiedName = dependencyCache.resolve(infoQName); + final String sourceFileName = cache.getSourceFileName(infoQName); + final VirtualFile file = sourceFileFinder.findSourceFile(qualifiedName, sourceFileName); + if (file != null) { + if (!compilerConfiguration.isExcludedFromCompilation(file)) { + dependentFiles.add(file); + if (ApplicationManager.getApplication().isUnitTestMode()) { + LOG.assertTrue(file.isValid()); + CompilerManagerImpl.addRecompiledPath(file.getPath()); + } + } + } + else { + LOG.info("No source file for " + dependencyCache.resolve(infoQName) + " found; source file name=" + sourceFileName); + } + } + for (final VirtualFile file : filteredDeps.getSecond()) { + if (!compilerConfiguration.isExcludedFromCompilation(file)) { + dependentFiles.add(file); + if (ApplicationManager.getApplication().isUnitTestMode()) { + LOG.assertTrue(file.isValid()); + CompilerManagerImpl.addRecompiledPath(file.getPath()); + } + } + } + } + catch (CacheCorruptedException e) { + _ex[0] = e; + } + } + }); + if (_ex[0] != null) { + throw _ex[0]; + } + context.getProgressIndicator().setText(CompilerBundle.message("progress.found.dependent.files", dependentFiles.size())); + + CompilerUtil.logDuration("Finding dependencies", System.currentTimeMillis() - start); + return dependentFiles; + } } diff --git a/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java b/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java index b1d2ce8a0131..7e9270ba30eb 100644 --- a/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java +++ b/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java @@ -28,7 +28,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; -import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pair; @@ -150,7 +149,7 @@ public class DependencyCache { } */ - public void update(ProgressIndicator indicator) throws CacheCorruptedException { + public void update() throws CacheCorruptedException { if (myToUpdate.isEmpty()) { return; // optimization } @@ -163,10 +162,8 @@ public class DependencyCache { final Cache newCache = getNewClassesCache(); final DependencyCacheNavigator navigator = getCacheNavigator(); - int i = 0; // remove unnecesary dependencies for (final int qName : namesToUpdate) { - indicator.setFraction(i++*1.0/namesToUpdate.length/4); // process use-dependencies for (int referencedClassQName : cache.getReferencedClasses(qName)) { if (!cache.containsClass(referencedClassQName)) { @@ -186,7 +183,6 @@ public class DependencyCache { // do update of classInfos for (final int qName : namesToUpdate) { - indicator.setFraction(i++*1.0/namesToUpdate.length/4); cache.importClassInfo(newCache, qName); } @@ -195,7 +191,6 @@ public class DependencyCache { final SymbolTable symbolTable = getSymbolTable(); for (final int qName : namesToUpdate) { - indicator.setFraction(i++*1.0/namesToUpdate.length/4); if (!newCache.containsClass(qName)) { continue; } @@ -223,9 +218,7 @@ public class DependencyCache { // building subclass dependencies for (final int qName : namesToUpdate) { - indicator.setFraction(i++*1.0/namesToUpdate.length/4); - final int classId = qName; - buildSubclassDependencies(getCache(), qName, classId); + buildSubclassDependencies(getCache(), qName, qName); } for (final int qName : myClassesWithSourceRemoved.toArray()) { @@ -410,11 +403,11 @@ public class DependencyCache { LOG.debug("====================Marking dependent files====================="); } // myToUpdate can be modified during the mark procedure, so use toArray() to iterate it - int[] qNamesToUpdate = myTraverseRoots.toArray(); + final int[] traverseRoots = myTraverseRoots.toArray(); final SourceFileFinder sourceFileFinder = new SourceFileFinder(project, context); final CachingSearcher searcher = new CachingSearcher(project); final ChangedRetentionPolicyDependencyProcessor changedRetentionPolicyDependencyProcessor = new ChangedRetentionPolicyDependencyProcessor(project, searcher, this); - for (final int qName : qNamesToUpdate) { + for (final int qName : traverseRoots) { if (!getCache().containsClass(qName)) { continue; } diff --git a/java/compiler/impl/src/com/intellij/compiler/make/StorageClassId.java b/java/compiler/impl/src/com/intellij/compiler/make/StorageClassId.java deleted file mode 100644 index e71d24021160..000000000000 --- a/java/compiler/impl/src/com/intellij/compiler/make/StorageClassId.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2000-2009 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.compiler.make; - -/** - * @author Eugene Zhuravlev - * Date: Dec 1, 2008 - */ -public class StorageClassId { - private final int myQName; - - public StorageClassId(int QName) { - myQName = QName; - } - - public int getClassQName() { - return myQName; - } - - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof StorageClassId)) return false; - - if (myQName != ((StorageClassId)o).myQName) return false; - - return true; - } - - public int hashCode() { - return myQName; - } - -} diff --git a/java/compiler/impl/src/com/intellij/compiler/make/StorageFieldId.java b/java/compiler/impl/src/com/intellij/compiler/make/StorageFieldId.java deleted file mode 100644 index a15d04613be2..000000000000 --- a/java/compiler/impl/src/com/intellij/compiler/make/StorageFieldId.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2000-2009 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.compiler.make; - -/** - * @author Eugene Zhuravlev - * Date: Dec 1, 2008 - */ -public final class StorageFieldId extends StorageClassId{ - private final int myFieldName; - - public StorageFieldId(int QName, int fieldName) { - super(QName); - myFieldName = fieldName; - } - - public int getFieldName() { - return myFieldName; - } - - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof StorageFieldId)) return false; - - final StorageFieldId that = (StorageFieldId)o; - return myFieldName == that.myFieldName && getClassQName() == that.getClassQName(); - } - - public int hashCode() { - int result = super.hashCode(); - result = 31 * result + myFieldName; - return result; - } -} diff --git a/java/compiler/impl/src/com/intellij/compiler/make/StorageMethodId.java b/java/compiler/impl/src/com/intellij/compiler/make/StorageMethodId.java deleted file mode 100644 index fb5efff27045..000000000000 --- a/java/compiler/impl/src/com/intellij/compiler/make/StorageMethodId.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2000-2009 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.compiler.make; - -/** - * @author Eugene Zhuravlev - * Date: Dec 1, 2008 - */ -public final class StorageMethodId extends StorageClassId{ - private final int myMethodName; - private final int myMethodDescriptor; - - public StorageMethodId(int QName, int methodName, int methodDescriptor) { - super(QName); - myMethodName = methodName; - myMethodDescriptor = methodDescriptor; - } - - public int getMethodName() { - return myMethodName; - } - - public int getMethodDescriptor() { - return myMethodDescriptor; - } - - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof StorageMethodId)) return false; - - StorageMethodId that = (StorageMethodId)o; - return myMethodDescriptor == that.myMethodDescriptor && myMethodName == that.myMethodName && getClassQName() == that.getClassQName(); - } - - public int hashCode() { - int result = super.hashCode(); - result = 31 * result + myMethodName; - result = 31 * result + myMethodDescriptor; - return result; - } -} \ No newline at end of file diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java index 019021a73096..3c56f8d9f67d 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java @@ -15,7 +15,9 @@ */ package com.intellij.openapi.compiler; +import com.intellij.openapi.module.Module; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Chunk; import java.util.Collection; @@ -63,7 +65,7 @@ public interface TranslatingCompiler extends Compiler { * @param file the file to check. * @param context the context for the current compile operation. * @return true if can compile the file, false otherwise. If the method returns false, file - * will not be included in the list of files passed to {@link #compile(CompileContext,com.intellij.openapi.vfs.VirtualFile[], com.intellij.openapi.compiler.TranslatingCompiler.OutputSink)}. + * will not be included in the list of files passed to {@link #compile(CompileContext,Chunk,com.intellij.openapi.vfs.VirtualFile[], com.intellij.openapi.compiler.TranslatingCompiler.OutputSink)}. */ boolean isCompilableFile(VirtualFile file, CompileContext context); @@ -71,8 +73,9 @@ public interface TranslatingCompiler extends Compiler { * Compiles the specified files. * * @param context the context for the current compile operation. - * @param files the source files to compile. + * @param moduleChunk contains modules that form a cycle. If project module graph has no cycles, a chunk corresponds to a single module + * @param files the source files to compile that correspond to the module chunk * @param sink storage that accepts compiler output results */ - void compile(CompileContext context, VirtualFile[] files, OutputSink sink); + void compile(CompileContext context, Chunk moduleChunk, VirtualFile[] files, OutputSink sink); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java index afb713c505cb..7c23640f104c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java @@ -17,7 +17,6 @@ package org.jetbrains.plugins.groovy.compiler; import com.intellij.compiler.CompilerConfiguration; -import com.intellij.compiler.ModuleCompilerUtil; import com.intellij.compiler.impl.CompilerUtil; import com.intellij.compiler.impl.FileSetCompileScope; import com.intellij.compiler.impl.javaCompiler.ModuleChunk; @@ -290,42 +289,45 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler { return new ModuleChunk((CompileContextEx)context, new Chunk(module), Collections.>emptyMap()); } - public void compile(final CompileContext compileContext, final VirtualFile[] virtualFiles, OutputSink sink) { - Map> mapModulesToVirtualFiles = CompilerUtil.buildModuleToFilesMap(compileContext, virtualFiles); - final List> chunks = - ModuleCompilerUtil.getSortedModuleChunks(myProject, new ArrayList(mapModulesToVirtualFiles.keySet())); - for (final Chunk chunk : chunks) { - for (final Module module : chunk.getNodes()) { - final List moduleFiles = mapModulesToVirtualFiles.get(module); - if (moduleFiles == null) { - continue; - } + public void compile(final CompileContext compileContext, Chunk moduleChunk, final VirtualFile[] virtualFiles, OutputSink sink) { + Map> mapModulesToVirtualFiles; + if (moduleChunk.getNodes().size() == 1) { + mapModulesToVirtualFiles = Collections.singletonMap(moduleChunk.getNodes().iterator().next(), Arrays.asList(virtualFiles)); + } + else { + mapModulesToVirtualFiles = CompilerUtil.buildModuleToFilesMap(compileContext, virtualFiles); + } + for (final Module module : moduleChunk.getNodes()) { + final List moduleFiles = mapModulesToVirtualFiles.get(module); + if (moduleFiles == null) { + continue; + } - final ModuleFileIndex index = ModuleRootManager.getInstance(module).getFileIndex(); - final List toCompile = new ArrayList(); - final List toCompileTests = new ArrayList(); - final CompilerConfiguration configuration = CompilerConfiguration.getInstance(myProject); + final ModuleFileIndex index = ModuleRootManager.getInstance(module).getFileIndex(); + final List toCompile = new ArrayList(); + final List toCompileTests = new ArrayList(); + final CompilerConfiguration configuration = CompilerConfiguration.getInstance(myProject); - if (module.getModuleType() instanceof JavaModuleType) { - for (final VirtualFile file : moduleFiles) { - final boolean shouldCompile = !configuration.isResourceFile(file) && - (file.getFileType() == GroovyFileType.GROOVY_FILE_TYPE || - file.getFileType() == StdFileTypes.JAVA); - if (shouldCompile) { - (index.isInTestSourceContent(file) ? toCompileTests : toCompile).add(file); - } + if (module.getModuleType() instanceof JavaModuleType) { + for (final VirtualFile file : moduleFiles) { + final boolean shouldCompile = !configuration.isResourceFile(file) && + (file.getFileType() == GroovyFileType.GROOVY_FILE_TYPE || + file.getFileType() == StdFileTypes.JAVA); + if (shouldCompile) { + (index.isInTestSourceContent(file) ? toCompileTests : toCompile).add(file); } } - - if (!toCompile.isEmpty()) { - compileFiles(compileContext, module, toCompile, sink, false); - } - if (!toCompileTests.isEmpty()) { - compileFiles(compileContext, module, toCompileTests, sink, true); - } - } + + if (!toCompile.isEmpty()) { + compileFiles(compileContext, module, toCompile, sink, false); + } + if (!toCompileTests.isEmpty()) { + compileFiles(compileContext, module, toCompileTests, sink, true); + } + } + } protected abstract void compileFiles(CompileContext compileContext, Module module, diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java index dcb5a25cfd33..b44e9462b2d8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java @@ -32,6 +32,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Chunk; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.compiler.GroovyCompilerBase; @@ -53,7 +54,7 @@ public class GroovycStubGenerator extends GroovyCompilerBase { } @Override - public void compile(CompileContext compileContext, VirtualFile[] virtualFiles, OutputSink sink) { + public void compile(CompileContext compileContext, Chunk moduleChunk, VirtualFile[] virtualFiles, OutputSink sink) { final CompileScope scope = compileContext.getCompileScope(); if (scope.getFiles(StdFileTypes.JAVA, true).length == 0) { return; @@ -75,7 +76,7 @@ public class GroovycStubGenerator extends GroovyCompilerBase { return; } - super.compile(compileContext, total.toArray(new VirtualFile[total.size()]), sink); + super.compile(compileContext, moduleChunk, total.toArray(new VirtualFile[total.size()]), sink); } @Override diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java b/plugins/ui-designer/src/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java index d49afd6db9d3..3b2165b16c56 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java @@ -297,7 +297,7 @@ public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler { final ArrayList list = module2itemsList.get(module); for (final MyInstrumentationItem item : list) { - context.getProgressIndicator().setFraction((double)++formsProcessed / (double)items.length); + //context.getProgressIndicator().setFraction((double)++formsProcessed / (double)items.length); final VirtualFile formFile = item.getFormFile(); context.getProgressIndicator().setText2(formFile.getPresentableUrl()); From 874aed3d9ef1b961480ca04bbfb0908a63b00b7e Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Wed, 11 Nov 2009 19:35:25 +0300 Subject: [PATCH 10/36] NPE --- .../com/intellij/ide/bookmarks/Bookmark.java | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/Bookmark.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/Bookmark.java index 9fb0104421d1..966c4e714d0c 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/Bookmark.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/Bookmark.java @@ -70,19 +70,21 @@ public class Bookmark { myHighlighter = markup.addPersistentLineHighlighter(line, HighlighterLayer.ERROR + 1, null); - myHighlighter.setGutterIconRenderer(new GutterIconRenderer() { - @NotNull - public Icon getIcon() { - return Bookmark.this.getIcon(); - } + if (myHighlighter != null) { + myHighlighter.setGutterIconRenderer(new GutterIconRenderer() { + @NotNull + public Icon getIcon() { + return Bookmark.this.getIcon(); + } - public String getTooltipText() { - return StringUtil.escapeXml(getNotEmptyDescription()); - } - }); + public String getTooltipText() { + return StringUtil.escapeXml(getNotEmptyDescription()); + } + }); - myHighlighter.setErrorStripeMarkColor(Color.black); - myHighlighter.setErrorStripeTooltip(StringUtil.escapeXml(getNotEmptyDescription())); + myHighlighter.setErrorStripeMarkColor(Color.black); + myHighlighter.setErrorStripeTooltip(StringUtil.escapeXml(getNotEmptyDescription())); + } } else { myHighlighter = null; From 42a6ec1b2c9d6ff419667aab1112523703847507 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Thu, 12 Nov 2009 20:52:44 +0300 Subject: [PATCH 11/36] Semaphore replaces InterruptedException with ProcessCancelledException --- .../openapi/progress/ProcessCanceledException.java | 2 +- .../src/com/intellij/util/concurrency/Semaphore.java | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) rename platform/{platform-api => util}/src/com/intellij/openapi/progress/ProcessCanceledException.java (98%) diff --git a/platform/platform-api/src/com/intellij/openapi/progress/ProcessCanceledException.java b/platform/util/src/com/intellij/openapi/progress/ProcessCanceledException.java similarity index 98% rename from platform/platform-api/src/com/intellij/openapi/progress/ProcessCanceledException.java rename to platform/util/src/com/intellij/openapi/progress/ProcessCanceledException.java index f22f0217b02d..6f322791f3b3 100644 --- a/platform/platform-api/src/com/intellij/openapi/progress/ProcessCanceledException.java +++ b/platform/util/src/com/intellij/openapi/progress/ProcessCanceledException.java @@ -17,8 +17,8 @@ package com.intellij.openapi.progress; public class ProcessCanceledException extends RuntimeException { public ProcessCanceledException() { - int i = 0; } + public ProcessCanceledException(Throwable cause) { super(cause); } diff --git a/platform/util/src/com/intellij/util/concurrency/Semaphore.java b/platform/util/src/com/intellij/util/concurrency/Semaphore.java index acb3e64c26df..9a33f0ec088a 100644 --- a/platform/util/src/com/intellij/util/concurrency/Semaphore.java +++ b/platform/util/src/com/intellij/util/concurrency/Semaphore.java @@ -16,6 +16,7 @@ package com.intellij.util.concurrency; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProcessCanceledException; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.AbstractQueuedSynchronizer; @@ -62,18 +63,16 @@ public class Semaphore { sync.acquireSharedInterruptibly(1); } catch (InterruptedException e) { - LOG.debug(e); - throw new RuntimeException(e); + throw new ProcessCanceledException(e); } } - public boolean waitFor(final long timeout) { + public boolean waitFor(final long timeout) { try { return sync.tryAcquireSharedNanos(1, TimeUnit.MILLISECONDS.toNanos(timeout)); } catch (InterruptedException e) { - LOG.debug(e); - throw new RuntimeException(e); + throw new ProcessCanceledException(e); } } From ddb62a5e83d194940f2d6f0ff6e8d86a2d9ae8ee Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 12 Nov 2009 16:31:21 +0300 Subject: [PATCH 12/36] cleanup --- .../impl/packagingCompiler/JarsBuilder.java | 49 +++---------------- 1 file changed, 7 insertions(+), 42 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/JarsBuilder.java b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/JarsBuilder.java index 64b8518924de..a5821f3c6325 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/JarsBuilder.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/JarsBuilder.java @@ -35,9 +35,7 @@ import org.jetbrains.annotations.Nullable; import java.io.*; import java.util.*; -import java.util.jar.JarFile; import java.util.jar.JarOutputStream; -import java.util.jar.Manifest; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -49,7 +47,6 @@ public class JarsBuilder { private final FileFilter myFileFilter; private final CompileContext myContext; private Map myBuiltJars; - private final List myJarsDestinations; private Set myJarsToDelete; public JarsBuilder(Set jarsToBuild, FileFilter fileFilter, CompileContext context) { @@ -60,7 +57,6 @@ public class JarsBuilder { myJarsToBuild = evaluator.getJars(); myFileFilter = fileFilter; myContext = context; - myJarsDestinations = new ArrayList(); } public boolean buildJars(Set writtenPaths) throws IOException { @@ -87,18 +83,10 @@ public class JarsBuilder { private void deleteTemporaryJars() { for (File file : myJarsToDelete) { - deleteFile(file); + FileUtil.delete(file); } } - protected void deleteFile(final File file) { - FileUtil.delete(file); - } - - public List getJarsDestinations() { - return myJarsDestinations; - } - private void copyJars(final Set writtenPaths) throws IOException { myJarsToDelete = new HashSet(myBuiltJars.values()); @@ -107,7 +95,6 @@ public class JarsBuilder { boolean first = true; for (DestinationInfo destination : entry.getKey().getAllDestinations()) { if (destination instanceof ExplodedDestinationInfo) { - myJarsDestinations.add((ExplodedDestinationInfo)destination); File toFile = new File(FileUtil.toSystemDependentName(destination.getOutputPath())); if (first) { @@ -116,7 +103,7 @@ public class JarsBuilder { fromFile = toFile; } else { - copyFile(fromFile, toFile, writtenPaths); + DeploymentUtil.getInstance().copyFile(fromFile, toFile, myContext, writtenPaths, myFileFilter); } } @@ -124,15 +111,11 @@ public class JarsBuilder { } } - protected void renameFile(final File fromFile, final File toFile, final Set writtenPaths) throws IOException { + private static void renameFile(final File fromFile, final File toFile, final Set writtenPaths) throws IOException { FileUtil.rename(fromFile, toFile); writtenPaths.add(toFile.getPath()); } - protected void copyFile(final File fromFile, final File toFile, final Set writtenPaths) throws IOException { - DeploymentUtil.getInstance().copyFile(fromFile, toFile, myContext, writtenPaths, myFileFilter); - } - @Nullable private JarInfo[] sortJars() { final DFSTBuilder builder = new DFSTBuilder(GraphGenerator.create(CachingSemiGraph.create(new JarsGraph()))); @@ -158,11 +141,11 @@ public class JarsBuilder { private void buildJar(final JarInfo jar) throws IOException { myContext.getProgressIndicator().setText(CompilerBundle.message("packaging.compiler.message.building.0", jar.getPresentableDestination())); - File jarFile = createTempFile(); + File jarFile = FileUtil.createTempFile("artifactCompiler", "tmp"); myBuiltJars.put(jar, jarFile); - Manifest manifest = null; - final JarOutputStream jarOutputStream = createJarOutputStream(jarFile, manifest); + FileUtil.createParentDirs(jarFile); + final JarOutputStream jarOutputStream = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(jarFile))); try { final THashSet writtenPaths = new THashSet(); @@ -181,25 +164,7 @@ public class JarsBuilder { } } - private static Manifest createManifest(final JarInfo jar) throws IOException { - for (Pair pair : jar.getPackedFiles()) { - if (JarFile.MANIFEST_NAME.equalsIgnoreCase(pair.getFirst())) { - return new Manifest(pair.getSecond().getInputStream()); - } - } - return new Manifest(); - } - - protected JarOutputStream createJarOutputStream(final File jarFile, final Manifest manifest) throws IOException { - FileUtil.createParentDirs(jarFile); - return new JarOutputStream(new BufferedOutputStream(new FileOutputStream(jarFile))); - } - - protected File createTempFile() throws IOException { - return FileUtil.createTempFile("packagingCompiler", "tmp"); - } - - protected void addFileToJar(final JarOutputStream jarOutputStream, final File file, String relativePath, + private void addFileToJar(final JarOutputStream jarOutputStream, final File file, String relativePath, final THashSet writtenPaths) throws IOException { //todo[nik] check file exists? while (relativePath.startsWith("/")) { From 0086c211e1c29ebfe19b03eff59be5fe009e519d Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 12 Nov 2009 16:58:18 +0300 Subject: [PATCH 13/36] =?UTF-8?q?IDEADEV-41335:=20Making=20an=20EAR=20modu?= =?UTF-8?q?le=20doesn=E2=80=8B'=E2=80=8Bt=20recompile=20JARs=20within=20we?= =?UTF-8?q?b=20apps=20which=20are=20then=20deployed=20in=20the=20EAR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/AdditionalCompileScopeProvider.java | 5 ++- .../intellij/compiler/impl/CompileDriver.java | 2 +- ...rtifactAdditionalCompileScopeProvider.java | 39 +++++++++++++++++++ .../impl/compiler/ArtifactCompileScope.java | 16 +++++++- .../IncrementalArtifactsCompiler.java | 4 ++ resources/src/META-INF/IdeaPlugin.xml | 1 + 6 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAdditionalCompileScopeProvider.java diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/AdditionalCompileScopeProvider.java b/java/compiler/impl/src/com/intellij/compiler/impl/AdditionalCompileScopeProvider.java index faa3c735d708..0b9ed31d0a59 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/AdditionalCompileScopeProvider.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/AdditionalCompileScopeProvider.java @@ -16,8 +16,11 @@ package com.intellij.compiler.impl; +import com.intellij.openapi.compiler.CompilerFilter; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.compiler.CompileScope; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -27,5 +30,5 @@ public abstract class AdditionalCompileScopeProvider { public static final ExtensionPointName EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.compiler.additionalCompileScopeProvider"); @Nullable - public abstract CompileScope getAdditionalScope(CompileScope baseScope); + public abstract CompileScope getAdditionalScope(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, @NotNull Project project); } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 38a99a7acbd2..05f5a90c39cc 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -313,7 +313,7 @@ public class CompileDriver { final AdditionalCompileScopeProvider[] scopeProviders = Extensions.getExtensions(AdditionalCompileScopeProvider.EXTENSION_POINT_NAME); CompileScope baseScope = scope; for (AdditionalCompileScopeProvider scopeProvider : scopeProviders) { - final CompileScope additionalScope = scopeProvider.getAdditionalScope(baseScope); + final CompileScope additionalScope = scopeProvider.getAdditionalScope(baseScope, filter, myProject); if (additionalScope != null) { scope = new CompositeScope(scope, additionalScope); } diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAdditionalCompileScopeProvider.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAdditionalCompileScopeProvider.java new file mode 100644 index 000000000000..9b57f409a01f --- /dev/null +++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAdditionalCompileScopeProvider.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2009 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.packaging.impl.compiler; + +import com.intellij.compiler.impl.AdditionalCompileScopeProvider; +import com.intellij.openapi.compiler.CompileScope; +import com.intellij.openapi.compiler.CompilerFilter; +import com.intellij.openapi.project.Project; +import com.intellij.packaging.artifacts.Artifact; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +/** + * @author nik + */ +public class ArtifactAdditionalCompileScopeProvider extends AdditionalCompileScopeProvider { + @Override + public CompileScope getAdditionalScope(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, @NotNull Project project) { + if (ArtifactCompileScope.getArtifacts(baseScope) != null || !filter.acceptCompiler(IncrementalArtifactsCompiler.getInstance(project))) { + return null; + } + final Set artifacts = ArtifactCompileScope.getArtifactsToBuild(project, baseScope); + return ArtifactCompileScope.createScopeForModulesInArtifacts(project, artifacts); + } +} diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompileScope.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompileScope.java index 53f94d73bdaa..4702d30f3f31 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompileScope.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompileScope.java @@ -29,6 +29,7 @@ import com.intellij.packaging.impl.elements.ModuleOutputElementType; import com.intellij.packaging.impl.elements.ModuleOutputPackagingElement; import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.Collection; @@ -40,6 +41,7 @@ import java.util.Set; */ public class ArtifactCompileScope { private static final Key ARTIFACTS_KEY = Key.create("artifacts"); + private static final Key> CACHED_ARTIFACTS_KEY = Key.create("cached_artifacts"); private ArtifactCompileScope() { } @@ -72,10 +74,16 @@ public class ArtifactCompileScope { } public static Set getArtifactsToBuild(final Project project, final CompileScope compileScope) { - final Artifact[] artifactsFromScope = compileScope.getUserData(ARTIFACTS_KEY); + final Artifact[] artifactsFromScope = getArtifacts(compileScope); if (artifactsFromScope != null) { return new HashSet(Arrays.asList(artifactsFromScope)); } + + final Set cached = compileScope.getUserData(CACHED_ARTIFACTS_KEY); + if (cached != null) { + return cached; + } + Set artifacts = new HashSet(); final ArtifactManager artifactManager = ArtifactManager.getInstance(project); final Set modules = new HashSet(Arrays.asList(compileScope.getAffectedModules())); @@ -87,9 +95,15 @@ public class ArtifactCompileScope { } } } + compileScope.putUserData(CACHED_ARTIFACTS_KEY, artifacts); return artifacts; } + @Nullable + public static Artifact[] getArtifacts(CompileScope compileScope) { + return compileScope.getUserData(ARTIFACTS_KEY); + } + private static boolean containsModuleOutput(Artifact artifact, final Set modules, ArtifactManager artifactManager) { final PackagingElementResolvingContext context = artifactManager.getResolvingContext(); return !ArtifactUtil.processPackagingElements(artifact, ModuleOutputElementType.MODULE_OUTPUT_ELEMENT_TYPE, diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalArtifactsCompiler.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalArtifactsCompiler.java index d2137abde3c0..c3a7643cd4ed 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalArtifactsCompiler.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalArtifactsCompiler.java @@ -73,6 +73,10 @@ public class IncrementalArtifactsCompiler implements PackagingCompiler { private static final Key BUILDER_CONTEXT_KEY = Key.create("artifacts_builder_context"); @Nullable private PackagingCompilerCache myOutputItemsCache; + public static IncrementalArtifactsCompiler getInstance(@NotNull Project project) { + return CompilerManager.getInstance(project).getCompilers(IncrementalArtifactsCompiler.class)[0]; + } + private static ArtifactPackagingProcessingItem[] collectItems(ArtifactsProcessingItemsBuilderContext builderContext, final Project project) { final CompileContext context = builderContext.getCompileContext(); diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 4101d1fb3478..7a84f1c0ec5a 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -241,6 +241,7 @@ + From b5a06dacbb7c58c3acd309fcf6c8de793848e23f Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 12 Nov 2009 18:12:21 +0300 Subject: [PATCH 14/36] type --- platform/util/src/com/intellij/util/containers/FList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/util/containers/FList.java b/platform/util/src/com/intellij/util/containers/FList.java index 079d60003f40..44252d9acd9b 100644 --- a/platform/util/src/com/intellij/util/containers/FList.java +++ b/platform/util/src/com/intellij/util/containers/FList.java @@ -18,7 +18,7 @@ package com.intellij.util.containers; import java.util.AbstractList; /** - * Immmutable list in functional style + * Immutable list in functional style * * @author nik */ From c6cf384a45bf530c53029e2c57dc5e2980366b9e Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 13 Nov 2009 13:04:54 +0300 Subject: [PATCH 15/36] IDEADEV-41348: IDEA 92.6 doesn't start - an error occurs during startup --- platform/util/src/com/intellij/util/io/URLUtil.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/platform/util/src/com/intellij/util/io/URLUtil.java b/platform/util/src/com/intellij/util/io/URLUtil.java index 16a9896f32d3..fad1eca2cc4d 100644 --- a/platform/util/src/com/intellij/util/io/URLUtil.java +++ b/platform/util/src/com/intellij/util/io/URLUtil.java @@ -17,12 +17,13 @@ package com.intellij.util.io; import com.intellij.openapi.util.io.FileUtil; -import gnu.trove.TIntArrayList; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import java.io.*; import java.net.URL; +import java.util.ArrayList; +import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -102,7 +103,7 @@ public class URLUtil { while (i < len) { char c = s.charAt(i); if (c == '%') { - TIntArrayList bytes = new TIntArrayList(); + List bytes = new ArrayList(); while (i + 2 < len && s.charAt(i) == '%') { final int d1 = decode(s.charAt(i + 1)); final int d2 = decode(s.charAt(i + 2)); @@ -117,7 +118,7 @@ public class URLUtil { if (!bytes.isEmpty()) { final byte[] bytesArray = new byte[bytes.size()]; for (int j = 0; j < bytes.size(); j++) { - bytesArray[j] = (byte)bytes.get(j); + bytesArray[j] = (byte)bytes.get(j).intValue(); } try { decoded.append(new String(bytesArray, "UTF-8")); From b2e952317be2df831a8df002eaa4c0b360f4d4ba Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 13 Nov 2009 15:36:15 +0300 Subject: [PATCH 16/36] test fixed --- .../compiler/ArtifactAdditionalCompileScopeProvider.java | 6 +++++- .../impl/compiler/IncrementalArtifactsCompiler.java | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAdditionalCompileScopeProvider.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAdditionalCompileScopeProvider.java index 9b57f409a01f..b546eca26731 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAdditionalCompileScopeProvider.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAdditionalCompileScopeProvider.java @@ -30,7 +30,11 @@ import java.util.Set; public class ArtifactAdditionalCompileScopeProvider extends AdditionalCompileScopeProvider { @Override public CompileScope getAdditionalScope(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, @NotNull Project project) { - if (ArtifactCompileScope.getArtifacts(baseScope) != null || !filter.acceptCompiler(IncrementalArtifactsCompiler.getInstance(project))) { + if (ArtifactCompileScope.getArtifacts(baseScope) != null) { + return null; + } + final IncrementalArtifactsCompiler compiler = IncrementalArtifactsCompiler.getInstance(project); + if (compiler == null || !filter.acceptCompiler(compiler)) { return null; } final Set artifacts = ArtifactCompileScope.getArtifactsToBuild(project, baseScope); diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalArtifactsCompiler.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalArtifactsCompiler.java index c3a7643cd4ed..d69002ac1c8f 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalArtifactsCompiler.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalArtifactsCompiler.java @@ -73,8 +73,10 @@ public class IncrementalArtifactsCompiler implements PackagingCompiler { private static final Key BUILDER_CONTEXT_KEY = Key.create("artifacts_builder_context"); @Nullable private PackagingCompilerCache myOutputItemsCache; + @Nullable public static IncrementalArtifactsCompiler getInstance(@NotNull Project project) { - return CompilerManager.getInstance(project).getCompilers(IncrementalArtifactsCompiler.class)[0]; + final IncrementalArtifactsCompiler[] compilers = CompilerManager.getInstance(project).getCompilers(IncrementalArtifactsCompiler.class); + return compilers.length == 1 ? compilers[0] : null; } private static ArtifactPackagingProcessingItem[] collectItems(ArtifactsProcessingItemsBuilderContext builderContext, final Project project) { From c63856f2f881f0724516da506156cf4efda3e4ff Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 12 Nov 2009 14:44:40 +0300 Subject: [PATCH 17/36] verbose diagnostics --- .../com/intellij/codeInspection/ProblemsHolder.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/platform/lang-api/src/com/intellij/codeInspection/ProblemsHolder.java b/platform/lang-api/src/com/intellij/codeInspection/ProblemsHolder.java index 30d46f0e7788..e625833667ba 100644 --- a/platform/lang-api/src/com/intellij/codeInspection/ProblemsHolder.java +++ b/platform/lang-api/src/com/intellij/codeInspection/ProblemsHolder.java @@ -37,7 +37,7 @@ public class ProblemsHolder { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ProblemsHolder"); private final InspectionManager myManager; private final PsiFile myFile; - private boolean myOnTheFly; + private final boolean myOnTheFly; private List myProblems = null; public ProblemsHolder(@NotNull InspectionManager manager, @NotNull PsiFile file, boolean onTheFly) { @@ -63,7 +63,13 @@ public class ProblemsHolder { } PsiElement element = problemDescriptor.getPsiElement(); if (element != null && !isInPsiFile(element)) { - LOG.error("Reported element " + element + " is not from the file '" + myFile + "' the inspection was invoked for. Message:" + problemDescriptor.getDescriptionTemplate()); + PsiFile containingFile = element.getContainingFile(); + PsiElement context = containingFile.getContext(); + PsiElement myContext = myFile.getContext(); + LOG.error("Reported element " + element + " is not from the file '" + myFile + "' the inspection was invoked for. Message: '" + problemDescriptor.getDescriptionTemplate()+"'.\n" + + "Element' containing file: "+ containingFile +"; context: "+(context == null ? null : context.getContainingFile())+"\n" + +"Inspection invoked for file: "+ myFile +"; context: "+(myContext == null ? null : myContext.getContainingFile())+"\n" + ); } myProblems.add(problemDescriptor); } From 8fad4b49675d1ae79d09656530a6ab3d869cccdf Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 12 Nov 2009 18:47:25 +0300 Subject: [PATCH 18/36] cleanup --- .../ui/configuration/ClasspathEditor.java | 4 +- .../ui/configuration/ClasspathPanel.java | 44 +++++++++---------- .../JavaContentEntriesEditor.java | 2 +- .../roots/AnnotationOrderRootType.java | 2 +- .../intellij/openapi/roots/OrderRootType.java | 18 +++++--- .../roots/PersistentOrderRootType.java | 5 +-- .../roots/impl/LibraryOrderEntryImpl.java | 21 +++------ .../roots/impl/ModuleJdkOrderEntryImpl.java | 16 ++----- .../roots/impl/libraries/LibraryImpl.java | 2 +- .../impl/VirtualFilePointerContainerImpl.java | 2 +- .../com/intellij/util/EventDispatcher.java | 3 +- 11 files changed, 51 insertions(+), 68 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java index 237fbcd40c41..8fcd543b41ae 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java @@ -213,11 +213,11 @@ public class ClasspathEditor extends ModuleElementsEditor implements ModuleRootL return ClasspathStorage.getStorageType(getModel().getModule()); } - boolean isModified () { + boolean isModified() { return cbClasspathFormat != null && !getSelectedClasspathFormat().equals(getModuleClasspathFormat()); } - void apply () throws ConfigurationException { + void apply() throws ConfigurationException { final String storageID = getSelectedClasspathFormat(); ClasspathStorage.getProvider(storageID).assertCompatible(getModel()); ClasspathStorage.setStorageType(getModel(), storageID); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java index 447e1d08e0f2..a6fe96046cad 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java @@ -24,7 +24,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.StdModuleTypes; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; @@ -83,7 +82,7 @@ public class ClasspathPanel extends JPanel { private PopupAction[] myPopupActions = null; private Icon[] myIcons = null; private JButton myEditButton; - private ModuleConfigurationState myState; + private final ModuleConfigurationState myState; protected ClasspathPanel(ModuleConfigurationState state) { super(new BorderLayout()); @@ -322,7 +321,7 @@ public class ClasspathPanel extends JPanel { removeButton.addActionListener(new ButtonAction() { protected void executeImpl() { final List removedRows = TableUtil.removeSelectedItems(myEntryTable); - if (removedRows.size() == 0) { + if (removedRows.isEmpty()) { return; } for (final Object removedRow : removedRows) { @@ -475,13 +474,12 @@ public class ClasspathPanel extends JPanel { return; } try { - final List chosen; dialog.doChoose(); if (!dialog.isOK()) { return; } - chosen = dialog.getChosenElements(); - if (chosen.size() == 0) { + final List chosen = dialog.getChosenElements(); + if (chosen.isEmpty()) { return; } final ModuleStructureConfigurable rootConfigurable = ModuleStructureConfigurable.getInstance(myState.getProject()); @@ -512,7 +510,8 @@ public class ClasspathPanel extends JPanel { @Nullable protected abstract TableItem createTableItem(final ItemType item); - protected abstract @Nullable ChooserDialog createChooserDialog(); + @Nullable + protected abstract ChooserDialog createChooserDialog(); } private void initPopupActions() { @@ -572,7 +571,7 @@ public class ClasspathPanel extends JPanel { } protected ChooserDialog createChooserDialog() { final List chooseItems = getDependencyModules(); - if (chooseItems.size() == 0) { + if (chooseItems.isEmpty()) { Messages.showMessageDialog(ClasspathPanel.this, ProjectBundle.message("message.no.module.dependency.candidates"), getTitle(), Messages.getInformationIcon()); return null; } @@ -615,7 +614,8 @@ public class ClasspathPanel extends JPanel { myEntryTable.getCellEditor().stopCellEditing(); } final ListSelectionModel selectionModel = myEntryTable.getSelectionModel(); - for(int row = increment < 0? 0 : myModel.getRowCount() - 1; increment < 0? row < myModel.getRowCount() : row >= 0; row += (increment < 0? +1 : -1)){ + for(int row = increment < 0? 0 : myModel.getRowCount() - 1; increment < 0? row < myModel.getRowCount() : row >= 0; row += + increment < 0? +1 : -1){ if (selectionModel.isSelectedIndex(row)) { final int newRow = moveRow(row, increment); selectionModel.removeSelectionInterval(row, row); @@ -703,8 +703,8 @@ public class ClasspathPanel extends JPanel { } - private static abstract class TableItem { - protected @Nullable T myEntry; + private abstract static class TableItem { + @Nullable protected final T myEntry; protected TableItem(@Nullable T entry) { myEntry = entry; @@ -715,12 +715,12 @@ public class ClasspathPanel extends JPanel { } public final boolean isExported() { - return isExportable() && myEntry != null && ((ExportableOrderEntry)myEntry).isExported(); + return isExportable() && ((ExportableOrderEntry)getEntry()).isExported(); } public final void setExported(boolean isExported) { - if (isExportable() && myEntry != null) { - ((ExportableOrderEntry)myEntry).setExported(isExported); + if (isExportable()) { + ((ExportableOrderEntry)getEntry()).setExported(isExported); } } @@ -735,7 +735,7 @@ public class ClasspathPanel extends JPanel { } } - public final @Nullable T getEntry() { + public final T getEntry() { return myEntry; } @@ -807,7 +807,7 @@ public class ClasspathPanel extends JPanel { public static final int ITEM_COLUMN = 1; public static final int SCOPE_COLUMN = 2; private final List myItems = new ArrayList(); - private ModuleConfigurationState myState; + private final ModuleConfigurationState myState; public MyTableModel(final ModuleConfigurationState state) { myState = state; @@ -834,16 +834,16 @@ public class ClasspathPanel extends JPanel { private void addOrderEntry(OrderEntry orderEntry) { if (orderEntry instanceof JdkOrderEntry) { - addItem(new JdkItem(((JdkOrderEntry)orderEntry))); + addItem(new JdkItem((JdkOrderEntry)orderEntry)); } else if (orderEntry instanceof LibraryOrderEntry) { - addItem(new LibItem(((LibraryOrderEntry)orderEntry))); + addItem(new LibItem((LibraryOrderEntry)orderEntry)); } else if (orderEntry instanceof ModuleOrderEntry) { - addItem(new ModuleItem(((ModuleOrderEntry)orderEntry))); + addItem(new ModuleItem((ModuleOrderEntry)orderEntry)); } else if (orderEntry instanceof ModuleSourceOrderEntry) { - addItem(new SelfModuleItem(((ModuleSourceOrderEntry)orderEntry))); + addItem(new SelfModuleItem((ModuleSourceOrderEntry)orderEntry)); } } @@ -1054,7 +1054,7 @@ public class ClasspathPanel extends JPanel { private static class ChooseModuleLibrariesDialog extends LibraryFileChooser implements ChooserDialog { private Pair myLastChosen; private final LibraryTable myLibraryTable; - private final @Nullable VirtualFile myFileToSelect; + @Nullable private final VirtualFile myFileToSelect; public ChooseModuleLibrariesDialog(Component parent, final LibraryTable libraryTable, final VirtualFile fileToSelect) { super(createFileChooserDescriptor(parent), parent, false, null); @@ -1166,8 +1166,6 @@ public class ClasspathPanel extends JPanel { public List getChosenElements() { final List chosen = new ArrayList(Arrays.asList(myEditor.getSelectedLibraries())); chosen.removeAll(getAlreadyAddedLibraries()); - final Module module = getRootModel().getModule(); - final Project project = module.getProject(); return chosen; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java index 127cf945ee6f..8ba4b2120925 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java @@ -60,7 +60,7 @@ public class JavaContentEntriesEditor extends CommonContentEntriesEditor { @Override protected List addContentEntries(VirtualFile[] files) { List contentEntries = super.addContentEntries(files); - if (contentEntries.size() > 0) { + if (!contentEntries.isEmpty()) { final ContentEntry[] contentEntriesArray = contentEntries.toArray(new ContentEntry[contentEntries.size()]); addSourceRoots(myProject, contentEntriesArray, new Runnable() { public void run() { diff --git a/java/openapi/src/com/intellij/openapi/roots/AnnotationOrderRootType.java b/java/openapi/src/com/intellij/openapi/roots/AnnotationOrderRootType.java index 8aac1d4c762a..9d8e7bc17209 100644 --- a/java/openapi/src/com/intellij/openapi/roots/AnnotationOrderRootType.java +++ b/java/openapi/src/com/intellij/openapi/roots/AnnotationOrderRootType.java @@ -27,7 +27,7 @@ import java.util.List; */ public class AnnotationOrderRootType extends PersistentOrderRootType { /** - * External annotations path + * @return External annotations path */ public static OrderRootType getInstance() { return getOrderRootType(AnnotationOrderRootType.class); diff --git a/platform/lang-api/src/com/intellij/openapi/roots/OrderRootType.java b/platform/lang-api/src/com/intellij/openapi/roots/OrderRootType.java index 72f545b89727..60cc400a8709 100644 --- a/platform/lang-api/src/com/intellij/openapi/roots/OrderRootType.java +++ b/platform/lang-api/src/com/intellij/openapi/roots/OrderRootType.java @@ -19,10 +19,7 @@ import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; import org.jetbrains.annotations.NonNls; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; +import java.util.*; /** * Root types that can be queried from OrderEntry. @@ -111,13 +108,22 @@ public class OrderRootType { } protected static T getOrderRootType(final Class orderRootTypeClass) { - for(OrderRootType rootType: Extensions.getExtensions(EP_NAME)) { + OrderRootType[] rootTypes = Extensions.getExtensions(EP_NAME); + for(OrderRootType rootType: rootTypes) { if (orderRootTypeClass.isInstance(rootType)) { //noinspection unchecked return (T)rootType; } } - assert false; + assert false : "Root type "+orderRootTypeClass+" not found. All roots: "+ Arrays.asList(rootTypes); return null; } + + public final int hashCode() { + return super.hashCode(); + } + + public final boolean equals(Object obj) { + return super.equals(obj); + } } diff --git a/platform/lang-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java b/platform/lang-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java index fe49cd0c69ca..b799e76ad351 100644 --- a/platform/lang-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java +++ b/platform/lang-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java @@ -37,7 +37,7 @@ public class PersistentOrderRootType extends OrderRootType { } /** - * Element name used for storing roots of this type in JDK and library definitions. + * @return Element name used for storing roots of this type in JDK and library definitions. */ public String getSdkRootName() { return mySdkRootName; @@ -48,10 +48,9 @@ public class PersistentOrderRootType extends OrderRootType { } /** - * Element name used for storing roots of this type in module definitions. + * @return Element name used for storing roots of this type in module definitions. */ public String getModulePathsName() { return myModulePathsName; } - } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/LibraryOrderEntryImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/LibraryOrderEntryImpl.java index 91999ebe9780..47f6bee10db2 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/LibraryOrderEntryImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/LibraryOrderEntryImpl.java @@ -68,7 +68,7 @@ class LibraryOrderEntryImpl extends LibraryOrderEntryBaseImpl implements Library String name = element.getAttributeValue(NAME_ATTR); if (name == null) throw new InvalidDataException(); if (level == null) throw new InvalidDataException(); - searchForLibrary(level, name); + searchForLibrary(name, level); init(getRootProvider()); addListeners(); } @@ -97,12 +97,12 @@ class LibraryOrderEntryImpl extends LibraryOrderEntryBaseImpl implements Library ProjectRootManagerImpl projectRootManager, VirtualFilePointerManager filePointerManager) { super(rootModel, projectRootManager, filePointerManager); - searchForLibrary(level, name); + searchForLibrary(name, level); init(getRootProvider()); addListeners(); } - private void searchForLibrary(@NotNull String level, @NotNull String name) { + private void searchForLibrary(@NotNull String name, @NotNull String level) { if (myLibrary != null) return; final LibraryTable libraryTable = LibraryTablesRegistrar.getInstance().getLibraryTableByLevel(level, getRootModel().getModule().getProject()); final Library library = libraryTable != null ? libraryTable.getLibraryByName(name) : null; @@ -158,12 +158,8 @@ class LibraryOrderEntryImpl extends LibraryOrderEntryBaseImpl implements Library } @Nullable - private RootProvider getRootProvider() { - if (myLibrary != null) { - return myLibrary.getRootProvider(); - } else { - return null; - } + protected RootProvider getRootProvider() { + return myLibrary == null ? null : myLibrary.getRootProvider(); } public boolean isValid() { @@ -203,12 +199,7 @@ class LibraryOrderEntryImpl extends LibraryOrderEntryBaseImpl implements Library } public String getLibraryName() { - if (myLibrary != null) { - return myLibrary.getName(); - } - else { - return myLibraryName; - } + return myLibrary == null ? myLibraryName : myLibrary.getName(); } private void addListeners () { diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java index b6315ffcef91..64da6ea3ac1c 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java @@ -116,13 +116,8 @@ public class ModuleJdkOrderEntryImpl extends LibraryOrderEntryBaseImpl implement myProjectRootManagerImpl.addJdkTableListener(this); } - private RootProvider getRootProvider() { - if (myJdk != null) { - return myJdk.getRootProvider(); - } - else { - return null; - } + protected RootProvider getRootProvider() { + return myJdk == null ? null : myJdk.getRootProvider(); } public Sdk getJdk() { @@ -144,12 +139,7 @@ public class ModuleJdkOrderEntryImpl extends LibraryOrderEntryBaseImpl implement public String getPresentableName() { - if (myJdk != null) { - return "< " + myJdk.getName() + " >"; - } - else { - return "< " + getJdkName() + " >"; - } + return "< " + (myJdk == null ? getJdkName() : myJdk.getName())+ " >"; } public boolean isValid() { diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java index 1bc8d9765fa9..cc56b5f5d031 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java @@ -405,7 +405,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { Disposer.dispose(this); } - private void commit(LibraryImpl fromModel) { + private void commit(@NotNull LibraryImpl fromModel) { if (myLibraryTable != null) { ApplicationManager.getApplication().assertWriteAccessAllowed(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java index e516be41d7a2..fe92039d329b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java @@ -182,7 +182,7 @@ public class VirtualFilePointerContainerImpl implements VirtualFilePointerContai result.add(file); } } - return result.toArray(new VirtualFile[result.size()]); + return result.isEmpty() ? VirtualFile.EMPTY_ARRAY : result.toArray(new VirtualFile[result.size()]); } @NotNull diff --git a/platform/util/src/com/intellij/util/EventDispatcher.java b/platform/util/src/com/intellij/util/EventDispatcher.java index 26dcda5c9224..a09e67dea290 100644 --- a/platform/util/src/com/intellij/util/EventDispatcher.java +++ b/platform/util/src/com/intellij/util/EventDispatcher.java @@ -26,7 +26,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.EventListener; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; /** * @author max @@ -36,7 +35,7 @@ public class EventDispatcher { private final T myMulticaster; - private final CopyOnWriteArrayList myListeners = ContainerUtil.createEmptyCOWList(); + private final List myListeners = ContainerUtil.createEmptyCOWList(); public static EventDispatcher create(Class listenerClass) { return new EventDispatcher(listenerClass); From 58567cd73af179edd9d6ff989aabc51c0c08c704 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 13 Nov 2009 14:11:59 +0300 Subject: [PATCH 19/36] cleanup --- ...urceItemIntoParentAndLinkViaManifestAction.java | 14 ++++++-------- .../openapi/projectRoots/ProjectJdkTable.java | 2 +- .../conversion/impl/ModuleSettingsImpl.java | 2 +- .../projectRoots/impl/ProjectJdkTableImpl.java | 2 +- .../openapi/roots/impl/RootModelComponentBase.java | 3 ++- .../configuration/CommonContentEntriesEditor.java | 11 ++++------- .../ExternalChangesAndRefreshingTest.java | 9 ++++----- .../wm/impl/status/InlineProgressIndicator.java | 6 ++---- 8 files changed, 21 insertions(+), 28 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/sourceItems/actions/PutSourceItemIntoParentAndLinkViaManifestAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/sourceItems/actions/PutSourceItemIntoParentAndLinkViaManifestAction.java index 4ec6bb455633..10ef5c62f411 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/sourceItems/actions/PutSourceItemIntoParentAndLinkViaManifestAction.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/sourceItems/actions/PutSourceItemIntoParentAndLinkViaManifestAction.java @@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactEditorEx; import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactEditorImpl; import com.intellij.openapi.roots.ui.configuration.artifacts.sourceItems.SourceItemsTree; +import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.packaging.artifacts.Artifact; @@ -100,10 +101,7 @@ public class PutSourceItemIntoParentAndLinkViaManifestAction extends PutIntoDefa final Artifact artifact = parentsInfo.getGrandparentArtifact(); final ArtifactEditorContext context = myArtifactEditor.getContext(); //todo[nik] improve - final Runnable emptyRunnable = new Runnable() { - public void run() { - } - }; + final Runnable emptyRunnable = EmptyRunnable.getInstance(); context.editLayout(artifact, emptyRunnable); context.editLayout(parentsInfo.getParentArtifact(), emptyRunnable); parentsInfo = findParentAndGrandParent(myArtifactEditor.getArtifact());//find elements under modifiable root @@ -134,10 +132,10 @@ public class PutSourceItemIntoParentAndLinkViaManifestAction extends PutIntoDefa } private static class ParentElementsInfo { - private Artifact myParentArtifact; - private CompositePackagingElement myParentElement; - private Artifact myGrandparentArtifact; - private CompositePackagingElement myGrandparentElement; + private final Artifact myParentArtifact; + private final CompositePackagingElement myParentElement; + private final Artifact myGrandparentArtifact; + private final CompositePackagingElement myGrandparentElement; private ParentElementsInfo(Artifact parentArtifact, CompositePackagingElement parentElement, diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/ProjectJdkTable.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/ProjectJdkTable.java index 41b4e613ec10..c52f64ce6833 100644 --- a/platform/lang-api/src/com/intellij/openapi/projectRoots/ProjectJdkTable.java +++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/ProjectJdkTable.java @@ -43,7 +43,7 @@ public abstract class ProjectJdkTable { public abstract void updateJdk(Sdk originalJdk, Sdk modifiedJdk); - public static interface Listener extends EventListener { + public interface Listener extends EventListener { void jdkAdded(Sdk jdk); void jdkRemoved(Sdk jdk); diff --git a/platform/lang-impl/src/com/intellij/conversion/impl/ModuleSettingsImpl.java b/platform/lang-impl/src/com/intellij/conversion/impl/ModuleSettingsImpl.java index b6d1672abf40..62c447c75947 100644 --- a/platform/lang-impl/src/com/intellij/conversion/impl/ModuleSettingsImpl.java +++ b/platform/lang-impl/src/com/intellij/conversion/impl/ModuleSettingsImpl.java @@ -42,7 +42,7 @@ import java.util.*; * @author nik */ public class ModuleSettingsImpl extends ComponentManagerSettingsImpl implements ModuleSettings { - private String myModuleName; + private final String myModuleName; @NonNls private static final String MODULE_ROOT_MANAGER_COMPONENT = "NewModuleRootManager"; public ModuleSettingsImpl(File moduleFile, ConversionContextImpl context) throws CannotConvertException { diff --git a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkTableImpl.java b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkTableImpl.java index 58b8a93583c0..1a026edf7caf 100644 --- a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkTableImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkTableImpl.java @@ -62,7 +62,7 @@ public class ProjectJdkTableImpl extends ProjectJdkTable implements PersistentSt @NonNls private static final String ELEMENT_JDK = "jdk"; private final Map myCachedProjectJdks = new HashMap(); - private MessageBus myMessageBus; + private final MessageBus myMessageBus; public ProjectJdkTableImpl() { myMessageBus = ApplicationManager.getApplication().getMessageBus(); diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootModelComponentBase.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootModelComponentBase.java index ca652919b0d4..3e20f034275f 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootModelComponentBase.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootModelComponentBase.java @@ -17,6 +17,7 @@ package com.intellij.openapi.roots.impl; import com.intellij.openapi.Disposable; +import org.jetbrains.annotations.NotNull; /** @@ -26,7 +27,7 @@ public abstract class RootModelComponentBase implements Disposable { private final RootModelImpl myRootModel; private boolean myDisposed; - RootModelComponentBase(RootModelImpl rootModel) { + RootModelComponentBase(@NotNull RootModelImpl rootModel) { rootModel.registerOnDispose(this); myRootModel = rootModel; } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java index 5048f1910bd8..0b4cfa3705b2 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java @@ -75,7 +75,7 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { private VirtualFile myLastSelectedDir = null; private final String myModuleName; private final ModulesProvider myModulesProvider; - private ModuleConfigurationState myState; + private final ModuleConfigurationState myState; public CommonContentEntriesEditor(String moduleName, ModuleConfigurationState state) { super(state); @@ -86,15 +86,12 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { public void afterRefreshFinish(boolean asynchronous) { final Module module = getModule(); if (module == null || module.isDisposed() || module.getProject().isDisposed()) return; - for (final String contentEntry : myEntryToEditorMap.keySet()) { - final ContentEntryEditor editor = myEntryToEditorMap.get(contentEntry); - if (editor != null) { - editor.update(); - } + for (final ContentEntryEditor editor : myEntryToEditorMap.values()) { + editor.update(); } } }; - final VirtualFileManagerEx fileManager = ((VirtualFileManagerEx)VirtualFileManager.getInstance()); + final VirtualFileManagerEx fileManager = (VirtualFileManagerEx)VirtualFileManager.getInstance(); fileManager.addVirtualFileManagerListener(fileManagerListener); registerDisposable(new Disposable() { public void dispose() { diff --git a/platform/lvcs-impl/testSrc/com/intellij/historyIntegrTests/ExternalChangesAndRefreshingTest.java b/platform/lvcs-impl/testSrc/com/intellij/historyIntegrTests/ExternalChangesAndRefreshingTest.java index d6e1ee66fdbd..ee3022a104ac 100644 --- a/platform/lvcs-impl/testSrc/com/intellij/historyIntegrTests/ExternalChangesAndRefreshingTest.java +++ b/platform/lvcs-impl/testSrc/com/intellij/historyIntegrTests/ExternalChangesAndRefreshingTest.java @@ -17,13 +17,13 @@ package com.intellij.historyIntegrTests; -import static com.intellij.history.core.LocalVcsTestCase.list; import com.intellij.history.core.Paths; import com.intellij.history.core.revisions.Revision; import com.intellij.history.utils.RunnableAdapter; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.*; @@ -31,6 +31,8 @@ import java.io.File; import java.io.IOException; import java.util.concurrent.Semaphore; +import static com.intellij.history.core.LocalVcsTestCase.list; + public class ExternalChangesAndRefreshingTest extends IntegrationTestCase { public void testRefreshingSynchronously() throws Exception { doTestRefreshing(false); @@ -113,10 +115,7 @@ public class ExternalChangesAndRefreshingTest extends IntegrationTestCase { } private void executeSomeCommand() { - CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { - public void run() { - } - }, "", null); + CommandProcessor.getInstance().executeCommand(myProject, EmptyRunnable.getInstance(), "", null); } public void testContentOfFileChangedDuringRefresh() throws Exception { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java index ca89ef58f9e3..c1e8166e82d3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java @@ -21,6 +21,7 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.progress.TaskInfo; import com.intellij.openapi.progress.util.ProgressIndicatorBase; import com.intellij.openapi.ui.popup.IconButton; +import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.wm.impl.content.GraphicsConfig; import com.intellij.ui.InplaceButton; @@ -143,10 +144,7 @@ public class InlineProgressIndicator extends ProgressIndicatorBase implements Di } private void updateRunning() { - queueRunningUpdate(new Runnable() { - public void run() { - } - }); + queueRunningUpdate(EmptyRunnable.getInstance()); } protected void updateProgress() { From 564485d8fc1e1cd78410cec081d4591f87b2c4c9 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 13 Nov 2009 14:41:43 +0300 Subject: [PATCH 20/36] do not suggest to inject inside injected --- .../plugins/intelliLang/inject/InjectLanguageAction.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java index e6441caaf9c5..693fd2938fac 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java @@ -17,6 +17,7 @@ package org.intellij.plugins.intelliLang.inject; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.ide.DataManager; +import com.intellij.injected.editor.EditorWindow; import com.intellij.lang.Language; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.extensions.Extensions; @@ -67,6 +68,7 @@ public class InjectLanguageAction implements IntentionAction { @Nullable protected static PsiLanguageInjectionHost findInjectionHost(Editor editor, PsiFile file) { + if (editor instanceof EditorWindow) return null; final int offset = editor.getCaretModel().getOffset(); final PsiLanguageInjectionHost host = PsiTreeUtil.getParentOfType(file.findElementAt(offset), PsiLanguageInjectionHost.class, false); if (host == null) return null; From 0ae456715602292b01e0ec713613dc14d62ca17b Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 13 Nov 2009 15:27:24 +0300 Subject: [PATCH 21/36] diagnostics --- .../impl/source/tree/injected/MultiHostRegistrarImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java index 29436af56b84..ffc6f6278ef9 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java @@ -204,7 +204,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar { assert parsedNode instanceof FileElement : "Parsed to "+parsedNode+" instead of FileElement"; String documentText = documentWindow.getText(); - assert outChars.toString().equals(parsedNode.getText()) : exceptionContext("Before patch: doc:\n" + documentText + "\n---PSI:\n" + parsedNode.getText() + "\n---chars:\n"+outChars); + assert outChars.toString().equals(parsedNode.getText()) : exceptionContext("Before patch: doc:\n'" + documentText + "'\n---PSI:\n'" + parsedNode.getText() + "'\n---chars:\n'"+outChars+"'"); try { patchLeafs(parsedNode, escapers, place); } @@ -214,7 +214,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar { catch (RuntimeException e) { throw new RuntimeException(exceptionContext("Patch error"), e); } - assert parsedNode.getText().equals(documentText) : exceptionContext("After patch: doc:\n" + documentText + "\n---PSI:\n" + parsedNode.getText() + "\n---chars:\n"+outChars); + assert parsedNode.getText().equals(documentText) : exceptionContext("After patch: doc:\n'" + documentText + "'\n---PSI:\n'" + parsedNode.getText() + "'\n---chars:\n'"+outChars+"'"); virtualFile.setContent(null, documentWindow.getText(), false); @@ -283,7 +283,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar { @NonNls private String exceptionContext(@NonNls String msg) { return msg + ".\n" + - "Language: " +myLanguage+";\n "+ + myLanguage+";\n "+ "Host file: "+myHostPsiFile+" in '" + myHostVirtualFile.getPresentableUrl() + "'\n" + "Context element "+myContextElement.getTextRange() + ": '" + myContextElement +"'; "+ "Ranges: "+shreds; From ed599b98adfa34ef710a06d76daa8817077af817 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Fri, 13 Nov 2009 15:50:38 +0300 Subject: [PATCH 22/36] calculate prefix for path completion contributor properly --- .../completion/FilePathCompletionContributor.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java index f4b84734a9f6..b1eacc72e434 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java @@ -101,8 +101,8 @@ public class FilePathCompletionContributor extends CompletionContributor { if (first == null) return; final FileReferenceSet set = first.getFileReferenceSet(); - String prefix = set.getPathString().replace(CompletionUtil.DUMMY_IDENTIFIER_TRIMMED, ""); - + String prefix = set.getPathString().substring(0, parameters.getOffset() - set.getElement().getTextRange().getStartOffset() - set.getStartInElement()); + final List[] pathPrefixParts = new List[] {null}; int lastSlashIndex; if ((lastSlashIndex = prefix.lastIndexOf('/')) != -1) { @@ -110,6 +110,8 @@ public class FilePathCompletionContributor extends CompletionContributor { prefix = prefix.substring(lastSlashIndex + 1); } + final CompletionResultSet __result = result.withPrefixMatcher(prefix).caseInsensitive(); + final PsiFile originalFile = parameters.getOriginalFile(); final VirtualFile contextFile = originalFile.getVirtualFile(); if (contextFile != null) { @@ -147,7 +149,7 @@ public class FilePathCompletionContributor extends CompletionContributor { if (virtualFile != null && virtualFile.isValid() && virtualFile != contextFile) { if (contextHelper.isMine(project, virtualFile)) { if (pathPrefixParts[0] == null || fileMatchesPathPrefix(contextHelper.getPsiFileSystemItem(project, virtualFile), pathPrefixParts[0])) { - result.addElement(new FilePathLookupItem(file, contextHelper)); + __result.addElement(new FilePathLookupItem(file, contextHelper)); } } } From 5162ab658e921eb83750994bfebc6c1daf396298 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 13 Nov 2009 16:27:40 +0300 Subject: [PATCH 23/36] - last selected dialect - made actions in popup DumdAware --- .../internal/psiView/PsiViewerDialog.java | 66 +++++++++++-------- .../internal/psiView/PsiViewerSettings.java | 1 + 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java index 46f25a7019e1..50335fc9b5fb 100644 --- a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java +++ b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java @@ -32,6 +32,7 @@ import com.intellij.openapi.editor.markup.*; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileTypes.*; import com.intellij.openapi.fileTypes.impl.AbstractFileType; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; @@ -94,6 +95,14 @@ public class PsiViewerDialog extends DialogWrapper { private Presentation myPresentation = new Presentation(); private Map handlers = new HashMap(); private DefaultActionGroup myGroup; + private Language[] myLanguageDialects; + private static final Comparator DIALECTS_COMPARATOR = new Comparator() { + public int compare(final Language o1, final Language o2) { + if (o1 == null) return o2 == null ? 0 : -1; + if (o2 == null) return 1; + return o1.getID().compareTo(o2.getID()); + } + }; public PsiViewerDialog(Project project, boolean modal) { super(project, true); @@ -195,19 +204,6 @@ public class PsiViewerDialog extends DialogWrapper { } }); - myDialectsComboBox.setRenderer(new DefaultListCellRenderer() { - @Override - public Component getListCellRendererComponent(final JList list, - final Object value, - final int index, - final boolean isSelected, - final boolean cellHasFocus) { - final Component result = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - if (value == null) setText(""); - return result; - } - }); - final ViewerTreeStructure treeStructure = (ViewerTreeStructure)myTreeBuilder.getTreeStructure(); myShowWhiteSpacesBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -226,12 +222,7 @@ public class PsiViewerDialog extends DialogWrapper { myGroup = new DefaultActionGroup(); for (final Presentation popupItem : popupItems) { - myGroup.add(new AnAction(popupItem.getText(), popupItem.getText(), popupItem.getIcon()) { - public void actionPerformed(AnActionEvent e) { - updatePresentation(e.getPresentation()); - updateDialectsCombo(); - } - }); + myGroup.add(new PopupItemAction(popupItem)); } final PsiViewerSettings settings = PsiViewerSettings.getSettings(); @@ -256,6 +247,14 @@ public class PsiViewerDialog extends DialogWrapper { myButtonPanel.add(typeButton.createCustomComponent(myPresentation), BorderLayout.CENTER); updateDialectsCombo(); + if (myDialectsComboBox.isVisible()) { + for (int i = 0; i < myLanguageDialects.length; i++) { + if (settings.dialect.equals(myLanguageDialects[i].toString())) { + myDialectsComboBox.setSelectedIndex(i); + break; + } + } + } registerCustomKeyboardActions(); super.init(); @@ -363,21 +362,19 @@ public class PsiViewerDialog extends DialogWrapper { } private void updateDialectsCombo() { - final SortedComboBoxModel model = new SortedComboBoxModel(new Comparator() { - public int compare(final Language o1, final Language o2) { - if (o1 == null) return o2 == null ? 0 : -1; - if (o2 == null) return 1; - return o1.getID().compareTo(o2.getID()); - } - }); + final SortedComboBoxModel model = new SortedComboBoxModel(DIALECTS_COMPARATOR); final Object handler = getHandler(); if (handler instanceof LanguageFileType) { final Language baseLang = ((LanguageFileType)handler).getLanguage(); - model.setAll(LanguageUtil.getLanguageDialects(baseLang)); - model.add(null); + myLanguageDialects = LanguageUtil.getLanguageDialects(baseLang); + Arrays.sort(myLanguageDialects, DIALECTS_COMPARATOR); + model.setAll(myLanguageDialects); } myDialectsComboBox.setModel(model); myDialectsComboBox.setVisible(model.getSize() > 1); + if (!myDialectsComboBox.isVisible()) { + myLanguageDialects = new Language[0]; + } } protected JComponent createCenterPanel() { @@ -503,6 +500,8 @@ public class PsiViewerDialog extends DialogWrapper { settings.text = myEditor.getDocument().getText(); settings.showTreeNodes = myShowTreeNodesCheckBox.isSelected(); settings.showWhiteSpaces = myShowWhiteSpacesBox.isSelected(); + final Object selectedDialect = myDialectsComboBox.getSelectedItem(); + settings.dialect = myDialectsComboBox.isVisible() && selectedDialect != null ? selectedDialect.toString() : ""; super.doCancelAction(); } @@ -644,4 +643,15 @@ public class PsiViewerDialog extends DialogWrapper { public void mouseExited(MouseEvent e) { } } + + private class PopupItemAction extends AnAction implements DumbAware { + public PopupItemAction(Presentation p) { + super(p.getText(), p.getText(), p.getIcon()); + } + + public void actionPerformed(AnActionEvent e) { + updatePresentation(e.getPresentation()); + updateDialectsCombo(); + } + } } diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerSettings.java b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerSettings.java index 7ae4cfd05509..1181b22dd7e1 100644 --- a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerSettings.java +++ b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerSettings.java @@ -32,6 +32,7 @@ public class PsiViewerSettings implements PersistentStateComponent Date: Fri, 13 Nov 2009 16:36:46 +0300 Subject: [PATCH 24/36] Win32fs caching optimized --- .../openapi/vfs/impl/win32/Win32Kernel.java | 12 ++- .../vfs/impl/win32/Win32LocalFileSystem.java | 4 +- .../vfs/newvfs/persistent/FSRecords.java | 96 ++++++++++++++----- .../intellij/util/io/storage/StorageTest.java | 31 +++--- 4 files changed, 99 insertions(+), 44 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java index 0b0e39dacc0a..2768e9af57f7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java @@ -50,6 +50,10 @@ public class Win32Kernel { private final WIN32_FIND_DATA myData = new WIN32_FIND_DATA(); + void clearCache() { + myCache.clear(); + } + private static class FileInfo { private FileInfo(WIN32_FIND_DATA data) { this.dwFileAttributes = data.dwFileAttributes; @@ -64,8 +68,6 @@ public class Win32Kernel { public String[] list(String absolutePath) { - myCache.clear(); - ArrayList list = new ArrayList(); WIN32_FIND_DATA data = myData; W32API.HANDLE hFind = myKernel.FindFirstFile(absolutePath.replace('/', '\\') + "\\*", data); @@ -92,7 +94,6 @@ public class Win32Kernel { } public boolean exists(String path) { - myCache.clear(); try { getInfo(path); return true; @@ -108,7 +109,9 @@ public class Win32Kernel { } public boolean isWritable(String path) throws FileNotFoundException { - return (getInfo(path).dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; + FileInfo fileInfo = getInfo(path); + myCache.remove(path); + return (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; } public long getTimeStamp(String path) throws FileNotFoundException { @@ -118,7 +121,6 @@ public class Win32Kernel { private FileInfo getInfo(String path) throws FileNotFoundException { FileInfo info = myCache.get(path); if (info == null) { - myCache.clear(); WIN32_FIND_DATA data = myData; W32API.HANDLE handle = myKernel.FindFirstFile(path.replace('/', '\\'), data); if (handle.equals(INVALID_HANDLE_VALUE)) { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java index ae06e76cdd98..a5e329b7f594 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java @@ -40,7 +40,9 @@ public class Win32LocalFileSystem extends LocalFileSystemBase { }; public static Win32LocalFileSystem getWin32Instance() { - return THREAD_LOCAL.get(); + Win32LocalFileSystem fileSystem = THREAD_LOCAL.get(); + fileSystem.myKernel.clearCache(); + return fileSystem; } private final Win32Kernel myKernel = new Win32Kernel(); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java index cb4b2d77ee45..91070d6f913e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java @@ -30,6 +30,8 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.containers.IntArrayList; import com.intellij.util.io.PersistentStringEnumerator; import com.intellij.util.io.ResizeableMappedFile; +import com.intellij.util.io.storage.AbstractStorage; +import com.intellij.util.io.storage.CompactStorage; import com.intellij.util.io.storage.HeavyProcessLatch; import com.intellij.util.io.storage.Storage; import gnu.trove.TIntArrayList; @@ -47,7 +49,7 @@ import java.util.concurrent.TimeUnit; public class FSRecords implements Disposable, Forceable { private static final Logger LOG = Logger.getInstance("#com.intellij.vfs.persistent.FSRecords"); - private static final int VERSION = 9; + private static final int VERSION = 10; private static final int PARENT_OFFSET = 0; private static final int PARENT_SIZE = 4; @@ -82,7 +84,6 @@ public class FSRecords implements Disposable, Forceable { private static final String CHILDREN_ATT = "FsRecords.DIRECTORY_CHILDREN"; private static final Object lock = new Object(); - private DbConnection myConnection; private volatile static int ourLocalModificationCount = 0; @@ -101,7 +102,7 @@ public class FSRecords implements Disposable, Forceable { private static int CONTENT_ID; private static PersistentStringEnumerator myNames; - private static Storage myAttributes; + private static AbstractStorage myAttributes; private static Storage myContents; private static ResizeableMappedFile myRecords; private static final TIntArrayList myFreeRecords = new TIntArrayList(); @@ -168,7 +169,7 @@ public class FSRecords implements Disposable, Forceable { if (!namesFile.exists()) { invalidateIndex(); } - + boolean compact = true; try { if (getCorruptionMarkerFile().exists()) { invalidateIndex(); @@ -176,7 +177,7 @@ public class FSRecords implements Disposable, Forceable { } myNames = new PersistentStringEnumerator(namesFile); - myAttributes = Storage.create(attributesFile.getCanonicalPath()); + myAttributes = compact ? new CompactStorage(attributesFile.getCanonicalPath()) : Storage.create(attributesFile.getCanonicalPath()); myContents = Storage.create(contentsFile.getCanonicalPath()); myRecords = new ResizeableMappedFile(recordsFile, 20 * 1024); @@ -203,7 +204,7 @@ public class FSRecords implements Disposable, Forceable { boolean deleted = true; deleted &= FileUtil.delete(getCorruptionMarkerFile()); deleted &= deleteWithSubordinates(namesFile); - deleted &= Storage.deleteFiles(attributesFile.getCanonicalPath()); + deleted &= compact ? CompactStorage.deleteFiles(attributesFile.getCanonicalPath()) : Storage.deleteFiles(attributesFile.getCanonicalPath()); deleted &= Storage.deleteFiles(contentsFile.getCanonicalPath()); deleted &= deleteWithSubordinates(recordsFile); @@ -349,7 +350,7 @@ public class FSRecords implements Disposable, Forceable { return myNames; } - public static Storage getAttributes(int attId) { + public static AbstractStorage getAttributes(int attId) { return attId == CONTENT_ID ? myContents : myAttributes; } @@ -434,14 +435,14 @@ public class FSRecords implements Disposable, Forceable { } public void connect() { - myConnection = DbConnection.connect(); + DbConnection.connect(); } private static ResizeableMappedFile getRecords() { return DbConnection.getRecords(); } - private static Storage getAttributes(int attId) { + private static AbstractStorage getAttributes(int attId) { return DbConnection.getAttributes(attId); } @@ -514,14 +515,15 @@ public class FSRecords implements Disposable, Forceable { private void deleteAttribute(int id, int isContent) throws IOException { int att_page = getAttributeRecordId(id, isContent); if (att_page != 0) { - final DataInputStream attStream = getAttributes(isContent).readStream(att_page); + AbstractStorage storage = getAttributes(isContent); + final DataInputStream attStream = storage.readStream(att_page); while (attStream.available() > 0) { attStream.readInt(); // Attribute ID; int attAddress = attStream.readInt(); - getAttributes(isContent).deleteRecord(attAddress); + storage.deleteRecord(attAddress); } attStream.close(); - getAttributes(isContent).deleteRecord(att_page); + storage.deleteRecord(att_page); } } @@ -677,7 +679,7 @@ public class FSRecords implements Disposable, Forceable { try { synchronized (lock) { int encodedAttId = DbConnection.getAttributeId(CHILDREN_ATT); - final int att = findAttributePage(id, encodedAttId, false); + final int att = findAttributePage(id, encodedAttId, false, 0); return att != 0; } } @@ -860,7 +862,9 @@ public class FSRecords implements Disposable, Forceable { } private static int getAttributeRecordId(final int id, int attributeId) throws IOException { - return getRecords().getInt(getAttrOffset(id, attributeId)); + final int record = getRecords().getInt(getAttrOffset(id, attributeId)); + assert record >= 0; + return record; } private static int getAttrOffset(int id, int attributeId) { @@ -875,7 +879,7 @@ public class FSRecords implements Disposable, Forceable { int encodedAttId; synchronized (lock) { encodedAttId = DbConnection.getAttributeId(attId); - page = findAttributePage(id, encodedAttId, false); + page = findAttributePage(id, encodedAttId, false, 0); if (page == 0) return null; } @@ -887,7 +891,7 @@ public class FSRecords implements Disposable, Forceable { } } - private int findAttributePage(int fileId, int attributeId, boolean createIfNotFound) throws IOException { + private int findAttributePage(int fileId, int attributeId, boolean createIfNotFound, int capacity) throws IOException { if (fileId <= 0) { throw DbConnection.handleError(new AssertionError("assert fileId > 0 failed")); } @@ -895,35 +899,58 @@ public class FSRecords implements Disposable, Forceable { if ((getFlags(fileId) & FREE_RECORD_FLAG) != 0) { // TODO: This assertion is a bit timey, will remove when bug is caught. throw DbConnection.handleError(new AssertionError("Trying to find an attribute of deleted page")); } + int attrsRecord = getAttributeRecordId(fileId, attributeId); + AbstractStorage storage = getAttributes(attributeId); if (attrsRecord == 0) { if (!createIfNotFound) return 0; - attrsRecord = getAttributes(attributeId).createNewRecord(); + attrsRecord = storage.createNewRecord(16 * 8); getRecords().putInt(getAttrOffset(fileId, attributeId), attrsRecord); } else { - final DataInputStream attrRefs = getAttributes(attributeId).readStream(attrsRecord); + final DataInputStream attrRefs = storage.readStream(attrsRecord); try { + int offset = 4; while (attrRefs.available() > 0) { final int attIdOnPage = attrRefs.readInt(); + if (attrRefs.available() < 4) { + LOG.error("bad"); + } final int attAddress = attrRefs.readInt(); - if (attIdOnPage == attributeId) return attAddress; + if (attIdOnPage == attributeId) { + if (capacity > 0) { + int newAddress = storage.ensureCapacity(attAddress, capacity); + if (newAddress == attAddress) { + return attAddress; + } + ((CompactStorage)storage).replaceIntInData(attrsRecord + offset, newAddress, attAddress); + return newAddress; + } else { + return attAddress; + } + } + offset += 8; } } finally { attrRefs.close(); } + + } if (createIfNotFound) { - Storage.AppenderStream appender = getAttributes(attributeId).appendStream(attrsRecord); + Storage.AppenderStream appender = storage.appendStream(attrsRecord); appender.writeInt(attributeId); - int attAddress = getAttributes(attributeId).createNewRecord(); + int attAddress = storage.createNewRecord(capacity); appender.writeInt(attAddress); appender.close(); + if (appender.getRecordId() != attrsRecord) { + getRecords().putInt(getAttrOffset(fileId, attributeId), appender.getRecordId()); + } return attAddress; } @@ -951,12 +978,35 @@ public class FSRecords implements Disposable, Forceable { DbConnection.markDirty(); incModCount(myFileId); encodedAttId = DbConnection.getAttributeId(myAttributeId); - page = findAttributePage(myFileId, encodedAttId, true); + page = findAttributePage(myFileId, encodedAttId, true, ((ByteArrayOutputStream)out).size()); } - final DataOutputStream sinkStream = getAttributes(encodedAttId).writeStream(page); + AbstractStorage storage = getAttributes(encodedAttId); + AbstractStorage.StorageDataOutput sinkStream = storage.writeStream(page); sinkStream.write(((ByteArrayOutputStream)out).toByteArray()); sinkStream.close(); + final int recordId = sinkStream.getRecordId(); + if (recordId != page) { + int attrsRecord = getAttributeRecordId(myFileId, encodedAttId); + DataInputStream stream = storage.readStream(attrsRecord); + try { + while (stream.available() > 0) { + if (encodedAttId == stream.readInt()) { + ((CompactStorage)storage).replaceIntInData(attrsRecord + 4, recordId, page); + break; + } + if (stream.available() < 4) { + LOG.error("wtf"); + } + stream.readInt(); + attrsRecord += 8; + } + } + finally { + stream.close(); + } + } + } } catch (Throwable e) { diff --git a/platform/util/testSrc/com/intellij/util/io/storage/StorageTest.java b/platform/util/testSrc/com/intellij/util/io/storage/StorageTest.java index 9795fca432f6..f5130bc25b04 100644 --- a/platform/util/testSrc/com/intellij/util/io/storage/StorageTest.java +++ b/platform/util/testSrc/com/intellij/util/io/storage/StorageTest.java @@ -29,14 +29,14 @@ import java.io.File; import java.io.IOException; public class StorageTest extends TestCase { - private Storage myStorage; + protected AbstractStorage myStorage; protected void setUp() throws Exception { super.setUp(); myStorage = Storage.create(getFileName()); } - private String getFileName() { + protected String getFileName() { return FileUtil.getTempDirectory() + File.separatorChar + getName(); } @@ -47,7 +47,7 @@ public class StorageTest extends TestCase { } public void testSmoke() throws Exception { - final int record = myStorage.createNewRecord(); + int record = myStorage.createNewRecord(0); myStorage.writeBytes(record, "Hello".getBytes()); assertEquals("Hello", new String(myStorage.readBytes(record))); } @@ -64,13 +64,15 @@ public class StorageTest extends TestCase { int[] records = new int[count]; for (int i = 0; i < count; i++) { - final int record = myStorage.createNewRecord(); - myStorage.writeBytes(record, hello.getBytes()); + byte[] bytes = hello.getBytes(); + int record = myStorage.createNewRecord(bytes.length); + myStorage.writeBytes(record, bytes); records[i] = record; } for (int record : records) { - assertEquals(hello, new String(myStorage.readBytes(record))); + byte[] bytes = myStorage.readBytes(record); + assertEquals(hello, new String(bytes)); } long timedelta = System.currentTimeMillis() - start; @@ -78,23 +80,22 @@ public class StorageTest extends TestCase { } public void testAppender() throws Exception { - final int r = myStorage.createNewRecord(); + final int count = 1000; + int r = myStorage.createNewRecord(count * 4); - DataOutputStream out = new DataOutputStream(myStorage.appendStream(r)); - for (int i = 0; i < 10000; i++) { + AbstractStorage.AppenderStream out = myStorage.appendStream(r); + for (int i = 0; i < count; i++) { out.writeInt(i); if (i % 100 == 0) { - myStorage.readStream(r); // Drop the appenders cache out.close(); - out = new DataOutputStream(myStorage.appendStream(r)); + out = myStorage.appendStream(r); } } out.close(); - - DataInputStream in = new DataInputStream(myStorage.readStream(r)); - for (int i = 0; i < 10000; i++) { + DataInputStream in = myStorage.readStream(r); + for (int i = 0; i < count; i++) { assertEquals(i, in.readInt()); } @@ -102,7 +103,7 @@ public class StorageTest extends TestCase { } public void testAppender2() throws Exception { - int r = myStorage.createNewRecord(); + int r = myStorage.createNewRecord(0); appendNBytes(r, 64); appendNBytes(r, 256); appendNBytes(r, 512); From 66cc77708230b9f88d9f774221c9765b67c17120 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Wed, 11 Nov 2009 22:36:43 +0300 Subject: [PATCH 25/36] SMRunner: defects priority for "select first failed test" action --- .../testframework/sm/runner/ProxyFilters.java | 3 +++ .../runner/ui/SMTRunnerUIActionsHandler.java | 23 +++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ProxyFilters.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ProxyFilters.java index 06927995bf74..68f71a176667 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ProxyFilters.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ProxyFilters.java @@ -38,4 +38,7 @@ public interface ProxyFilters { return ((SMTestProxy)test).getMagnitudeInfo() == TestStateInfo.Magnitude.FAILED_INDEX; } }; + + Filter ERROR_LEAF = FILTER_ERRORS.and(Filter.LEAF); + Filter FAILURE_LEAF = FILTER_FAILURES.and(Filter.LEAF); } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandler.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandler.java index e755034203c8..460216522a7a 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandler.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandler.java @@ -19,6 +19,7 @@ import com.intellij.execution.testframework.AbstractTestProxy; import com.intellij.execution.testframework.Filter; import com.intellij.execution.testframework.TestConsoleProperties; import com.intellij.execution.testframework.TestFrameworkRunningModel; +import com.intellij.execution.testframework.sm.runner.ProxyFilters; import com.intellij.execution.testframework.ui.PrintableTestProxy; import com.intellij.execution.testframework.actions.ScrollToTestSourceAction; import com.intellij.execution.testframework.sm.runner.SMTestProxy; @@ -28,6 +29,8 @@ import com.intellij.openapi.application.ModalityState; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + /** * @author Roman Chernyatchik */ @@ -52,8 +55,24 @@ public class SMTRunnerUIActionsHandler implements TestResultsViewer.EventsListen // select first defect at the end (my be TRACK_RUNNING_TEST was enabled and affects on the fly selection) final SMTestProxy testsRootNode = sender.getTestsRootNode(); if (TestConsoleProperties.SELECT_FIRST_DEFECT.value(myConsoleProperties)) { - final AbstractTestProxy firstDefect = - Filter.DEFECTIVE_LEAF.detectIn(testsRootNode.getAllTests()); + final AbstractTestProxy firstDefect; + + // defects priority: + // ERROR -> FAILURE -> GENERAL DEFECTIVE NODE + final List allTests = testsRootNode.getAllTests(); + final AbstractTestProxy firstError = ProxyFilters.ERROR_LEAF.detectIn(allTests); + if (firstError != null) { + firstDefect = firstError; + } else { + final AbstractTestProxy firstFailure = ProxyFilters.FAILURE_LEAF.detectIn(allTests); + if (firstFailure != null) { + firstDefect = firstFailure; + } else { + firstDefect = Filter.DEFECTIVE_LEAF.detectIn(allTests); + } + } + + // select if detected if (firstDefect != null) { sender.selectAndNotify(firstDefect); } From d942f2978d1639d69fc29daa3ed15f50420c82d4 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Wed, 11 Nov 2009 23:52:00 +0300 Subject: [PATCH 26/36] =?UTF-8?q?fixed=20[IDEADEV-41302]=20Change=20File?= =?UTF-8?q?=E2=80=8B-=E2=80=8B>=E2=80=8BReopen=20to=20'=E2=80=8BOpen=20Rec?= =?UTF-8?q?ent'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../platform-resources-en/src/messages/ActionsBundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 6a7fb6c9eb57..f5eb71f1702d 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -200,7 +200,7 @@ action.OpenProject.text=_Open Project... action.OpenProject.description=Open an existing project action.OpenFile.text=Open Fi_le... action.OpenFile.description=Open file in editor -group.$LRU.text=_Reopen +group.$LRU.text=Open _Recent group.$LRU.description=List of recently opened projects action.CloseProject.text=Close Pro_ject action.CloseProject.description=Close current project From 8fc03ec705a1464104027aac6a381eec8b446e40 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Thu, 12 Nov 2009 00:31:21 +0300 Subject: [PATCH 27/36] fixed [IDEADEV-41319] test runner: do not show green balloon and green progress bar if no tests were found --- .../progress/util/ColorProgressBar.java | 4 + .../ui/SMTRunnerNotificationsHandler.java | 7 ++ .../sm/runner/ui/SMTestRunnerResultsForm.java | 8 ++ .../ui/SMTRunnerUIActionsHandlerTest.java | 114 ++++++++++++++++++ .../ui/SMTestRunnerResultsFormTest.java | 22 +++- .../testframework/ui/TestStatusLine.java | 4 + 6 files changed, 158 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java index 0da4cb0dc021..b93d42c055a8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java @@ -211,6 +211,10 @@ public class ColorProgressBar extends JComponent { return dimension; } + public Color getColor() { + return myColor; + } + @SuppressWarnings({"HardCodedStringLiteral"}) public static void main(String[] args) { JFrame frame = new JFrame("ColorProgressBar Test"); diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerNotificationsHandler.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerNotificationsHandler.java index e1ddd11800ee..442b67fdbbc0 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerNotificationsHandler.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerNotificationsHandler.java @@ -16,6 +16,7 @@ package com.intellij.execution.testframework.sm.runner.ui; import com.intellij.execution.testframework.TestConsoleProperties; +import com.intellij.execution.testframework.sm.SMTestsRunnerBundle; import com.intellij.execution.testframework.sm.runner.SMTRunnerEventsAdapter; import com.intellij.execution.testframework.sm.runner.SMTestProxy; import com.intellij.execution.testframework.sm.runner.states.TestStateInfo; @@ -66,6 +67,12 @@ public class SMTRunnerNotificationsHandler extends SMTRunnerEventsAdapter { type = MessageType.ERROR; break; case COMPLETE_INDEX: + if (testsRoot.getChildren().size() == 0) { + msg = SMTestsRunnerBundle.message("sm.test.runner.ui.tests.tree.presentation.labels.no.tests.were.found"); + type = MessageType.ERROR; + break; + } + // else same as: PASSED_INDEX case PASSED_INDEX: msg = "Tests passed"; type = MessageType.INFO; diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java index 7dfaff2867ec..3ebd4baa0c9f 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java @@ -216,6 +216,10 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra } updateStatusLabel(); + if (myTestsRootNode.getChildren().size() == 0) { + // no tests found + myStatusLine.setStatusColor(ColorProgressBar.RED); + } myAnimator.stopMovie(); myTreeBuilder.updateFromRoot(); @@ -374,6 +378,10 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra return myTestsFailuresCount; } + protected Color getTestsStatusColor() { + return myStatusLine.getStatusColor(); + } + protected int getTestsTotal() { return myTestsTotal; } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandlerTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandlerTest.java index 1964c0a211ba..76d35f45431e 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandlerTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandlerTest.java @@ -171,6 +171,120 @@ public class SMTRunnerUIActionsHandlerTest extends BaseSMTRunnerTestCase { } + public void testSelectFirstDeffect_Priority_Error() { + // Priority: error -> failure -> pending + TestConsoleProperties.SELECT_FIRST_DEFECT.set(myProperties, true); + mySuite.setStarted(); + + final SMTestProxy testsSuite = createSuiteProxy("my suite", mySuite); + testsSuite.setStarted(); + + // pending test + final SMTestProxy testPending = createTestProxy("testPending", testsSuite); + testPending.setStarted(); + myUIActionsHandler.onTestNodeAdded(myResultsViewer, testPending); + testPending.setTestIgnored("", ""); + + //failed test + final SMTestProxy testFailed = createTestProxy("testFailed", testsSuite); + testFailed.setStarted(); + myUIActionsHandler.onTestNodeAdded(myResultsViewer, testFailed); + testFailed.setTestFailed("", "", false); + + //error test + final SMTestProxy testError = createTestProxy("testError", testsSuite); + testError.setStarted(); + myUIActionsHandler.onTestNodeAdded(myResultsViewer, testError); + testError.setTestFailed("", "", true); + + // Second error test just to check that first failed will be selected + final SMTestProxy testError2 = createTestProxy("testError2", testsSuite); + testError2.setStarted(); + myUIActionsHandler.onTestNodeAdded(myResultsViewer, testError2); + testError2.setTestFailed("", "", true); + + // finish suite + testsSuite.setFinished(); + assertNull(mySelectedTestProxy); + + //testing finished + mySuite.setFinished(); + assertNull(mySelectedTestProxy); + + myUIActionsHandler.onTestingFinished(myResultsViewer); + assertEquals(testError, mySelectedTestProxy); + } + + public void testSelectFirstDeffect_Priority_Failure() { + // Priority: error -> failure -> pending + TestConsoleProperties.SELECT_FIRST_DEFECT.set(myProperties, true); + mySuite.setStarted(); + + final SMTestProxy testsSuite = createSuiteProxy("my suite", mySuite); + testsSuite.setStarted(); + + // pending test + final SMTestProxy testPending = createTestProxy("testPending", testsSuite); + testPending.setStarted(); + myUIActionsHandler.onTestNodeAdded(myResultsViewer, testPending); + testPending.setTestIgnored("", ""); + + //failed test + final SMTestProxy testFailed = createTestProxy("testFailed", testsSuite); + testFailed.setStarted(); + myUIActionsHandler.onTestNodeAdded(myResultsViewer, testFailed); + testFailed.setTestFailed("", "", false); + + // Second failed test just to check that first failed will be selected + final SMTestProxy testFailed2 = createTestProxy("testFailed2", testsSuite); + testFailed2.setStarted(); + myUIActionsHandler.onTestNodeAdded(myResultsViewer, testFailed2); + testFailed2.setTestFailed("", "", false); + + // finish suite + testsSuite.setFinished(); + assertNull(mySelectedTestProxy); + + //testing finished + mySuite.setFinished(); + assertNull(mySelectedTestProxy); + + myUIActionsHandler.onTestingFinished(myResultsViewer); + assertEquals(testFailed, mySelectedTestProxy); + } + + public void testSelectFirstDeffect_Priority_Pending() { + // Priority: error -> failure -> pending + TestConsoleProperties.SELECT_FIRST_DEFECT.set(myProperties, true); + mySuite.setStarted(); + + final SMTestProxy testsSuite = createSuiteProxy("my suite", mySuite); + testsSuite.setStarted(); + + // pending test + final SMTestProxy testPending = createTestProxy("testPending", testsSuite); + testPending.setStarted(); + myUIActionsHandler.onTestNodeAdded(myResultsViewer, testPending); + testPending.setTestIgnored("", ""); + + // Second pending test just to check that first failed will be selected + final SMTestProxy testPending2 = createTestProxy("testPending2", testsSuite); + testPending2.setStarted(); + myUIActionsHandler.onTestNodeAdded(myResultsViewer, testPending2); + testPending2.setTestIgnored("", ""); + + // finish suite + testsSuite.setFinished(); + assertNull(mySelectedTestProxy); + + //testing finished + mySuite.setFinished(); + assertNull(mySelectedTestProxy); + + myUIActionsHandler.onTestingFinished(myResultsViewer); + assertEquals(testPending, mySelectedTestProxy); + } + public void testTrackRunningTest() { TestConsoleProperties.TRACK_RUNNING_TEST.set(myProperties, true); mySuite.setStarted(); diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsFormTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsFormTest.java index 72efb172db95..aa25e75e99c8 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsFormTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsFormTest.java @@ -21,6 +21,7 @@ import com.intellij.execution.testframework.sm.Marker; import com.intellij.execution.testframework.sm.runner.BaseSMTRunnerTestCase; import com.intellij.execution.testframework.sm.runner.GeneralToSMTRunnerEventsConvertor; import com.intellij.execution.testframework.sm.runner.SMTestProxy; +import com.intellij.openapi.progress.util.ColorProgressBar; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Ref; import org.jetbrains.annotations.NotNull; @@ -338,6 +339,26 @@ public class SMTestRunnerResultsFormTest extends BaseSMTRunnerTestCase { myResultsViewer.onCustomProgressTestFailed(); assertEquals(1, myResultsViewer.getTestsFailuresCount()); + + assertEquals(ColorProgressBar.RED, myResultsViewer.getTestsStatusColor()); + } + + public void testCustomProgress_Terminated() { + myResultsViewer.onTestingStarted(myTestsRootNode); + + final SMTestProxy test1 = createTestProxy("some_test1", myTestsRootNode); + myResultsViewer.onTestStarted(test1); + + myResultsViewer.onTestingFinished(myTestsRootNode); + + assertEquals(ColorProgressBar.GREEN, myResultsViewer.getTestsStatusColor()); + } + + public void testCustomProgress_NotRun() { + myResultsViewer.onTestingStarted(myTestsRootNode); + myResultsViewer.onTestingFinished(myTestsRootNode); + + assertEquals(ColorProgressBar.RED, myResultsViewer.getTestsStatusColor()); } public void testCustomProgress_UnSetCount() { @@ -482,5 +503,4 @@ public class SMTestRunnerResultsFormTest extends BaseSMTRunnerTestCase { myResultsViewer.onTestStarted(createTestProxy("some_test1", myTestsRootNode)); assertEquals(4, myResultsViewer.getTestsCurrentCount()); } - } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestStatusLine.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestStatusLine.java index afae1cc0e61a..7e8a7fd6be0f 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestStatusLine.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestStatusLine.java @@ -41,6 +41,10 @@ public class TestStatusLine extends JPanel { myProgressBar.setColor(color); } + public Color getStatusColor() { + return myProgressBar.getColor(); + } + public void setFraction(double v) { myProgressBar.setFraction(v); } From a09ba5c7977d458b12201de022ce346e1fee6049 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Thu, 12 Nov 2009 00:35:09 +0300 Subject: [PATCH 28/36] string were moved to bundle --- .../src/messages/SMTestsRunnerBundle.properties | 7 ++++++- .../sm/runner/ui/SMTRunnerNotificationsHandler.java | 9 +++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/platform/platform-resources-en/src/messages/SMTestsRunnerBundle.properties b/platform/platform-resources-en/src/messages/SMTestsRunnerBundle.properties index 8c45ba04faa4..74f3c5c264cd 100644 --- a/platform/platform-resources-en/src/messages/SMTestsRunnerBundle.properties +++ b/platform/platform-resources-en/src/messages/SMTestsRunnerBundle.properties @@ -41,4 +41,9 @@ sm.test.runner.magnitude.assertion.failed.title=Assertion failed sm.test.runner.magnitude.testerror.title=Error sm.test.runner.states.suite.is.empty=Empty test suite. -sm.test.runner.states.test.is.ignored=Test ignored. \ No newline at end of file +sm.test.runner.states.test.is.ignored=Test ignored. + +sm.test.runner.notifications.tests.passed=Tests passed +sm.test.runner.notifications.tests.failed=Tests failed +sm.test.runner.notifications.tests.skipped=Tests skipped +sm.test.runner.notifications.tests.not.run=Tests were not started diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerNotificationsHandler.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerNotificationsHandler.java index 442b67fdbbc0..6d76efed1d8c 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerNotificationsHandler.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerNotificationsHandler.java @@ -49,21 +49,22 @@ public class SMTRunnerNotificationsHandler extends SMTRunnerEventsAdapter { final MessageType type; final TestStateInfo.Magnitude magnitude = testsRoot.getMagnitudeInfo(); + //noinspection EnumSwitchStatementWhichMissesCases switch (magnitude) { case SKIPPED_INDEX: case IGNORED_INDEX: - msg = "Tests skipped"; + msg = SMTestsRunnerBundle.message("sm.test.runner.notifications.tests.skipped"); type = MessageType.WARNING; break; case NOT_RUN_INDEX: - msg = "Tests were not started"; + msg = SMTestsRunnerBundle.message("sm.test.runner.notifications.tests.not.run"); type = MessageType.WARNING; break; case FAILED_INDEX: case ERROR_INDEX: - msg = "Tests failed"; + msg = SMTestsRunnerBundle.message("sm.test.runner.notifications.tests.failed"); type = MessageType.ERROR; break; case COMPLETE_INDEX: @@ -74,7 +75,7 @@ public class SMTRunnerNotificationsHandler extends SMTRunnerEventsAdapter { } // else same as: PASSED_INDEX case PASSED_INDEX: - msg = "Tests passed"; + msg = SMTestsRunnerBundle.message("sm.test.runner.notifications.tests.passed"); type = MessageType.INFO; break; From b36ae98a8c1475af0d33d4f162f8388071db62e5 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Thu, 12 Nov 2009 18:10:06 +0300 Subject: [PATCH 29/36] title fixed --- .../ide/actions/QuickSwitchSchemeAction.java | 15 +++++++++++---- .../src/messages/VcsBundle.properties | 1 + .../vcs/actions/VcsQuickListPopupAction.java | 4 ++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/actions/QuickSwitchSchemeAction.java b/platform/platform-api/src/com/intellij/ide/actions/QuickSwitchSchemeAction.java index 98cfecd18bf1..3ca1d4ff0df1 100644 --- a/platform/platform-api/src/com/intellij/ide/actions/QuickSwitchSchemeAction.java +++ b/platform/platform-api/src/com/intellij/ide/actions/QuickSwitchSchemeAction.java @@ -42,18 +42,25 @@ public abstract class QuickSwitchSchemeAction extends AnAction implements DumbAw protected abstract void fillActions(Project project, DefaultActionGroup group, DataContext dataContext); - private static void showPopup(AnActionEvent e, DefaultActionGroup group) { + private void showPopup(AnActionEvent e, DefaultActionGroup group) { if (group.getChildrenCount() == 0) return; final ListPopup popup = JBPopupFactory.getInstance() - .createActionGroupPopup(e.getPresentation().getText(), + .createActionGroupPopup(QuickSwitchSchemeAction.this.getPopupTitle(e), group, - e.getDataContext(), - JBPopupFactory.ActionSelectionAid.NUMBERING, + e.getDataContext(), getAidMethod(), true); popup.showCenteredInCurrentWindow(e.getData(PlatformDataKeys.PROJECT)); } + protected JBPopupFactory.ActionSelectionAid getAidMethod() { + return JBPopupFactory.ActionSelectionAid.NUMBERING; + } + + protected String getPopupTitle(AnActionEvent e) { + return e.getPresentation().getText(); + } + public void update(AnActionEvent e) { super.update(e); e.getPresentation().setEnabled(e.getData(PlatformDataKeys.PROJECT) != null && isEnabled()); diff --git a/platform/platform-resources-en/src/messages/VcsBundle.properties b/platform/platform-resources-en/src/messages/VcsBundle.properties index e4e40386ee0f..f097c83195cd 100644 --- a/platform/platform-resources-en/src/messages/VcsBundle.properties +++ b/platform/platform-resources-en/src/messages/VcsBundle.properties @@ -533,4 +533,5 @@ all.vcs.init.message.text=Initializing VCS... switch.to.changelist=Switch &to changelist (''{0}'') move.to.changelist=&Move changes to active changelist (''{0}'') vcs.config.track.changed.on.server=Check "changed on server" conflicts in background +vcs.quicklist.pupup.title=VCS Quick List vcs.quicklist.pupup.section.local.history=Local History diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/VcsQuickListPopupAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/VcsQuickListPopupAction.java index 3119f90ad3be..781c28f93db7 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/VcsQuickListPopupAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/VcsQuickListPopupAction.java @@ -189,6 +189,10 @@ public class VcsQuickListPopupAction extends QuickSwitchSchemeAction implements toGroup.add(separator); } + protected String getPopupTitle(AnActionEvent e) { + return VcsBundle.message("vcs.quicklist.pupup.title"); + } + public enum SupportedVCS { VCS, NOT_IN_VCS From 4d94b2be6038cac5d57c8034e6c26e2a76d6ee8d Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Thu, 12 Nov 2009 19:48:42 +0300 Subject: [PATCH 30/36] type inference for "create" and "create!" active record methods --- .../testframework/sm/runner/ui/SMTestRunnerResultsForm.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java index 3ebd4baa0c9f..aa88e936684d 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java @@ -296,7 +296,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra } public void setFilter(final Filter filter) { - // is usded by Test Runner actions, e.g. hide passed, etc + // is used by Test Runner actions, e.g. hide passed, etc final SMTRunnerTreeStructure treeStructure = myTreeBuilder.getRTestUnitTreeStructure(); treeStructure.setFilter(filter); myTreeBuilder.updateFromRoot(); @@ -320,7 +320,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra } /** - * Manual test proxy selectio in tests tree. E.g. do select root node on + * Manual test proxy selection in tests tree. E.g. do select root node on * testing started or do select current node if TRACK_RUNNING_TEST is enabled * * @@ -341,7 +341,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra addTestsTreeSelectionListener(new TreeSelectionListener() { public void valueChanged(final TreeSelectionEvent e) { //We should fire event only if it was generated by this component, - //e.g. it is focused. Otherwise it is side effect of selecing proxy in + //e.g. it is focused. Otherwise it is side effect of selecting proxy in //try by other component //if (myTreeView.isFocusOwner()) { @Nullable final PrintableTestProxy selectedProxy = (PrintableTestProxy)getTreeView().getSelectedTest(); From 17310a327497a0e22785f41788ad03d40d40a44a Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Thu, 12 Nov 2009 20:11:17 +0300 Subject: [PATCH 31/36] pending test shouldn't be considered as failure/error in "select first failed test" --- .../runner/ui/SMTRunnerUIActionsHandler.java | 2 +- .../ui/SMTRunnerUIActionsHandlerTest.java | 21 +++++++------------ 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandler.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandler.java index 460216522a7a..dc1c8428ff64 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandler.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandler.java @@ -68,7 +68,7 @@ public class SMTRunnerUIActionsHandler implements TestResultsViewer.EventsListen if (firstFailure != null) { firstDefect = firstFailure; } else { - firstDefect = Filter.DEFECTIVE_LEAF.detectIn(allTests); + firstDefect = null; } } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandlerTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandlerTest.java index 76d35f45431e..7d7638e25ef8 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandlerTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandlerTest.java @@ -171,8 +171,8 @@ public class SMTRunnerUIActionsHandlerTest extends BaseSMTRunnerTestCase { } - public void testSelectFirstDeffect_Priority_Error() { - // Priority: error -> failure -> pending + public void testSelectFirstDefect_Priority_Error() { + // Priority: error -> failure TestConsoleProperties.SELECT_FIRST_DEFECT.set(myProperties, true); mySuite.setStarted(); @@ -215,8 +215,8 @@ public class SMTRunnerUIActionsHandlerTest extends BaseSMTRunnerTestCase { assertEquals(testError, mySelectedTestProxy); } - public void testSelectFirstDeffect_Priority_Failure() { - // Priority: error -> failure -> pending + public void testSelectFirstDefect_Priority_Failure() { + // Priority: error -> failure TestConsoleProperties.SELECT_FIRST_DEFECT.set(myProperties, true); mySuite.setStarted(); @@ -253,8 +253,8 @@ public class SMTRunnerUIActionsHandlerTest extends BaseSMTRunnerTestCase { assertEquals(testFailed, mySelectedTestProxy); } - public void testSelectFirstDeffect_Priority_Pending() { - // Priority: error -> failure -> pending + public void testSelectFirstDefect_Priority_Pending() { + // Priority: error -> failure TestConsoleProperties.SELECT_FIRST_DEFECT.set(myProperties, true); mySuite.setStarted(); @@ -267,12 +267,6 @@ public class SMTRunnerUIActionsHandlerTest extends BaseSMTRunnerTestCase { myUIActionsHandler.onTestNodeAdded(myResultsViewer, testPending); testPending.setTestIgnored("", ""); - // Second pending test just to check that first failed will be selected - final SMTestProxy testPending2 = createTestProxy("testPending2", testsSuite); - testPending2.setStarted(); - myUIActionsHandler.onTestNodeAdded(myResultsViewer, testPending2); - testPending2.setTestIgnored("", ""); - // finish suite testsSuite.setFinished(); assertNull(mySelectedTestProxy); @@ -282,7 +276,8 @@ public class SMTRunnerUIActionsHandlerTest extends BaseSMTRunnerTestCase { assertNull(mySelectedTestProxy); myUIActionsHandler.onTestingFinished(myResultsViewer); - assertEquals(testPending, mySelectedTestProxy); + // pending tests shouldn't be considered as errors/failures + assertNull(mySelectedTestProxy); } public void testTrackRunningTest() { From 8cea92b350b14a07745cfc61f5ec0260f5871155 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Thu, 12 Nov 2009 21:22:15 +0300 Subject: [PATCH 32/36] =?UTF-8?q?fix=20improved=20:=20[IDEADEV-41302]=20Ch?= =?UTF-8?q?ange=20File=E2=80=8B-=E2=80=8B>=E2=80=8BReopen=20to=20'?= =?UTF-8?q?=E2=80=8BOpen=20Recent'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../intellij/ide/actions/RecentProjectsGroup.java | 14 ++++++++++++++ .../actionSystem/impl/ActionManagerImpl.java | 15 ++++++++++++--- .../src/messages/ActionsBundle.properties | 3 ++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/RecentProjectsGroup.java b/platform/platform-impl/src/com/intellij/ide/actions/RecentProjectsGroup.java index a0d76ea2100f..1ed87056ec14 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/RecentProjectsGroup.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/RecentProjectsGroup.java @@ -16,14 +16,28 @@ package com.intellij.ide.actions; import com.intellij.ide.RecentProjectsManagerBase; +import com.intellij.idea.ActionsBundle; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.util.SystemInfo; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class RecentProjectsGroup extends ActionGroup { + public RecentProjectsGroup() { + super(); + + final Presentation templatePresentation = getTemplatePresentation(); + // Let's make tile more macish + if (SystemInfo.isMac) { + templatePresentation.setText(ActionsBundle.message("group.reopen.mac.text")); + } else { + templatePresentation.setText(ActionsBundle.message("group.reopen.win.text")); + } + } + @NotNull public AnAction[] getChildren(@Nullable AnActionEvent e) { return RecentProjectsManagerBase.getInstance().getRecentProjectsActions(true); diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java index 3d50db775fdf..013fb4ef825c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java @@ -477,13 +477,22 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat if (id != null) { registerAction(id, group); } - // text Presentation presentation = group.getTemplatePresentation(); + + // text String text = loadTextForElement(element, bundle, id, GROUP_ELEMENT_NAME); - presentation.setText(text); + // don't override value which was set in API with empty value from xml descriptor + if (!StringUtil.isEmpty(text) || presentation.getText() == null) { + presentation.setText(text); + } + // description String description = loadDescriptionForElement(element, bundle, id, GROUP_ELEMENT_NAME); - presentation.setDescription(description); + // don't override value which was set in API with empty value from xml descriptor + if (!StringUtil.isEmpty(description) || presentation.getDescription() == null) { + presentation.setDescription(description); + } + // icon setIcon(element.getAttributeValue(ICON_ATTR_NAME), className, loader, presentation, pluginId); // popup diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index f5eb71f1702d..88eea572851e 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -200,7 +200,8 @@ action.OpenProject.text=_Open Project... action.OpenProject.description=Open an existing project action.OpenFile.text=Open Fi_le... action.OpenFile.description=Open file in editor -group.$LRU.text=Open _Recent +group.reopen.win.text=_Reopen +group.reopen.mac.text=Open _Recent group.$LRU.description=List of recently opened projects action.CloseProject.text=Close Pro_ject action.CloseProject.description=Close current project From 81c874dedaaa75a0ed9ca45d529b8cb877178213 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Fri, 13 Nov 2009 16:43:06 +0300 Subject: [PATCH 33/36] revert --- .../vfs/newvfs/persistent/FSRecords.java | 96 +++++-------------- .../intellij/util/io/storage/StorageTest.java | 31 +++--- 2 files changed, 38 insertions(+), 89 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java index 91070d6f913e..cb4b2d77ee45 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java @@ -30,8 +30,6 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.containers.IntArrayList; import com.intellij.util.io.PersistentStringEnumerator; import com.intellij.util.io.ResizeableMappedFile; -import com.intellij.util.io.storage.AbstractStorage; -import com.intellij.util.io.storage.CompactStorage; import com.intellij.util.io.storage.HeavyProcessLatch; import com.intellij.util.io.storage.Storage; import gnu.trove.TIntArrayList; @@ -49,7 +47,7 @@ import java.util.concurrent.TimeUnit; public class FSRecords implements Disposable, Forceable { private static final Logger LOG = Logger.getInstance("#com.intellij.vfs.persistent.FSRecords"); - private static final int VERSION = 10; + private static final int VERSION = 9; private static final int PARENT_OFFSET = 0; private static final int PARENT_SIZE = 4; @@ -84,6 +82,7 @@ public class FSRecords implements Disposable, Forceable { private static final String CHILDREN_ATT = "FsRecords.DIRECTORY_CHILDREN"; private static final Object lock = new Object(); + private DbConnection myConnection; private volatile static int ourLocalModificationCount = 0; @@ -102,7 +101,7 @@ public class FSRecords implements Disposable, Forceable { private static int CONTENT_ID; private static PersistentStringEnumerator myNames; - private static AbstractStorage myAttributes; + private static Storage myAttributes; private static Storage myContents; private static ResizeableMappedFile myRecords; private static final TIntArrayList myFreeRecords = new TIntArrayList(); @@ -169,7 +168,7 @@ public class FSRecords implements Disposable, Forceable { if (!namesFile.exists()) { invalidateIndex(); } - boolean compact = true; + try { if (getCorruptionMarkerFile().exists()) { invalidateIndex(); @@ -177,7 +176,7 @@ public class FSRecords implements Disposable, Forceable { } myNames = new PersistentStringEnumerator(namesFile); - myAttributes = compact ? new CompactStorage(attributesFile.getCanonicalPath()) : Storage.create(attributesFile.getCanonicalPath()); + myAttributes = Storage.create(attributesFile.getCanonicalPath()); myContents = Storage.create(contentsFile.getCanonicalPath()); myRecords = new ResizeableMappedFile(recordsFile, 20 * 1024); @@ -204,7 +203,7 @@ public class FSRecords implements Disposable, Forceable { boolean deleted = true; deleted &= FileUtil.delete(getCorruptionMarkerFile()); deleted &= deleteWithSubordinates(namesFile); - deleted &= compact ? CompactStorage.deleteFiles(attributesFile.getCanonicalPath()) : Storage.deleteFiles(attributesFile.getCanonicalPath()); + deleted &= Storage.deleteFiles(attributesFile.getCanonicalPath()); deleted &= Storage.deleteFiles(contentsFile.getCanonicalPath()); deleted &= deleteWithSubordinates(recordsFile); @@ -350,7 +349,7 @@ public class FSRecords implements Disposable, Forceable { return myNames; } - public static AbstractStorage getAttributes(int attId) { + public static Storage getAttributes(int attId) { return attId == CONTENT_ID ? myContents : myAttributes; } @@ -435,14 +434,14 @@ public class FSRecords implements Disposable, Forceable { } public void connect() { - DbConnection.connect(); + myConnection = DbConnection.connect(); } private static ResizeableMappedFile getRecords() { return DbConnection.getRecords(); } - private static AbstractStorage getAttributes(int attId) { + private static Storage getAttributes(int attId) { return DbConnection.getAttributes(attId); } @@ -515,15 +514,14 @@ public class FSRecords implements Disposable, Forceable { private void deleteAttribute(int id, int isContent) throws IOException { int att_page = getAttributeRecordId(id, isContent); if (att_page != 0) { - AbstractStorage storage = getAttributes(isContent); - final DataInputStream attStream = storage.readStream(att_page); + final DataInputStream attStream = getAttributes(isContent).readStream(att_page); while (attStream.available() > 0) { attStream.readInt(); // Attribute ID; int attAddress = attStream.readInt(); - storage.deleteRecord(attAddress); + getAttributes(isContent).deleteRecord(attAddress); } attStream.close(); - storage.deleteRecord(att_page); + getAttributes(isContent).deleteRecord(att_page); } } @@ -679,7 +677,7 @@ public class FSRecords implements Disposable, Forceable { try { synchronized (lock) { int encodedAttId = DbConnection.getAttributeId(CHILDREN_ATT); - final int att = findAttributePage(id, encodedAttId, false, 0); + final int att = findAttributePage(id, encodedAttId, false); return att != 0; } } @@ -862,9 +860,7 @@ public class FSRecords implements Disposable, Forceable { } private static int getAttributeRecordId(final int id, int attributeId) throws IOException { - final int record = getRecords().getInt(getAttrOffset(id, attributeId)); - assert record >= 0; - return record; + return getRecords().getInt(getAttrOffset(id, attributeId)); } private static int getAttrOffset(int id, int attributeId) { @@ -879,7 +875,7 @@ public class FSRecords implements Disposable, Forceable { int encodedAttId; synchronized (lock) { encodedAttId = DbConnection.getAttributeId(attId); - page = findAttributePage(id, encodedAttId, false, 0); + page = findAttributePage(id, encodedAttId, false); if (page == 0) return null; } @@ -891,7 +887,7 @@ public class FSRecords implements Disposable, Forceable { } } - private int findAttributePage(int fileId, int attributeId, boolean createIfNotFound, int capacity) throws IOException { + private int findAttributePage(int fileId, int attributeId, boolean createIfNotFound) throws IOException { if (fileId <= 0) { throw DbConnection.handleError(new AssertionError("assert fileId > 0 failed")); } @@ -899,58 +895,35 @@ public class FSRecords implements Disposable, Forceable { if ((getFlags(fileId) & FREE_RECORD_FLAG) != 0) { // TODO: This assertion is a bit timey, will remove when bug is caught. throw DbConnection.handleError(new AssertionError("Trying to find an attribute of deleted page")); } - int attrsRecord = getAttributeRecordId(fileId, attributeId); - AbstractStorage storage = getAttributes(attributeId); if (attrsRecord == 0) { if (!createIfNotFound) return 0; - attrsRecord = storage.createNewRecord(16 * 8); + attrsRecord = getAttributes(attributeId).createNewRecord(); getRecords().putInt(getAttrOffset(fileId, attributeId), attrsRecord); } else { - final DataInputStream attrRefs = storage.readStream(attrsRecord); + final DataInputStream attrRefs = getAttributes(attributeId).readStream(attrsRecord); try { - int offset = 4; while (attrRefs.available() > 0) { final int attIdOnPage = attrRefs.readInt(); - if (attrRefs.available() < 4) { - LOG.error("bad"); - } final int attAddress = attrRefs.readInt(); - if (attIdOnPage == attributeId) { - if (capacity > 0) { - int newAddress = storage.ensureCapacity(attAddress, capacity); - if (newAddress == attAddress) { - return attAddress; - } - ((CompactStorage)storage).replaceIntInData(attrsRecord + offset, newAddress, attAddress); - return newAddress; - } else { - return attAddress; - } - } - offset += 8; + if (attIdOnPage == attributeId) return attAddress; } } finally { attrRefs.close(); } - - } if (createIfNotFound) { - Storage.AppenderStream appender = storage.appendStream(attrsRecord); + Storage.AppenderStream appender = getAttributes(attributeId).appendStream(attrsRecord); appender.writeInt(attributeId); - int attAddress = storage.createNewRecord(capacity); + int attAddress = getAttributes(attributeId).createNewRecord(); appender.writeInt(attAddress); appender.close(); - if (appender.getRecordId() != attrsRecord) { - getRecords().putInt(getAttrOffset(fileId, attributeId), appender.getRecordId()); - } return attAddress; } @@ -978,35 +951,12 @@ public class FSRecords implements Disposable, Forceable { DbConnection.markDirty(); incModCount(myFileId); encodedAttId = DbConnection.getAttributeId(myAttributeId); - page = findAttributePage(myFileId, encodedAttId, true, ((ByteArrayOutputStream)out).size()); + page = findAttributePage(myFileId, encodedAttId, true); } - AbstractStorage storage = getAttributes(encodedAttId); - AbstractStorage.StorageDataOutput sinkStream = storage.writeStream(page); + final DataOutputStream sinkStream = getAttributes(encodedAttId).writeStream(page); sinkStream.write(((ByteArrayOutputStream)out).toByteArray()); sinkStream.close(); - final int recordId = sinkStream.getRecordId(); - if (recordId != page) { - int attrsRecord = getAttributeRecordId(myFileId, encodedAttId); - DataInputStream stream = storage.readStream(attrsRecord); - try { - while (stream.available() > 0) { - if (encodedAttId == stream.readInt()) { - ((CompactStorage)storage).replaceIntInData(attrsRecord + 4, recordId, page); - break; - } - if (stream.available() < 4) { - LOG.error("wtf"); - } - stream.readInt(); - attrsRecord += 8; - } - } - finally { - stream.close(); - } - } - } } catch (Throwable e) { diff --git a/platform/util/testSrc/com/intellij/util/io/storage/StorageTest.java b/platform/util/testSrc/com/intellij/util/io/storage/StorageTest.java index f5130bc25b04..9795fca432f6 100644 --- a/platform/util/testSrc/com/intellij/util/io/storage/StorageTest.java +++ b/platform/util/testSrc/com/intellij/util/io/storage/StorageTest.java @@ -29,14 +29,14 @@ import java.io.File; import java.io.IOException; public class StorageTest extends TestCase { - protected AbstractStorage myStorage; + private Storage myStorage; protected void setUp() throws Exception { super.setUp(); myStorage = Storage.create(getFileName()); } - protected String getFileName() { + private String getFileName() { return FileUtil.getTempDirectory() + File.separatorChar + getName(); } @@ -47,7 +47,7 @@ public class StorageTest extends TestCase { } public void testSmoke() throws Exception { - int record = myStorage.createNewRecord(0); + final int record = myStorage.createNewRecord(); myStorage.writeBytes(record, "Hello".getBytes()); assertEquals("Hello", new String(myStorage.readBytes(record))); } @@ -64,15 +64,13 @@ public class StorageTest extends TestCase { int[] records = new int[count]; for (int i = 0; i < count; i++) { - byte[] bytes = hello.getBytes(); - int record = myStorage.createNewRecord(bytes.length); - myStorage.writeBytes(record, bytes); + final int record = myStorage.createNewRecord(); + myStorage.writeBytes(record, hello.getBytes()); records[i] = record; } for (int record : records) { - byte[] bytes = myStorage.readBytes(record); - assertEquals(hello, new String(bytes)); + assertEquals(hello, new String(myStorage.readBytes(record))); } long timedelta = System.currentTimeMillis() - start; @@ -80,22 +78,23 @@ public class StorageTest extends TestCase { } public void testAppender() throws Exception { - final int count = 1000; - int r = myStorage.createNewRecord(count * 4); + final int r = myStorage.createNewRecord(); - AbstractStorage.AppenderStream out = myStorage.appendStream(r); - for (int i = 0; i < count; i++) { + DataOutputStream out = new DataOutputStream(myStorage.appendStream(r)); + for (int i = 0; i < 10000; i++) { out.writeInt(i); if (i % 100 == 0) { + myStorage.readStream(r); // Drop the appenders cache out.close(); - out = myStorage.appendStream(r); + out = new DataOutputStream(myStorage.appendStream(r)); } } out.close(); - DataInputStream in = myStorage.readStream(r); - for (int i = 0; i < count; i++) { + + DataInputStream in = new DataInputStream(myStorage.readStream(r)); + for (int i = 0; i < 10000; i++) { assertEquals(i, in.readInt()); } @@ -103,7 +102,7 @@ public class StorageTest extends TestCase { } public void testAppender2() throws Exception { - int r = myStorage.createNewRecord(0); + int r = myStorage.createNewRecord(); appendNBytes(r, 64); appendNBytes(r, 256); appendNBytes(r, 512); From 4514422ec7265f3934d6a7c7aecf23344839cda3 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Fri, 13 Nov 2009 17:50:34 +0300 Subject: [PATCH 34/36] fix ComponentVersionProcessingTest --- .../openapi/application/impl/ApplicationImpl.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 3d8504e5d5f7..0e71eb79b4a3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -954,9 +954,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application } } - - public void saveSettings() { - if (myDoNotSave || isUnitTestMode() || isHeadlessEnvironment()) return; + public void _saveSettings() { // for testing purposes if (mySaveSettingsIsInProgress.compareAndSet(false, true)) { try { doSave(); @@ -994,6 +992,11 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application } } + public void saveSettings() { + if (myDoNotSave || isUnitTestMode() || isHeadlessEnvironment()) return; + _saveSettings(); + } + public void saveAll() { if (myDoNotSave || isUnitTestMode() || isHeadlessEnvironment()) return; From c93403e861dcc6fa0448e780549570e4273c9469 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Fri, 13 Nov 2009 18:53:41 +0300 Subject: [PATCH 35/36] AE due to null pomTargets: logging & workaround --- .../com/intellij/codeInsight/TargetElementUtilBase.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtilBase.java b/platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtilBase.java index 515245fce8ae..399f8b35092c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtilBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtilBase.java @@ -200,7 +200,7 @@ public class TargetElementUtilBase { final List targets = CollectionFactory.arrayList(); final Consumer consumer = new Consumer() { - public void consume(PomTarget target) { + public void consume(@NotNull PomTarget target) { if (target instanceof PsiDeclaredTarget) { final PsiDeclaredTarget declaredTarget = (PsiDeclaredTarget)target; final PsiElement navigationElement = declaredTarget.getNavigationElement(); @@ -221,7 +221,10 @@ public class TargetElementUtilBase { for (PomDeclarationSearcher searcher : PomDeclarationSearcher.EP_NAME.getExtensions()) { searcher.findDeclarationsAt(parent, offset, consumer); if (!targets.isEmpty()) { - return PomService.convertToPsi(element.getProject(), targets.get(0)); + final PomTarget target = targets.get(0); + if (target != null) { + return PomService.convertToPsi(element.getProject(), target); + } } } offset += parent.getStartOffsetInParent(); From 5db6c1f88b09275387abf38be74eef6688c055a2 Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Fri, 13 Nov 2009 18:48:36 +0300 Subject: [PATCH 36/36] Platform specific tips --- resources-en/src/tips/ColorFiles.html | 13 +++++++++++++ resources-en/src/tips/CopyWithNoSelection.html | 10 ++++++++++ .../src/tips/SelectRunDebugConfiguration.html | 11 +++++++++++ resources-en/src/tips/Spellchecker.html | 12 ++++++++++++ .../src/tips/SpellcheckerDictionaries.html | 10 ++++++++++ resources-en/src/tips/VcsQuickList.html | 13 +++++++++++++ resources-en/src/tips/images/coloredFiles.gif | Bin 0 -> 6229 bytes resources-en/src/tips/images/vcsQuickList.gif | Bin 0 -> 5503 bytes resources-en/src/tips/moveFileToChangelist.html | 12 ++++++++++++ resources-en/src/tips/tips.xml | 7 +++++++ 10 files changed, 88 insertions(+) create mode 100644 resources-en/src/tips/ColorFiles.html create mode 100644 resources-en/src/tips/CopyWithNoSelection.html create mode 100644 resources-en/src/tips/SelectRunDebugConfiguration.html create mode 100644 resources-en/src/tips/Spellchecker.html create mode 100644 resources-en/src/tips/SpellcheckerDictionaries.html create mode 100644 resources-en/src/tips/VcsQuickList.html create mode 100644 resources-en/src/tips/images/coloredFiles.gif create mode 100644 resources-en/src/tips/images/vcsQuickList.gif create mode 100644 resources-en/src/tips/moveFileToChangelist.html diff --git a/resources-en/src/tips/ColorFiles.html b/resources-en/src/tips/ColorFiles.html new file mode 100644 index 000000000000..24366bcb3bc3 --- /dev/null +++ b/resources-en/src/tips/ColorFiles.html @@ -0,0 +1,13 @@ + +
+ +You don't need to guess which index.html file you are looking at... + +

+Make editor tabs and lines in navigation lists stand out using the File Colors page of the project settings. +

+ +

+ +
+ diff --git a/resources-en/src/tips/CopyWithNoSelection.html b/resources-en/src/tips/CopyWithNoSelection.html new file mode 100644 index 000000000000..0484a04b0811 --- /dev/null +++ b/resources-en/src/tips/CopyWithNoSelection.html @@ -0,0 +1,10 @@ + + +
+ +

+If you press &shortcut:$Copy; then the whole line at caret will be copied to Clipboard. +

+ +
+ diff --git a/resources-en/src/tips/SelectRunDebugConfiguration.html b/resources-en/src/tips/SelectRunDebugConfiguration.html new file mode 100644 index 000000000000..ef5519bd63ae --- /dev/null +++ b/resources-en/src/tips/SelectRunDebugConfiguration.html @@ -0,0 +1,11 @@ + + + + + + +
By pressing &shortcut:RunConfiguration; you can access the Run/Debug dropdown on the main toolbar, + without the need to use your mouse. +
+ + \ No newline at end of file diff --git a/resources-en/src/tips/Spellchecker.html b/resources-en/src/tips/Spellchecker.html new file mode 100644 index 000000000000..caa027a7e854 --- /dev/null +++ b/resources-en/src/tips/Spellchecker.html @@ -0,0 +1,12 @@ + +
+ +Keep your source code typo-free with the help of the built-in Spellchecker. + +

All texts, including comments, textual strings and literals, are inspected against the pre-defined dictionaries. +All typos are highlighted, which leaves you with the task of choosing the correct word, accepting the current spelling, or disabling inspection. +Use &shortcut:ShowIntentionActions; to see the list of available actions. +

+ +
+ diff --git a/resources-en/src/tips/SpellcheckerDictionaries.html b/resources-en/src/tips/SpellcheckerDictionaries.html new file mode 100644 index 000000000000..4de7ff27e52a --- /dev/null +++ b/resources-en/src/tips/SpellcheckerDictionaries.html @@ -0,0 +1,10 @@ + +
+ +

If you lack words in the pre-defined dictionaries, you can create your own ones. A custom dictionary is a mere +textual file with *.dic extension, with each word starting from a new line.

+

All you have to do is to point to the directories where your dictionaries are stored, in the +Spelling of the Settings dialog. +

+
+ diff --git a/resources-en/src/tips/VcsQuickList.html b/resources-en/src/tips/VcsQuickList.html new file mode 100644 index 000000000000..2cc68eaea978 --- /dev/null +++ b/resources-en/src/tips/VcsQuickList.html @@ -0,0 +1,13 @@ + +
+ +All your most indispensable VCS commands are just one-click away... +

+Choose Version Control | VCS Quick List +on the main menu, and get a popup with the VCS commands that are relevant to the current context: +

+ +

+ +
+ diff --git a/resources-en/src/tips/images/coloredFiles.gif b/resources-en/src/tips/images/coloredFiles.gif new file mode 100644 index 0000000000000000000000000000000000000000..f24c6c1b30a5e7ce65a76dc4a573d598fbfa4323 GIT binary patch literal 6229 zcmW-fbyO3M*Tx6J=z$41!2BWzDj`aPO^eBBQKUhT8a+Bj*G6}b5QL2$y^ThC0n*(u zYP|m5=iK{z&b{}X``7bE^|iE&Nd#Rwz!d|Jw!sBkcbh_WywWn_w{P zKasHcgsp!UU@Sl29Kd?livI`XhN}_Zsmx6uz{5|5q6X;?OjSf|-wU0*l>GShiC(zG zcNK9bJt-1Eg8V_^%v|oHh0GTXX|pUDM}29JA*D!5#eM_1<4-c@j?bSxe{B+`Y*+T$ z*;vWV>=o4dS-`0BnZ3Gcu$o!4mJLG9KL4#tu{wP6ZI6x0gqi04_jhOR+UCI@>=Lvs zGqr;qKcwhAMLa40f@ra*!{^n?5KqnwQry$#R& z&CJZc+IoF;jx%veF>x*Y>R4jxmT2OZX6l)5>Q?;CujFfBl?h_<8_x6FHq^!&VdH$n5Iy(t)twvyq*dVJk`D$61I-o#>33_(B)pbnD6466{(Y3-jrASrvNvf*LRq+hRULr=N_TU zA4?Tk=oI~)Dqj9w1prh?0%{&hRaO2*R}WU={-C?(tGAn~4zSo;x0^&nnm-y~+}!JX zN!Zcp#^KGz(ZlB5uCBe_&Re%y8q%>1@)nckv8>e);>|@1+P3 zslM!tp02{)u35st;3xnv!b3O2!!>C7Z3GGUQ*ALiSTXviZ)9Y2cxrFt@5@PJ_!Q@w`8PETSM=I7@&j}~`M zmycIh_D|=Jmo@=_Wyy=n&j1_vuFcNAwVjiVy_2nj)6MhELsq(j{{TDHRfm0jJENof z>l=sL-TOyp$ERoKTny(g10E&j}x?;GGMvf6^V?x>}z{L1ct^GI5eaKCc8qHewj<5R87#m9mC ziwy9UdEE%HZ-i9Us{Gy*X~z{3zN(-vg&V>3U`&b`-X(yMSlvkbJWt*s*6WT zAXQdmLUoCb%nNwfE9gh$M3u##V#Ds5QX<-ZmXM~7E+f}NcUQ>u+^Df;SXJV@I;P@p zTgYV*qaNw9DQxr|C4Lg7a=sfWY2A4WsWk78e+n1Stoyx8NK+~S@*V$P9jo}(rqx(? zFgjZ4xJuEiOG2x*dLO;NYtsw75nxF)vb*|pb8#RCd?2_PD`vbq!%W29e7M^2+z~JlwSaM;7Lr@bY&;;l8$mJU7Fw z@zgKj_W1FezOoV)2=)h=gE*Mve2)6!_< z)%!I$?>*M5bG=K1(a$M?^w-B4{N7x{EZmm6rCbw1|y`jFA)g}wJ zjTnlZd{8&?^W;(6xU9Tg?c}A?88qcJ>PMvoh4F=WUM5|eN!^fjN+XW7M?A8*c+Ikk z9*q*LPPiSu(8{sM=Mc&D*5+XcC02i9;BiLxqkcEWcRg$&2{t=cLY$tc>^HO4HY4I- zk=<@!$tz*K_@Mf#zRTA7j|a>$Y!3>hFGoBX;QeNU7}AK7-~7|?yk4A!&6HjF)*Mko zKu-xXZB&vZ1=(wUHvzpIu&FhyPYWGhDDD*$nDx!Hda2jxfPS?P?6EM#+Z`_#7L*;Y zpwJt~s}(7f4F3SHqB$aTs!pdm&=mU7&yC1-r)iFl6tGTA7psi~g)c`xW) zM&b`F%bV1OcDVWJc8Dq?jcWhSoZn^AVM@VqDsGc@lGDgN4L-2!L;`+x442;+HZgD2)_1s z2D)N$vjCtRsvVvUiV^AnOKc0jMP*+@Qy<^|8Kb1*G{fDc^7;(=D_ra1*AJB;olok- z#mqftLt8PgWhS>HbwYFaM?$VVsk|5kW1oA!C-g>Yr9{BzO787#72MOEi!rLIbGPp; zcfPKRiF(_UeODNd7uTzdKnCOr$*HQnrD?;XJ`x1g@oN8hUy3LSHx)4#?$AjTPxQ*o zdl+G%E-~{nzMg&I%3IwIIBDp1#Ak^Cs`6E@>3Vj^X=U>Mkp^$A1-@Q|@=4+)by_dI}T|@%`S%yBPqELS-hk z0l({enarAn&u4i%E=%uaaYYoqyr(u8rni^P(_8rZDPb_ueJ|%GN0G`KwV`0(PMVNr zk(v%+D6wuYPwbW2Umy&}P&gnZ|bpeGeA5J~&5%pO-!ruWn*2zrS{0fwn2 z%LGv8?d9uc7~q{C`{3^6gWrXk>!yCrQyg@E?(wT9uk17v)ITf;VrzZ$9s=yHlNV@j>Ux|v9Luc@H|$*N>hp?SeOQfh z6S)h<_m!-gB~Oa?|<*Pz(`t77gK zQVkeyNVhP1|M0l6W`t@QE99nF1_jrdT)3fA3bw2G+``Z}O3(dkAM#p;a*-2?dBL4w z!31+&F`<{Ec3z}agj{9+%Rh^3kq0?A|Iwe`Hbd7A6Xu` zHNMuebN{7I7W#46P4@a3b5H(jukkw~wmO?MME2Z0S-o5pWgGr`Kq0AwD zMDDNPE>Fv|pt1})j=9^Lkp3&3yAIYGCK8wHy7jytN5`#LZ0H^Lvo!5waM&!#U6viZ z)oBBeQaAopGYhU33zmyDVbSpP=a)?1^9PrbUS5!G3rTm1+HIKLa6uB91gc8YG`=z2 znIL4j?3MXyF24|QAJb7R|E*9u{|r9SwZ&f@sva?JUGeRDm3EM*vUr4p!JScLx>Wux z8*2;hlrhE6H31&IYj6K}jL)5k*BnNyyR1$&^aUN3O7j1(649GDUns5Vja_IH%w!)B z0?OIEV|pp=&;LsZSogQo&SRE$n2xEofF{>ua|`S_L9b+AsHF8>b5nPWw&9v_%WLyS zcgl2%qFWAQ_^L!#-e0G{*PSCV%nPKspins) zxb9>uQoH=&u+FJO({x=TrC+k((6ygrU8CcLdmmL-ais8RRDx6;5*S43XgRdMGP?=p zET7&roJgqRZhIpo|L$tWFi@Jd9UbL)VJjVWJHCbOGp^xk_7{dbYniP6oC?~#AV?=u z;-0$H**h>`7@q;zv;Hm@lEri~d7iMZifi0(E%z96BpzTno3`pPY9rnC*1PbE63a-r_eR|2$WDFp>Eatj z>KNzeyo$dxYV)}irT_fPbK_%xice5AhyelvLSf8E7%K+GJ`Mv>VO%`Em!y5KKzy%3 zeR+_+*D=0)7+>;J9}2g(#E9=*h@T+TPYCIEALA!F?spyPz1-!ow&?d5;{OEdFOBq< zMfz`Z`|XT*d~t?}hy}caaL7ReRFDB`m;eo^@A(@qIw3!ey8#mw9D`gOceVi7fdGT? zKqG447Yn}|81Lz){y+>p5yo0Dz;cHR2(o80;R*gJ9qdF66yph`m-aK~;jqR96=pJk zGFhFaLjoWnK~O)Mg0#>3afatS90J-b31alI()3rbu=95?VLuoG2}^nZ8*n zzErU=CP)~wMHpLQSnzmQFg0L_JJ1XQ6M?Y{L^DNwVfM{rN{gmrV+O1O!dpT@fz08p zxKJDw*2NqK#)WY$g)=ZmfP^B-AQ3;MgOsTLO|F1&Xi&`(P^E&wX$u%V4QI6oXMl!x zheR&&gs)KVZQvr?r6c$X!wN&fR$)=c$S9OW6cqx?qedNBL@?+EyD|sXKZP@3=xe9x zRHA|MSbF^mriH@LWoQhKO!#$tXlr34Q%K}06*esGdnO$w$PzsWjTLeW16qU~K%&KX zX~Cf?LCVrF^YLh_Eufw~-BSS5Ro(F2r5JE+_zjsTuv^RyG`?iq_YrS|)=~V!iP$2c z1QzL7akm6HX1F*q_yaVkz@AR;CQ!GpI=0EWBvbk|@P%q?T=SmLdPlVVt6-|!+n zxrO~#l$3-=+^>!DbVIniA)Jp8`9=Oryl@uY0COG|?k^Yq!_r*>&^_Ejc3?u2s4wh$@gtlP~o4t4)5Q3iqQ`FxiU% zHDDJW4$#%8hB)&2y6O7QtER1}`soS7QM#}jne?~BGHzwkUDu|Yl?ho^MbJ<9oz$iS z!hC&ogEX7~hP;`~$(gJxu%aSwI3|tSAkn%f^4Zln(ld!Vwf0f9#dVk=QxWubBG@@&onF#oSYL- zOCQM`8mAJPh)Y3-CdFC$w${e;QZw3h6Z)hPP`&(7>0E!^+-fMCR*Qi*QsLKyG6m5Q$r3^%Jy)ZL4PNyJcv~ z1-~yTFjkNK04|kY$-FCDW8sngUwuf|K#ko=jXfCsQx5HK*pybFT_}jJ?b$j^>y|24Meo2GBXz3&??tZzFOlv zud8xNFQ=NNk=W38(l7vS3_7VF)ovW6c{Gj^?cr?tm9O-FzhWE$H_ga3&8;>J!yA{Z zIVPTSY?E7Sdy?8FWq^L+*{0};=3hgD`J!#vu=H!~3=QoX zr1rO{W_nNdKGhD$TJwjs8g)Lb4ts|YsRJU~3e;f!FBRKSkF{AavlldXI%t)b?|Ng? z?i}8>Thiua(BdhIhKjb)By5_Wu(wHz;#^YNy;52XP#xbJIyBchZl2;INVvD`_%Ek5 za2q_b0Ux`DOXlk^ldrpL(0b1RSdeH{GHO*W*d;I8?xE2IV{dbpZ&r}Ux$t$nkh+|} z?G^IqkW}0k1AJ^MK2089lNBS4pK{qX#bEw?Qm*S9-qTy z9S3fN0}0j5{Ge|+yqiMmt+46i=-6BhiK6!#dgAzc`O@&0bg5ywGuagK#3Tw@ZaLKPD5NpSCHZ+GNxIRBN6Rx%%j^OEwNHt&Mo3 z3|SkZ4{V04IK~_v)P5=L4BD^J9snX189fadKXEa>003QyZE^}@wqCWS8l6Gwqj3IO z=d?y^(s-=GM7(X2MQW!Y-$X*=L@IgWkLLu^t2JF=GS_g@_hdZDYb?KU5=EYLf={ln zeeM?{{x&4mco8va#JYb$Cli~_h**A7s{*Orkksi#!ljW2jU)mGkwb?VuKpQA!;*## z$)jH6@ig*eBbh`dH>{H?HHpsqwQJEjrPJi4G|EaNWsOYPuq991LI!$4zle~iYSzuP zspH0}Q}Pr|fwcYL!)`A~br95s1?AjiOx~Jer%Z!r(_DQdy1thKWb9G3aaJ@-Jb>{c z<*xwk?@h||WeUU9vepL&Uo)^E!!N}17BYZqriwg+jo`#<&Q93Q_V7p3B4))v)0t_V z{SPR%r)CaM%

>AJP7*Dw5O%NSYL)ydCKsjr{|S_`zttBVzujbY6i*R?;H;RUqbv zTNQU&mATA`(%2=+79KS%2w$3gKwGeRIQz42!9|PcK%0Zo?$JCbbDoNe){%3z>2v;| z`ELICK2@S@*%CZ`sj7E2Ph~z@U^z-_HhyC%HgYzmX*tD+7-6>@r?s49M>L?!*DA~m zD1fF8I2P?e!mz>M;?Y}yk!}P7TQHZ`;iw%Y=lHSCS zvZbhvwSKLYT)Wv}(0c5{^>n-SY^`~c(fXkG@?hWkjN-u|H`lQh^o6kH; z`SOt6GVA90jQ4!c^40>4xb$#gjEikGokgXE#<5=kP-?ZM{W#ZW8Jw}4EwBxqsv6chVQ=25IN$ZZv2SeDYofUC z{&Z(QdjDSkK4;nD4a)B4GO|na3E_Dh!g+*GyX^W wHR}wf+O!2@+C^`(`exeN4O%1TK=TxBN9la;{O^qMIW^<_c$0EjfD0h^e=xHc^#A|> literal 0 HcmV?d00001 diff --git a/resources-en/src/tips/images/vcsQuickList.gif b/resources-en/src/tips/images/vcsQuickList.gif new file mode 100644 index 0000000000000000000000000000000000000000..00ca331224e2a5461e2d9b802ef158a08ad34176 GIT binary patch literal 5503 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 BtHl5S literal 0 HcmV?d00001 diff --git a/resources-en/src/tips/moveFileToChangelist.html b/resources-en/src/tips/moveFileToChangelist.html new file mode 100644 index 000000000000..8d36ad85ca40 --- /dev/null +++ b/resources-en/src/tips/moveFileToChangelist.html @@ -0,0 +1,12 @@ + +
+ + +

+You can move any file in the currently active editor to a changelist of your choice. To do that, just choose +Move to Changelist on the context menu. +

+ + +
+ diff --git a/resources-en/src/tips/tips.xml b/resources-en/src/tips/tips.xml index 1ccb172c851f..e24101cfdd71 100644 --- a/resources-en/src/tips/tips.xml +++ b/resources-en/src/tips/tips.xml @@ -97,4 +97,11 @@ + + + + + + +