diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java b/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java index 815ee23f9b3f..250186e74ae9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java @@ -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; + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java index 07bfe319d62f..2570d9a01f8d 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -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(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 invokeCommand = new InvokeCommand(args) { + return new InvokeCommand(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 diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerEx.java b/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerEx.java index bac53b15a4f9..b05e8b41589f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerEx.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerEx.java @@ -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); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerUtil.java b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerUtil.java index e53f9d5a520e..8113121d3e1d 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerUtil.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerUtil.java @@ -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 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 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 iterator = context.myResumedThreads.iterator(); iterator.hasNext();) { - ThreadReferenceProxyImpl resumedThreads = iterator.next(); + for (ThreadReferenceProxyImpl resumedThreads : context.myResumedThreads) { resumedThreads.suspend(); } context.myResumedThreads = null; diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java index a205bb25fd70..b6ca9eafe1f1 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java @@ -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(); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java index 464aa6ea4f35..57b1a44bb3c5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java @@ -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; } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ConditionalExpressionEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ConditionalExpressionEvaluator.java index 3514d357610b..7eacd4ace313 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ConditionalExpressionEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ConditionalExpressionEvaluator.java @@ -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)) { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ExpressionEvaluatorImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ExpressionEvaluatorImpl.java index 4b974c183b54..66fd0eb3971e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ExpressionEvaluatorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ExpressionEvaluatorImpl.java @@ -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); + } } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/LocalVariableEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/LocalVariableEvaluator.java index ce060c0bfd26..b02ec96fad31 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/LocalVariableEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/LocalVariableEvaluator.java @@ -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); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java index a4f9a8d55d48..ed1ad4c2ab46 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java @@ -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)); } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java b/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java index 8b2d875279da..72f9abf97af3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java @@ -39,6 +39,7 @@ public abstract class InvokeThread { myOwner = owner; } + @Override public void run() { synchronized (this) { while (myRequestFuture == null) { @@ -174,7 +175,7 @@ public abstract class InvokeThread { } if (LOG.isDebugEnabled()) { - LOG.debug("Request " + this.toString() + " exited"); + LOG.debug("Request " + toString() + " exited"); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java index a7fbffa5906e..94ff89a4dc31 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java @@ -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 myAllValues; + private Map 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 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 values = stackFrame.getValues(stackFrame.visibleVariables()); - myAllValues = new HashMap(values.size()); - for (final LocalVariable variable : values.keySet()) { - final Value value = values.get(variable); - myAllValues.put(variable, value); - } + StackFrame stackFrame = getStackFrame(); + myAllValues = new THashMap(stackFrame.getValues(stackFrame.visibleVariables())); } catch (InconsistentDebugInfoException ignored) { clearCaches(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java index bffe66493868..e013d7ccdcfb 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java @@ -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

implements if (!typeMatchesClassFilters(typeName)) return false; } - if (isConditionEnabled() && !getCondition().getText().isEmpty()) { - try { - ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(context.getProject(), new EvaluatingComputable() { - @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() { + @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; } diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluationContext.java b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluationContext.java index 4df12415a9b1..f6e1531cb978 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluationContext.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluationContext.java @@ -31,10 +31,12 @@ public interface EvaluationContext extends StackFrameContext{ EvaluationContext createEvaluationContext(Value value); + @NotNull SuspendContext getSuspendContext(); Project getProject(); + @Nullable ClassLoaderReference getClassLoader() throws EvaluateException; @Nullable diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java index e0c820e4da9b..474f8ddcee05 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java @@ -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 panel = new Ref(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 diff --git a/platform/platform-api/src/com/intellij/ui/components/OrphanGuardian.java b/platform/platform-api/src/com/intellij/ui/components/OrphanGuardian.java new file mode 100644 index 000000000000..c8a044c16a3c --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/components/OrphanGuardian.java @@ -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 processor); +} diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java index 8d6ff1c06035..035f7eaad846 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java @@ -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)); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java index 65eedc0b99c2..60ceeb3a015a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java @@ -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 diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index be7faaec1c56..db250af6a36d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -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 consumer) { + JComponent component = getPermanentHeaderComponent(); + if (component != null && !component.isValid()) { + consumer.consume(component); + } + } + }); + myHeaderPanel = new MyHeaderPanel(); myVerticalScrollBar = new MyScrollBar(Adjustable.VERTICAL); myGutterComponent = new EditorGutterComponentImpl(this); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/TextPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/TextPanel.java index dbd555ca941c..609b73b87111 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/TextPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/TextPanel.java @@ -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; diff --git a/platform/platform-impl/src/com/intellij/util/IJSwingUtilities.java b/platform/platform-impl/src/com/intellij/util/IJSwingUtilities.java index fc85301f9736..60c5f90c8b73 100644 --- a/platform/platform-impl/src/com/intellij/util/IJSwingUtilities.java +++ b/platform/platform-impl/src/com/intellij/util/IJSwingUtilities.java @@ -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 UI_TREE_UPDATER = new Consumer() { + @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) { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java index 5b1e1a0e7a0e..8a7ad42cb9e1 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java @@ -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; } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java index fac9b67225bc..ee95c1fea673 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/AbstractPaddingCellRender.java @@ -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); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReference.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReference.java index cee35f91c019..bebd44da248c 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReference.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReference.java @@ -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() { + @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() { + @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 result, String name, @NotNull Object element, @Nullable String prefix, @NotNull Icon icon) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenJUnitPatcher.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenJUnitPatcher.java index 0dbfc4f5e21b..d28c86af9f71 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenJUnitPatcher.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenJUnitPatcher.java @@ -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)); } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java index 047fc823199b..04039a2f95f9 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java @@ -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)); } } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenPluginDescriptor.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenPluginDescriptor.java index 56bc0fdf0c33..49b8b995dd9f 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenPluginDescriptor.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenPluginDescriptor.java @@ -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 processor, MavenDomConfiguration cfg) { + Map>>> map = getDescriptorsMap(); + + DomElement parent = cfg.getParent(); + + MavenDomPlugin plugin = DomUtil.getParentOfType(parent, MavenDomPlugin.class, false); + if (plugin == null) return true; + + Map>> groupMap = map.get(plugin.getArtifactId().getStringValue()); + if (groupMap == null) return true; + + Map> goalsMap = groupMap.get(plugin.getGroupId().getStringValue()); + if (goalsMap == null) return true; + + List 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 descriptors = goalsMap.get(goal.getStringValue()); + if (descriptors != null) { + for (MavenPluginDescriptor descriptor : descriptors) { + if (!processor.process(descriptor)) return false; + } + } + } + } + + return true; + } } diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml index 5ef7e212f02b..c1d210a8278a 100644 --- a/plugins/maven/src/main/resources/META-INF/plugin.xml +++ b/plugins/maven/src/main/resources/META-INF/plugin.xml @@ -183,6 +183,9 @@ + + + diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/plugins/surefire/MavenSurefirePluginTest.groovy b/plugins/maven/src/test/java/org/jetbrains/idea/maven/plugins/surefire/MavenSurefirePluginTest.groovy index 2d76b7028440..b57b52837249 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/plugins/surefire/MavenSurefirePluginTest.groovy +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/plugins/surefire/MavenSurefirePluginTest.groovy @@ -51,4 +51,131 @@ class MavenSurefirePluginTest extends MavenDomTestCase { assertCompletionVariants(myProjectPom, "main", "test") } + void testCompletionSurefireProperties() { + importProject(""" + simpleMaven + simpleMaven + 1.0 + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + \${surefire.} + + + + + +""") + + assertCompletionVariants(myProjectPom, "surefire.forkNumber", "surefire.threadNumber") + } + + void testCompletionSurefirePropertiesOutsideConfiguration() { + importProject(""" + simpleMaven + simpleMaven + 1.0 + + + \${surefire.} + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + +""") + + assertCompletionVariants(myProjectPom) + } + + void testSurefirePropertiesHighlighting() { + importProject(""" + simpleMaven + simpleMaven + 1.0 + + + \${surefire.forkNumber} + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + \${surefire.forkNumber} + + + + + + + test + \${surefire.threadNumber} + + + \${surefire.threadNumber} + + + + + + +""") + + createProjectPom(""" + simpleMaven + simpleMaven + 1.0 + + + \${surefire.forkNumber} + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + \${surefire.forkNumber} + + + + + + + test + \${surefire.threadNumber} + + + \${surefire.threadNumber} + + + + + + + +""") + + checkHighlighting() + } + + } diff --git a/python/src/com/jetbrains/python/inspections/PyAssignmentToLoopOrWithParameterInspection.java b/python/src/com/jetbrains/python/inspections/PyAssignmentToLoopOrWithParameterInspection.java index 2efaf9868243..e51c2d5b056a 100644 --- a/python/src/com/jetbrains/python/inspections/PyAssignmentToLoopOrWithParameterInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyAssignmentToLoopOrWithParameterInspection.java @@ -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 { - 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 varsDeclaredInStatement = ((NameDefiner)psiElement).iterateNames(); - for (PsiElement varDeclaredInStatement : varsDeclaredInStatement) { + final Iterable 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); } } diff --git a/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/bad.py b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/bad.py index c6492c1713d1..5743a85553f6 100644 --- a/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/bad.py +++ b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/bad.py @@ -59,4 +59,18 @@ class Foo(object): def foo(self): for self.data in [1,2,3]: for self.data in [1,2,3]: - pass \ No newline at end of file + pass + +for elt in range(10): + print elt +else: + for elt in range(10): + for elt in range(10): + pass + +for elt in range(10): + for elt in range(10): + pass +else: + for elt in range(10): + pass \ No newline at end of file diff --git a/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/good.py b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/good.py index f324656ca216..2e52d144c8a7 100644 --- a/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/good.py +++ b/python/testData/inspections/PyAssignmentToLoopOrWithParameterInspection/good.py @@ -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 \ No newline at end of file