Merge remote-tracking branch 'origin/master'

This commit is contained in:
Vladimir.Orlov
2015-04-16 07:21:40 +03:00
55 changed files with 880 additions and 286 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -240,7 +240,14 @@ public class DebuggerManagerImpl extends DebuggerManagerEx implements Persistent
}
});
DebuggerSession session = new DebuggerSession(environment.getSessionName(), debugProcess);
final ExecutionResult executionResult = session.attach(environment);
ExecutionResult executionResult;
try {
executionResult = session.attach(environment);
}
catch (ExecutionException e) {
session.dispose();
throw e;
}
if (executionResult == null) {
return null;
}
@@ -30,6 +30,7 @@ import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.testframework.sm.runner.SMTRunnerConsoleProperties;
import org.jetbrains.annotations.Nullable;
import javax.swing.tree.TreeSelectionModel;
import java.util.Collection;
public abstract class JavaAwareTestConsoleProperties<T extends ModuleBasedConfiguration<JavaRunConfigurationModule> & CommonJavaRunConfigurationParameters> extends SMTRunnerConsoleProperties {
@@ -48,6 +49,11 @@ public abstract class JavaAwareTestConsoleProperties<T extends ModuleBasedConfig
return (T)super.getConfiguration();
}
@Override
protected int getSelectionMode() {
return TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION;
}
@Override
public boolean fixEmptySuite() {
return ResetConfigurationModuleAdapter.tryWithAnotherModule(getConfiguration(), isDebug());
@@ -82,7 +82,7 @@ public class ImportModuleAction extends AnAction {
}
public static List<Module> createFromWizard(@Nullable Project project, AbstractProjectWizard wizard) {
if (project == null && wizard.getStepCount() > 0) {
if (project == null) {
Project newProject = NewProjectUtil.createFromWizard(wizard, null);
return newProject == null ? Collections.<Module>emptyList() : Arrays.asList(ModuleManager.getInstance(newProject).getModules());
}
@@ -94,7 +94,6 @@ public class ImportModuleAction extends AnAction {
return Collections.singletonList(module);
}
else {
assert project != null;
return projectBuilder.commit(project);
}
}
@@ -136,8 +136,9 @@ public class ConfigurationsTest extends BaseConfigurationTestCase {
JUnitConfiguration configuration = createConfiguration(testA);
JavaParameters parameters = checkCanRun(configuration);
CHECK.empty(parameters.getVMParametersList().getList());
final SegmentedOutputStream notifications = new SegmentedOutputStream(System.out);
assertTrue(JUnitStarter.checkVersion(parameters.getProgramParametersList().getArray(),
new SegmentedOutputStream(System.out)));
new PrintStream(notifications)));
assertTrue(parameters.getProgramParametersList().getList().contains(testA.getQualifiedName()));
assertEquals(JUnitStarter.class.getName(), parameters.getMainClass());
assertEquals(myJdk.getHomeDirectory().getPresentableUrl(), parameters.getJdkPath());
@@ -54,7 +54,7 @@ public class FCTSBackedLighterAST extends LighterAST {
}
LighterASTNode[] elements = into.get();
assert elements != null : myTreeStructure +" ("+parent+")";
return ContainerUtil.newArrayList(elements, 0, numKids);
return new LighterASTNodeList(numKids, elements);
}
public void disposeChildren(@NotNull List<LighterASTNode> children) {
@@ -19,6 +19,8 @@ import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.PossiblyDumbAware;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.registry.RegistryValue;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.util.containers.Stack;
@@ -38,7 +40,7 @@ import java.util.Set;
public abstract class CustomFoldingBuilder extends FoldingBuilderEx implements PossiblyDumbAware {
private CustomFoldingProvider myDefaultProvider;
private static final int MAX_LOOKUP_DEPTH = 10;
private final RegistryValue myMaxLookupDepth = Registry.get("custom.folding.max.lookup.depth");
private static final ThreadLocal<Set<ASTNode>> ourCustomRegionElements = new ThreadLocal<Set<ASTNode>>();
@NotNull
@@ -103,7 +105,7 @@ public abstract class CustomFoldingBuilder extends FoldingBuilderEx implements P
}
}
else {
if (currDepth < MAX_LOOKUP_DEPTH) {
if (currDepth < myMaxLookupDepth.asInteger()) {
addCustomFoldingRegionsRecursively(localFoldingStack, child, descriptors, currDepth + 1);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +37,8 @@ public class ListUtil {
boolean myIsEngaged = false;
public void mouseMoved(MouseEvent e) {
if (myIsEngaged && !UIUtil.isSelectionButtonDown(e)) {
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (myIsEngaged && !UIUtil.isSelectionButtonDown(e) && !(focusOwner instanceof JRootPane)) {
Point point = e.getPoint();
int index = list.locationToIndex(point);
list.putClientProperty(SELECTED_BY_MOUSE_EVENT, Boolean.TRUE);
@@ -45,6 +45,7 @@ import java.util.EventObject;
public class JBTable extends JTable implements ComponentWithEmptyText, ComponentWithExpandableItems<TableCell> {
public static final int PREFERRED_SCROLLABLE_VIEWPORT_HEIGHT_IN_ROWS = 7;
public static final int COLUMN_RESIZE_AREA_WIDTH = 3; // same as in BasicTableHeaderUI
private static final int DEFAULT_MIN_COLUMN_WIDTH = 15; // see TableColumn constructor javadoc
private final StatusText myEmptyText;
private final ExpandableItemsHandler<TableCell> myExpandableItemsHandler;
@@ -794,27 +795,6 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
});
}
protected int getExpandedColumnWidth(int columnToExpand) {
int expandedWidth = getPreferredHeaderWidth(columnToExpand);
for (int row = 0; row < getRowCount(); row++) {
TableCellRenderer cellRenderer = getCellRenderer(row, columnToExpand);
if (cellRenderer != null) {
Component c = JBTable.this.prepareRenderer(cellRenderer, row, columnToExpand);
expandedWidth = Math.max(expandedWidth, c.getPreferredSize().width);
}
}
return expandedWidth;
}
private int getPreferredHeaderWidth(int columnIdx) {
TableColumn column = getColumnModel().getColumn(columnIdx);
TableCellRenderer renderer = column.getHeaderRenderer();
renderer = renderer == null ? getDefaultRenderer() : renderer;
Object headerValue = column.getHeaderValue();
Component headerCellRenderer = renderer.getTableCellRendererComponent(JBTable.this, headerValue, false, false, -1, columnIdx);
return headerCellRenderer.getPreferredSize().width;
}
private int getColumnToPack(Point p) {
int viewColumnIdx = JBTable.this.columnAtPoint(p);
if (viewColumnIdx == -1) return -1;
@@ -836,6 +816,33 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
}
}
public int getExpandedColumnWidth(int columnToExpand) {
int expandedWidth = getPreferredHeaderWidth(columnToExpand);
for (int row = 0; row < getRowCount(); row++) {
TableCellRenderer cellRenderer = getCellRenderer(row, columnToExpand);
if (cellRenderer != null) {
Component c = prepareRenderer(cellRenderer, row, columnToExpand);
expandedWidth = Math.max(expandedWidth, c.getPreferredSize().width);
}
}
return expandedWidth;
}
private int getPreferredHeaderWidth(int columnIdx) {
TableColumn column = getColumnModel().getColumn(columnIdx);
TableCellRenderer renderer = column.getHeaderRenderer();
if (renderer == null) {
JTableHeader header = getTableHeader();
if (header == null) {
return DEFAULT_MIN_COLUMN_WIDTH;
}
renderer = header.getDefaultRenderer();
}
Object headerValue = column.getHeaderValue();
Component headerCellRenderer = renderer.getTableCellRendererComponent(this, headerValue, false, false, -1, columnIdx);
return headerCellRenderer.getPreferredSize().width;
}
/**
* JTable gets table data from model lazily - only for a table part to be shown.
* JBTable loads <i>all</i> the data on initialization to calculate cell size.
@@ -27,6 +27,7 @@ import com.intellij.ui.PopupHandler;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.speedSearch.ListWithFilter;
import com.intellij.ui.speedSearch.NameFilteringListModel;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
@@ -80,17 +81,44 @@ public class NewRecentProjectPanel extends RecentProjectPanel {
list.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
FlatWelcomeFrame frame = UIUtil.getParentOfType(FlatWelcomeFrame.class, list);
if (frame != null) {
FocusTraversalPolicy policy = frame.getFocusTraversalPolicy();
if (policy != null) {
Component next = policy.getComponentAfter(frame, list);
if (next != null) {
next.requestFocus();
Object selected = list.getSelectedValue();
final ProjectGroup group;
if (selected instanceof ProjectGroupActionGroup) {
group = ((ProjectGroupActionGroup)selected).getGroup();
} else {
group = null;
}
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_RIGHT) {
if (group != null) {
if (!group.isExpanded()) {
group.setExpanded(true);
ListModel model = ((NameFilteringListModel)list.getModel()).getOriginalModel();
int index = list.getSelectedIndex();
RecentProjectsWelcomeScreenActionBase.rebuildRecentProjectDataModel((DefaultListModel)model);
list.setSelectedIndex(group.getProjects().isEmpty() ? index : index + 1);
}
} else {
FlatWelcomeFrame frame = UIUtil.getParentOfType(FlatWelcomeFrame.class, list);
if (frame != null) {
FocusTraversalPolicy policy = frame.getFocusTraversalPolicy();
if (policy != null) {
Component next = policy.getComponentAfter(frame, list);
if (next != null) {
next.requestFocus();
}
}
}
}
} else if (keyCode == KeyEvent.VK_LEFT ) {
if (group != null && group.isExpanded()) {
group.setExpanded(false);
int index = list.getSelectedIndex();
ListModel model = ((NameFilteringListModel)list.getModel()).getOriginalModel();
RecentProjectsWelcomeScreenActionBase.rebuildRecentProjectDataModel((DefaultListModel)model);
list.setSelectedIndex(index);
}
}
}
});
@@ -186,7 +214,7 @@ public class NewRecentProjectPanel extends RecentProjectPanel {
return new JPanel() {
{
setLayout(new BorderLayout());
setBackground(UIUtil.getListBackground(isSelected));
setBackground(back);
boolean isGroup = value instanceof ProjectGroupActionGroup;
boolean isInsideGroup = false;
@@ -235,7 +235,8 @@ public class RecentProjectPanel extends JPanel {
boolean myIsEngaged = false;
@Override
public void mouseMoved(MouseEvent e) {
if (myIsEngaged && !UIUtil.isSelectionButtonDown(e)) {
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (myIsEngaged && !UIUtil.isSelectionButtonDown(e) && !(focusOwner instanceof JRootPane)) {
Point point = e.getPoint();
int index = myList.locationToIndex(point);
myList.setSelectedIndex(index);
@@ -35,7 +35,7 @@ import java.util.List;
*/
public abstract class RecentProjectsWelcomeScreenActionBase extends DumbAwareAction {
@Nullable
public DefaultListModel getDataModel(AnActionEvent e) {
public static DefaultListModel getDataModel(AnActionEvent e) {
final JList list = getList(e);
if (list != null) {
ListModel model = list.getModel();
@@ -50,7 +50,7 @@ public abstract class RecentProjectsWelcomeScreenActionBase extends DumbAwareAct
}
@NotNull
public List<AnAction> getSelectedElements(AnActionEvent e) {
public static List<AnAction> getSelectedElements(AnActionEvent e) {
final JList list = getList(e);
final List<AnAction> actions = new ArrayList<AnAction>();
if (list != null) {
@@ -64,7 +64,7 @@ public abstract class RecentProjectsWelcomeScreenActionBase extends DumbAwareAct
}
@Nullable
public JList getList(AnActionEvent e) {
public static JList getList(AnActionEvent e) {
final Component component = e.getData(PlatformDataKeys.CONTEXT_COMPONENT);
if (component instanceof JList) {
return (JList)component;
@@ -72,7 +72,7 @@ public abstract class RecentProjectsWelcomeScreenActionBase extends DumbAwareAct
return null;
}
public boolean hasGroupSelected(AnActionEvent e) {
public static boolean hasGroupSelected(AnActionEvent e) {
for (AnAction action : getSelectedElements(e)) {
if (action instanceof ProjectGroupActionGroup) {
return true;
@@ -81,14 +81,18 @@ public abstract class RecentProjectsWelcomeScreenActionBase extends DumbAwareAct
return false;
}
public void rebuildRecentProjectsList(AnActionEvent e) {
public static void rebuildRecentProjectsList(AnActionEvent e) {
final DefaultListModel model = getDataModel(e);
if (model != null) {
model.clear();
for (AnAction action : RecentProjectsManager.getInstance().getRecentProjectsActions(false, FlatWelcomeFrame.isUseProjectGroups())) {
//noinspection unchecked
model.addElement(action);
}
rebuildRecentProjectDataModel(model);
}
}
public static void rebuildRecentProjectDataModel(@NotNull DefaultListModel model) {
model.clear();
for (AnAction action : RecentProjectsManager.getInstance().getRecentProjectsActions(false, FlatWelcomeFrame.isUseProjectGroups())) {
//noinspection unchecked
model.addElement(action);
}
}
}
@@ -555,7 +555,7 @@
</group>
<group id="WelcomeScreenRecentProjectActionGroup">
<action id="WelcomeScreen.OpenSelected" class="com.intellij.openapi.wm.impl.welcomeScreen.OpenSelectedProjectsAction"/>
<action id="WelcomeScreen.OpenSelected" class="com.intellij.openapi.wm.impl.welcomeScreen.OpenSelectedProjectsAction" text="Open Selected"/>
<action id="WelcomeScreen.NewGroup" class="com.intellij.openapi.wm.impl.welcomeScreen.CreateNewProjectGroupAction" text="New Project Group"/>
<group id="WelcomeScreen.MoveToGroup" class="com.intellij.openapi.wm.impl.welcomeScreen.MoveProjectToGroupActionGroup" text="Move To Group" popup="true"/>
</group>
@@ -37,9 +37,11 @@ import com.intellij.util.config.ToggleBooleanProperty;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerManager;
import org.intellij.lang.annotations.JdkConstants;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.tree.TreeSelectionModel;
import java.util.List;
import java.util.Map;
@@ -195,4 +197,9 @@ public abstract class TestConsoleProperties extends StoringPropertyContainer imp
Icon icon = AllIcons.RunConfigurations.IncludeNonStartedTests_Rerun;
return new ToggleBooleanProperty(text, null, icon, this, INCLUDE_NON_STARTED_IN_RERUN_FAILED);
}
@JdkConstants.TreeSelectionMode
protected int getSelectionMode() {
return TreeSelectionModel.SINGLE_TREE_SELECTION;
}
}
@@ -21,7 +21,6 @@
package com.intellij.execution.testframework;
import com.intellij.execution.Location;
import com.intellij.execution.testframework.actions.ViewAssertEqualsDiffAction;
import com.intellij.ide.CopyProvider;
import com.intellij.ide.actions.CopyReferenceAction;
import com.intellij.openapi.Disposable;
@@ -35,12 +34,14 @@ import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.EditSourceOnDoubleClickHandler;
import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.tree.TreeUtil;
import org.intellij.lang.annotations.JdkConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.plaf.TreeUI;
import javax.swing.tree.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import java.awt.datatransfer.StringSelection;
import java.util.ArrayList;
import java.util.List;
@@ -68,7 +69,7 @@ public abstract class TestTreeView extends Tree implements DataProvider, CopyPro
public void attachToModel(final TestFrameworkRunningModel model) {
setModel(new DefaultTreeModel(new DefaultMutableTreeNode(model.getRoot())));
getSelectionModel().setSelectionMode(getSelectionMode());
getSelectionModel().setSelectionMode(model.getProperties().getSelectionMode());
myModel = model;
Disposer.register(myModel, myModel.getRoot());
Disposer.register(myModel, new Disposable() {
@@ -169,9 +170,4 @@ public abstract class TestTreeView extends Tree implements DataProvider, CopyPro
TreeUtil.installActions(this);
PopupHandler.installPopupHandler(this, IdeActions.GROUP_TESTTREE_POPUP, ActionPlaces.TESTTREE_VIEW_POPUP);
}
@JdkConstants.TreeSelectionMode
protected int getSelectionMode() {
return TreeSelectionModel.SINGLE_TREE_SELECTION;
}
}
@@ -575,3 +575,6 @@ search.everywhere.pattern.checking.description=Avoid searching classes and symbo
idea.concurrent.scanning.files.to.index=true
welcome.screen.project.grouping.enabled=true
welcome.screen.project.grouping.enabled.description=Allows to group recent projects
custom.folding.max.lookup.depth=50
custom.folding.max.lookup.depth.description=Max lookup depth for custom folding comments in a PSI tree.
@@ -149,6 +149,9 @@
<localInspection groupPath="Java" language="JAVA" shortName="ArrayHashCode" bundle="com.siyeh.InspectionGadgetsBundle" key="array.hash.code.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.probable.bugs" enabledByDefault="true" level="WARNING"
implementationClass="com.siyeh.ig.bugs.ArrayHashCodeInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="ArrayObjectsEquals" bundle="com.siyeh.InspectionGadgetsBundle"
key="array.objects.equals.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.probable.bugs"
enabledByDefault="true" level="WARNING" implementationClass="com.siyeh.ig.bugs.ArrayObjectsEqualsInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="AssertWithSideEffects" bundle="com.siyeh.InspectionGadgetsBundle"
key="assert.with.side.effects.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.probable.bugs" enabledByDefault="true" level="WARNING"
@@ -2154,4 +2154,7 @@ dangling.javadoc.convert.quickfix=Replace with block comment
dangling.javadoc.delete.quickfix=Remove dangling comment
equals.replaceable.by.objects.call.display.name='equals()' expression replaceable by 'Objects.equals()' expression
equals.replaceable.by.objects.call.problem.descriptor=<code>#ref</code> replaceable by 'Objects.equals()' expression #loc
equals.replaceable.by.objects.call.quickfix=Replace with 'Objects.equals()' expression
equals.replaceable.by.objects.call.quickfix=Replace with 'Objects.equals()' expression
array.objects.equals.display.name='Objects.equals()' called on arrays
array.objects.equals.problem.descriptor=<code>Objects.#ref()</code> on arrays should probably be 'Arrays.equals()' #loc
array.objects.deep.equals.problem.descriptor=<code>Objects.#ref()</code> on arrays should probably be 'Arrays.deepEquals()' #loc
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 Dave Griffith, Bas Leijdekkers
* Copyright 2011-2015 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -79,7 +79,7 @@ public class ArrayEqualityInspection extends BaseInspection {
@NotNull
@Override
public String getFamilyName() {
return "Replace with implicit equals";
return InspectionGadgetsBundle.message("replace.with.arrays.equals");
}
@Override
@@ -0,0 +1,149 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.bugs;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.siyeh.HardcodedMethodConstants;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.PsiReplacementUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
*/
public class ArrayObjectsEqualsInspection extends BaseInspection {
@Nls
@NotNull
@Override
public String getDisplayName() {
return InspectionGadgetsBundle.message("array.objects.equals.display.name");
}
@NotNull
@Override
protected String buildErrorString(Object... infos) {
final boolean deep = ((Boolean)infos[0]).booleanValue();
return deep
? InspectionGadgetsBundle.message("array.objects.deep.equals.problem.descriptor")
: InspectionGadgetsBundle.message("array.objects.equals.problem.descriptor");
}
@Override
public boolean isEnabledByDefault() {
return true;
}
@Nullable
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
final boolean deep = ((Boolean)infos[0]).booleanValue();
return new ArrayObjectsEqualsFix(deep);
}
private static class ArrayObjectsEqualsFix extends InspectionGadgetsFix {
private final boolean myDeep;
public ArrayObjectsEqualsFix(boolean deep) {
myDeep = deep;
}
@Nls
@NotNull
@Override
public String getName() {
return myDeep ?
InspectionGadgetsBundle.message("replace.with.arrays.deep.equals") :
InspectionGadgetsBundle.message("replace.with.arrays.equals");
}
@NotNull
@Override
public String getFamilyName() {
return InspectionGadgetsBundle.message("replace.with.arrays.equals");
}
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement().getParent().getParent();
if (!(element instanceof PsiMethodCallExpression)) {
return;
}
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)element;
final StringBuilder newExpression = new StringBuilder("java.util.Arrays.");
if (myDeep) {
newExpression.append("deepEquals");
}
else {
newExpression.append("equals");
}
newExpression.append(methodCallExpression.getArgumentList().getText());
PsiReplacementUtil.replaceExpressionAndShorten(methodCallExpression, newExpression.toString());
}
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new ArrayObjectsEqualsVisitor();
}
private static class ArrayObjectsEqualsVisitor extends BaseInspectionVisitor {
@Override
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final String methodName = methodExpression.getReferenceName();
if (!HardcodedMethodConstants.EQUALS.equals(methodName)) {
return;
}
final PsiExpressionList argumentList = expression.getArgumentList();
final PsiExpression[] expressions = argumentList.getExpressions();
if (expressions.length != 2) {
return;
}
final PsiExpression argument1 = expressions[0];
final PsiType type1 = argument1.getType();
if (!(type1 instanceof PsiArrayType)) {
return;
}
final PsiExpression argument2 = expressions[1];
final PsiType type2 = argument2.getType();
if (!(type2 instanceof PsiArrayType)) {
return;
}
final int dimensions = type1.getArrayDimensions();
if (dimensions != type2.getArrayDimensions()) {
return;
}
final PsiMethod method = expression.resolveMethod();
if (method == null) {
return;
}
final PsiClass containingClass = method.getContainingClass();
if (containingClass == null || !"java.util.Objects".equals(containingClass.getQualifiedName())) {
return;
}
registerMethodCallError(expression, Boolean.valueOf(dimensions > 1));
}
}
}
@@ -1,7 +1,7 @@
<html>
<body>
Reports any use of <b>==</b> to test for Array equality,
rather than the <b>"java.util.Arrays.equals()"</b> method.
Reports any use of <b>==</b> or <b>!=</b> to test for array equality,
rather than the <b>java.util.Arrays.equals()</b> method.
<!-- tooltip end -->
<p>
</body>
@@ -0,0 +1,11 @@
<html>
<body>
Reports <b>java.util.Objects.equals()</b> called on two arrays.
Calling <b>java.util.Objects.equals()</b> with array arguments compares identity and is equivalent to using <b>==</b>.
Use <b>Arrays.equals()</b> to compare the contents of two arrays
or <b>Arrays.deepEquals()</b> to compare the contents of two multi-dimensional arrays.
<!-- tooltip end -->
<p>
<small>New in 15</small>
</body>
</html>
@@ -1,7 +1,7 @@
<html>
<body>
Reports any use of <b>==</b> to test for Number equality,
rather than the <b>".equals()"</b> method. With auto-boxing it is easy
Reports any use of <b>==</b> or <b>!=</b> to test for Number equality,
rather than the <b>equals()</b> method. With auto-boxing it is easy
to make the mistake of comparing two Integer (or other subclass of java.lang.Number) objects instead
of two ints.
<!-- tooltip end -->
@@ -1,7 +1,7 @@
<html>
<body>
Reports any use of <b>==</b>
to test for Object equality, rather than the <b>".equals()"</b> method.
Reports any use of <b>==</b> or <b>!=</b>
to test for Object equality, rather than the <b>equals()</b> method.
Note that comparison of Strings or Numbers using <b>==</b> is not reported by this
inspection, nor is the comparison of an object to <b>null</b> using
<b>==</b>, or the comparison of two array objects.
@@ -1,7 +1,7 @@
<html>
<body>
Reports any use of <b>==</b> to test for String equality,
rather than the <b>".equals()"</b> method.
Reports any use of <b>==</b> or <b>!=</b> to test for String equality,
rather than the <b>equals()</b> method.
<!-- tooltip end -->
<p>
@@ -0,0 +1,14 @@
class ArrayObjectsEquals {
boolean one(String[] ss1, String[] ss2) {
return java.util.Objects.<warning descr="'Objects.equals()' on arrays should probably be 'Arrays.equals()'">equals</warning>(ss1, ss2);
}
boolean two(String[][] ss1, String[][] ss2) {
return java.util.Objects.<warning descr="'Objects.equals()' on arrays should probably be 'Arrays.deepEquals()'">equals</warning>(ss1, ss2);
}
boolean noWarn(String s1, String[] ss2) {
return java.util.Objects.equals(s1, ss2);
}
}
@@ -0,0 +1,47 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.bugs;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
import junit.framework.TestCase;
/**
* @author Bas Leijdekkers
*/
public class ArrayObjectsEqualsInspectionTest extends LightInspectionTestCase {
public void testArrayObjectsEquals() {
doTest();
}
@Override
protected InspectionProfileEntry getInspection() {
return new ArrayObjectsEqualsInspection();
}
@Override
protected String[] getEnvironmentClasses() {
return new String[]{
"package java.util;" +
"public class Objects {" +
" public static boolean equals(Object a, Object b) {" +
" return (a == b) || (a != null && a.equals(b));" +
" }" +
"}"
};
}
}
@@ -48,7 +48,7 @@ public class LineEndingsManager extends FileDocumentManagerAdapter {
@Override
public void run() {
IdeFrame frame = WindowManager.getInstance().getIdeFrame(myProject);
StatusBar statusBar = frame.getStatusBar();
StatusBar statusBar = frame != null ? frame.getStatusBar() : null;
StatusBarWidget widget = statusBar != null ? statusBar.getWidget("LineSeparator") : null;
if (widget instanceof LineSeparatorPanel) {
@@ -29,6 +29,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcsUtil.VcsFileUtil;
import git4idea.GitUtil;
import git4idea.GitVcs;
import git4idea.branch.GitBranchUtil;
import git4idea.i18n.GitBundle;
import git4idea.repo.GitRepository;
import git4idea.repo.GitRepositoryManager;
@@ -57,22 +58,8 @@ public abstract class GitRepositoryAction extends DumbAwareAction {
GitVcs vcs = GitVcs.getInstance(project);
final List<VirtualFile> roots = getGitRoots(project, vcs);
if (roots == null) return;
// get default root
final VirtualFile[] vFiles = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY);
VirtualFile defaultRootVar = null;
if (vFiles != null) {
for (VirtualFile file : vFiles) {
final VirtualFile root = GitUtil.gitRootOrNull(file);
if (root != null) {
defaultRootVar = root;
break;
}
}
}
if (defaultRootVar == null) {
defaultRootVar = roots.get(0);
}
final VirtualFile defaultRoot = defaultRootVar;
final VirtualFile defaultRoot = getDefaultRoot(project, roots, e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY));
final Set<VirtualFile> affectedRoots = new HashSet<VirtualFile>();
String actionName = getActionName();
@@ -88,6 +75,20 @@ public abstract class GitRepositoryAction extends DumbAwareAction {
}
}
@NotNull
private static VirtualFile getDefaultRoot(@NotNull Project project, @NotNull List<VirtualFile> roots, @Nullable VirtualFile[] vFiles) {
if (vFiles != null) {
for (VirtualFile file : vFiles) {
VirtualFile root = GitUtil.gitRootOrNull(file);
if (root != null) {
return root;
}
}
}
GitRepository currentRepository = GitBranchUtil.getCurrentRepository(project);
return currentRepository != null ? currentRepository.getRoot() : roots.get(0);
}
protected final void runFinalTasks(Project project, GitVcs vcs, Set<VirtualFile> affectedRoots, String actionName,
List<VcsException> exceptions) {
VcsFileUtil.refreshFiles(project, affectedRoots);
@@ -21,14 +21,21 @@ import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.Cell;
import com.intellij.ui.TableSpeedSearch;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ListWithSelection;
import com.intellij.util.PairFunction;
import com.intellij.util.ui.ComboBoxTableCellRenderer;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import git4idea.GitUtil;
import git4idea.config.GitConfigUtil;
import git4idea.i18n.GitBundle;
import git4idea.util.StringScanner;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
@@ -53,7 +60,7 @@ public class GitRebaseEditor extends DialogWrapper {
/**
* The table that lists all commits
*/
private JTable myCommitsTable;
private JBTable myCommitsTable;
/**
* The move up button
*/
@@ -115,6 +122,7 @@ public class GitRebaseEditor extends DialogWrapper {
myTableModel.load(file);
myCommitsTable.setModel(myTableModel);
myCommitsTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
myCommitsTable.setIntercellSpacing(JBUI.emptySize());
final JComboBox editorComboBox = new JComboBox();
for (Object option : GitRebaseEntry.Action.values()) {
@@ -128,9 +136,9 @@ public class GitRebaseEditor extends DialogWrapper {
public void valueChanged(final ListSelectionEvent e) {
myViewButton.setEnabled(myCommitsTable.getSelectedRowCount() == 1);
final ListSelectionModel selectionModel = myCommitsTable.getSelectionModel();
myMoveUpButton.setEnabled( selectionModel.getMinSelectionIndex() > 0);
myMoveDownButton.setEnabled( selectionModel.getMaxSelectionIndex() != -1 &&
selectionModel.getMaxSelectionIndex() < myTableModel.myEntries.size() - 1);
myMoveUpButton.setEnabled(selectionModel.getMinSelectionIndex() > 0);
myMoveDownButton.setEnabled(selectionModel.getMaxSelectionIndex() != -1 &&
selectionModel.getMaxSelectionIndex() < myTableModel.myEntries.size() - 1);
}
});
myViewButton.addActionListener(new ActionListener() {
@@ -152,8 +160,37 @@ public class GitRebaseEditor extends DialogWrapper {
validateFields();
}
});
installSpeedSearch();
adjustColumnWidth(0);
adjustColumnWidth(1);
init();
}
private void installSpeedSearch() {
new TableSpeedSearch(myCommitsTable, new PairFunction<Object, Cell, String>() {
@Nullable
@Override
public String fun(Object o, Cell cell) {
return cell.column == 0 ? null : String.valueOf(o);
}
});
}
@Nullable
@Override
public JComponent getPreferredFocusedComponent() {
return myCommitsTable;
}
private void adjustColumnWidth(int columnIndex) {
int contentWidth = myCommitsTable.getExpandedColumnWidth(columnIndex) + UIUtil.DEFAULT_HGAP;
TableColumn column = myCommitsTable.getColumnModel().getColumn(columnIndex);
column.setMaxWidth(contentWidth);
column.setPreferredWidth(contentWidth);
}
/**
* Validate fields
*/
@@ -71,7 +71,7 @@ public class GroovyConsoleStateService implements PersistentStateComponent<Groov
final Entry e = new Entry();
e.url = file.getUrl();
e.moduleName = module == null ? "" : module.getName();
e.title = module == null ? "" : GroovyConsoleUtil.getTitle(module);
e.title = pair == null ? "" : pair.second;
result.list.add(e);
}
return result;
@@ -22,7 +22,6 @@ import com.intellij.execution.testframework.TestTreeView;
import org.jetbrains.annotations.NotNull;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
public class JUnitTestTreeView extends TestTreeView {
@@ -42,9 +41,4 @@ public class JUnitTestTreeView extends TestTreeView {
final boolean hasFocus) {
return Formatters.printTest(TestProxyClient.from(value));
}
@Override
protected int getSelectionMode() {
return TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION;
}
}
@@ -17,15 +17,14 @@ package com.intellij.junit3;
import com.intellij.rt.execution.junit.*;
import com.intellij.rt.execution.junit.segments.OutputObjectRegistry;
import com.intellij.rt.execution.junit.segments.SegmentedOutputStream;
import com.intellij.rt.execution.junit.segments.PacketProcessor;
import jetbrains.buildServer.messages.serviceMessages.ServiceMessage;
import jetbrains.buildServer.messages.serviceMessages.ServiceMessageTypes;
import junit.framework.*;
import junit.textui.ResultPrinter;
import junit.textui.TestRunner;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
import java.util.*;
public class JUnit3IdeaTestRunner extends TestRunner implements IdeaTestRunner {
private TestListener myTestsListener;
@@ -39,7 +38,7 @@ public class JUnit3IdeaTestRunner extends TestRunner implements IdeaTestRunner {
public int startRunnerWithArgs(String[] args, ArrayList listeners, String name, int count, boolean sendTree) {
myListeners = listeners;
mySendTree = sendTree;
mySendTree = sendTree && !(myTestsListener instanceof SMTestListener);
if (sendTree) {
setPrinter(new TimeSender(myRegistry));
}
@@ -69,9 +68,13 @@ public class JUnit3IdeaTestRunner extends TestRunner implements IdeaTestRunner {
super.runFailed(message);
}
public void setStreams(SegmentedOutputStream segmentedOut, SegmentedOutputStream segmentedErr, int lastIdx) {
myRegistry = new JUnit3OutputObjectRegistry(segmentedOut, lastIdx);
myTestsListener = new TestResultsSender(myRegistry);
public void setStreams(Object segmentedOut, Object segmentedErr, int lastIdx) {
if (JUnitStarter.SM_RUNNER) {
myTestsListener = new SMTestListener();
} else {
myRegistry = new JUnit3OutputObjectRegistry((PacketProcessor)segmentedOut, lastIdx);
myTestsListener = new TestResultsSender(myRegistry);
}
}
public Object getTestToStart(String[] args, String name) {
@@ -138,7 +141,11 @@ public class JUnit3IdeaTestRunner extends TestRunner implements IdeaTestRunner {
System.err.println("Internal Error occured.");
e.printStackTrace(System.err);
}
return super.doRun(suite, wait);
final TestResult testResult = super.doRun(suite, wait);
if (myTestsListener instanceof SMTestListener) {
((SMTestListener)myTestsListener).finishSuite();
}
return testResult;
}
static Vector getTestCasesOf(Test test) {
@@ -163,4 +170,53 @@ public class JUnit3IdeaTestRunner extends TestRunner implements IdeaTestRunner {
super(DeafStream.DEAF_PRINT_STREAM);
}
}
private static class SMTestListener implements TestListener {
private String myClassName;
public void addError(Test test, Throwable e) {
final String failureMessage = e.getMessage();
final Map attrs = new HashMap();
attrs.put("name", getMethodName(test));
attrs.put("message", failureMessage != null ? failureMessage : "");
System.out.println(ServiceMessage.asString(ServiceMessageTypes.TEST_FAILED, attrs));
}
private static String getMethodName(Test test) {
final String toString = test.toString();
final int braceIdx = toString.indexOf("(");
return braceIdx > 0 ? toString.substring(0, braceIdx) : toString;
}
private static String getClassName(Test test) {
final String toString = test.toString();
final int braceIdx = toString.indexOf("(");
return braceIdx > 0 && toString.endsWith(")") ? toString.substring(braceIdx + 1, toString.length() - 1) : null;
}
public void addFailure(Test test, AssertionFailedError e) {
addError(test, e);
}
public void endTest(Test test) {
System.out.println("\n##teamcity[testFinished name=\'" + getMethodName(test) + "\']");
}
public void startTest(Test test) {
final String className = getClassName(test);
if (className != null && !className.equals(myClassName)) {
finishSuite();
myClassName = className;
System.out.println("##teamcity[testSuiteStarted name =\'" + myClassName + "\' locationHint=\'java:suite://" + className + "\']");
}
final String methodName = getMethodName(test);
System.out.println("##teamcity[testStarted name=\'" + methodName + "\' locationHint=\'java:test://" + className + "." + methodName + "\']");
}
protected void finishSuite() {
if (myClassName != null) {
System.out.println("##teamcity[testSuiteFinished name=\'" + myClassName + "\']");
}
}
}
}
@@ -17,8 +17,7 @@ package com.intellij.junit4;
import com.intellij.rt.execution.junit.*;
import com.intellij.rt.execution.junit.segments.OutputObjectRegistry;
import com.intellij.rt.execution.junit.segments.Packet;
import com.intellij.rt.execution.junit.segments.SegmentedOutputStream;
import com.intellij.rt.execution.junit.segments.PacketProcessor;
import org.junit.internal.requests.ClassRequest;
import org.junit.internal.requests.FilterRequest;
import org.junit.runner.*;
@@ -183,11 +182,11 @@ public class JUnit4IdeaTestRunner implements IdeaTestRunner {
}
public void setStreams(SegmentedOutputStream segmentedOut, SegmentedOutputStream segmentedErr, int lastIdx) {
public void setStreams(Object segmentedOut, Object segmentedErr, int lastIdx) {
if (JUnitStarter.SM_RUNNER) {
myTestsListener = new SMTestSender();
} else {
myRegistry = new JUnit4OutputObjectRegistry(segmentedOut, lastIdx);
myRegistry = new JUnit4OutputObjectRegistry((PacketProcessor)segmentedOut, lastIdx);
myTestsListener = new JUnit4TestResultsSender(myRegistry);
}
}
@@ -46,15 +46,15 @@ class SMTestSender extends RunListener {
public void testRunStarted(Description description) throws Exception {
myCurrentClassName = myIgnoreTopSuite ? description.toString() : null;
System.out.println("##teamcity[enteredTheMatrix]");
System.out.println("##teamcity[enteredTheMatrix]\n");
}
public void testRunFinished(Result result) throws Exception {
if (myParamName != null) {
System.out.println("##teamcity[testSuiteFinished name=\'" + myParamName + "\']");
System.out.println("##teamcity[testSuiteFinished name=\'" + myParamName + "\']\n");
}
if (myCurrentClassName != null) {
System.out.println("##teamcity[testSuiteFinished name=\'" + myCurrentClassName + "\']");
System.out.println("##teamcity[testSuiteFinished name=\'" + myCurrentClassName + "\']\n");
}
}
@@ -87,7 +87,7 @@ class SMTestSender extends RunListener {
}
public void testFinished(Description description) throws Exception {
System.out.println("##teamcity[testFinished name=\'" + JUnit4ReflectionUtil.getMethodName(description) + "\']");
System.out.println("\n##teamcity[testFinished name=\'" + JUnit4ReflectionUtil.getMethodName(description) + "\']");
}
public void testFailure(Failure failure) throws Exception {
@@ -21,7 +21,6 @@
package com.intellij.rt.execution.junit;
import com.intellij.rt.execution.junit.segments.OutputObjectRegistry;
import com.intellij.rt.execution.junit.segments.SegmentedOutputStream;
import java.util.ArrayList;
import java.util.List;
@@ -29,7 +28,7 @@ import java.util.List;
public interface IdeaTestRunner {
int startRunnerWithArgs(String[] args, ArrayList listeners, String name, int count, boolean sendTree);
void setStreams(SegmentedOutputStream segmentedOut, SegmentedOutputStream segmentedErr, int lastIdx);
void setStreams(Object segmentedOut, Object segmentedErr, int lastIdx);
Object getTestToStart(String[] args, String name);
List getChildTests(Object description);
@@ -72,8 +72,8 @@ public class JUnitForkedStarter {
String[] args,
boolean isJUnit4,
List listeners,
String params, SegmentedOutputStream out,
SegmentedOutputStream err,
String params, Object out,
Object err,
String forkMode,
String path) throws Exception {
final List parameters = new ArrayList();
@@ -178,8 +178,8 @@ public class JUnitForkedStarter {
private static int processChildren(boolean isJUnit4,
List listeners,
SegmentedOutputStream out,
SegmentedOutputStream err,
Object out,
Object err,
List parameters,
IdeaTestRunner testRunner,
List children,
@@ -206,8 +206,8 @@ public class JUnitForkedStarter {
private static int runChild(boolean isJUnit4,
List listeners,
SegmentedOutputStream out,
SegmentedOutputStream err,
Object out,
Object err,
List parameters,
String description,
File workingDir,
@@ -265,7 +265,9 @@ public class JUnitForkedStarter {
final Process exec = builder.createProcess();
final int result = exec.waitFor();
ForkedVMWrapper.readWrapped(testOutputPath, out.getPrintStream(), err.getPrintStream());
ForkedVMWrapper.readWrapped(testOutputPath,
JUnitStarter.SM_RUNNER ? ((PrintStream)out) : ((SegmentedOutputStream)out).getPrintStream(),
JUnitStarter.SM_RUNNER ? ((PrintStream)err) : ((SegmentedOutputStream)err).getPrintStream());
return result;
}
}
@@ -51,8 +51,6 @@ public class JUnitStarter {
}
public static void main(String[] args) throws IOException {
SegmentedOutputStream out = new SegmentedOutputStream(System.out);
SegmentedOutputStream err = new SegmentedOutputStream(System.err);
Vector argList = new Vector();
for (int i = 0; i < args.length; i++) {
String arg = args[i];
@@ -64,18 +62,16 @@ public class JUnitStarter {
boolean isJUnit4 = processParameters(argList, listeners, name);
if (!canWorkWithJUnitVersion(err, isJUnit4)) {
err.flush();
if (!canWorkWithJUnitVersion(System.err, isJUnit4)) {
System.exit(-3);
}
if (!checkVersion(args, err)) {
err.flush();
if (!checkVersion(args, System.err)) {
System.exit(-3);
}
String[] array = new String[argList.size()];
argList.copyInto(array);
int exitCode = prepareStreamsAndStart(array, isJUnit4, listeners, name[0], out, err);
int exitCode = prepareStreamsAndStart(array, isJUnit4, listeners, name[0]);
System.exit(exitCode);
}
@@ -171,15 +167,14 @@ public class JUnitStarter {
}
}
public static boolean checkVersion(String[] args, SegmentedOutputStream notifications) {
public static boolean checkVersion(String[] args, PrintStream printStream) {
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.startsWith(IDE_VERSION)) {
int ideVersion = Integer.parseInt(arg.substring(IDE_VERSION.length(), arg.length()));
if (ideVersion != VERSION) {
PrintStream stream = new PrintStream(notifications);
stream.println("Wrong agent version: " + VERSION + ". IDE expects version: " + ideVersion);
stream.flush();
printStream.println("Wrong agent version: " + VERSION + ". IDE expects version: " + ideVersion);
printStream.flush();
return false;
} else
return true;
@@ -188,18 +183,17 @@ public class JUnitStarter {
return false;
}
private static boolean canWorkWithJUnitVersion(OutputStream notifications, boolean isJUnit4) {
final PrintStream stream = new PrintStream(notifications);
private static boolean canWorkWithJUnitVersion(PrintStream printStream, boolean isJUnit4) {
try {
junitVersionChecks(isJUnit4);
} catch (Throwable e) {
stream.println("!!! JUnit version 3.8 or later expected:");
stream.println();
e.printStackTrace(stream);
stream.flush();
printStream.println("!!! JUnit version 3.8 or later expected:");
printStream.println();
e.printStackTrace(printStream);
printStream.flush();
return false;
} finally {
stream.flush();
printStream.flush();
}
return true;
}
@@ -214,20 +208,22 @@ public class JUnitStarter {
private static int prepareStreamsAndStart(String[] args,
final boolean isJUnit4,
ArrayList listeners,
String name,
SegmentedOutputStream out,
SegmentedOutputStream err) {
String name) {
PrintStream oldOut = System.out;
PrintStream oldErr = System.err;
try {
System.setOut(new PrintStream(out));
System.setErr(new PrintStream(err));
IdeaTestRunner testRunner = (IdeaTestRunner)getAgentClass(isJUnit4).newInstance();
Object out = SM_RUNNER ? System.out : (Object)new SegmentedOutputStream(System.out);
Object err = SM_RUNNER ? System.err : (Object)new SegmentedOutputStream(System.err);
if (!SM_RUNNER) {
System.setOut(new PrintStream((OutputStream)out));
System.setErr(new PrintStream((OutputStream)err));
}
if (ourCommandFileName != null) {
if (!"none".equals(ourForkMode) || ourWorkingDirs != null && new File(ourWorkingDirs).length() > 0) {
return JUnitForkedStarter.startForkedVMs(ourWorkingDirs, args, isJUnit4, listeners, name, out, err, ourForkMode, ourCommandFileName);
}
}
IdeaTestRunner testRunner = (IdeaTestRunner)getAgentClass(isJUnit4).newInstance();
testRunner.setStreams(out, err, 0);
return testRunner.startRunnerWithArgs(args, listeners, name, ourCount, !SM_RUNNER);
}
@@ -0,0 +1,119 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.lang.properties.editor;
import com.intellij.lang.properties.IProperty;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiTreeChangeAdapter;
import com.intellij.psi.PsiTreeChangeEvent;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.hash.HashMap;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* @author Dmitry Batkovich
*/
public class PropertiesAnchorizer {
private final static Logger LOG = Logger.getInstance(PropertiesAnchorizer.class);
private final Map<IProperty, PropertyAnchor> myAnchors = new HashMap<IProperty, PropertyAnchor>();
public PropertiesAnchorizer(Project project) {
PsiManager.getInstance(project).addPsiTreeChangeListener(new PsiTreeChangeAdapter() {
@Override
public void childRemoved(@NotNull PsiTreeChangeEvent event) {
final PsiElement removed = event.getChild();
if (removed instanceof IProperty) {
myAnchors.remove(removed);
}
}
});
}
public static final class PropertyAnchor {
private final Collection<IProperty> myProperties;
public PropertyAnchor(Collection<IProperty> properties) {
myProperties = new ArrayList<IProperty>(properties);
}
@NotNull
public String getName() {
return getRepresentative().getName();
}
@NotNull
public IProperty getRepresentative() {
return ContainerUtil.getFirstItem(myProperties);
}
@Override
public String toString() {
return "PropertyAnchor:" + getName();
}
private void addProperties(final Collection<IProperty> properties) {
myProperties.addAll(properties);
}
}
@NotNull
public PropertyAnchor get(IProperty property) {
final PropertyAnchor anchor = myAnchors.get(property);
LOG.assertTrue(anchor != null);
return anchor;
}
public PropertyAnchor createOrUpdate(final Collection<IProperty> properties) {
LOG.assertTrue(!properties.isEmpty());
final List<IProperty> propertiesWithoutAnchor = new SmartList<IProperty>();
PropertyAnchor representativeAnchor = null;
for (IProperty property : properties) {
final PropertyAnchor anchor = myAnchors.get(property);
if (anchor == null) {
propertiesWithoutAnchor.add(property);
} else {
if (representativeAnchor != null) {
LOG.assertTrue(representativeAnchor == anchor);
}
representativeAnchor = anchor;
}
}
if (representativeAnchor == null) {
LOG.assertTrue(propertiesWithoutAnchor.size() == properties.size());
representativeAnchor = new PropertyAnchor(properties);
} else {
representativeAnchor.addProperties(propertiesWithoutAnchor);
}
for (IProperty property : propertiesWithoutAnchor) {
myAnchors.put(property, representativeAnchor);
}
return representativeAnchor;
}
}
@@ -28,23 +28,23 @@ import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.PsiElement;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import gnu.trove.TObjectIntHashMap;
import gnu.trove.TObjectIntProcedure;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
public class ResourceBundleFileStructureViewElement implements StructureViewTreeElement, ResourceBundleEditorViewElement {
private final ResourceBundle myResourceBundle;
private boolean myShowOnlyIncomplete;
private PropertiesAnchorizer myAnchorizer;
public ResourceBundleFileStructureViewElement(final ResourceBundle resourceBundle) {
public ResourceBundleFileStructureViewElement(final ResourceBundle resourceBundle, PropertiesAnchorizer anchorizer) {
myResourceBundle = resourceBundle;
myAnchorizer = anchorizer;
}
public void setShowOnlyIncomplete(boolean showOnlyIncomplete) {
@@ -62,50 +62,49 @@ public class ResourceBundleFileStructureViewElement implements StructureViewTree
@NotNull
public StructureViewTreeElement[] getChildren() {
final Map<String, IProperty> propertyNames = getPropertiesMap(myResourceBundle, myShowOnlyIncomplete);
final MultiMap<String, IProperty> propertyNames = getPropertiesMap(myResourceBundle, myShowOnlyIncomplete);
List<StructureViewTreeElement> result = new ArrayList<StructureViewTreeElement>(propertyNames.size());
for (IProperty property : propertyNames.values()) {
result.add(new ResourceBundlePropertyStructureViewElement(myResourceBundle, property));
for (Map.Entry<String, Collection<IProperty>> entry : propertyNames.entrySet()) {
final Collection<IProperty> properties = entry.getValue();
final PropertiesAnchorizer.PropertyAnchor anchor = myAnchorizer.createOrUpdate(properties);
result.add(new ResourceBundlePropertyStructureViewElement(myResourceBundle, anchor));
}
return result.toArray(new StructureViewTreeElement[result.size()]);
}
public static Map<String, IProperty> getPropertiesMap(ResourceBundle resourceBundle, boolean onlyIncomplete) {
public static MultiMap<String, IProperty> getPropertiesMap(ResourceBundle resourceBundle, boolean onlyIncomplete) {
List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles();
final Map<String, IProperty> propertyNames;
final MultiMap<String, IProperty> propertyNames;
if (onlyIncomplete) {
propertyNames = getChildrenIdShowOnlyIncomplete(resourceBundle);
} else {
propertyNames = new LinkedHashMap<String, IProperty>();
propertyNames = MultiMap.createLinked();
for (PropertiesFile propertiesFile : propertiesFiles) {
List<IProperty> properties = propertiesFile.getProperties();
for (IProperty property : properties) {
String name = property.getKey();
if (!propertyNames.containsKey(name)) {
propertyNames.put(name, property);
}
propertyNames.putValue(name, property);
}
}
}
return propertyNames;
}
private static Map<String, IProperty> getChildrenIdShowOnlyIncomplete(ResourceBundle resourceBundle) {
final Map<String, IProperty> propertyNames = new LinkedHashMap<String, IProperty>();
private static MultiMap<String, IProperty> getChildrenIdShowOnlyIncomplete(ResourceBundle resourceBundle) {
final MultiMap<String, IProperty> propertyNames = MultiMap.createLinked();
TObjectIntHashMap<String> occurrences = new TObjectIntHashMap<String>();
for (PropertiesFile file : resourceBundle.getPropertiesFiles()) {
Map<String, IProperty> currentFilePropertyNames = new LinkedHashMap<String, IProperty>();
MultiMap<String, IProperty> currentFilePropertyNames = MultiMap.createLinked();
for (IProperty property : file.getProperties()) {
String name = property.getKey();
if (!currentFilePropertyNames.containsKey(name)) {
currentFilePropertyNames.put(name, property);
}
currentFilePropertyNames.putValue(name, property);
}
propertyNames.putAll(currentFilePropertyNames);
propertyNames.putAllValues(currentFilePropertyNames);
for (String propertyName : currentFilePropertyNames.keySet()) {
if (occurrences.contains(propertyName)) {
occurrences.adjustValue(propertyName, 1);
} else {
}
else {
occurrences.put(propertyName, 1);
}
}
@@ -41,7 +41,7 @@ import java.awt.*;
public class ResourceBundlePropertyStructureViewElement implements StructureViewTreeElement, ResourceBundleEditorViewElement {
private final ResourceBundle myResourceBundle;
private final IProperty myProperty;
@NotNull private final PropertiesAnchorizer.PropertyAnchor myAnchor;
private String myPresentableName;
private static final TextAttributesKey INCOMPLETE_PROPERTY_KEY;
@@ -64,18 +64,18 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
INCOMPLETE_GROUP_KEY = TextAttributesKey.createTextAttributesKey("INCOMPLETE_GROUP_KEY", incompleteGroupKeyTextAttribute);
}
public ResourceBundlePropertyStructureViewElement(final ResourceBundle resourceBundle, final IProperty property) {
public ResourceBundlePropertyStructureViewElement(final ResourceBundle resourceBundle, final @NotNull PropertiesAnchorizer.PropertyAnchor anchor) {
myResourceBundle = resourceBundle;
myProperty = property;
myAnchor = anchor;
}
public IProperty getProperty() {
return myProperty;
return getValue().getRepresentative();
}
@Override
public PsiElement[] getPsiElements() {
return new PsiElement[] {getValue()};
return new PsiElement[] {getProperty().getPsiElement()};
}
public void setPresentableName(final String presentableName) {
@@ -83,8 +83,8 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
}
@Override
public PsiElement getValue() {
return myProperty.getPsiElement();
public PropertiesAnchorizer.PropertyAnchor getValue() {
return myAnchor;
}
@Override
@@ -99,7 +99,7 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
return new ColoredItemPresentation() {
@Override
public String getPresentableText() {
return myPresentableName == null ? myProperty.getName() : myPresentableName.isEmpty() ? PROPERTY_GROUP_KEY_TEXT : myPresentableName;
return myPresentableName == null ? getProperty().getName() : myPresentableName.isEmpty() ? PROPERTY_GROUP_KEY_TEXT : myPresentableName;
}
@Override
@@ -115,11 +115,11 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
@Override
public TextAttributesKey getTextAttributesKey() {
if (myPresentableName != null && myPresentableName.isEmpty()) {
return PropertiesUtil.isPropertyComplete(myResourceBundle, myProperty.getName())
return PropertiesUtil.isPropertyComplete(myResourceBundle, getProperty().getName())
? GROUP_KEY
: INCOMPLETE_GROUP_KEY;
}
return PropertiesUtil.isPropertyComplete(myResourceBundle, myProperty.getName())
return PropertiesUtil.isPropertyComplete(myResourceBundle, getProperty().getName())
? PropertiesHighlighter.PROPERTY_KEY
: INCOMPLETE_PROPERTY_KEY;
}
@@ -35,12 +35,12 @@ public class ResourceBundleStructureViewModel implements PropertiesGroupingStruc
private final GroupByWordPrefixes myByWordPrefixesGrouper;
private final ResourceBundleFileStructureViewElement myRoot;
public ResourceBundleStructureViewModel(ResourceBundle root) {
public ResourceBundleStructureViewModel(ResourceBundle root, PropertiesAnchorizer anchorizer) {
myResourceBundle = root;
String separator = PropertiesSeparatorManager.getInstance(root.getProject()).
getSeparator(myResourceBundle);
myByWordPrefixesGrouper = new GroupByWordPrefixes(separator);
myRoot = new ResourceBundleFileStructureViewElement(myResourceBundle);
myRoot = new ResourceBundleFileStructureViewElement(myResourceBundle, anchorizer);
}
public void setSeparator(String separator) {
@@ -21,6 +21,7 @@ import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.ide.util.treeView.smartTree.*;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.PropertiesBundle;
import com.intellij.lang.properties.editor.PropertiesAnchorizer;
import com.intellij.lang.properties.editor.ResourceBundlePropertyStructureViewElement;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
@@ -69,7 +70,10 @@ public class GroupByWordPrefixes implements Grouper, Sorter {
if (!(element instanceof StructureViewTreeElement)) {
continue;
}
final Object value = ((StructureViewTreeElement)element).getValue();
Object value = ((StructureViewTreeElement)element).getValue();
if (value instanceof PropertiesAnchorizer.PropertyAnchor) {
value = ((PropertiesAnchorizer.PropertyAnchor)value).getRepresentative();
}
if (!(value instanceof IProperty)) {
continue;
}
@@ -182,6 +186,11 @@ public class GroupByWordPrefixes implements Grouper, Sorter {
this.words = words;
this.node = node;
}
@Override
public String toString() {
return "Key{words=" + words + ", node=" + node + '}';
}
}
}
@@ -20,6 +20,7 @@ import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.util.treeView.smartTree.Group;
import com.intellij.ide.util.treeView.smartTree.TreeElement;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.editor.PropertiesAnchorizer;
import com.intellij.lang.properties.editor.ResourceBundleEditorViewElement;
import com.intellij.lang.properties.editor.ResourceBundlePropertyStructureViewElement;
import com.intellij.lang.properties.psi.Property;
@@ -95,7 +96,10 @@ public class PropertiesPrefixGroup implements Group, ResourceBundleEditorViewEle
if (!(treeElement instanceof StructureViewTreeElement)) {
continue;
}
final Object value = ((StructureViewTreeElement)treeElement).getValue();
Object value = ((StructureViewTreeElement)treeElement).getValue();
if (value instanceof PropertiesAnchorizer.PropertyAnchor) {
value = ((PropertiesAnchorizer.PropertyAnchor)value).getRepresentative();
}
if (!(value instanceof IProperty)) {
continue;
}
@@ -105,6 +105,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
// we cannot store it back to properties file right now, so just append the backslash to the editor and wait for the subsequent chars
private final Set<PropertiesFile> myBackSlashPressed = new THashSet<PropertiesFile>();
private final Alarm mySelectionChangeAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
private final PropertiesAnchorizer myPropertiesAnchorizer;
private JPanel myValuesPanel;
private JPanel myStructureViewPanel;
@@ -131,7 +132,8 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
myResourceBundle = resourceBundle;
myPropertiesInsertDeleteManager = ResourceBundlePropertiesInsertManagerImpl.create(resourceBundle);
myStructureViewComponent = new ResourceBundleStructureViewComponent(myResourceBundle, this);
myPropertiesAnchorizer = new PropertiesAnchorizer(myResourceBundle.getProject());
myStructureViewComponent = new ResourceBundleStructureViewComponent(myResourceBundle, this, myPropertiesAnchorizer);
myStructureViewPanel.setLayout(new BorderLayout());
myStructureViewPanel.add(myStructureViewComponent, BorderLayout.CENTER);
@@ -284,10 +286,11 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
while (!toCheck.isEmpty()) {
TreeElement element = toCheck.pop();
PsiElement value = element instanceof ResourceBundlePropertyStructureViewElement
? ((ResourceBundlePropertyStructureViewElement)element).getValue()
? ((ResourceBundlePropertyStructureViewElement)element).getProperty().getPsiElement()
: null;
if (value instanceof IProperty && propertyName.equals(((IProperty)value).getUnescapedKey())) {
myStructureViewComponent.select(value, true);
final PropertiesAnchorizer.PropertyAnchor anchor = myPropertiesAnchorizer.get((IProperty)value);
myStructureViewComponent.select(anchor, true);
selectionChanged();
return;
}
@@ -361,7 +364,6 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
}
}
});
}
});
}
@@ -596,11 +598,11 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
@Override
public void childrenChanged(@NotNull PsiTreeChangeEvent event) {
final PsiFile file = event.getFile();
PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file);
if (propertiesFile == null) return;
if (!propertiesFile.getResourceBundle().equals(myResourceBundle)) return;
updateEditorsFromProperties();
// final PsiFile file = event.getFile();
//PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file);
//if (propertiesFile == null) return;
//if (!propertiesFile.getResourceBundle().equals(myResourceBundle)) return;
//updateEditorsFromProperties();
}
};
PsiManager.getInstance(myProject).addPsiTreeChangeListener(psiTreeChangeAdapter, this);
@@ -693,10 +695,9 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
final ResourceBundleFileStructureViewElement root =
(ResourceBundleFileStructureViewElement)myStructureViewComponent.getTreeModel().getRoot();
final Map<String, IProperty> propertiesMap =
ResourceBundleFileStructureViewElement.getPropertiesMap(myResourceBundle, root.isShowOnlyIncomplete());
final Set<String> propertyKeys = ResourceBundleFileStructureViewElement.getPropertiesMap(myResourceBundle, root.isShowOnlyIncomplete()).keySet();
final boolean isAlphaSorted = myStructureViewComponent.isActionActive(Sorter.ALPHA_SORTER_ID);
final List<String> keysOrder = new ArrayList<String>(propertiesMap.keySet());
final List<String> keysOrder = new ArrayList<String>(propertyKeys);
if (isAlphaSorted) {
Collections.sort(keysOrder);
}
@@ -53,8 +53,10 @@ public class ResourceBundleStructureViewComponent extends PropertiesGroupingStru
private final ResourceBundle myResourceBundle;
public ResourceBundleStructureViewComponent(final ResourceBundle resourceBundle, final ResourceBundleEditor editor) {
super(resourceBundle.getProject(), editor, new ResourceBundleStructureViewModel(resourceBundle));
public ResourceBundleStructureViewComponent(final ResourceBundle resourceBundle,
final ResourceBundleEditor editor,
final PropertiesAnchorizer anchorizer) {
super(resourceBundle.getProject(), editor, new ResourceBundleStructureViewModel(resourceBundle, anchorizer));
myResourceBundle = resourceBundle;
tunePopupActionGroup();
}
@@ -40,7 +40,6 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PackageScope;
import com.intellij.psi.search.searches.AnnotatedMembersSearch;
import com.intellij.psi.util.ClassUtil;
import com.intellij.util.containers.ContainerUtil;
import com.theoryinpractice.testng.model.IDEARemoteTestRunnerClient;
import com.theoryinpractice.testng.model.TestClassFilter;
import com.theoryinpractice.testng.model.TestData;
@@ -48,10 +47,7 @@ import com.theoryinpractice.testng.model.TestType;
import com.theoryinpractice.testng.util.TestNGUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.testng.xml.LaunchSuite;
import org.testng.xml.Parser;
import org.testng.xml.SuiteGenerator;
import org.testng.xml.XmlSuite;
import org.testng.xml.*;
import java.io.*;
import java.net.ServerSocket;
@@ -61,7 +57,7 @@ import java.util.regex.PatternSyntaxException;
public class SearchingForTestsTask extends SearchForTestsTask {
private static final Logger LOG = Logger.getInstance("#" + SearchingForTestsTask.class.getName());
private final Map<PsiClass, Collection<PsiMethod>> myClasses;
private final Map<PsiClass, Map<PsiMethod, List<String>>> myClasses;
private final TestData myData;
private final Project myProject;
private final TestNGConfiguration myConfig;
@@ -78,7 +74,7 @@ public class SearchingForTestsTask extends SearchForTestsTask {
myProject = config.getProject();
myConfig = config;
myTempFile = tempFile;
myClasses = new LinkedHashMap<PsiClass, Collection<PsiMethod>>();
myClasses = new LinkedHashMap<PsiClass, Map<PsiMethod, List<String>>>();
}
@Override
@@ -126,20 +122,20 @@ public class SearchingForTestsTask extends SearchForTestsTask {
}
private void composeTestSuiteFromClasses() {
Map<String, Collection<String>> map = new LinkedHashMap<String, Collection<String>>();
Map<String, Map<String, List<String>>> map = new LinkedHashMap<String, Map<String, List<String>>>();
final boolean findTestMethodsForClass = shouldSearchForTestMethods();
for (final Map.Entry<PsiClass, Collection<PsiMethod>> entry : myClasses.entrySet()) {
final Collection<PsiMethod> depMethods = entry.getValue();
Collection<String> methods = new LinkedHashSet<String>(depMethods.size());
for (PsiMethod method : depMethods) {
methods.add(method.getName());
for (final Map.Entry<PsiClass, Map<PsiMethod, List<String>>> entry : myClasses.entrySet()) {
final Map<PsiMethod, List<String>> depMethods = entry.getValue();
LinkedHashMap<String, List<String>> methods = new LinkedHashMap<String, List<String>>();
for (Map.Entry<PsiMethod, List<String>> method : depMethods.entrySet()) {
methods.put(method.getKey().getName(), method.getValue());
}
if (findTestMethodsForClass && depMethods.isEmpty()) {
for (PsiMethod method : entry.getKey().getMethods()) {
if (TestNGUtil.hasTest(method)) {
methods.add(method.getName());
methods.put(method.getName(), Collections.<String>emptyList());
}
}
}
@@ -180,10 +176,53 @@ public class SearchingForTestsTask extends SearchForTestsTask {
logLevel = 1;
}
LaunchSuite suite =
SuiteGenerator.createSuite(myProject.getName(), null, map, groupNames, testParams, "jdk", logLevel);
File xmlFile = suite.save(new File(PathManager.getSystemPath()));
File xmlFile;
if (groupNames != null) {
final LinkedHashMap<String, Collection<String>> methodNames = new LinkedHashMap<String, Collection<String>>();
for (Map.Entry<String, Map<String, List<String>>> entry : map.entrySet()) {
methodNames.put(entry.getKey(), entry.getValue().keySet());
}
LaunchSuite suite =
SuiteGenerator.createSuite(myProject.getName(), null, methodNames, groupNames, testParams, "jdk", logLevel);
xmlFile = suite.save(new File(PathManager.getSystemPath()));
}
else {
final XmlSuite xmlSuite = new XmlSuite();
XmlTest xmlTest = new XmlTest(xmlSuite);
xmlTest.setName(myProject.getName());
xmlTest.setParameters(testParams);
List<XmlClass> xmlClasses = new ArrayList<XmlClass>();
int idx = 0;
for (String className : map.keySet()) {
final XmlClass xmlClass = new XmlClass(className, idx++, false);
final ArrayList<XmlInclude> includedMethods = new ArrayList<XmlInclude>();
final Map<String, List<String>> collection = map.get(className);
int mIdx = 0;
for (String methodName : collection.keySet()) {
final List<Integer> includes = new ArrayList<Integer>();
for (String include : collection.get(methodName)) {
try {
includes.add(Integer.parseInt(include));
}
catch (NumberFormatException e) {
LOG.error(e);
}
}
includedMethods.add(new XmlInclude(methodName, includes, mIdx++));
}
xmlClass.setIncludedMethods(includedMethods);
xmlClasses.add(xmlClass);
}
xmlTest.setXmlClasses(xmlClasses);
xmlFile = new File(PathManager.getSystemPath(), "temp-testng-customsuite.xml");
final String toXml = xmlSuite.toXml();
try {
FileUtil.writeToFile(xmlFile, toXml);
}
catch (IOException e) {
LOG.error(e);
}
}
String path = xmlFile.getAbsolutePath() + "\n";
try {
FileUtil.writeToFile(myTempFile, path.getBytes(CharsetToolkit.UTF8_CHARSET), true);
@@ -195,7 +234,7 @@ public class SearchingForTestsTask extends SearchForTestsTask {
private boolean shouldSearchForTestMethods() {
boolean dependantMethods = false;
for (Collection<PsiMethod> methods : myClasses.values()) {
for (Map<PsiMethod, List<String>> methods : myClasses.values()) {
if (!methods.isEmpty()) {
dependantMethods = true;
break;
@@ -239,7 +278,7 @@ public class SearchingForTestsTask extends SearchForTestsTask {
}
}
protected void fillTestObjects(final Map<PsiClass, Collection<PsiMethod>> classes)
protected void fillTestObjects(final Map<PsiClass, Map<PsiMethod, List<String>>> classes)
throws CantRunException {
final TestData data = myConfig.getPersistantData();
final PsiManager psiManager = PsiManager.getInstance(myProject);
@@ -322,7 +361,7 @@ public class SearchingForTestsTask extends SearchForTestsTask {
.getAllTestClasses(new TestClassFilter(data.getScope().getSourceScope(myConfig).getGlobalSearchScope(), myProject, true, true), false);
if (testClasses != null) {
for (PsiClass c : testClasses) {
classes.put(c, new HashSet<PsiMethod>());
classes.put(c, new LinkedHashMap<PsiMethod, List<String>>());
}
}
}
@@ -401,7 +440,7 @@ public class SearchingForTestsTask extends SearchForTestsTask {
}
}
private void collectTestMethods(Map<PsiClass, Collection<PsiMethod>> classes, final PsiClass psiClass, final String methodName) {
private void collectTestMethods(Map<PsiClass, Map<PsiMethod, List<String>>> classes, final PsiClass psiClass, final String methodName) {
final PsiMethod[] methods = ApplicationManager.getApplication().runReadAction(
new Computable<PsiMethod[]>() {
public PsiMethod[] compute() {
@@ -410,12 +449,14 @@ public class SearchingForTestsTask extends SearchForTestsTask {
}
);
calculateDependencies(methods, classes, psiClass);
Collection<PsiMethod> psiMethods = classes.get(psiClass);
Map<PsiMethod, List<String>> psiMethods = classes.get(psiClass);
if (psiMethods == null) {
psiMethods = new LinkedHashSet<PsiMethod>();
psiMethods = new LinkedHashMap<PsiMethod, List<String>>();
classes.put(psiClass, psiMethods);
}
ContainerUtil.addAll(psiMethods, methods);
for (PsiMethod method : methods) {
psiMethods.put(method, Collections.<String>emptyList());
}
}
private Map<String, String> buildTestParameters() {
@@ -452,13 +493,13 @@ public class SearchingForTestsTask extends SearchForTestsTask {
}
private void calculateDependencies(PsiMethod[] methods,
final Map<PsiClass, Collection<PsiMethod>> results,
final Map<PsiClass, Map<PsiMethod, List<String>>> results,
@Nullable final PsiClass... classes) {
calculateDependencies(methods, results, new LinkedHashSet<PsiMember>(), classes);
}
private void calculateDependencies(final PsiMethod[] methods,
final Map<PsiClass, Collection<PsiMethod>> results,
final Map<PsiClass, Map<PsiMethod, List<String>>> results,
final Set<PsiMember> alreadyMarkedToBeChecked,
@Nullable final PsiClass... classes) {
if (classes != null && classes.length > 0) {
@@ -488,7 +529,7 @@ public class SearchingForTestsTask extends SearchForTestsTask {
if (methods == null) {
for (PsiClass c : classes) {
results.put(c, new LinkedHashSet<PsiMethod>());
results.put(c, new LinkedHashMap<PsiMethod, List<String>>());
}
} else {
for (PsiMember psiMember : membersToCheckNow) {
@@ -506,7 +547,7 @@ public class SearchingForTestsTask extends SearchForTestsTask {
}
}
private static void collectDependsOnMethods(final Map<PsiClass, Collection<PsiMethod>> results,
private static void collectDependsOnMethods(final Map<PsiClass, Map<PsiMethod, List<String>>> results,
final Set<PsiMember> alreadyMarkedToBeChecked,
final Set<PsiMember> membersToCheckNow,
final PsiMethod[] methods,
@@ -557,7 +598,7 @@ public class SearchingForTestsTask extends SearchForTestsTask {
PsiClass containingClass,
Set<PsiMember> alreadyMarkedToBeChecked,
Set<PsiMember> membersToCheckNow,
Map<PsiClass, Collection<PsiMethod>> results) {
Map<PsiClass, Map<PsiMethod, List<String>>> results) {
final PsiMethod[] psiMethods = containingClass.findMethodsByName(methodName, true);
for (PsiMethod method : psiMethods) {
if (AnnotationUtil.isAnnotated(method, TestNGUtil.TEST_ANNOTATION_FQN, false) &&
@@ -569,19 +610,19 @@ public class SearchingForTestsTask extends SearchForTestsTask {
private static boolean appendMember(final PsiMember psiMember,
final Set<PsiMember> underConsideration,
final Map<PsiClass, Collection<PsiMethod>> results) {
final Map<PsiClass, Map<PsiMethod, List<String>>> results) {
boolean result = false;
final PsiClass psiClass = psiMember instanceof PsiClass ? ((PsiClass)psiMember) : psiMember.getContainingClass();
Collection<PsiMethod> psiMethods = results.get(psiClass);
Map<PsiMethod, List<String>> psiMethods = results.get(psiClass);
if (psiMethods == null) {
psiMethods = new LinkedHashSet<PsiMethod>();
psiMethods = new LinkedHashMap<PsiMethod, List<String>>();
results.put(psiClass, psiMethods);
if (psiMember instanceof PsiClass) {
result = underConsideration.add(psiMember);
}
}
if (psiMember instanceof PsiMethod) {
final boolean add = psiMethods.add((PsiMethod)psiMember);
final boolean add = psiMethods.put((PsiMethod)psiMember, Collections.<String>emptyList()) != null;
if (add) {
return underConsideration.add(psiMember);
}
@@ -69,7 +69,7 @@ public abstract class TestNGConfigurationProducer extends JavaRunConfigurationPr
return false;
}
protected static String getInvocationNumber(String str) {
public static String getInvocationNumber(String str) {
final int indexOf = str.indexOf(IDEATestNGRemoteListener.INVOCATION_NUMBER);
if (indexOf > 0) {
final int lastIdx = str.indexOf(")", indexOf);
@@ -94,7 +94,7 @@ public class TestClassFilter implements ClassFilter.ClassFilterWithScope
return true;
}
return includeConfig && TestNGUtil.hasConfig(psiClass);
return includeConfig && TestNGUtil.hasConfig(psiClass, TestNGUtil.CONFIG_ANNOTATIONS_FQN_NO_TEST_LEVEL);
}
});
}
@@ -17,7 +17,6 @@ package com.theoryinpractice.testng.ui;
import com.intellij.execution.testframework.TestConsoleProperties;
import com.intellij.execution.testframework.TestTreeView;
import com.theoryinpractice.testng.model.TestNGConsoleProperties;
import com.theoryinpractice.testng.model.TestNodeDescriptor;
import com.theoryinpractice.testng.model.TestProxy;
import org.jetbrains.annotations.NotNull;
@@ -25,7 +24,6 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
/**
* @author Hani Suleiman Date: Aug 1, 2005 Time: 11:33:12 AM
@@ -54,9 +52,4 @@ public class TestNGTestTreeView extends TestTreeView {
}
return "";
}
@Override
protected int getSelectionMode() {
return TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION;
}
}
@@ -5,9 +5,9 @@ import com.intellij.execution.Executor;
import com.intellij.execution.Location;
import com.intellij.execution.actions.JavaRerunFailedTestsAction;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.junit2.PsiMemberParameterizedLocation;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.testframework.AbstractTestProxy;
import com.intellij.execution.testframework.SourceScope;
import com.intellij.execution.testframework.TestConsoleProperties;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
@@ -22,12 +22,11 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.containers.ContainerUtil;
import com.theoryinpractice.testng.configuration.SearchingForTestsTask;
import com.theoryinpractice.testng.configuration.TestNGConfiguration;
import com.theoryinpractice.testng.configuration.TestNGConfigurationProducer;
import com.theoryinpractice.testng.configuration.TestNGRunnableState;
import com.theoryinpractice.testng.util.TestNGUtil;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.net.ServerSocket;
import java.util.*;
public class RerunFailedTestsAction extends JavaRerunFailedTestsAction {
@@ -53,8 +52,8 @@ public class RerunFailedTestsAction extends JavaRerunFailedTestsAction {
public SearchingForTestsTask createSearchingForTestsTask() {
return new SearchingForTestsTask(myServerSocket, getConfiguration(), myTempFile, client) {
@Override
protected void fillTestObjects(final Map<PsiClass, Collection<PsiMethod>> classes) throws CantRunException {
final HashMap<PsiClass, Collection<PsiMethod>> fullClassList = ContainerUtil.newHashMap();
protected void fillTestObjects(final Map<PsiClass, Map<PsiMethod, List<String>>> classes) throws CantRunException {
final HashMap<PsiClass, Map<PsiMethod, List<String>>> fullClassList = ContainerUtil.newHashMap();
super.fillTestObjects(fullClassList);
for (final PsiClass aClass : fullClassList.keySet()) {
if (!ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@@ -78,7 +77,7 @@ public class RerunFailedTestsAction extends JavaRerunFailedTestsAction {
}
}
private void includeFailedTestWithDependencies(Map<PsiClass, Collection<PsiMethod>> classes,
private void includeFailedTestWithDependencies(Map<PsiClass, Map<PsiMethod, List<String>>> classes,
GlobalSearchScope scope,
Project project,
AbstractTestProxy proxy) {
@@ -95,12 +94,23 @@ public class RerunFailedTestsAction extends JavaRerunFailedTestsAction {
psiClass = (PsiClass)elt;
}
}
Collection<PsiMethod> psiMethods = classes.get(psiClass);
Map<PsiMethod, List<String>> psiMethods = classes.get(psiClass);
if (psiMethods == null) {
psiMethods = new ArrayList<PsiMethod>();
psiMethods = new LinkedHashMap<PsiMethod, List<String>>();
classes.put(psiClass, psiMethods);
}
psiMethods.add(psiMethod);
List<String> strings = psiMethods.get(psiMethod);
if (strings == null) {
strings = new ArrayList<String>();
}
if (location instanceof PsiMemberParameterizedLocation) {
final String paramSetName = ((PsiMemberParameterizedLocation)location).getParamSetName();
final String invocationNumber = TestNGConfigurationProducer.getInvocationNumber(paramSetName);
if (invocationNumber != null) {
strings.add(invocationNumber);
}
}
psiMethods.put(psiMethod, strings);
}
}
}
@@ -25,7 +25,6 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.JarUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
@@ -91,6 +90,20 @@ public class TestNGUtil {
AfterTest.class.getName()
};
@SuppressWarnings("deprecation") public static final String[] CONFIG_ANNOTATIONS_FQN_NO_TEST_LEVEL = {
Configuration.class.getName(),
Factory.class.getName(),
ObjectFactory.class.getName(),
BeforeClass.class.getName(),
BeforeGroups.class.getName(),
BeforeSuite.class.getName(),
BeforeTest.class.getName(),
AfterClass.class.getName(),
AfterGroups.class.getName(),
AfterSuite.class.getName(),
AfterTest.class.getName()
};
@NonNls
private static final String[] CONFIG_JAVADOC_TAGS = {
"testng.configuration",
@@ -113,19 +126,24 @@ public class TestNGUtil {
private static final String SUITE_TAG_NAME = "suite";
public static boolean hasConfig(PsiModifierListOwner element) {
return hasConfig(element, CONFIG_ANNOTATIONS_FQN);
}
public static boolean hasConfig(PsiModifierListOwner element,
String[] configAnnotationsFqn) {
if (element instanceof PsiClass) {
for (PsiMethod method : ((PsiClass)element).getAllMethods()) {
if (isConfigMethod(method)) return true;
if (isConfigMethod(method, configAnnotationsFqn)) return true;
}
} else {
if (!(element instanceof PsiMethod)) return false;
return isConfigMethod((PsiMethod)element);
return isConfigMethod((PsiMethod)element, configAnnotationsFqn);
}
return false;
}
private static boolean isConfigMethod(PsiMethod method) {
for (String fqn : CONFIG_ANNOTATIONS_FQN) {
private static boolean isConfigMethod(PsiMethod method, String[] configAnnotationsFqn) {
for (String fqn : configAnnotationsFqn) {
if (AnnotationUtil.isAnnotated(method, fqn, false)) return true;
}
@@ -191,21 +209,29 @@ public class TestNGUtil {
if (element instanceof PsiClass) {
PsiClass psiClass = (PsiClass) element;
for (PsiMethod method : psiClass.getAllMethods()) {
if (AnnotationUtil.isAnnotated(method, TEST_ANNOTATION_FQN, false, true)) return true;
PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, true, TEST_ANNOTATION_FQN);
if (annotation != null) {
if (checkDisabled) {
if (isDisabled(annotation)) continue;
}
return true;
}
if (AnnotationUtil.isAnnotated(method, FACTORY_ANNOTATION_FQN, false, true)) return true;
if (hasTestJavaDoc(method, checkJavadoc)) return true;
}
return AnnotationUtil.isAnnotated(element, TEST_ANNOTATION_FQN, true, true);
return false;
} else if (element instanceof PsiMethod) {
//if it's a method, we check if the class it's in has a global @Test annotation
PsiClass psiClass = ((PsiMethod)element).getContainingClass();
if (psiClass != null) {
if (AnnotationUtil.isAnnotated(psiClass, TEST_ANNOTATION_FQN, true, true)) {
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(psiClass, true, TEST_ANNOTATION_FQN);
if (annotation != null) {
if (checkDisabled && isDisabled(annotation)) return false;
//even if it has a global test, we ignore private methods
boolean isPrivate = element.hasModifierProperty(PsiModifier.PRIVATE);
return !isPrivate && !element.hasModifierProperty(PsiModifier.STATIC) && !hasConfig(element);
}
if (hasTestJavaDoc(psiClass, checkJavadoc)) return true;
else if (hasTestJavaDoc(psiClass, checkJavadoc)) return true;
}
}
return false;
@@ -73,8 +73,8 @@ public class IDEARemoteTestNG extends TestNG {
final HashMap<String, String> map = new HashMap<String, String>();
map.put("count", String.valueOf(testCount));
System.out.println(ServiceMessage.asString("testCount", map));
addListener((ISuiteListener) new IDEATestNGRemoteListener(myParam));
addListener((ITestListener) new IDEATestNGRemoteListener(myParam));
addListener((ISuiteListener) new IDEATestNGRemoteListener());
addListener((ITestListener) new IDEATestNGRemoteListener());
super.run();
}
else {
@@ -7,6 +7,7 @@ import org.testng.internal.IResultListener;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@@ -16,25 +17,29 @@ import java.util.Map;
public class IDEATestNGRemoteListener implements ISuiteListener, IResultListener{
public static final String INVOCATION_NUMBER = "invocation number: ";
private final String myParam;
private String myCurrentClassName;
private String myMethodName;
private int myInvocationCount = 0;
public IDEATestNGRemoteListener(String param) {
myParam = param;
public void onConfigurationSuccess(ITestResult result) {
final String className = result.getTestClass().getName();
System.out.println("##teamcity[testSuiteStarted name=\'" + className + "\']");
final String methodName = result.getMethod().getMethodName();
System.out.println("##teamcity[testStarted name=\'" + methodName + "\']");
onTestSuccess(result);
System.out.println("\n##teamcity[testSuiteFinished name=\'" + className + "\']");
}
public void onConfigurationSuccess(ITestResult itr) {
//won't be called
}
public void onConfigurationFailure(ITestResult itr) {
//won't be called
public void onConfigurationFailure(ITestResult result) {
final String className = result.getTestClass().getName();
System.out.println("##teamcity[testSuiteStarted name=\'" + className + "\']");
final String methodName = result.getMethod().getMethodName();
System.out.println("##teamcity[testStarted name=\'" + methodName + "\']");
onTestFailure(result);
System.out.println("\n##teamcity[testSuiteFinished name=\'" + className + "\']");
}
public void onConfigurationSkip(ITestResult itr) {
//won't be called
}
public void onStart(ISuite suite) {
@@ -68,14 +73,14 @@ public class IDEATestNGRemoteListener implements ISuiteListener, IResultListener
private String getMethodName(ITestResult result, boolean changeCount) {
String methodName = result.getMethod().getMethodName();
final Object[] parameters = result.getParameters();
if (changeCount) {
if (!methodName.equals(myMethodName)) {
myInvocationCount = 0;
myMethodName = methodName;
}
if (!methodName.equals(myMethodName)) {
myInvocationCount = 0;
myMethodName = methodName;
}
if (parameters.length > 0) {
methodName += "[" + parameters[0].toString() + (myParam == null ? (" (" + INVOCATION_NUMBER + myInvocationCount + ")") : "") + "]";
final List<Integer> invocationNumbers = result.getMethod().getInvocationNumbers();
methodName += "[" + parameters[0].toString() + " (" + INVOCATION_NUMBER +
(invocationNumbers.isEmpty() ? myInvocationCount : invocationNumbers.get(myInvocationCount)) + ")" + "]";
if (changeCount) {
myInvocationCount++;
}
@@ -84,7 +89,7 @@ public class IDEATestNGRemoteListener implements ISuiteListener, IResultListener
}
public void onTestSuccess(ITestResult result) {
System.out.println("##teamcity[testFinished name=\'" + getMethodName(result) + "\']");
System.out.println("\n##teamcity[testFinished name=\'" + getMethodName(result) + "\']");
}
public String getTrace(Throwable tr) {
@@ -106,11 +111,11 @@ public class IDEATestNGRemoteListener implements ISuiteListener, IResultListener
attrs.put("details", trace);
attrs.put("error", "true");
System.out.println(ServiceMessage.asString(ServiceMessageTypes.TEST_FAILED, attrs));
System.out.println("##teamcity[testFinished name=\'" + methodName + "\']");
System.out.println("\n##teamcity[testFinished name=\'" + methodName + "\']");
}
public void onTestSkipped(ITestResult result) {
System.out.println("##teamcity[testFinished name=\'" + getMethodName(result) + "\']");
System.out.println("\n##teamcity[testFinished name=\'" + getMethodName(result) + "\']");
}
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
@@ -134,6 +134,7 @@ final class CommandConsole extends LanguageConsoleImpl implements Consumer<Strin
console.switchToCommandMode();
console.getComponent(); // For some reason console does not have component until this method is called which leads to some errros.
console.getConsoleEditor().getSettings().setAdditionalLinesCount(1); // to prevent PY-15583
return console;
}
@@ -163,14 +164,13 @@ final class CommandConsole extends LanguageConsoleImpl implements Consumer<Strin
*/
private void switchToCommandMode() {
// "upper" and "bottom" parts of console both need padding in command mode
configureLeftBorder(true, getConsoleEditor(), getHistoryViewer());
myProcessHandler = null;
setPrompt(getTitle() + " > ");
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
notifyStateChangeListeners();
configureLeftBorder(true, getConsoleEditor(), getHistoryViewer());
setLanguage(CommandLineLanguage.INSTANCE);
final CommandLineFile file = PyUtil.as(getFile(), CommandLineFile.class);
resetConsumer(null);
@@ -190,11 +190,11 @@ final class CommandConsole extends LanguageConsoleImpl implements Consumer<Strin
* @param processHandler process to attach to
*/
private void switchToProcessMode(@NotNull final ProcessHandler processHandler) {
configureLeftBorder(false, getConsoleEditor()); // "bottom" part of console do not need padding now because it is used for user input
myProcessHandler = processHandler;
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
configureLeftBorder(false, getConsoleEditor()); // "bottom" part of console do not need padding now because it is used for user inputA
notifyStateChangeListeners();
resetConsumer(new ProcessModeConsumer(processHandler));
// In process mode we do not need prompt and highlighting
+12
View File
@@ -76,4 +76,16 @@
<option name="PATTERN" value="org.springsource.loaded.*" />
<option name="ENABLED" value="true" />
</filter>
<filter>
<option name="PATTERN" value="javassist.*" />
<option name="ENABLED" value="true" />
</filter>
<filter>
<option name="PATTERN" value="org.apache.webbeans.*" />
<option name="ENABLED" value="true" />
</filter>
<filter>
<option name="PATTERN" value="com.ibm.ws.*" />
<option name="ENABLED" value="true" />
</filter>
</component>