diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderRegistry.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderRegistry.java index ee20e5a5d8e3..51a128ddc6ff 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderRegistry.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderRegistry.java @@ -2,7 +2,7 @@ package org.jetbrains.jps.incremental; import org.jetbrains.jps.incremental.groovy.GroovyBuilder; import org.jetbrains.jps.incremental.java.JavaBuilder; -import org.jetbrains.jps.incremental.resourses.ResourcesBuilder; +import org.jetbrains.jps.incremental.resources.ResourcesBuilder; import java.util.*; import java.util.concurrent.ExecutorService; diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/resourses/ResourcesBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/resources/ResourcesBuilder.java similarity index 98% rename from jps/jps-builders/src/org/jetbrains/jps/incremental/resourses/ResourcesBuilder.java rename to jps/jps-builders/src/org/jetbrains/jps/incremental/resources/ResourcesBuilder.java index 7aaeb0068972..a318f8ef4dd7 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/resourses/ResourcesBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/resources/ResourcesBuilder.java @@ -1,4 +1,4 @@ -package org.jetbrains.jps.incremental.resourses; +package org.jetbrains.jps.incremental.resources; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.io.FileUtil; diff --git a/platform/platform-resources-en/src/messages/ExecutionBundle.properties b/platform/platform-resources-en/src/messages/ExecutionBundle.properties index 3be53cf875b1..0181271196aa 100644 --- a/platform/platform-resources-en/src/messages/ExecutionBundle.properties +++ b/platform/platform-resources-en/src/messages/ExecutionBundle.properties @@ -133,6 +133,8 @@ tests.passed.with.warnings.message=Tests passed (with warnings) junit.run.hide.passed.action.name=Hide Passed junit.run.hide.passed.action.description=Hide passed tests junit.runing.info.track.test.action.name=Track Running Test +junit.runing.info.sort.alphabetically.action.name=Sort Alphabetically +junit.runing.info.sort.alphabetically.action.description=Sort tests or suites alphabetically junit.runing.info.track.test.action.description=Select currently running test in tree junit.runing.info.collapse.test.action.name=Collapse all test suites junit.runing.info.expand.test.action.name=Expand all test suites diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerNodeDescriptor.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerNodeDescriptor.java index a5afce41398c..eccd92344e1f 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerNodeDescriptor.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerNodeDescriptor.java @@ -15,41 +15,18 @@ */ package com.intellij.execution.testframework.sm.runner; +import com.intellij.execution.testframework.ui.BaseTestProxyNodeDescriptor; import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.project.Project; /** * @author: Roman Chernyatchik */ -public class SMTRunnerNodeDescriptor extends NodeDescriptor -{ - private final SMTestProxy myElement; - +public class SMTRunnerNodeDescriptor extends BaseTestProxyNodeDescriptor { public SMTRunnerNodeDescriptor(final Project project, - final SMTestProxy element, - final NodeDescriptor parentDesc) { - super(project, parentDesc); - myElement = element; - myName = element.getName(); - } - - @Override - public boolean update() { - return false; - } - - @Override - public SMTestProxy getElement() { - return myElement; - } - - public boolean expandOnDoubleClick() { - return !myElement.isLeaf(); - } - - @Override - public String toString() { - return myName; + final SMTestProxy testProxy, + final NodeDescriptor parentDesc) { + super(project, testProxy, parentDesc); } } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeBuilder.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeBuilder.java index 95280b7fdd7c..e4d9ff5c9c08 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeBuilder.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeBuilder.java @@ -16,13 +16,10 @@ package com.intellij.execution.testframework.sm.runner; import com.intellij.execution.testframework.ui.AbstractTestTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.ide.util.treeView.AbstractTreeUpdater; import com.intellij.ide.util.treeView.IndexComparator; import com.intellij.ide.util.treeView.NodeDescriptor; -import com.intellij.ide.util.treeView.AbstractTreeUpdater; -import com.intellij.ide.util.treeView.AbstractTreeStructure; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.util.StatusBarProgress; -import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; @@ -43,7 +40,7 @@ public class SMTRunnerTreeBuilder extends AbstractTestTreeBuilder { } public SMTRunnerTreeStructure getSMRunnerTreeStructure() { - return ((SMTRunnerTreeStructure)getTreeStructure()) ; + return ((SMTRunnerTreeStructure)getTreeStructure()); } public void updateTestsSubtree(final SMTestProxy parentTestProxy) { @@ -64,32 +61,16 @@ public class SMTRunnerTreeBuilder extends AbstractTestTreeBuilder { } if (((SMTestProxy)nodeElement).getParent() == rootElement - && ((SMTestProxy)rootElement).getChildren().size() == 1){ + && ((SMTestProxy)rootElement).getChildren().size() == 1) { return true; } return false; } - protected boolean isAlwaysShowPlus(final NodeDescriptor descriptor) { - //TODO[romeo] move to base class - return false; - } - - @NotNull - protected ProgressIndicator createProgressIndicator() { - //TODO[romeo] maybe move to base class - return new StatusBarProgress(); - } - - protected boolean isSmartExpand() { - //TODO[romeo] move to base class - return false; - } - /** * for java unit tests */ public void performUpdate() { getUpdater().performUpdate(); - } + } } 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 34f025b606ac..c2b5e04dc23c 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 @@ -54,7 +54,8 @@ import java.util.Set; /** * @author: Roman Chernyatchik */ -public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFrameworkRunningModel, TestResultsViewer, SMTRunnerEventsListener { +public class SMTestRunnerResultsForm extends TestResultsPanel + implements TestFrameworkRunningModel, TestResultsViewer, SMTRunnerEventsListener { @NonNls private static final String DEFAULT_SM_RUNNER_SPLITTER_PROPERTY = "SMTestRunner.Splitter.Proportion"; public static final Color DARK_YELLOW = Color.YELLOW.darker(); @@ -131,12 +132,12 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra final KeyStroke shiftEnterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_MASK); SMRunnerUtil.registerAsAction(shiftEnterKey, "show-statistics-for-test-proxy", - new Runnable() { - public void run() { - showStatisticsForSelectedProxy(); - } - }, - myTreeView); + new Runnable() { + public void run() { + showStatisticsForSelectedProxy(); + } + }, + myTreeView); } protected ToolbarPanel createToolbarPanel() { @@ -161,7 +162,9 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra final SMTRunnerTreeStructure structure = new SMTRunnerTreeStructure(myProject, myTestsRootNode); myTreeBuilder = new SMTRunnerTreeBuilder(myTreeView, structure); + myTreeBuilder.setTestsComparator(TestConsoleProperties.SORT_ALPHABETICALLY.value(myProperties)); Disposer.register(this, myTreeBuilder); + myAnimator = new MyAnimator(this, myTreeBuilder); //TODO always hide root node @@ -192,6 +195,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra /** * Is used for navigation from tree view to other UI components + * * @param handler */ public void setShowStatisticForProxyHandler(final PropagateSelectionHandler handler) { @@ -200,8 +204,9 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra /** * Returns root node, fake parent suite for all tests and suites - * @return + * * @param testsRoot + * @return */ public void onTestingStarted(@NotNull SMTestProxy.SMRootTestProxy testsRoot) { myAnimator.setCurrentTestCase(myTestsRootNode); @@ -333,6 +338,11 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra return myTreeView; } + @Override + public SMTRunnerTreeBuilder getTreeBuilder() { + return myTreeBuilder; + } + public boolean hasTestSuites() { return getRoot().getChildren().size() > 0; } @@ -345,10 +355,11 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra /** * 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 - * - * + *

+ *

* Will select proxy in Event Dispatch Thread. Invocation of this * method may be not in event dispatch thread + * * @param testProxy Test or suite */ public void selectAndNotify(@Nullable final AbstractTestProxy testProxy) { @@ -469,7 +480,8 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra private void updateStatusLabel(final boolean testingFinished) { if (myTestsFailuresCount > 0) { myStatusLine.setStatusColor(ColorProgressBar.RED); - } else if (myContainsIgnoredTests) { + } + else if (myContainsIgnoredTests) { myStatusLine.setStatusColor(DARK_YELLOW); } @@ -477,7 +489,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra if (myTestsTotal == 0) { myStatusLine.setStatusColor(myTestsRootNode.wasLaunched() || !myTestsRootNode.isTestsReporterAttached() ? Color.LIGHT_GRAY - : ColorProgressBar.RED ); + : ColorProgressBar.RED); } // else color will be according failed/passed tests } @@ -486,9 +498,9 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra // initializing will be "launchedAndFinished" final boolean launchedAndFinished = myTestsRootNode.wasLaunched() && !myTestsRootNode.isInProgress(); myStatusLine.setText(TestsPresentationUtil.getProgressStatus_Text(myStartTime, myEndTime, - myTestsTotal, myTestsCurrentCount, - myTestsFailuresCount, myMentionedCategories, - launchedAndFinished)); + myTestsTotal, myTestsCurrentCount, + myTestsFailuresCount, myMentionedCategories, + launchedAndFinished)); } /** @@ -501,12 +513,13 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra /** * On event change selection and probably requests focus. Is used when we want * navigate from other component to this + * * @return Listener */ public PropagateSelectionHandler createSelectMeListener() { return new PropagateSelectionHandler() { public void handlePropagateSelectionRequest(@Nullable final SMTestProxy selectedTestProxy, @NotNull final Object sender, - final boolean requestFocus) { + final boolean requestFocus) { SMRunnerUtil.addToInvokeLater(new Runnable() { public void run() { selectWithoutNotify(selectedTestProxy); @@ -543,7 +556,8 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra if (!isModeConsistent(isCustomMessage)) return; // for mixed tests results : mention category only if it contained tests - myMentionedCategories.add(myCurrentCustomProgressCategory != null ? myCurrentCustomProgressCategory : TestsPresentationUtil.DEFAULT_TESTS_CATEGORY); + myMentionedCategories + .add(myCurrentCustomProgressCategory != null ? myCurrentCustomProgressCategory : TestsPresentationUtil.DEFAULT_TESTS_CATEGORY); // Counters myTestsCurrentCount++; @@ -558,7 +572,8 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra if (myTestsTotal != 0) { // if total is set myStatusLine.setFraction((double)myTestsCurrentCount / myTestsTotal); - } else { + } + else { // if at least one test was launcher than just set progress in the middle to show user that tests are running myStatusLine.setFraction(myTestsCurrentCount > 1 ? 0.5 : 0); // > 1 because count already ++ } @@ -583,34 +598,34 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra } - private static class MyFocusTraversalPolicy extends FocusTraversalPolicy { - final List myComponents; + private static class MyFocusTraversalPolicy extends FocusTraversalPolicy { + final List myComponents; - private MyFocusTraversalPolicy(final List components) { - myComponents = components; - } + private MyFocusTraversalPolicy(final List components) { + myComponents = components; + } - public Component getComponentAfter(final Container container, final Component component) { - return myComponents.get((myComponents.indexOf(component) + 1) % myComponents.size()); - } + public Component getComponentAfter(final Container container, final Component component) { + return myComponents.get((myComponents.indexOf(component) + 1) % myComponents.size()); + } - public Component getComponentBefore(final Container container, final Component component) { - final int prevIndex = myComponents.indexOf(component) - 1; - final int normalizedIndex = prevIndex < 0 ? myComponents.size() - 1 : prevIndex; + public Component getComponentBefore(final Container container, final Component component) { + final int prevIndex = myComponents.indexOf(component) - 1; + final int normalizedIndex = prevIndex < 0 ? myComponents.size() - 1 : prevIndex; - return myComponents.get(normalizedIndex); - } + return myComponents.get(normalizedIndex); + } - public Component getFirstComponent(final Container container) { - return myComponents.get(0); - } + public Component getFirstComponent(final Container container) { + return myComponents.get(0); + } - public Component getLastComponent(final Container container) { - return myComponents.get(myComponents.size() - 1); - } + public Component getLastComponent(final Container container) { + return myComponents.get(myComponents.size() - 1); + } - public Component getDefaultComponent(final Container container) { - return getFirstComponent(container); - } + public Component getDefaultComponent(final Container container) { + return getFirstComponent(container); + } } } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java b/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java index 57332b78d476..fa670d6c4308 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java @@ -41,6 +41,7 @@ import java.util.HashMap; public abstract class TestConsoleProperties extends StoringPropertyContainer implements Disposable { public static final BooleanProperty SCROLL_TO_STACK_TRACE = new BooleanProperty("scrollToStackTrace", false); + public static final BooleanProperty SORT_ALPHABETICALLY = new BooleanProperty("sortTestsAlphabetically", false); public static final BooleanProperty SELECT_FIRST_DEFECT = new BooleanProperty("selectFirtsDefect", false); public static final BooleanProperty TRACK_RUNNING_TEST = new BooleanProperty("trackRunningTest", true); public static final BooleanProperty HIDE_PASSED_TESTS = new BooleanProperty("hidePassedTests", true); @@ -69,7 +70,7 @@ public abstract class TestConsoleProperties extends StoringPropertyContainer imp public GlobalSearchScope getScope() { Module[] modules = getConfiguration().getModules(); if (modules.length == 0) return GlobalSearchScope.allScope(myProject); - + GlobalSearchScope scope = GlobalSearchScope.EMPTY_SCOPE; for (Module each : modules) { scope = scope.uniteWith(GlobalSearchScope.moduleRuntimeScope(each, true)); @@ -135,12 +136,12 @@ public abstract class TestConsoleProperties extends StoringPropertyContainer imp /** * Allows to make console editable and disable/enable input sending in process stdin stream. * Normally tests shouldn't ask anything in stdin so console is view only by default. - * + *

* NB1: Process input support feature isn't fully implemented. Input text will be lost after * switching to any other test/suite in tests results view. It's highly not recommended to change * default behaviour. Please do it only in critical cases and only if you are sure that you need this feature. - * - * + *

+ *

* NB2: If you are using Service Messages based test runner please ensure that before each service message * (e.g. #teamcity[...]) you always send "\n" to the output stream. * diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestFrameworkRunningModel.java b/platform/testRunner/src/com/intellij/execution/testframework/TestFrameworkRunningModel.java index a018a613fc41..9080d7f466fc 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/TestFrameworkRunningModel.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/TestFrameworkRunningModel.java @@ -20,20 +20,23 @@ */ package com.intellij.execution.testframework; +import com.intellij.execution.testframework.ui.AbstractTestTreeBuilder; import com.intellij.openapi.Disposable; public interface TestFrameworkRunningModel extends Disposable { TestConsoleProperties getProperties(); - void setFilter(final Filter filter); + void setFilter(Filter filter); boolean isRunning(); TestTreeView getTreeView(); + AbstractTestTreeBuilder getTreeBuilder(); + boolean hasTestSuites(); AbstractTestProxy getRoot(); - void selectAndNotify(final AbstractTestProxy testProxy); + void selectAndNotify(AbstractTestProxy testProxy); } \ No newline at end of file diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ToolbarPanel.java b/platform/testRunner/src/com/intellij/execution/testframework/ToolbarPanel.java index c8672fca7366..9538c13bd891 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ToolbarPanel.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ToolbarPanel.java @@ -28,6 +28,7 @@ import com.intellij.execution.testframework.actions.ShowStatisticsAction; import com.intellij.execution.testframework.actions.TestFrameworkActions; import com.intellij.execution.testframework.actions.TestTreeExpander; import com.intellij.execution.testframework.export.ExportTestResultsAction; +import com.intellij.execution.testframework.ui.AbstractTestTreeBuilder; import com.intellij.ide.CommonActionsManager; import com.intellij.ide.OccurenceNavigator; import com.intellij.openapi.Disposable; @@ -54,19 +55,25 @@ public class ToolbarPanel extends JPanel implements OccurenceNavigator, Disposab public ToolbarPanel(final TestConsoleProperties properties, final RunnerSettings runnerSettings, final ConfigurationPerRunnerSettings configurationSettings, JComponent parent) { - super (new BorderLayout()); + super(new BorderLayout()); final DefaultActionGroup actionGroup = new DefaultActionGroup(null, false); actionGroup.addAction(new ToggleBooleanProperty(ExecutionBundle.message("junit.run.hide.passed.action.name"), ExecutionBundle.message("junit.run.hide.passed.action.description"), TestsUIUtil.loadIcon("hidePassed"), properties, TestConsoleProperties.HIDE_PASSED_TESTS)); actionGroup.addSeparator(); - + actionGroup.addAction(new ToggleBooleanProperty(ExecutionBundle.message("junit.runing.info.track.test.action.name"), ExecutionBundle.message("junit.runing.info.track.test.action.description"), TestsUIUtil.loadIcon("trackTests"), properties, TestConsoleProperties.TRACK_RUNNING_TEST)).setAsSecondary(true); + actionGroup.addAction(new ToggleBooleanProperty(ExecutionBundle.message("junit.runing.info.sort.alphabetically.action.name"), + ExecutionBundle.message("junit.runing.info.sort.alphabetically.action.description"), + IconLoader.getIcon("/objectBrowser/sorted.png"), + properties, TestConsoleProperties.SORT_ALPHABETICALLY)); + actionGroup.addSeparator(); + AnAction action = CommonActionsManager.getInstance().createCollapseAllAction(myTreeExpander, parent); action.getTemplatePresentation().setDescription(ExecutionBundle.message("junit.runing.info.collapse.test.action.name")); actionGroup.add(action); @@ -92,7 +99,8 @@ public class ToolbarPanel extends JPanel implements OccurenceNavigator, Disposab myScrollToSource = new ScrollToTestSourceAction(properties); actionGroup.addAction(myScrollToSource).setAsSecondary(true); actionGroup.addAction(new ToggleBooleanProperty(ExecutionBundle.message("junit.runing.info.open.source.at.exception.action.name"), - ExecutionBundle.message("junit.runing.info.open.source.at.exception.action.description"), + ExecutionBundle + .message("junit.runing.info.open.source.at.exception.action.description"), IconLoader.getIcon("/runConfigurations/sourceAtException.png"), properties, TestConsoleProperties.OPEN_FAILURE_LINE)).setAsSecondary(true); @@ -110,8 +118,8 @@ public class ToolbarPanel extends JPanel implements OccurenceNavigator, Disposab appendAdditionalActions(actionGroup, properties, runnerSettings, configurationSettings, parent); add(ActionManager.getInstance(). - createActionToolbar(ActionPlaces.TESTTREE_VIEW_TOOLBAR, actionGroup, true). - getComponent(), BorderLayout.CENTER); + createActionToolbar(ActionPlaces.TESTTREE_VIEW_TOOLBAR, actionGroup, true). + getComponent(), BorderLayout.CENTER); } protected void appendAdditionalActions(DefaultActionGroup actionGroup, TestConsoleProperties properties, RunnerSettings runnerSettings, @@ -128,6 +136,15 @@ public class ToolbarPanel extends JPanel implements OccurenceNavigator, Disposab for (ToggleModelAction action : myActions) { action.setModel(model); } + TestFrameworkActions.addPropertyListener(TestConsoleProperties.SORT_ALPHABETICALLY, new TestFrameworkPropertyListener() { + @Override + public void onChanged(Boolean value) { + final AbstractTestTreeBuilder builder = model.getTreeBuilder(); + if (builder != null) { + builder.setTestsComparator(value); + } + } + }, model, true); } public boolean hasNextOccurence() { @@ -158,5 +175,4 @@ public class ToolbarPanel extends JPanel implements OccurenceNavigator, Disposab myScrollToSource.setModel(null); myExportAction.setModel(null); } - } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/AbstractTestTreeBuilder.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/AbstractTestTreeBuilder.java index 94a41caadb32..4db467ae7c7f 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ui/AbstractTestTreeBuilder.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/AbstractTestTreeBuilder.java @@ -16,9 +16,10 @@ package com.intellij.execution.testframework.ui; import com.intellij.execution.testframework.AbstractTestProxy; -import com.intellij.ide.util.treeView.AbstractTreeBuilder; -import com.intellij.ide.util.treeView.AbstractTreeStructure; -import com.intellij.ide.util.treeView.IndexComparator; +import com.intellij.ide.util.treeView.*; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.util.StatusBarProgress; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; @@ -51,4 +52,22 @@ public abstract class AbstractTestTreeBuilder extends AbstractTreeBuilder { } while (current != null); } + + protected boolean isAlwaysShowPlus(final NodeDescriptor descriptor) { + return false; + } + + @NotNull + protected ProgressIndicator createProgressIndicator() { + return new StatusBarProgress(); + } + + protected boolean isSmartExpand() { + return false; + } + + public void setTestsComparator(boolean sortAlphabetically) { + setNodeDescriptorComparator(sortAlphabetically ? AlphaComparator.INSTANCE : null); + queueUpdate(); + } } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/BaseTestProxyNodeDescriptor.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/BaseTestProxyNodeDescriptor.java new file mode 100644 index 000000000000..80c979a4f4e4 --- /dev/null +++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/BaseTestProxyNodeDescriptor.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.execution.testframework.ui; + +import com.intellij.execution.testframework.AbstractTestProxy; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Roman.Chernyatchik + */ +public class BaseTestProxyNodeDescriptor extends NodeDescriptor { + @NotNull private final T myTestProxy; + + public BaseTestProxyNodeDescriptor(@Nullable final Project project, + @NotNull final T testProxy, + @Nullable final NodeDescriptor parentDescriptor) { + super(project, parentDescriptor); + myTestProxy = testProxy; + myName = testProxy.getName(); + } + + @Override + public int getWeight() { + return myTestProxy.isLeaf() ? 10 : 5; + } + + public String getName() { + return myTestProxy.getName(); + } + + public boolean expandOnDoubleClick() { + return !getElement().isLeaf(); + } + + @Override + public boolean update() { + return false; + } + + @Override + public T getElement() { + return myTestProxy; + } + + @Override + public String toString() { + return myName; + } +} diff --git a/plugins/InspectionGadgets/src/META-INF/plugin.xml b/plugins/InspectionGadgets/src/META-INF/plugin.xml index 6569e065320d..cc4fbc49ed02 100644 --- a/plugins/InspectionGadgets/src/META-INF/plugin.xml +++ b/plugins/InspectionGadgets/src/META-INF/plugin.xml @@ -1824,10 +1824,6 @@ bundle="com.siyeh.InspectionGadgetsBundle" key="string.buffer.must.have.initial.capacity.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.performance.issues" enabledByDefault="false" level="WARNING" implementationClass="com.siyeh.ig.performance.StringBufferMustHaveInitialCapacityInspection"/> - + #ref replaceable wit inner.class.may.be.static.problem.descriptor=Inner class #ref may be 'static' #loc string.buffer.must.have.initial.capacity.problem.descriptor=#ref without initial capacity #loc string.buffer.replaceable.by.string.builder.problem.descriptor=StringBuffer #ref may be declared as ''StringBuilder'' #loc -string.buffer.replaceable.by.string.problem.descriptor=Constant {0} #ref may be declared as ''String'' #loc +string.buffer.replaceable.by.string.problem.descriptor={0} #ref can be replaced with ''String'' #loc string.replaceable.by.string.buffer.problem.descriptor=Non-constant String #ref should probably be declared as ''StringBuilder'' #loc collections.must.have.initial.capacity.problem.descriptor=#ref without initial capacity #loc string.concatenation.in.loops.problem.descriptor=String concatenation #ref in loop #loc diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/StringBufferReplaceableByStringInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java similarity index 99% rename from plugins/InspectionGadgets/src/com/siyeh/ig/performance/StringBufferReplaceableByStringInspection.java rename to plugins/InspectionGadgets/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java index a77d0cc4161c..9d56ab1b5c69 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/StringBufferReplaceableByStringInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.siyeh.ig.performance; +package com.siyeh.ig.style; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/VariableIsModifiedVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/VariableIsModifiedVisitor.java similarity index 98% rename from plugins/InspectionGadgets/src/com/siyeh/ig/performance/VariableIsModifiedVisitor.java rename to plugins/InspectionGadgets/src/com/siyeh/ig/style/VariableIsModifiedVisitor.java index fcccb5a96a46..748ce1bc5966 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/VariableIsModifiedVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/VariableIsModifiedVisitor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.siyeh.ig.performance; +package com.siyeh.ig.style; import com.intellij.psi.*; import org.jetbrains.annotations.NonNls; diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferReplaceableByString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferReplaceableByString.html index 2273ce2f01f6..832b4e495ec3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferReplaceableByString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferReplaceableByString.html @@ -1,8 +1,8 @@ -This inspection reports any variables declared as java.lang.StringBuffer -and java.lang.StringBuilder which are -effectively constant, and may thus be declared more efficiently declared as java.lang.String. +This inspection reports any variables declared as or uses of java.lang.StringBuffer and java.lang.StringBuilder +which are effectively constant. These may be replaced with java.lang.String expressions which results in simpler and possibly +more efficient code.

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/StringBufferReplaceableByStringInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/StringBufferReplaceableByStringInspection.java deleted file mode 100644 index 085519f5c4ab..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/StringBufferReplaceableByStringInspection.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.siyeh.igtest.performance; - -public class StringBufferReplaceableByStringInspection { - public void foo() - { - final StringBuffer buffer = new StringBuffer(); - System.out.println(buffer.toString()); - } - - public void foo2() - { - final StringBuffer buffer = new StringBuffer("foo").append("bar"); - System.out.println(buffer.toString()); - } -} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/constant_string_buffer_may_be_string/StringBufferReplaceableByString.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/constant_string_buffer_may_be_string/StringBufferReplaceableByString.java deleted file mode 100644 index 7f0eb5b6fbfa..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/constant_string_buffer_may_be_string/StringBufferReplaceableByString.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.siyeh.igtest.performance.constant_string_buffer_may_be_string; - -public class StringBufferReplaceableByString { - - StringBuilder foo() { - StringBuilder builder = new StringBuilder("asdfasdfasdf"); - StringBuffer buffer = new StringBuffer("test"); - StringBuilder result = new StringBuilder("return"); - return result; - } -} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/constant_string_buffer_may_be_string/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/constant_string_buffer_may_be_string/expected.xml deleted file mode 100644 index 79e526123f19..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/constant_string_buffer_may_be_string/expected.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - StringBufferReplaceableByString.java - 6 - Constant StringBuffer may be String - Constant <code>StringBuilder builder</code> may be declared as 'String' #loc - - - - StringBufferReplaceableByString.java - 7 - Constant StringBuffer may be String - Constant <code>StringBuffer buffer</code> may be declared as 'String' #loc - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/string_buffer_replaceable_by_string/StringBufferReplaceableByString.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/string_buffer_replaceable_by_string/StringBufferReplaceableByString.java new file mode 100644 index 000000000000..6c13850a1212 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/string_buffer_replaceable_by_string/StringBufferReplaceableByString.java @@ -0,0 +1,27 @@ +package com.siyeh.igtest.performance.string_buffer_replaceable_by_string; + +public class StringBufferReplaceableByString { + + StringBuilder foo() { + StringBuilder builder = new StringBuilder("asdfasdfasdf"); + StringBuffer buffer = new StringBuffer("test"); + StringBuilder result = new StringBuilder("return"); + return result; + } + + public void foo1() + { + final StringBuffer buffer = new StringBuffer(); + System.out.println(buffer.toString()); + } + + public void foo2() + { + final StringBuffer buffer = new StringBuffer("foo").append("bar"); + System.out.println(buffer.toString()); + } + + public void bar(int i) { + System.out.println(new StringBuilder("asdf").append(i).toString()); + } +} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/string_buffer_replaceable_by_string/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/string_buffer_replaceable_by_string/expected.xml new file mode 100644 index 000000000000..fbc4c4e90c9d --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/string_buffer_replaceable_by_string/expected.xml @@ -0,0 +1,30 @@ + + + + StringBufferReplaceableByString.java + 6 + 'StringBuffer' can be replaced with 'String' + <code>StringBuilder builder</code> can be replaced with 'String' #loc + + + + StringBufferReplaceableByString.java + 7 + 'StringBuffer' can be replaced with 'String' + <code>StringBuffer buffer</code> can be replaced with 'String' #loc + + + + StringBufferReplaceableByString.java + 14 + 'StringBuffer' can be replaced with 'String' + <code>StringBuffer buffer</code> can be replaced with 'String' #loc + + + + StringBufferReplaceableByString.java + 20 + 'StringBuffer' can be replaced with 'String' + <code>StringBuffer buffer</code> can be replaced with 'String' #loc + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/performance/StringBufferReplaceableByStringInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/StringBufferReplaceableByStringInspectionTest.java similarity index 67% rename from plugins/InspectionGadgets/testsrc/com/siyeh/ig/performance/StringBufferReplaceableByStringInspectionTest.java rename to plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/StringBufferReplaceableByStringInspectionTest.java index 7b9a0e928b64..b27d8cd46527 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/performance/StringBufferReplaceableByStringInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/StringBufferReplaceableByStringInspectionTest.java @@ -1,11 +1,11 @@ -package com.siyeh.ig.performance; +package com.siyeh.ig.style; import com.siyeh.ig.IGInspectionTestCase; public class StringBufferReplaceableByStringInspectionTest extends IGInspectionTestCase { public void test() throws Exception { - doTest("com/siyeh/igtest/performance/constant_string_buffer_may_be_string", + doTest("com/siyeh/igtest/performance/string_buffer_replaceable_by_string", new StringBufferReplaceableByStringInspection()); } } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/AlignmentProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/AlignmentProvider.java new file mode 100644 index 000000000000..58c06baaa67c --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/AlignmentProvider.java @@ -0,0 +1,140 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.formatter; + +import com.intellij.formatting.Alignment; +import com.intellij.lang.ASTNode; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.util.containers.hash.HashSet; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * @author Max Medvedev + */ +class AlignmentProvider { + private final static Logger LOG = Logger.getInstance(AlignmentProvider.class); + + private final Map> myTree = new HashMap>(); + private final Map, Alignment> myAlignments = new HashMap, Alignment>(); + + public void addPair(PsiElement e1, PsiElement e2) { + LOG.assertTrue(e1 != e2); + + final Set set1 = myTree.get(e1); + final Set set2 = myTree.get(e2); + + LOG.assertTrue(!(set1 != null && set2 != null)); + + if (set1 != null) { + set1.add(e2); + myTree.put(e2, set1); + } + else if (set2 != null) { + set2.add(e1); + myTree.put(e1, set2); + } + else { + final HashSet set = createHashSet(); + + myTree.put(e1, set); + myTree.put(e2, set); + } + } + + private static HashSet createHashSet() { + return new HashSet() { + private final int myhash = new Object().hashCode(); + + @Override + public int hashCode() { + return myhash; + } + }; + } + + public void addPair(ASTNode node1, ASTNode node2) { + addPair(node1.getPsi(), node2.getPsi()); + } + + private void add(PsiElement element) { + if (myTree.get(element) != null) return; + + final HashSet set = createHashSet(); + set.add(element); + myTree.put(element, set); + } + + @Nullable + public Alignment getAlignment(PsiElement e) { + final Set set = myTree.get(e); + if (set == null) { + return null; + } + + Alignment alignment = myAlignments.get(set); + if (alignment != null) return alignment; + + alignment = Alignment.createAlignment(true); + myAlignments.put(set, alignment); + return alignment; + } + + @Nullable + public Alignment getAlignment(ASTNode node) { + return getAlignment(node.getPsi()); + } + + public Aligner createAligner(PsiElement expression) { + return new Aligner(expression); + } + + public Aligner createAligner() { + return new Aligner(); + } + + /** + * This class helps to assign one alignment to some elements. + * You can create an instance of Aligner and apply 'append' to any element, you want to be aligned. + * + * @author Max Medvedev + */ + class Aligner { + private PsiElement myRef = null; + + private Aligner(){} + + private Aligner(PsiElement initial) { + myRef = initial; + } + + void append(@Nullable PsiElement element) { + if (element == null) return; + + if (myRef == null) { + myRef = element; + add(element); + } + else { + addPair(myRef, element); + } + } + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java index b3482defa348..cf080d546e77 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java @@ -15,7 +15,6 @@ */ package org.jetbrains.plugins.groovy.formatter; -import com.intellij.formatting.Alignment; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiElement; @@ -29,8 +28,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethod import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; -import java.util.Map; - import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mRCURLY; import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.WHITE_SPACES_SET; import static org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes.CLOSABLE_BLOCK; @@ -81,12 +78,11 @@ public class GeeseUtil { return next; } - @Nullable - static Alignment calculateRBraceAlignment(PsiElement rBrace, Map alignments) { + static void calculateRBraceAlignment(PsiElement rBrace, AlignmentProvider alignments) { int leadingBraceCount = 0; PsiElement next; - if (!isClosureContainLF(rBrace)) return null; + if (!isClosureContainLF(rBrace)) return; for (next = getPreviousNonWhitespaceToken(rBrace); isClosureRBrace(next) && isClosureContainLF(next); @@ -131,7 +127,7 @@ public class GeeseUtil { int endOffset = rBrace.getTextRange().getStartOffset(); if (rBrace.getContainingFile().getText().substring(startOffset, endOffset).indexOf('\n') < 0) { - return null; + return; } while (true) { @@ -143,13 +139,7 @@ public class GeeseUtil { break; } } - - Alignment alignment = alignments.get(cur); - if (alignment == null) { - alignment = Alignment.createAlignment(true); - alignments.put(cur, alignment); - } - return alignment; + alignments.addPair(rBrace, cur); } public static boolean isClosureContainLF(PsiElement rBrace) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java index 48d99924c203..9ed0e9a3a0d5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java @@ -48,7 +48,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrComman import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList; import java.util.List; -import java.util.Map; /** * Block implementation for Groovy formatter @@ -62,34 +61,25 @@ public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { final protected Wrap myWrap; final protected CommonCodeStyleSettings mySettings; final protected GroovyCodeStyleSettings myGroovySettings; - final protected Map myInnerAlignments; + final protected AlignmentProvider myAlignmentProvider; protected List mySubBlocks = null; public GroovyBlock(@NotNull final ASTNode node, - @Nullable Alignment alignment, @NotNull final Indent indent, @Nullable final Wrap wrap, final CommonCodeStyleSettings settings, GroovyCodeStyleSettings groovySettings, - @NotNull Map innerAlignments) { + @NotNull AlignmentProvider alignmentProvider) { myNode = node; - if (groovySettings.USE_FLYING_GEESE_BRACES) { - PsiElement psi = myNode.getPsi(); - if (alignment == null) { - alignment = innerAlignments.get(psi); - } - else { - innerAlignments.put(psi, alignment); - } - } - myAlignment = alignment; myIndent = indent; myWrap = wrap; mySettings = settings; myGroovySettings = groovySettings; - myInnerAlignments = innerAlignments; + myAlignmentProvider = alignmentProvider; + + myAlignment = myAlignmentProvider.getAlignment(node.getPsi()); } @NotNull @@ -106,8 +96,8 @@ public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { return myGroovySettings; } - public Map getInnerAlignments() { - return myInnerAlignments; + public AlignmentProvider getAlignmentProvider() { + return myAlignmentProvider; } @NotNull @@ -193,7 +183,7 @@ public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { SWITCH_STATEMENT.equals(astNode.getElementType())) { // PsiElement psi = ((GroovyBlock)getSubBlocks().get(newChildIndex)).getNode().getPsi(); // if (GeeseUtil.isClosureRBrace(psi)) { - // return new ChildAttributes(Indent.getNoneIndent(), GeeseUtil.calculateRBraceAlignment(psi, myInnerAlignments)); + // return new ChildAttributes(Indent.getNoneIndent(), GeeseUtil.calculateRBraceAlignment(psi, myAlignmentProvider)); // } return new ChildAttributes(Indent.getNormalIndent(), null); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java index dcc7e2719d92..cf293b66cb19 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java @@ -33,7 +33,6 @@ import com.intellij.psi.impl.source.tree.LeafPsiElement; import com.intellij.psi.templateLanguages.OuterLanguageElement; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; @@ -60,7 +59,9 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterLi import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrExtendsClause; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody; -import java.util.*; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; /** * Utility class to generate myBlock hierarchy @@ -81,7 +82,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { private final Alignment myAlignment; private final Wrap myWrap; private final CommonCodeStyleSettings mySettings; - private final Map myInnerAlignments; + private final AlignmentProvider myAlignmentProvider; private final GroovyCodeStyleSettings myGroovySettings; public GroovyBlockGenerator(GroovyBlock block) { @@ -90,7 +91,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { myAlignment = myBlock.getAlignment(); myWrap = myBlock.getWrap(); mySettings = myBlock.getSettings(); - myInnerAlignments = myBlock.getInnerAlignments(); + myAlignmentProvider = myBlock.getAlignmentProvider(); myGroovySettings = myBlock.getGroovySettings(); } @@ -134,7 +135,10 @@ public class GroovyBlockGenerator implements GroovyElementTypes { for (ASTNode childNode : children) { if (childNode.getTextRange().getLength() > 0) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); - subBlocks.add(new GroovyBlock(childNode, myAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); + if (myAlignment != null) { + myAlignmentProvider.addPair(myNode, childNode); + } + subBlocks.add(new GroovyBlock(childNode, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider)); } } return subBlocks; @@ -143,8 +147,8 @@ public class GroovyBlockGenerator implements GroovyElementTypes { // chained properties, calls, indexing, etc if (NESTED.contains(myNode.getElementType()) && blockPsi.getParent() != null && !NESTED.contains(blockPsi.getParent().getNode().getElementType())) { final List subBlocks = new ArrayList(); - Alignment dotsAlignment = mySettings.ALIGN_MULTILINE_CHAINED_METHODS ? Alignment.createAlignment() : null; - addNestedChildren(myNode.getPsi(), subBlocks, dotsAlignment, true); + AlignmentProvider.Aligner dotsAligner = mySettings.ALIGN_MULTILINE_CHAINED_METHODS ? myAlignmentProvider.createAligner() : null; + addNestedChildren(myNode.getPsi(), subBlocks, dotsAligner, true); return subBlocks; } @@ -152,10 +156,16 @@ public class GroovyBlockGenerator implements GroovyElementTypes { if (isListLikeClause(blockPsi)) { final ArrayList subBlocks = new ArrayList(); List astNodes = visibleChildren(myNode); - final Alignment newAlignment = mustAlign(blockPsi, astNodes) ? Alignment.createAlignment() : null; + + if (mustAlign(blockPsi, astNodes)) { + final AlignmentProvider.Aligner aligner = myAlignmentProvider.createAligner(); + for (ASTNode node : astNodes) { + if (!isKeyword(node)) aligner.append(node.getPsi()); + } + } for (ASTNode childNode : astNodes) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); - subBlocks.add(new GroovyBlock(childNode, isKeyword(childNode) ? null : newAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); + subBlocks.add(new GroovyBlock(childNode, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider)); } return subBlocks; } @@ -165,10 +175,16 @@ public class GroovyBlockGenerator implements GroovyElementTypes { List children = visibleChildren(myNode); calculateAlignments(children, classLevel); final ArrayList subBlocks = new ArrayList(); + + if (classLevel && myAlignment != null) { + final AlignmentProvider.Aligner aligner = myAlignmentProvider.createAligner(); + for (ASTNode child : children) { + aligner.append(child.getPsi()); + } + } for (ASTNode childNode : children) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); - Alignment alignmentToUse = classLevel ? myAlignment : myInnerAlignments.get(childNode.getPsi()); - subBlocks.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); + subBlocks.add(new GroovyBlock(childNode, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider)); } return subBlocks; } @@ -177,13 +193,14 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final ArrayList subBlocks = new ArrayList(); for (ASTNode childNode : visibleChildren(myNode)) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); - subBlocks.add(new GroovyBlock(childNode, myInnerAlignments.get(childNode.getPsi()), indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); + subBlocks.add(new GroovyBlock(childNode, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider)); } return subBlocks; } + private void calculateAlignments(List children, boolean classLevel) { - List currentGroup = null; + List currentGroup = null; for (ASTNode child : children) { PsiElement psi = child.getPsi(); if (psi instanceof GrLabeledStatement) { @@ -192,43 +209,46 @@ public class GroovyBlockGenerator implements GroovyElementTypes { currentGroup = null; } else { - currentGroup = new ArrayList(); + currentGroup = new ArrayList(); for (LeafPsiElement expression : table) { - Alignment alignment = Alignment.createAlignment(true); - currentGroup.add(alignment); - ContainerUtil.putIfNotNull(expression, alignment, myInnerAlignments); + currentGroup.add(myAlignmentProvider.createAligner(expression)); } } - } else if (currentGroup != null && isTablePart(psi)) { + } + else if (currentGroup != null && isTablePart(psi)) { List table = getSpockTable((GrStatement)psi); for (int i = 0; i < Math.min(table.size(), currentGroup.size()); i++) { - myInnerAlignments.put(table.get(i), currentGroup.get(i)); + currentGroup.get(i).append(table.get(i)); } - } else if (psi instanceof GrVariableDeclaration) { - if (!classLevel || currentGroup == null || fieldGroupEnded(psi)) { - currentGroup = Arrays.asList(Alignment.createAlignment(true), Alignment.createAlignment(true), Alignment.createAlignment(true)); - } - - GrVariable[] variables = ((GrVariableDeclaration)psi).getVariables(); + } + else if (psi instanceof GrVariableDeclaration) { + final GrVariableDeclaration varDeclaration = (GrVariableDeclaration)psi; + GrVariable[] variables = varDeclaration.getVariables(); if (variables.length > 0) { - Alignment varName = currentGroup.get(1); + if (!classLevel || currentGroup == null || fieldGroupEnded(psi)) { + currentGroup = new ArrayList(); + currentGroup.add(myAlignmentProvider.createAligner()); + currentGroup.add(myAlignmentProvider.createAligner()); + currentGroup.add(myAlignmentProvider.createAligner()); + } + + AlignmentProvider.Aligner varName = currentGroup.get(1); for (GrVariable variable : variables) { - myInnerAlignments.put(variable.getNameIdentifierGroovy(), varName); + varName.append(variable.getNameIdentifierGroovy()); } if (classLevel && mySettings.ALIGN_GROUP_FIELD_DECLARATIONS) { - ContainerUtil.putIfNotNull(((GrVariableDeclaration)psi).getTypeElementGroovy(), currentGroup.get(0), myInnerAlignments); + final AlignmentProvider.Aligner typeElement = currentGroup.get(0); + typeElement.append(varDeclaration.getTypeElementGroovy()); - ASTNode eq = variables[variables.length - 1].getNode().findChildByType(GroovyTokenTypes.mASSIGN); - if (eq != null) { - myInnerAlignments.put(eq.getPsi(), currentGroup.get(2)); + ASTNode current_eq = variables[variables.length - 1].getNode().findChildByType(GroovyTokenTypes.mASSIGN); + final AlignmentProvider.Aligner eq = currentGroup.get(2); + if (current_eq != null) { + eq.append(current_eq.getPsi()); } } } } - /*else if (GeeseUtil.isClosureRBrace(psi) && myGroovySettings.USE_FLYING_GEESE_BRACES) { - myInnerAlignments.put(psi, GeeseUtil.calculateRBraceAlignment(psi, myInnerAlignments, myBlocks)); - }*/ else { if (psi instanceof PsiComment) { PsiElement prev = psi.getPrevSibling(); @@ -319,19 +339,19 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final int start = myNode.getTextRange().getStartOffset(); final int end = myNode.getTextRange().getEndOffset(); - subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { + subBlocks.add(new GroovyBlock(myNode, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myAlignmentProvider) { @NotNull public TextRange getTextRange() { return new TextRange(start, start + 3); } }); - subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { + subBlocks.add(new GroovyBlock(myNode, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myAlignmentProvider) { @NotNull public TextRange getTextRange() { return new TextRange(start + 3, end - 3); } }); - subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { + subBlocks.add(new GroovyBlock(myNode, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myAlignmentProvider) { @NotNull public TextRange getTextRange() { return new TextRange(end - 3, end); @@ -345,13 +365,13 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final int start = myNode.getTextRange().getStartOffset(); final int end = myNode.getTextRange().getEndOffset(); - subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { + subBlocks.add(new GroovyBlock(myNode, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myAlignmentProvider) { @NotNull public TextRange getTextRange() { return new TextRange(start, start + 3); } }); - subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { + subBlocks.add(new GroovyBlock(myNode, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myAlignmentProvider) { @NotNull public TextRange getTextRange() { return new TextRange(start + 3, end); @@ -402,12 +422,12 @@ public class GroovyBlockGenerator implements GroovyElementTypes { */ private List generateForBinaryExpr() { final ArrayList subBlocks = new ArrayList(); - Alignment alignment = mySettings.ALIGN_MULTILINE_BINARY_OPERATION ? Alignment.createAlignment() : null; + AlignmentProvider.Aligner + alignment = mySettings.ALIGN_MULTILINE_BINARY_OPERATION ? myAlignmentProvider.createAligner() : null; GrBinaryExpression binary = (GrBinaryExpression)myNode.getPsi(); LOG.assertTrue(binary != null); - addBinaryChildrenRecursively(binary, subBlocks, Indent.getContinuationWithoutFirstIndent(), alignment - ); + addBinaryChildrenRecursively(binary, subBlocks, Indent.getContinuationWithoutFirstIndent(), alignment); return subBlocks; } @@ -417,37 +437,35 @@ public class GroovyBlockGenerator implements GroovyElementTypes { * @param elem * @param list * @param indent - * @param alignment + * @param aligner */ - private void addBinaryChildrenRecursively(PsiElement elem, List list, Indent indent, Alignment alignment) { + private void addBinaryChildrenRecursively(PsiElement elem, List list, Indent indent, @Nullable AlignmentProvider.Aligner aligner) { if (elem == null) return; // For binary expressions if ((elem instanceof GrBinaryExpression)) { GrBinaryExpression myExpr = ((GrBinaryExpression) elem); if (myExpr.getLeftOperand() instanceof GrBinaryExpression) { - addBinaryChildrenRecursively(myExpr.getLeftOperand(), list, Indent.getContinuationWithoutFirstIndent(), alignment - ); + addBinaryChildrenRecursively(myExpr.getLeftOperand(), list, Indent.getContinuationWithoutFirstIndent(), aligner); } PsiElement op = ((GrBinaryExpression)elem).getOperationToken(); for (ASTNode childNode : visibleChildren(elem.getNode())) { PsiElement psi = childNode.getPsi(); if (!(psi instanceof GrBinaryExpression)) { - Alignment alignmentToUse = op == psi ? myInnerAlignments.get(op) : alignment; - list.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); + if (op != psi && aligner != null) { + aligner.append(psi); + } + list.add(new GroovyBlock(childNode, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider)); } } if (myExpr.getRightOperand() instanceof GrBinaryExpression) { - addBinaryChildrenRecursively(myExpr.getRightOperand(), list, Indent.getContinuationWithoutFirstIndent(), alignment + addBinaryChildrenRecursively(myExpr.getRightOperand(), list, Indent.getContinuationWithoutFirstIndent(), aligner ); } } } - private void addNestedChildren(final PsiElement elem, - List list, - @Nullable final Alignment alignment, - final boolean topLevel) { + private void addNestedChildren(final PsiElement elem, List list, @Nullable AlignmentProvider.Aligner aligner, final boolean topLevel) { final List children = visibleChildren(elem.getNode()); if (elem instanceof GrMethodCallExpression) { GrExpression invokedExpression = ((GrMethodCallExpression)elem).getInvokedExpression(); @@ -458,11 +476,11 @@ public class GroovyBlockGenerator implements GroovyElementTypes { int i = 0; while (i < grandChildren.size() && nameElement != grandChildren.get(i).getPsi()) { i++; } if (i > 0) { - processNestedChildrenPrefix(list, alignment, false, grandChildren, i); + processNestedChildrenPrefix(list, aligner, false, grandChildren, i); } if (i < grandChildren.size()) { LOG.assertTrue(nameElement == grandChildren.get(i).getPsi()); - list.add(new MethodCallWithoutQualifierBlock(nameElement, null, myWrap, mySettings, myGroovySettings, topLevel, children, elem, myInnerAlignments)); + list.add(new MethodCallWithoutQualifierBlock(nameElement, myWrap, mySettings, myGroovySettings, topLevel, children, elem, myAlignmentProvider)); } return; } @@ -471,24 +489,23 @@ public class GroovyBlockGenerator implements GroovyElementTypes { } - processNestedChildrenPrefix(list, alignment, topLevel, children, children.size()); + processNestedChildrenPrefix(list, aligner, topLevel, children, children.size()); } - private void processNestedChildrenPrefix(List list, Alignment alignment, boolean topLevel, List children, int limit) { + private void processNestedChildrenPrefix(List list, @Nullable AlignmentProvider.Aligner aligner, boolean topLevel, List children, int limit) { ASTNode fst = children.get(0); LOG.assertTrue(limit > 0); if (NESTED.contains(fst.getElementType())) { - addNestedChildren(fst.getPsi(), list, alignment, false); + addNestedChildren(fst.getPsi(), list, aligner, false); } else { - Alignment alignmentToUse = myInnerAlignments.get(fst.getPsi()); Indent indent = Indent.getContinuationWithoutFirstIndent(); - list.add(new GroovyBlock(fst, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); + list.add(new GroovyBlock(fst, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider)); } - addNestedChildrenSuffix(list, alignment, topLevel, children, limit); + addNestedChildrenSuffix(list, aligner, topLevel, children, limit); } - void addNestedChildrenSuffix(List list, Alignment alignment, boolean topLevel, List children, int limit) { + void addNestedChildrenSuffix(List list, @Nullable AlignmentProvider.Aligner aligner, boolean topLevel, List children, int limit) { for (int i = 1; i < limit; i++) { ASTNode childNode = children.get(i); if (canBeCorrectBlock(childNode)) { @@ -496,8 +513,13 @@ public class GroovyBlockGenerator implements GroovyElementTypes { Indent indent = topLevel || NESTED.contains(type) || type == mIDENT || TokenSets.DOTS.contains(type) ? Indent.getContinuationWithoutFirstIndent() : Indent.getNoneIndent(); - Alignment alignmentToUse = TokenSets.DOTS.contains(type) ? alignment : myInnerAlignments.get(childNode.getPsi()); - list.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); + + + if (aligner != null && TokenSets.DOTS.contains(type)) { + aligner.append(childNode.getPsi()); + } + + list.add(new GroovyBlock(childNode, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider)); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java index 6fd00921d65f..fe67d4f85fd1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java @@ -16,7 +16,10 @@ package org.jetbrains.plugins.groovy.formatter; -import com.intellij.formatting.*; +import com.intellij.formatting.Block; +import com.intellij.formatting.FormattingModel; +import com.intellij.formatting.FormattingModelBuilder; +import com.intellij.formatting.Indent; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; @@ -30,14 +33,12 @@ import com.intellij.psi.formatter.FormattingDocumentModelImpl; import com.intellij.psi.formatter.PsiBasedFormattingModel; import com.intellij.psi.impl.source.tree.TreeUtil; import com.intellij.psi.tree.IElementType; -import com.intellij.util.containers.CollectionFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; -import java.util.Map; /** * @author ilyas @@ -54,14 +55,13 @@ public class GroovyFormattingModelBuilder implements FormattingModelBuilder { CommonCodeStyleSettings groovySettings = settings.getCommonSettings(GroovyFileType.GROOVY_LANGUAGE); GroovyCodeStyleSettings customSettings = settings.getCustomSettings(GroovyCodeStyleSettings.class); - final Map innerAlignments = CollectionFactory.hashMap(); + final AlignmentProvider alignments = new AlignmentProvider(); if (customSettings.USE_FLYING_GEESE_BRACES) { element.accept(new PsiRecursiveElementVisitor() { @Override public void visitElement(PsiElement element) { if (GeeseUtil.isClosureRBrace(element)) { - final Alignment alignment = GeeseUtil.calculateRBraceAlignment(element, innerAlignments); - innerAlignments.put(element, alignment); + GeeseUtil.calculateRBraceAlignment(element, alignments); } else { super.visitElement(element); @@ -69,8 +69,7 @@ public class GroovyFormattingModelBuilder implements FormattingModelBuilder { } }); } - final GroovyBlock block = - new GroovyBlock(astNode, null, Indent.getAbsoluteNoneIndent(), null, groovySettings, customSettings, innerAlignments); + final GroovyBlock block = new GroovyBlock(astNode, Indent.getAbsoluteNoneIndent(), null, groovySettings, customSettings, alignments); return new GroovyFormattingModel(containingFile, block, FormattingDocumentModelImpl.createOn(containingFile)); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java index 001814778e3a..b5d8a481de22 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java @@ -15,7 +15,6 @@ */ package org.jetbrains.plugins.groovy.formatter; -import com.intellij.formatting.Alignment; import com.intellij.formatting.Block; import com.intellij.formatting.Indent; import com.intellij.formatting.Wrap; @@ -27,7 +26,6 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import java.util.Map; /** * @author peter @@ -39,15 +37,14 @@ public class MethodCallWithoutQualifierBlock extends GroovyBlock { private final PsiElement myElem; public MethodCallWithoutQualifierBlock(PsiElement nameElement, - Alignment alignment, Wrap wrap, CommonCodeStyleSettings settings, GroovyCodeStyleSettings groovySettings, boolean topLevel, List children, PsiElement elem, - Map innerAlignments) { - super(nameElement.getNode(), alignment, Indent.getContinuationWithoutFirstIndent(), wrap, settings, groovySettings, innerAlignments); + AlignmentProvider alignmentProvider) { + super(nameElement.getNode(), Indent.getContinuationWithoutFirstIndent(), wrap, settings, groovySettings, alignmentProvider); myNameElement = nameElement; myTopLevel = topLevel; myChildren = children; @@ -59,10 +56,9 @@ public class MethodCallWithoutQualifierBlock extends GroovyBlock { public List getSubBlocks() { if (mySubBlocks == null) { mySubBlocks = new ArrayList(); - mySubBlocks.add( - new GroovyBlock(myNameElement.getNode(), myInnerAlignments.get(myNameElement), Indent.getContinuationWithoutFirstIndent(), myWrap, - mySettings, myGroovySettings, myInnerAlignments)); - new GroovyBlockGenerator(this).addNestedChildrenSuffix(mySubBlocks, myAlignment, myTopLevel, myChildren, myChildren.size()); + final Indent indent = Indent.getContinuationWithoutFirstIndent(); + mySubBlocks.add(new GroovyBlock(myNameElement.getNode(), indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider)); + new GroovyBlockGenerator(this).addNestedChildrenSuffix(mySubBlocks, null, myTopLevel, myChildren, myChildren.size()); } return mySubBlocks; } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.java index 1256e756a2fb..2c91e3c82686 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.java @@ -231,6 +231,7 @@ public class FormatterTest extends GroovyFormatterTestCase { public void testGeese5() {doGeeseTest();} public void testGeese6() {doGeeseTest();} public void testGeese7() {doGeeseTest();} + public void testGeese8() {doGeeseTest();} private void doGeeseTest() { GroovyCodeStyleSettings customSettings = myTempSettings.getCustomSettings(GroovyCodeStyleSettings.class); diff --git a/plugins/groovy/testdata/groovy/formatter/geese8.test b/plugins/groovy/testdata/groovy/formatter/geese8.test new file mode 100644 index 000000000000..596d14a020d0 --- /dev/null +++ b/plugins/groovy/testdata/groovy/formatter/geese8.test @@ -0,0 +1,17 @@ +setupModel( + intellijProject { + module { + faq. + dependencies { + lib(name: "lib1") +}}} +) +----- +setupModel( + intellijProject { + module { + faq. + dependencies { + lib(name: "lib1") + } } } +) \ No newline at end of file diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/model/TestProxyDescriptor.java b/plugins/junit/src/com/intellij/execution/junit2/ui/model/TestProxyDescriptor.java index 30fcb1f92321..d5ef71bdeed5 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/ui/model/TestProxyDescriptor.java +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/model/TestProxyDescriptor.java @@ -17,45 +17,47 @@ package com.intellij.execution.junit2.ui.model; import com.intellij.execution.junit2.TestProxy; +import com.intellij.execution.testframework.ui.BaseTestProxyNodeDescriptor; import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; -class TestProxyDescriptor extends NodeDescriptor { +class TestProxyDescriptor extends BaseTestProxyNodeDescriptor { private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit2.ui.model.TestProxyDescriptor"); private static final int STATE_UP_TO_DATE = 0; private static final int STATE_OUT_OF_DATE = 1; private static final int STATE_UNKNOWN = 2; - private final TestProxy myTest; private int myTimestamp = -1; private int myLastChildCount = -1; //private int myNeedsUpdate = STATE_UNKNOWN; private int myLastMagnitude = -1; public TestProxyDescriptor(final Project project, final NodeDescriptor parentDescriptor, final TestProxy test) { - super(project, parentDescriptor); - myTest = test; - myTimestamp = myTest.getStateTimestamp(); - myLastChildCount = myTest.getChildCount(); + super(project, test, parentDescriptor); + myTimestamp = test.getStateTimestamp(); + myLastChildCount = test.getChildCount(); myName = test.toString(); } public boolean update() { - boolean needsUpdate = checkNeedsUpdate(); - myTimestamp = myTest.getStateTimestamp(); - myLastChildCount = myTest.getChildCount(); + final TestProxy test = getElement(); + + boolean needsUpdate = checkNeedsUpdate(test); + myTimestamp = test.getStateTimestamp(); + myLastChildCount = test.getChildCount(); return needsUpdate; } - private boolean checkNeedsUpdate() { + private boolean checkNeedsUpdate(TestProxy test) { + int needsUpdate = STATE_UP_TO_DATE; - if (myTest.getChildCount() != myLastChildCount) { + if (test.getChildCount() != myLastChildCount) { needsUpdate = STATE_OUT_OF_DATE; } - else if (myTest.getStateTimestamp() != myTimestamp) needsUpdate = STATE_UNKNOWN; + else if (test.getStateTimestamp() != myTimestamp) needsUpdate = STATE_UNKNOWN; if (needsUpdate == STATE_UNKNOWN) { - final int magnitude = myTest.getState().getMagnitude(); + final int magnitude = test.getState().getMagnitude(); needsUpdate = magnitude == myLastMagnitude ? STATE_UP_TO_DATE : STATE_OUT_OF_DATE; myLastMagnitude = magnitude; } @@ -66,8 +68,4 @@ class TestProxyDescriptor extends NodeDescriptor { LOG.error(String.valueOf(needsUpdate)); return true; } - - public Object getElement() { - return myTest; - } } diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/model/TestTreeBuilder.java b/plugins/junit/src/com/intellij/execution/junit2/ui/model/TestTreeBuilder.java index f26d6aa0a1cf..e51fafe2e1e3 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/ui/model/TestTreeBuilder.java +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/model/TestTreeBuilder.java @@ -16,8 +16,8 @@ package com.intellij.execution.junit2.ui.model; -import com.intellij.execution.junit2.events.TestEvent; import com.intellij.execution.junit2.TestProxy; +import com.intellij.execution.junit2.events.TestEvent; import com.intellij.execution.junit2.ui.properties.JUnitConsoleProperties; import com.intellij.execution.testframework.AbstractTestProxy; import com.intellij.execution.testframework.TestTreeView; @@ -25,9 +25,6 @@ import com.intellij.execution.testframework.ui.AbstractTestTreeBuilder; import com.intellij.ide.util.treeView.IndexComparator; import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.util.StatusBarProgress; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -41,8 +38,9 @@ public class TestTreeBuilder extends AbstractTestTreeBuilder { private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit2.ui.model.TestTreeBuilder"); private JUnitRunningModel myModel; - private final JUnitAdapter myListener = new JUnitAdapter(){ + private final JUnitAdapter myListener = new JUnitAdapter() { private final Collection myNodesToUpdate = new HashSet(); + public void onEventsDispatched(final List events) { for (final TestEvent event : events) { final TestProxy testSubtree = (TestProxy)event.getTestSubtree(); @@ -75,18 +73,11 @@ public class TestTreeBuilder extends AbstractTestTreeBuilder { treeStructure.setSpecialNode(new SpecialNode(this, model)); myModel = model; myModel.addListener(myListener); - init(tree, new DefaultTreeModel(new DefaultMutableTreeNode(treeStructure.createDescriptor(model.getRoot(), null))), treeStructure, IndexComparator.INSTANCE, true); + init(tree, new DefaultTreeModel(new DefaultMutableTreeNode(treeStructure.createDescriptor(model.getRoot(), null))), treeStructure, + IndexComparator.INSTANCE, true); initRootNode(); } - protected boolean isSmartExpand() { - return false; - } - - protected boolean isAlwaysShowPlus(final NodeDescriptor nodeDescriptor) { - return false; - } - protected boolean isAutoExpandNode(final NodeDescriptor nodeDescriptor) { return nodeDescriptor.getElement() == myModel.getRoot(); } @@ -96,7 +87,7 @@ public class TestTreeBuilder extends AbstractTestTreeBuilder { DefaultMutableTreeNode node = getNodeForElement(test); if (node != null) { if (node.getParent() != null) { - expandNodeChildren((DefaultMutableTreeNode) node.getParent()); + expandNodeChildren((DefaultMutableTreeNode)node.getParent()); node = getNodeForElement(test); } return node; @@ -112,9 +103,4 @@ public class TestTreeBuilder extends AbstractTestTreeBuilder { } return node; } - - @NotNull - protected ProgressIndicator createProgressIndicator() { - return new StatusBarProgress(); - } } diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestNodeDescriptor.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestNodeDescriptor.java index e0a06884dbfc..f9b78b7a9407 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TestNodeDescriptor.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestNodeDescriptor.java @@ -15,33 +15,15 @@ */ package com.theoryinpractice.testng.model; +import com.intellij.execution.testframework.ui.BaseTestProxyNodeDescriptor; import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.project.Project; /** * @author Hani Suleiman Date: Jul 28, 2005 Time: 10:44:26 PM */ -public class TestNodeDescriptor extends NodeDescriptor -{ - private final TestProxy node; - - public TestNodeDescriptor(Project project, TestProxy node, NodeDescriptor parent) { - super(project, parent); - this.node = node; - myName = node.getName(); - } - - @Override - public boolean update() { - return false; - } - - @Override - public TestProxy getElement() { - return node; - } - - public boolean expandOnDoubleClick() { - return !node.isResult(); - } +public class TestNodeDescriptor extends BaseTestProxyNodeDescriptor { + public TestNodeDescriptor(Project project, TestProxy node, NodeDescriptor parent) { + super(project, node, parent); + } } diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestTreeBuilder.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestTreeBuilder.java index 1bf037826de8..24b45f076088 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TestTreeBuilder.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestTreeBuilder.java @@ -27,36 +27,26 @@ import javax.swing.tree.DefaultTreeModel; /** * @author Hani Suleiman Date: Jul 28, 2005 Time: 10:49:36 PM */ -public class TestTreeBuilder extends AbstractTestTreeBuilder -{ - public TestTreeBuilder(JTree tree, AbstractTreeStructure structure) { - super(tree, new DefaultTreeModel(new DefaultMutableTreeNode(structure.getRootElement())), structure, IndexComparator.INSTANCE); - initRootNode(); - } +public class TestTreeBuilder extends AbstractTestTreeBuilder { + public TestTreeBuilder(JTree tree, AbstractTreeStructure structure) { + super(tree, new DefaultTreeModel(new DefaultMutableTreeNode(structure.getRootElement())), structure, IndexComparator.INSTANCE); + initRootNode(); + } - @Override - protected boolean isSmartExpand() { - return false; - } + @Override + protected boolean isAutoExpandNode(NodeDescriptor descriptor) { + return descriptor.getElement() == getTreeStructure().getRootElement(); + } - @Override - protected boolean isAlwaysShowPlus(NodeDescriptor descriptor) { - return false; + public void addItem(TestProxy parent, TestProxy proxy) { + parent.addChild(proxy); + DefaultMutableTreeNode parentNode = getNodeForElement(parent); + if (parentNode != null) { + updateSubtree(parentNode); } + } - @Override - protected boolean isAutoExpandNode(NodeDescriptor descriptor) { - return descriptor.getElement() == getTreeStructure().getRootElement(); - } - - public void addItem(TestProxy parent, TestProxy proxy) { - parent.addChild(proxy); - DefaultMutableTreeNode parentNode = getNodeForElement(parent); - if (parentNode != null) - updateSubtree(parentNode); - } - - public TestProxy getRoot() { - return (TestProxy) getTreeStructure().getRootElement(); - } + public TestProxy getRoot() { + return (TestProxy)getTreeStructure().getRootElement(); + } } diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java index a6c33689e7b5..c75ec170d5bf 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java @@ -214,7 +214,8 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn final String testMethodDescriptor = result.getTestClass() + result.getMethod(); if (startedMethods.contains(testMethodDescriptor)) { total++; - } else { + } + else { startedMethods.add(testMethodDescriptor); } animator.setCurrentTestCase(proxy); @@ -241,13 +242,15 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn final PsiElement element = getPackageClassNodeFor(result).getPsiElement(); if (element instanceof PsiClass) { final PsiMethod[] methods = ApplicationManager.getApplication().runReadAction( - new Computable() { - public PsiMethod[] compute() { - return ((PsiClass)element).findMethodsByName(result.getMethod(), true); - } + new Computable() { + public PsiMethod[] compute() { + return ((PsiClass)element).findMethodsByName(result.getMethod(), true); } + } ); - if (methods.length > 0 && methods[0] != null && !AnnotationUtil.isAnnotated(methods[0], Arrays.asList(TestNGUtil.CONFIG_ANNOTATIONS_FQN))) { + if (methods.length > 0 && + methods[0] != null && + !AnnotationUtil.isAnnotated(methods[0], Arrays.asList(TestNGUtil.CONFIG_ANNOTATIONS_FQN))) { for (List proxies : started.values()) { if (proxies != null) { for (TestProxy proxy : proxies) { @@ -283,7 +286,8 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn if (failedToStart != null) { failedToStart.addChild(testCase); failedToStart.setTearDownFailure(true); - } else { + } + else { failedToStart = testCase; } } @@ -294,7 +298,8 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn if (result.getResult() == MessageHelper.FAILED_TEST) { myStatusLine.setStatusColor(ColorProgressBar.RED); myStatus = MessageHelper.FAILED_TEST; - } else if (result.getResult() == MessageHelper.SKIPPED_TEST && myStatus == MessageHelper.PASSED_TEST) { + } + else if (result.getResult() == MessageHelper.SKIPPED_TEST && myStatus == MessageHelper.PASSED_TEST) { myStatus = MessageHelper.SKIPPED_TEST; } myStatusLine.setFraction((double)count / total); @@ -393,6 +398,11 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn return tree; } + @Override + public TestTreeBuilder getTreeBuilder() { + return treeBuilder; + } + public boolean hasTestSuites() { return rootNode.getChildren().size() > 0; }