| /* |
| * 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.debugger.ui.impl.watch; |
| |
| import com.intellij.debugger.DebuggerBundle; |
| import com.intellij.debugger.DebuggerContext; |
| import com.intellij.debugger.SourcePosition; |
| import com.intellij.debugger.engine.DebuggerUtils; |
| import com.intellij.debugger.engine.evaluation.EvaluateException; |
| import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; |
| import com.intellij.debugger.impl.DebuggerContextImpl; |
| import com.intellij.debugger.impl.DebuggerContextUtil; |
| import com.intellij.debugger.impl.PositionUtil; |
| import com.intellij.debugger.jdi.LocalVariableProxyImpl; |
| import com.intellij.debugger.jdi.StackFrameProxyImpl; |
| import com.intellij.debugger.settings.NodeRendererSettings; |
| import com.intellij.debugger.ui.tree.LocalVariableDescriptor; |
| import com.intellij.debugger.ui.tree.NodeDescriptor; |
| import com.intellij.debugger.ui.tree.render.ClassRenderer; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.psi.*; |
| import com.intellij.util.IncorrectOperationException; |
| import com.intellij.util.StringBuilderSpinAllocator; |
| import com.sun.jdi.Value; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| public class LocalVariableDescriptorImpl extends ValueDescriptorImpl implements LocalVariableDescriptor { |
| private final StackFrameProxyImpl myFrameProxy; |
| private final LocalVariableProxyImpl myLocalVariable; |
| |
| private String myTypeName = DebuggerBundle.message("label.unknown.value"); |
| private boolean myIsPrimitive; |
| |
| private boolean myIsNewLocal = true; |
| |
| public LocalVariableDescriptorImpl(Project project, |
| @NotNull LocalVariableProxyImpl local) { |
| super(project); |
| setLvalue(true); |
| myFrameProxy = local.getFrame(); |
| myLocalVariable = local; |
| } |
| |
| @Override |
| public LocalVariableProxyImpl getLocalVariable() { |
| return myLocalVariable; |
| } |
| |
| @Nullable |
| public SourcePosition getSourcePosition(final Project project, final DebuggerContextImpl context) { |
| return getSourcePosition(project, context, false); |
| } |
| |
| @Nullable |
| public SourcePosition getSourcePosition(final Project project, final DebuggerContextImpl context, boolean nearest) { |
| StackFrameProxyImpl frame = context.getFrameProxy(); |
| if (frame == null) return null; |
| |
| PsiElement place = PositionUtil.getContextElement(context); |
| |
| if (place == null) { |
| return null; |
| } |
| |
| PsiVariable psiVariable = JavaPsiFacade.getInstance(project).getResolveHelper().resolveReferencedVariable(getName(), place); |
| if (psiVariable == null) { |
| return null; |
| } |
| |
| PsiFile containingFile = psiVariable.getContainingFile(); |
| if(containingFile == null) return null; |
| if (nearest) { |
| return DebuggerContextUtil.findNearest(context, psiVariable, containingFile); |
| } |
| return SourcePosition.createFromOffset(containingFile, psiVariable.getTextOffset()); |
| } |
| |
| public boolean isNewLocal() { |
| return myIsNewLocal; |
| } |
| |
| @Override |
| public boolean isPrimitive() { |
| return myIsPrimitive; |
| } |
| |
| @Override |
| public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException { |
| boolean isVisible = myFrameProxy.isLocalVariableVisible(getLocalVariable()); |
| if (isVisible) { |
| final String typeName = getLocalVariable().typeName(); |
| myTypeName = typeName; |
| myIsPrimitive = DebuggerUtils.isPrimitiveType(typeName); |
| return myFrameProxy.getValue(getLocalVariable()); |
| } |
| |
| return null; |
| } |
| |
| public void setNewLocal(boolean aNew) { |
| myIsNewLocal = aNew; |
| } |
| |
| @Override |
| public void displayAs(NodeDescriptor descriptor) { |
| super.displayAs(descriptor); |
| if(descriptor instanceof LocalVariableDescriptorImpl) { |
| myIsNewLocal = ((LocalVariableDescriptorImpl)descriptor).myIsNewLocal; |
| } |
| } |
| |
| @Override |
| public String getName() { |
| return myLocalVariable.name(); |
| } |
| |
| @Override |
| public String calcValueName() { |
| final ClassRenderer classRenderer = NodeRendererSettings.getInstance().getClassRenderer(); |
| StringBuilder buf = StringBuilderSpinAllocator.alloc(); |
| try { |
| buf.append(getName()); |
| if (classRenderer.SHOW_DECLARED_TYPE) { |
| buf.append(": "); |
| buf.append(classRenderer.renderTypeName(myTypeName)); |
| } |
| return buf.toString(); |
| } |
| finally { |
| StringBuilderSpinAllocator.dispose(buf); |
| } |
| } |
| |
| @Override |
| public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException { |
| PsiElementFactory elementFactory = JavaPsiFacade.getInstance(context.getProject()).getElementFactory(); |
| try { |
| return elementFactory.createExpressionFromText(getName(), PositionUtil.getContextElement(context)); |
| } |
| catch (IncorrectOperationException e) { |
| throw new EvaluateException(DebuggerBundle.message("error.invalid.local.variable.name", getName()), e); |
| } |
| } |
| } |