Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2014-03-12 21:49:11 +01:00
32 changed files with 585 additions and 195 deletions
@@ -18,8 +18,10 @@ package com.intellij.debugger.engine;
import com.intellij.debugger.NoDataException;
import com.intellij.debugger.PositionManager;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.evaluation.EvaluationContext;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.requests.ClassPrepareRequestor;
import com.intellij.util.ThreeState;
import com.intellij.xdebugger.frame.XStackFrame;
import com.sun.jdi.Location;
import com.sun.jdi.ReferenceType;
@@ -111,4 +113,20 @@ public class CompoundPositionManager extends PositionManagerEx {
}
return null;
}
@Override
public ThreeState evaluateCondition(@NotNull EvaluationContext context,
@NotNull StackFrameProxyImpl frame,
@NotNull Location location,
@NotNull String expression) {
for (PositionManager positionManager : myPositionManagers) {
if (positionManager instanceof PositionManagerEx) {
ThreeState result = ((PositionManagerEx)positionManager).evaluateCondition(context, frame, location, expression);
if (result != ThreeState.UNSURE) {
return result;
}
}
}
return ThreeState.UNSURE;
}
}
@@ -908,8 +908,11 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
ClassNotLoadedException,
IncompatibleThreadStateException,
InvalidTypeException;
public E start(EvaluationContextImpl evaluationContext, Method method) throws EvaluateException {
return start(evaluationContext, method, false);
}
public E start(EvaluationContextImpl evaluationContext, Method method, boolean internalEvaluate) throws EvaluateException {
DebuggerManagerThreadImpl.assertIsManagerThread();
SuspendContextImpl suspendContext = evaluationContext.getSuspendContext();
SuspendManagerUtil.assertSuspendContext(suspendContext);
@@ -924,11 +927,11 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
final ThreadReference invokeThreadRef = invokeThread.getThreadReference();
myEvaluationDispatcher.getMulticaster().evaluationStarted(suspendContext);
beforeMethodInvocation(suspendContext, method);
beforeMethodInvocation(suspendContext, method, internalEvaluate);
Object resumeData = null;
try {
for (final SuspendContextImpl suspendingContext : suspendingContexts) {
for (SuspendContextImpl suspendingContext : suspendingContexts) {
final ThreadReferenceProxyImpl suspendContextThread = suspendingContext.getThread();
if (suspendContextThread != invokeThread) {
if (LOG.isDebugEnabled()) {
@@ -947,11 +950,11 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
while (true) {
try {
return invokeMethodAndFork(suspendContext);
}
}
catch (ClassNotLoadedException e) {
ReferenceType loadedClass;
try {
loadedClass = evaluationContext.isAutoLoadClasses()? loadClass(evaluationContext, e.className(), evaluationContext.getClassLoader()) : null;
loadedClass = evaluationContext.isAutoLoadClasses() ? loadClass(evaluationContext, e.className(), evaluationContext.getClassLoader()) : null;
}
catch (EvaluateException ignored) {
loadedClass = null;
@@ -998,7 +1001,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
LOG.debug("getVirtualMachine().clearCaches()");
}
getVirtualMachineProxy().clearCaches();
afterMethodInvocation(suspendContext);
afterMethodInvocation(suspendContext, internalEvaluate);
myEvaluationDispatcher.getMulticaster().evaluationFinished(suspendContext);
}
@@ -1087,13 +1090,13 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
}
@Override
public Value invokeMethod(final EvaluationContext evaluationContext, final ObjectReference objRef, final Method method, final List args) throws EvaluateException {
public Value invokeMethod(@NotNull EvaluationContext evaluationContext, @NotNull ObjectReference objRef, @NotNull Method method, final List args) throws EvaluateException {
return invokeInstanceMethod(evaluationContext, objRef, method, args, 0);
}
@Override
public Value invokeInstanceMethod(final EvaluationContext evaluationContext, final ObjectReference objRef, final Method method,
final List args, final int invocationOptions) throws EvaluateException {
public Value invokeInstanceMethod(@NotNull EvaluationContext evaluationContext, @NotNull final ObjectReference objRef, final Method method,
final List args, final int invocationOptions) throws EvaluateException {
final ThreadReference thread = getEvaluationThread(evaluationContext);
return new InvokeCommand<Value>(args) {
@Override
@@ -1118,9 +1121,16 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
public Value invokeMethod(final EvaluationContext evaluationContext, final ClassType classType,
final Method method,
final List args) throws EvaluateException {
return invokeMethod(evaluationContext, classType, method, args, false);
}
public Value invokeMethod(@NotNull EvaluationContext evaluationContext,
@NotNull final ClassType classType,
@NotNull final Method method,
final List args,
boolean internalEvaluate) throws EvaluateException {
final ThreadReference thread = getEvaluationThread(evaluationContext);
InvokeCommand<Value> invokeCommand = new InvokeCommand<Value>(args) {
return new InvokeCommand<Value>(args) {
@Override
protected Value invokeMethod(int invokePolicy, final List args) throws InvocationException,
ClassNotLoadedException,
@@ -1131,8 +1141,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
}
return classType.invokeMethod(thread, method, args, invokePolicy);
}
};
return invokeCommand.start((EvaluationContextImpl)evaluationContext, method);
}.start((EvaluationContextImpl)evaluationContext, method, internalEvaluate);
}
@Override
@@ -1179,25 +1188,29 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
clearCashes(suspendContext.getSuspendPolicy());
}
private void beforeMethodInvocation(SuspendContextImpl suspendContext, Method method) {
private void beforeMethodInvocation(SuspendContextImpl suspendContext, Method method, boolean internalEvaluate) {
if (LOG.isDebugEnabled()) {
LOG.debug(
"before invocation in thread " + suspendContext.getThread().name() + " method " + (method == null ? "null" : method.name()));
}
if (method != null) {
showStatusText(DebuggerBundle.message("progress.evaluating", DebuggerUtilsEx.methodName(method)));
}
else {
showStatusText(DebuggerBundle.message("title.evaluating"));
if (!internalEvaluate) {
if (method != null) {
showStatusText(DebuggerBundle.message("progress.evaluating", DebuggerUtilsEx.methodName(method)));
}
else {
showStatusText(DebuggerBundle.message("title.evaluating"));
}
}
}
private void afterMethodInvocation(SuspendContextImpl suspendContext) {
private void afterMethodInvocation(SuspendContextImpl suspendContext, boolean internalEvaluate) {
if (LOG.isDebugEnabled()) {
LOG.debug("after invocation in thread " + suspendContext.getThread().name());
}
showStatusText("");
if (!internalEvaluate) {
showStatusText("");
}
}
@Override
@@ -16,7 +16,9 @@
package com.intellij.debugger.engine;
import com.intellij.debugger.PositionManager;
import com.intellij.debugger.engine.evaluation.EvaluationContext;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.util.ThreeState;
import com.intellij.xdebugger.frame.XStackFrame;
import com.sun.jdi.Location;
import org.jetbrains.annotations.NotNull;
@@ -25,4 +27,9 @@ import org.jetbrains.annotations.Nullable;
public abstract class PositionManagerEx implements PositionManager {
@Nullable
public abstract XStackFrame createStackFrame(@NotNull StackFrameProxyImpl frame, @NotNull DebugProcessImpl debugProcess, @NotNull Location location);
public abstract ThreeState evaluateCondition(@NotNull EvaluationContext context,
@NotNull StackFrameProxyImpl frame,
@NotNull Location location,
@NotNull String expression);
}
@@ -19,8 +19,6 @@ import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.openapi.diagnostic.Logger;
import java.util.HashSet;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Set;
public class SuspendManagerUtil {
@@ -36,9 +34,8 @@ public class SuspendManagerUtil {
}
public static SuspendContextImpl findContextByThread(SuspendManager suspendManager, ThreadReferenceProxyImpl thread) {
for (ListIterator<SuspendContextImpl> iterator = ((SuspendManagerImpl) suspendManager).getPausedContexts().listIterator(); iterator.hasNext();) {
SuspendContextImpl context = iterator.next();
if(context.getThread() == thread) {
for (SuspendContextImpl context : ((SuspendManagerImpl)suspendManager).getPausedContexts()) {
if (context.getThread() == thread) {
return context;
}
}
@@ -78,8 +75,7 @@ public class SuspendManagerUtil {
LOG.assertTrue(context.myResumedThreads == null);
if(data.myResumedThreads != null) {
for (Iterator<ThreadReferenceProxyImpl> iterator = data.myResumedThreads.iterator(); iterator.hasNext();) {
ThreadReferenceProxyImpl resumedThreads = iterator.next();
for (ThreadReferenceProxyImpl resumedThreads : data.myResumedThreads) {
resumedThreads.resume();
}
context.myResumedThreads = data.myResumedThreads;
@@ -101,8 +97,7 @@ public class SuspendManagerUtil {
LOG.debug("Resuming SuspendContextImpl...");
}
if(context.myResumedThreads != null) {
for (Iterator<ThreadReferenceProxyImpl> iterator = context.myResumedThreads.iterator(); iterator.hasNext();) {
ThreadReferenceProxyImpl resumedThreads = iterator.next();
for (ThreadReferenceProxyImpl resumedThreads : context.myResumedThreads) {
resumedThreads.suspend();
}
context.myResumedThreads = null;
@@ -25,11 +25,6 @@ import com.sun.jdi.Value;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* User: lex
* Date: Aug 28, 2003
* Time: 2:02:29 PM
*/
public final class EvaluationContextImpl implements EvaluationContext{
private final Value myThisObject;
private final SuspendContextImpl mySuspendContext;
@@ -48,6 +43,7 @@ public final class EvaluationContextImpl implements EvaluationContext{
return myThisObject;
}
@NotNull
@Override
public SuspendContextImpl getSuspendContext() {
return mySuspendContext;
@@ -77,6 +73,7 @@ public final class EvaluationContextImpl implements EvaluationContext{
return copy;
}
@Nullable
@Override
public ClassLoaderReference getClassLoader() throws EvaluateException {
DebuggerManagerThreadImpl.assertIsManagerThread();
@@ -28,6 +28,7 @@ public class BlockStatementEvaluator implements Evaluator {
myStatements = statements;
}
@Override
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
Object result = context.getSuspendContext().getDebugProcess().getVirtualMachineProxy().mirrorOf();
for (Evaluator statement : myStatements) {
@@ -36,6 +37,7 @@ public class BlockStatementEvaluator implements Evaluator {
return result;
}
@Override
public Modifier getModifier() {
return myStatements.length > 0 ? myStatements[myStatements.length - 1].getModifier() : null;
}
@@ -20,10 +20,10 @@
*/
package com.intellij.debugger.engine.evaluation.expression;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.sun.jdi.BooleanValue;
import com.sun.jdi.Value;
@@ -38,10 +38,12 @@ class ConditionalExpressionEvaluator implements Evaluator {
myElseEvaluator = elseEvaluator;
}
@Override
public Modifier getModifier() {
return null;
}
@Override
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
Value condition = (Value)myConditionEvaluator.evaluate(context);
if (condition == null || !(condition instanceof BooleanValue)) {
@@ -15,11 +15,11 @@
*/
package com.intellij.debugger.engine.evaluation.expression;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
import com.intellij.debugger.engine.evaluation.EvaluationContext;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.sun.jdi.Value;
@@ -40,16 +40,19 @@ public class ExpressionEvaluatorImpl implements ExpressionEvaluator {
}
//call evaluate before
@Override
public Value getValue() {
return myValue;
}
//call evaluate before
@Override
public Modifier getModifier() {
return myEvaluator.getModifier();
}
// EvaluationContextImpl should be at the same stackFrame as it was in the call to EvaluatorBuilderImpl.build
@Override
public Value evaluate(final EvaluationContext context) throws EvaluateException {
if (!context.getDebugProcess().isAttached()) {
throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("error.vm.disconnected"));
@@ -61,22 +64,24 @@ public class ExpressionEvaluatorImpl implements ExpressionEvaluator {
Object value = myEvaluator.evaluate((EvaluationContextImpl)context);
if(value != null && !(value instanceof Value)) {
if (value != null && !(value instanceof Value)) {
throw EvaluateExceptionUtil
.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", ""));
}
myValue = (Value) value;
myValue = (Value)value;
return myValue;
}
catch (Throwable/*IncompatibleThreadStateException*/ e) {
if (LOG.isDebugEnabled()) {
LOG.debug(e);
}
if(e instanceof EvaluateException)
if (e instanceof EvaluateException) {
throw ((EvaluateException)e);
else
}
else {
throw EvaluateExceptionUtil.createEvaluateException(e);
}
}
}
}
@@ -53,6 +53,7 @@ class LocalVariableEvaluator implements Evaluator {
myParameterIndex = parameterIndex;
}
@Override
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
StackFrameProxyImpl frameProxy = context.getFrameProxy();
if (frameProxy == null) {
@@ -109,37 +110,45 @@ class LocalVariableEvaluator implements Evaluator {
}
}
@Override
public Modifier getModifier() {
Modifier modifier = null;
if (myEvaluatedVariable != null && myContext != null) {
modifier = new Modifier() {
@Override
public boolean canInspect() {
return true;
}
@Override
public boolean canSetValue() {
return true;
}
@Override
public void setValue(Value value) throws ClassNotLoadedException, InvalidTypeException {
StackFrameProxyImpl frameProxy = myContext.getFrameProxy();
try {
assert frameProxy != null;
frameProxy.setValue(myEvaluatedVariable, value);
}
catch (EvaluateException e) {
LOG.error(e);
LOG.error(e);
}
}
@Override
public Type getExpectedType() throws ClassNotLoadedException {
try {
return myEvaluatedVariable.getType();
} catch (EvaluateException e) {
}
catch (EvaluateException e) {
LOG.error(e);
return null;
}
}
@Override
public NodeDescriptorImpl getInspectItem(Project project) {
return new LocalVariableDescriptorImpl(project, myEvaluatedVariable);
}
@@ -22,6 +22,7 @@ package com.intellij.debugger.engine.evaluation.expression;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.engine.JVMName;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
@@ -53,10 +54,12 @@ public class MethodEvaluator implements Evaluator {
myArgumentEvaluators = argumentEvaluators;
}
@Override
public Modifier getModifier() {
return null;
}
@Override
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
if(!context.getDebugProcess().isAttached()) return null;
DebugProcessImpl debugProcess = context.getDebugProcess();
@@ -126,7 +129,7 @@ public class MethodEvaluator implements Evaluator {
if (requiresSuperObject && (referenceType instanceof ClassType)) {
_refType = ((ClassType)referenceType).superclass();
}
final Method jdiMethod = DebuggerUtilsEx.findMethod(_refType, myMethodName, signature);
final Method jdiMethod = DebuggerUtils.findMethod(_refType, myMethodName, signature);
if (jdiMethod == null) {
throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.no.instance.method", methodName));
}
@@ -39,6 +39,7 @@ public abstract class InvokeThread<E extends PrioritizedTask> {
myOwner = owner;
}
@Override
public void run() {
synchronized (this) {
while (myRequestFuture == null) {
@@ -174,7 +175,7 @@ public abstract class InvokeThread<E extends PrioritizedTask> {
}
if (LOG.isDebugEnabled()) {
LOG.debug("Request " + this.toString() + " exited");
LOG.debug("Request " + toString() + " exited");
}
}
@@ -26,11 +26,15 @@ import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
import com.intellij.debugger.engine.jdi.StackFrameProxy;
import com.intellij.openapi.diagnostic.Logger;
import com.sun.jdi.*;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.jdi.StackFrameProxyImpl");
@@ -43,7 +47,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
private ObjectReference myThisReference;
private ClassLoaderReference myClassLoader;
private Boolean myIsObsolete = null;
private Map<LocalVariable,Value> myAllValues;
private Map<LocalVariable, Value> myAllValues;
public StackFrameProxyImpl(ThreadReferenceProxyImpl threadProxy, @NotNull StackFrame frame, int fromBottomIndex /* 1-based */) {
super(threadProxy.getVirtualMachine());
@@ -252,6 +256,12 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
return variable != null ? new LocalVariableProxyImpl(this, variable) : null;
}
@Nullable
public Value visibleValueByName(@NotNull String name) throws EvaluateException {
LocalVariable variable = visibleVariableByNameInt(name);
return variable != null ? getValue(new LocalVariableProxyImpl(this, variable)) : null;
}
protected LocalVariable visibleVariableByNameInt(String name) throws EvaluateException {
DebuggerManagerThreadImpl.assertIsManagerThread();
InvalidStackFrameException error = null;
@@ -283,8 +293,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
InvalidStackFrameException error = null;
for (int attempt = 0; attempt < 2; attempt++) {
try {
final Map<LocalVariable, Value> allValues = getAllValues();
return allValues.get(localVariable.getVariable());
return getAllValues().get(localVariable.getVariable());
}
catch (InvalidStackFrameException e) {
error = e;
@@ -332,13 +341,8 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
checkValid();
if (myAllValues == null) {
try {
final StackFrame stackFrame = getStackFrame();
final Map<LocalVariable, Value> values = stackFrame.getValues(stackFrame.visibleVariables());
myAllValues = new HashMap<LocalVariable, Value>(values.size());
for (final LocalVariable variable : values.keySet()) {
final Value value = values.get(variable);
myAllValues.put(variable, value);
}
StackFrame stackFrame = getStackFrame();
myAllValues = new THashMap<LocalVariable, Value>(stackFrame.getValues(stackFrame.visibleVariables()));
}
catch (InconsistentDebugInfoException ignored) {
clearCaches();
@@ -41,6 +41,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.ui.AppUIUtil;
import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.ThreeState;
import com.intellij.xdebugger.breakpoints.SuspendPolicy;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
@@ -322,41 +323,52 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
if (!typeMatchesClassFilters(typeName)) return false;
}
if (isConditionEnabled() && !getCondition().getText().isEmpty()) {
try {
ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(context.getProject(), new EvaluatingComputable<ExpressionEvaluator>() {
@Override
public ExpressionEvaluator compute() throws EvaluateException {
final SourcePosition contextSourcePosition = ContextUtil.getSourcePosition(context);
// IMPORTANT: calculate context psi element basing on the location where the exception
// has been hit, not on the location where it was set. (For line breakpoints these locations are the same, however,
// for method, exception and field breakpoints these locations differ)
PsiElement contextPsiElement = ContextUtil.getContextElement(contextSourcePosition);
if (contextPsiElement == null) {
contextPsiElement = getEvaluationElement(); // as a last resort
}
return EvaluatorBuilderImpl.build(getCondition(), contextPsiElement, contextSourcePosition);
}
});
final Value value = evaluator.evaluate(context);
if (!(value instanceof BooleanValue)) {
throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.boolean.expected"));
}
if (!((BooleanValue)value).booleanValue()) {
return false;
}
}
catch (EvaluateException ex) {
if (ex.getCause() instanceof VMDisconnectedException) {
return false;
}
throw EvaluateExceptionUtil.createEvaluateException(
DebuggerBundle.message("error.failed.evaluating.breakpoint.condition", getCondition(), ex.getMessage())
);
}
if (!isConditionEnabled() || getCondition().getText().isEmpty()) {
return true;
}
StackFrameProxyImpl frame = context.getFrameProxy();
if (frame != null) {
Location location = frame.location();
if (location != null) {
ThreeState result = debugProcess.getPositionManager().evaluateCondition(context, frame, location, getCondition().getText());
if (result != ThreeState.UNSURE) {
return result == ThreeState.YES;
}
}
}
try {
ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(context.getProject(), new EvaluatingComputable<ExpressionEvaluator>() {
@Override
public ExpressionEvaluator compute() throws EvaluateException {
final SourcePosition contextSourcePosition = ContextUtil.getSourcePosition(context);
// IMPORTANT: calculate context psi element basing on the location where the exception
// has been hit, not on the location where it was set. (For line breakpoints these locations are the same, however,
// for method, exception and field breakpoints these locations differ)
PsiElement contextPsiElement = ContextUtil.getContextElement(contextSourcePosition);
if (contextPsiElement == null) {
contextPsiElement = getEvaluationElement(); // as a last resort
}
return EvaluatorBuilderImpl.build(getCondition(), contextPsiElement, contextSourcePosition);
}
});
final Value value = evaluator.evaluate(context);
if (!(value instanceof BooleanValue)) {
throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.boolean.expected"));
}
if (!((BooleanValue)value).booleanValue()) {
return false;
}
}
catch (EvaluateException ex) {
if (ex.getCause() instanceof VMDisconnectedException) {
return false;
}
throw EvaluateExceptionUtil.createEvaluateException(
DebuggerBundle.message("error.failed.evaluating.breakpoint.condition", getCondition(), ex.getMessage())
);
}
return true;
}
@@ -31,10 +31,12 @@ public interface EvaluationContext extends StackFrameContext{
EvaluationContext createEvaluationContext(Value value);
@NotNull
SuspendContext getSuspendContext();
Project getProject();
@Nullable
ClassLoaderReference getClassLoader() throws EvaluateException;
@Nullable
@@ -21,7 +21,6 @@
package com.intellij.ide.navigationToolbar;
import com.intellij.ide.navigationToolbar.ui.NavBarUIManager;
import com.intellij.ide.ui.LafManager;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
import com.intellij.ide.ui.customization.CustomActionsSchema;
@@ -30,7 +29,6 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.wm.IdeRootPaneNorthExtension;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
import com.intellij.ui.ScrollPaneFactory;
@@ -198,47 +196,7 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
}
private JComponent buildNavBarPanel() {
final Ref<JPanel> panel = new Ref<JPanel>(null);
final Runnable updater = new Runnable() {
String laf;
@Override
public void run() {
//if (LafManager.getInstance().getCurrentLookAndFeel().getName().equals(laf)) return;
laf = LafManager.getInstance().getCurrentLookAndFeel().getName();
panel.get().removeAll();
myScrollPane = null;
if (myNavigationBar != null && !Disposer.isDisposed(myNavigationBar)) {
Disposer.dispose(myNavigationBar);
}
if (myProject == null) {
return;
}
myNavigationBar = new NavBarPanel(myProject, true);
myWrapperPanel.putClientProperty("NavBarPanel", myNavigationBar);
myNavigationBar.getModel().setFixedComponent(true);
myScrollPane = ScrollPaneFactory.createScrollPane(myNavigationBar);
myScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
myScrollPane.setHorizontalScrollBar(null);
myScrollPane.setBorder(new NavBarBorder(true, 0));
myScrollPane.setOpaque(false);
myScrollPane.getViewport().setOpaque(false);
panel.get().setOpaque(true);
//panel.get().setBorder();
myNavigationBar.setBorder(null);
panel.get().add(myScrollPane, BorderLayout.CENTER);
}
};
panel.set(new JPanel(new BorderLayout()) {
@Override
public void updateUI() {
super.updateUI();
if (UISettings.getInstance().SHOW_NAVIGATION_BAR && !UISettings.getInstance().PRESENTATION_MODE) {
SwingUtilities.invokeLater(updater);
}
}
JPanel panel = new JPanel(new BorderLayout()) {
@Override
protected void paintComponent(Graphics g) {
@@ -274,10 +232,23 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
navBar.setBounds(x, (r.height - preferredSize.height) / 2,
r.width - insets.left - insets.right, preferredSize.height);
}
});
};
updater.run();
return panel.get();
myNavigationBar = new NavBarPanel(myProject, true);
myWrapperPanel.putClientProperty("NavBarPanel", myNavigationBar);
myNavigationBar.getModel().setFixedComponent(true);
myScrollPane = ScrollPaneFactory.createScrollPane(myNavigationBar);
myScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
myScrollPane.setHorizontalScrollBar(null);
myScrollPane.setBorder(new NavBarBorder(true, 0));
myScrollPane.setOpaque(false);
myScrollPane.getViewport().setOpaque(false);
panel.setOpaque(true);
myNavigationBar.setBorder(null);
panel.add(myScrollPane, BorderLayout.CENTER);
return panel;
}
@Override
@@ -0,0 +1,31 @@
/*
* Copyright 2000-2014 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.ui.components;
import com.intellij.openapi.util.Key;
import com.intellij.util.Consumer;
import javax.swing.*;
/**
* @author gregsh
*/
public interface OrphanGuardian {
Key CLIENT_PROPERTY_KEY = Key.create("OrphanGuardian");
void iterateOrphans(Consumer<JComponent> processor);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -29,6 +29,8 @@ import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.JBPopupMenu;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.util.PopupUtil;
@@ -36,8 +38,11 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.JBColor;
import com.intellij.ui.ScreenUtil;
import com.intellij.ui.content.Content;
import com.intellij.ui.mac.MacPopupMenuUI;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.PlatformUtils;
@@ -513,12 +518,33 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
fixSeparatorColor(uiDefaults);
updateToolWindows();
for (Frame frame : Frame.getFrames()) {
updateUI(frame);
}
fireLookAndFeelChanged();
}
public static void updateToolWindows() {
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project);
for (String id : toolWindowManager.getToolWindowIds()) {
final ToolWindow toolWindow = toolWindowManager.getToolWindow(id);
for (Content content : toolWindow.getContentManager().getContents()) {
final JComponent component = content.getComponent();
if (component != null) {
IJSwingUtilities.updateComponentTreeUI(component);
}
}
final JComponent c = toolWindow.getComponent();
if (c != null) {
IJSwingUtilities.updateComponentTreeUI(c);
}
}
}
}
private static void fixMenuIssues(UIDefaults uiDefaults) {
if (UIUtil.isUnderAquaLookAndFeel()) {
// update ui for popup menu to get round corners
@@ -629,7 +655,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
}
private static void patchFileChooserStrings(final UIDefaults defaults) {
if (!defaults.containsKey(ourFileChooserTextKeys [0])) {
if (!defaults.containsKey(ourFileChooserTextKeys[0])) {
// Alloy L&F does not define strings for names of context menu actions, so we have to patch them in here
for (String key : ourFileChooserTextKeys) {
defaults.put(key, IdeBundle.message(key));
@@ -37,6 +37,7 @@ import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.options.*;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.EventDispatcher;
import com.intellij.util.ui.UIUtil;
import org.jdom.Document;
@@ -44,6 +45,7 @@ import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
@@ -86,7 +88,7 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Name
loadAdditionalTextAttributes();
setGlobalScheme(myDefaultColorSchemesManager.getAllSchemes()[0]);
setGlobalSchemeInner(myDefaultColorSchemesManager.getAllSchemes()[0]);
}
private static boolean isUnitTestOrHeadlessMode() {
@@ -225,15 +227,20 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Name
}
@Override
public void setGlobalScheme(EditorColorsScheme scheme) {
String newValue = scheme == null ? getDefaultScheme().getName() : scheme.getName();
EditorColorsScheme oldValue = mySchemesManager.getCurrentScheme();
mySchemesManager.setCurrentSchemeName(newValue);
if (oldValue != null && !Comparing.equal(newValue, oldValue.getName())) {
public void setGlobalScheme(@Nullable EditorColorsScheme scheme) {
if (setGlobalSchemeInner(scheme)) {
fireChanges(scheme);
LafManager.getInstance().updateUI();
EditorFactory.getInstance().refreshAllEditors();
}
fireChanges(scheme);
}
private boolean setGlobalSchemeInner(@Nullable EditorColorsScheme scheme) {
String newValue = scheme == null ? getDefaultScheme().getName() : scheme.getName();
EditorColorsScheme oldValue = mySchemesManager.getCurrentScheme();
mySchemesManager.setCurrentSchemeName(newValue);
return oldValue != null && !Comparing.equal(newValue, oldValue.getName());
}
@NotNull
@@ -330,25 +337,14 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Name
Element element = parentNode.getChild(NODE_NAME);
if (element != null) {
String name = element.getAttributeValue(NAME_ATTR);
if (name != null && !"".equals(name.trim())) {
if (StringUtil.isNotEmpty(name)) {
myGlobalSchemeName = name;
}
}
initGlobalScheme();
}
private void initGlobalScheme() {
if (myGlobalSchemeName != null) {
setGlobalSchemeByName(myGlobalSchemeName);
}
else {
setGlobalScheme(myDefaultColorSchemesManager.getAllSchemes()[0]);
}
}
private void setGlobalSchemeByName(String schemeName) {
setGlobalScheme(mySchemesManager.findSchemeByName(schemeName));
EditorColorsScheme globalScheme =
myGlobalSchemeName != null ? mySchemesManager.findSchemeByName(myGlobalSchemeName) : myDefaultColorSchemesManager.getAllSchemes()[0];
setGlobalSchemeInner(globalScheme);
}
@Override
@@ -76,10 +76,8 @@ import com.intellij.ui.SideBorder;
import com.intellij.ui.components.JBLayeredPane;
import com.intellij.ui.components.JBScrollBar;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.Alarm;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.Processor;
import com.intellij.util.Producer;
import com.intellij.ui.components.OrphanGuardian;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.containers.Convertor;
@@ -489,6 +487,17 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myScrollPane = new MyScrollPane();
myPanel = new JPanel();
myPanel.putClientProperty(OrphanGuardian.CLIENT_PROPERTY_KEY, new OrphanGuardian() {
@Override
public void iterateOrphans(Consumer<JComponent> consumer) {
JComponent component = getPermanentHeaderComponent();
if (component != null && !component.isValid()) {
consumer.consume(component);
}
}
});
myHeaderPanel = new MyHeaderPanel();
myVerticalScrollBar = new MyScrollBar(Adjustable.VERTICAL);
myGutterComponent = new EditorGutterComponentImpl(this);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -35,10 +35,14 @@ public class TextPanel extends JComponent {
private int myRightPadding = 20;
protected TextPanel() {
setFont(SystemInfo.isMac ? UIUtil.getLabelFont().deriveFont(11.0f) : UIUtil.getLabelFont());
setOpaque(false);
}
@Override
public Font getFont() {
return SystemInfo.isMac ? UIUtil.getLabelFont().deriveFont(11.0f) : UIUtil.getLabelFont();
}
protected TextPanel(final boolean decorate) {
this();
myDecorate = decorate;
@@ -19,6 +19,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.components.OrphanGuardian;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.FilteringIterator;
import com.intellij.util.ui.UIUtil;
@@ -234,6 +235,13 @@ public class IJSwingUtilities {
c.repaint();
}
private static final Consumer<JComponent> UI_TREE_UPDATER = new Consumer<JComponent>() {
@Override
public void consume(JComponent component) {
updateComponentTreeUI0(component);
}
};
private static void updateComponentTreeUI0(Component c) {
Component[] children = null;
if (c instanceof JMenu) {
@@ -249,6 +257,10 @@ public class IJSwingUtilities {
}
if (c instanceof JComponent) {
JComponent jc = (JComponent)c;
OrphanGuardian orphans = (OrphanGuardian)jc.getClientProperty(OrphanGuardian.CLIENT_PROPERTY_KEY);
if (orphans != null) {
orphans.iterateOrphans(UI_TREE_UPDATER);
}
jc.updateUI();
JPopupMenu jpm = jc.getComponentPopupMenu();
if (jpm != null && jpm.isVisible() && jpm.getInvoker() == jc) {
@@ -68,7 +68,7 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
myDataPack = initialDataPack;
myGraphCommitCellRender = new GraphCommitCellRender(myUI.getColorManager(), logDataHolder, myDataPack.getGraphFacade(), this);
setDefaultRenderer(VirtualFile.class, new RootCellRenderer(myUI));
setDefaultRenderer(VirtualFile.class, new RootCellRenderer(myUI, myLogDataHolder.isMultiRoot()));
setDefaultRenderer(GraphCommitCell.class, myGraphCommitCellRender);
setDefaultRenderer(String.class, new StringCellRenderer());
@@ -347,8 +347,10 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
@NotNull private Color myColor = UIUtil.getTableBackground();
RootCellRenderer(@NotNull VcsLogUiImpl ui) {
RootCellRenderer(@NotNull VcsLogUiImpl ui, boolean multiRoot) {
myUi = ui;
int rootWidth = multiRoot ? ROOT_INDICATOR_WIDTH : 0;
setPreferredSize(new Dimension(rootWidth, -1));
}
@Override
@@ -376,6 +378,7 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component rendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
setBackground(isSelected ? table.getSelectionBackground() : JBColor.WHITE);
setBorder(null);
applyHighlighters(rendererComponent, row, isSelected);
return rendererComponent;
}
@@ -69,6 +69,7 @@ public abstract class AbstractPaddingCellRender extends ColoredTableCellRenderer
}
int textPadding = graphPadding + calcRefsPadding(myRefs);
setBorder(null);
append("");
appendFixedTextFragmentWidth(textPadding);
myGraphTable.applyHighlighters(this, row, isSelected);
@@ -32,6 +32,7 @@ import com.intellij.psi.xml.XmlTagChild;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.PlatformIcons;
import com.intellij.util.Processor;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomUtil;
import com.intellij.xml.XmlElementDescriptor;
@@ -43,12 +44,14 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.dom.MavenDomProjectProcessorUtils;
import org.jetbrains.idea.maven.dom.MavenDomUtil;
import org.jetbrains.idea.maven.dom.MavenSchemaProvider;
import org.jetbrains.idea.maven.dom.model.MavenDomConfiguration;
import org.jetbrains.idea.maven.dom.model.MavenDomProfile;
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
import org.jetbrains.idea.maven.dom.model.MavenDomSettingsModel;
import org.jetbrains.idea.maven.execution.MavenRunner;
import org.jetbrains.idea.maven.execution.MavenRunnerSettings;
import org.jetbrains.idea.maven.model.MavenId;
import org.jetbrains.idea.maven.plugins.api.MavenPluginDescriptor;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.utils.MavenUtil;
import org.jetbrains.idea.maven.vfs.MavenPropertiesVirtualFileSystem;
@@ -182,6 +185,27 @@ public class MavenPropertyPsiReference extends MavenPsiReference {
if (result != null) return result;
}
MavenDomConfiguration pluginCfg = DomUtil.findDomElement(myElement, MavenDomConfiguration.class);
if (pluginCfg != null) {
boolean notFound = MavenPluginDescriptor.processDescriptors(new Processor<MavenPluginDescriptor>() {
@Override
public boolean process(MavenPluginDescriptor descriptor) {
if (descriptor.properties != null) {
for (MavenPluginDescriptor.ModelProperty property : descriptor.properties) {
if (property.insideConfigurationOnly && property.name.equals(myText)) {
return false;
}
}
}
return true;
}
}, pluginCfg);
if (!notFound) {
return myElement;
}
}
if (myProjectDom != null) {
PsiElement result = MavenDomProjectProcessorUtils.searchProperty(myText, myProjectDom, myProject);
if (result != null) return result;
@@ -393,6 +417,23 @@ public class MavenPropertyPsiReference extends MavenPsiReference {
}
}
}
MavenDomConfiguration pluginCfg = DomUtil.findDomElement(myElement, MavenDomConfiguration.class);
if (pluginCfg != null) {
MavenPluginDescriptor.processDescriptors(new Processor<MavenPluginDescriptor>() {
@Override
public boolean process(MavenPluginDescriptor descriptor) {
if (descriptor.properties != null) {
for (MavenPluginDescriptor.ModelProperty property : descriptor.properties) {
if (property.insideConfigurationOnly) {
result.add(LookupElementBuilder.create(property.name).withIcon(PlatformIcons.PROPERTY_ICON));
}
}
}
return true;
}
}, pluginCfg);
}
}
private static void addVariant(List<Object> result, String name, @NotNull Object element, @Nullable String prefix, @NotNull Icon icon) {
@@ -56,7 +56,7 @@ public class MavenJUnitPatcher extends JUnitPatcher {
path = MavenPropertyResolver.resolve(path, domModel);
}
javaParameters.getClassPath().add(path);
javaParameters.getClassPath().add(resolveSurefireProperties(path));
}
}
@@ -66,7 +66,7 @@ public class MavenJUnitPatcher extends JUnitPatcher {
String propertyName = element.getName();
if (!javaParameters.getVMParametersList().hasProperty(propertyName)) {
javaParameters.getVMParametersList().addProperty(propertyName, element.getValue());
javaParameters.getVMParametersList().addProperty(propertyName, resolveSurefireProperties(element.getValue()));
}
}
}
@@ -77,7 +77,7 @@ public class MavenJUnitPatcher extends JUnitPatcher {
String variableName = element.getName();
if (javaParameters.getEnv() == null || !javaParameters.getEnv().containsKey(variableName)) {
javaParameters.addEnv(variableName, element.getValue());
javaParameters.addEnv(variableName, resolveSurefireProperties(element.getValue()));
}
}
}
@@ -86,11 +86,15 @@ public class MavenJUnitPatcher extends JUnitPatcher {
if (argLine != null && isEnabled("argLine")) {
String value = argLine.getTextTrim();
if (StringUtil.isNotEmpty(value)) {
javaParameters.getVMParametersList().addParametersString(value);
javaParameters.getVMParametersList().addParametersString(resolveSurefireProperties(value));
}
}
}
private static String resolveSurefireProperties(String value) {
return value.replaceAll("\\$\\{surefire\\.(forkNumber|threadNumber)\\}", "1");
}
private static boolean isEnabled(String s) {
return !Boolean.valueOf(System.getProperty("idea.maven.surefire.disable." + s));
}
@@ -47,8 +47,8 @@ public class MavenModelPropertiesPatcher {
for (MavenPluginDescriptor descriptor : descriptors) {
if (descriptor.properties != null) {
for (MavenPluginDescriptor.ModelProperty property : descriptor.properties) {
if (StringUtil.isNotEmpty(property.name)) {
modelProperties.setProperty(property.name, "");
if (!property.insideConfigurationOnly && StringUtil.isNotEmpty(property.name)) {
modelProperties.setProperty(property.name, StringUtil.notNullize(property.value));
}
}
}
@@ -18,12 +18,19 @@ package org.jetbrains.idea.maven.plugins.api;
import com.intellij.openapi.extensions.AbstractExtensionPointBean;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.util.Pair;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomUtil;
import com.intellij.util.xml.Required;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Property;
import com.intellij.util.xmlb.annotations.Tag;
import org.jetbrains.idea.maven.dom.model.MavenDomConfiguration;
import org.jetbrains.idea.maven.dom.model.MavenDomGoal;
import org.jetbrains.idea.maven.dom.model.MavenDomPlugin;
import org.jetbrains.idea.maven.dom.model.MavenDomPluginExecution;
import org.jetbrains.idea.maven.utils.MavenUtil;
import java.util.HashMap;
@@ -63,6 +70,12 @@ public class MavenPluginDescriptor extends AbstractExtensionPointBean {
@Attribute("name")
@Required
public String name;
@Attribute
public String value;
@Attribute
public boolean insideConfigurationOnly;
}
@Tag("param")
@@ -144,4 +157,39 @@ public class MavenPluginDescriptor extends AbstractExtensionPointBean {
return res;
}
public static boolean processDescriptors(Processor<MavenPluginDescriptor> processor, MavenDomConfiguration cfg) {
Map<String, Map<String, Map<String, List<MavenPluginDescriptor>>>> map = getDescriptorsMap();
DomElement parent = cfg.getParent();
MavenDomPlugin plugin = DomUtil.getParentOfType(parent, MavenDomPlugin.class, false);
if (plugin == null) return true;
Map<String, Map<String, List<MavenPluginDescriptor>>> groupMap = map.get(plugin.getArtifactId().getStringValue());
if (groupMap == null) return true;
Map<String, List<MavenPluginDescriptor>> goalsMap = groupMap.get(plugin.getGroupId().getStringValue());
if (goalsMap == null) return true;
List<MavenPluginDescriptor> descriptorsForAllGoals = goalsMap.get(null);
if (descriptorsForAllGoals != null) {
for (MavenPluginDescriptor descriptor : descriptorsForAllGoals) {
if (!processor.process(descriptor)) return false;
}
}
if (parent instanceof MavenDomPluginExecution) {
for (MavenDomGoal goal : ((MavenDomPluginExecution)parent).getGoals().getGoals()) {
List<MavenPluginDescriptor> descriptors = goalsMap.get(goal.getStringValue());
if (descriptors != null) {
for (MavenPluginDescriptor descriptor : descriptors) {
if (!processor.process(descriptor)) return false;
}
}
}
}
return true;
}
}
@@ -183,6 +183,9 @@
<param name="reportFormat" values="brief, plain" soft="true"/>
<param name="runOrder" values="alphabetical, reversealphabetical, random, hourly, failedfirst, balanced, filesystem" soft="true"/>
<param name="testNGArtifactName" refProvider="org.jetbrains.idea.maven.plugins.api.common.MavenCommonParamReferenceProviders$DependencyWithoutVersion"/>
<property name="surefire.threadNumber" insideConfigurationOnly="true" />
<property name="surefire.forkNumber" insideConfigurationOnly="true" />
</pluginDescriptor>
<pluginDescriptor mavenId="org.apache.maven.plugins:maven-failsafe-plugin">
@@ -51,4 +51,131 @@ class MavenSurefirePluginTest extends MavenDomTestCase {
assertCompletionVariants(myProjectPom, "main", "test")
}
void testCompletionSurefireProperties() {
importProject("""
<groupId>simpleMaven</groupId>
<artifactId>simpleMaven</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>\${surefire.<caret>}</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
</plugins>
</build>
""")
assertCompletionVariants(myProjectPom, "surefire.forkNumber", "surefire.threadNumber")
}
void testCompletionSurefirePropertiesOutsideConfiguration() {
importProject("""
<groupId>simpleMaven</groupId>
<artifactId>simpleMaven</artifactId>
<version>1.0</version>
<properties>
<aaa>\${surefire.<caret>}</aaa>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
</configuration>
</plugin>
</plugins>
</build>
""")
assertCompletionVariants(myProjectPom)
}
void testSurefirePropertiesHighlighting() {
importProject("""
<groupId>simpleMaven</groupId>
<artifactId>simpleMaven</artifactId>
<version>1.0</version>
<properties>
<aaa>\${surefire.forkNumber}</aaa>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>\${surefire.forkNumber}</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
<executions>
<execution>
<goals>
<goal>test</goal>
<goal>\${surefire.threadNumber}</goal>
</goals>
<configuration>
<debugForkedProcess>\${surefire.threadNumber}</debugForkedProcess>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
""")
createProjectPom("""
<groupId>simpleMaven</groupId>
<artifactId>simpleMaven</artifactId>
<version>1.0</version>
<properties>
<aaa>\${<error>surefire.forkNumber</error>}</aaa>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>\${surefire.forkNumber}</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
<executions>
<execution>
<goals>
<goal>test</goal>
<goal>\${<error>surefire.threadNumber</error>}</goal>
</goals>
<configuration>
<debugForkedProcess>\${surefire.threadNumber}</debugForkedProcess>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
""")
checkHighlighting()
}
}
@@ -51,23 +51,23 @@ public class PyAssignmentToLoopOrWithParameterInspection extends PyInspection {
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder,
boolean isOnTheFly,
final boolean isOnTheFly,
@NotNull final LocalInspectionToolSession session) {
return new Visitor(holder, session);
}
private static class Visitor extends PyInspectionVisitor {
private Visitor(@Nullable ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
private Visitor(@Nullable final ProblemsHolder holder, @NotNull final LocalInspectionToolSession session) {
super(holder, session);
}
@Override
public void visitPyWithStatement(PyWithStatement node) {
public void visitPyWithStatement(final PyWithStatement node) {
checkNotReDeclaringUpperLoopOrStatement(node);
}
@Override
public void visitPyForStatement(PyForStatement node) {
public void visitPyForStatement(final PyForStatement node) {
checkNotReDeclaringUpperLoopOrStatement(node);
}
@@ -75,11 +75,15 @@ public class PyAssignmentToLoopOrWithParameterInspection extends PyInspection {
* Finds first parent of specific type (See {@link #isRequiredStatement(com.intellij.psi.PsiElement)})
* that declares one of names, declared in this statement
*/
private void checkNotReDeclaringUpperLoopOrStatement(NameDefiner statement) {
for (PsiElement declaredVar : statement.iterateNames()) {
Filter filter = new Filter(handleSubscriptionsAndResolveSafely(declaredVar));
PsiElement firstParent = PsiTreeUtil.findFirstParent(statement, true, filter);
if (firstParent != null && isRequiredStatement(firstParent)) {
private void checkNotReDeclaringUpperLoopOrStatement(@NotNull final NameDefiner statement) {
for (final PsiElement declaredVar : statement.iterateNames()) {
final Filter filter = new Filter(handleSubscriptionsAndResolveSafely(declaredVar));
final PsiElement firstParent = PsiTreeUtil.findFirstParent(statement, true, filter);
if ((firstParent != null) && isRequiredStatement(firstParent)) {
// If parent is "for", we need to check that statement not declared in "else": PY-12367
if ((firstParent instanceof PyForStatement) && isDeclaredInElse(statement, (PyForStatement)firstParent)) {
continue;
}
registerProblem(declaredVar,
PyBundle.message("INSP.NAME.assignment.to.loop.or.with.parameter.display.message", declaredVar.getText()));
}
@@ -88,36 +92,52 @@ public class PyAssignmentToLoopOrWithParameterInspection extends PyInspection {
}
/**
* Filters list of parents trying to find parent that declares var that refers to {@link #node}
* Checks that element is declared in "else" statement of "for" statement
*
* @param elementToCheck element to check
* @param forStatement statement to obtain "else" part from
* @return true if declated in "Else" block
*/
private static boolean isDeclaredInElse(@NotNull final PsiElement elementToCheck, @NotNull final PyForStatement forStatement) {
final PyElsePart elsePart = forStatement.getElsePart();
if (elsePart != null) {
if (PsiTreeUtil.isAncestor(elsePart, elementToCheck, false)) {
return true;
}
}
return false;
}
/**
* Filters list of parents trying to find parent that declares var that refers to {@link #myNode}
* Returns {@link com.jetbrains.python.codeInsight.controlflow.ScopeOwner} if nothing found.
* Returns parent otherwise.
*/
private static class Filter implements Condition<PsiElement> {
private final PsiElement node;
private final PsiElement myNode;
private Filter(PsiElement node) {
this.node = node;
private Filter(final PsiElement node) {
this.myNode = node;
}
@Override
public boolean value(PsiElement psiElement) {
public boolean value(final PsiElement psiElement) {
if (psiElement instanceof ScopeOwner) {
return true; //Do not go any further
}
if (!(isRequiredStatement(psiElement))) {
if (!isRequiredStatement(psiElement)) {
return false; //Parent has wrong type, skip
}
Iterable<PyElement> varsDeclaredInStatement = ((NameDefiner)psiElement).iterateNames();
for (PsiElement varDeclaredInStatement : varsDeclaredInStatement) {
final Iterable<PyElement> varsDeclaredInStatement = ((NameDefiner)psiElement).iterateNames();
for (final PsiElement varDeclaredInStatement : varsDeclaredInStatement) {
//For each variable, declared by this parent take first declaration and open subscription list if any
PsiReference reference = handleSubscriptionsAndResolveSafely(varDeclaredInStatement).getReference();
if (reference != null && reference.isReferenceTo(node)) {
final PsiReference reference = handleSubscriptionsAndResolveSafely(varDeclaredInStatement).getReference();
if ((reference != null) && reference.isReferenceTo(myNode)) {
return true; //One of variables declared by this parent refers to node
}
}
return false;
}
}
/**
@@ -142,8 +162,8 @@ public class PyAssignmentToLoopOrWithParameterInspection extends PyInspection {
* @param element to check
* @return true if inspection should work with this element
*/
private static boolean isRequiredStatement(PsiElement element) {
private static boolean isRequiredStatement(final PsiElement element) {
assert element != null;
return element instanceof PyWithStatement || element instanceof PyForStatement;
return (element instanceof PyWithStatement) || (element instanceof PyForStatement);
}
}
@@ -59,4 +59,18 @@ class Foo(object):
def foo(self):
for self.data in [1,2,3]:
for <weak_warning descr="Variable 'self.data' already declared in 'for' loop or 'with' statement above">self.data</weak_warning> in [1,2,3]:
pass
pass
for elt in range(10):
print elt
else:
for elt in range(10):
for <weak_warning descr="Variable 'elt' already declared in 'for' loop or 'with' statement above">elt</weak_warning> in range(10):
pass
for elt in range(10):
for <weak_warning descr="Variable 'elt' already declared in 'for' loop or 'with' statement above">elt</weak_warning> in range(10):
pass
else:
for elt in range(10):
pass
@@ -87,3 +87,13 @@ class Foo(object):
for data in [1,2,3]:
for self.data in [1,2,3]:
pass
def contains_even_number(l):
"""
See: PY-12367
"""
for elt in range(10):
print elt
else:
for elt in range(10):
pass