catch INRE in debugger
[fedora-idea.git] / java / debugger / impl / src / com / intellij / debugger / engine / ContextUtil.java
blob161fb5846467a2fb00da0cdac700ab90802c071c
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.debugger.engine;
18 import com.intellij.debugger.SourcePosition;
19 import com.intellij.debugger.engine.evaluation.EvaluateException;
20 import com.intellij.debugger.engine.jdi.StackFrameProxy;
21 import com.intellij.debugger.jdi.LocalVariableProxyImpl;
22 import com.intellij.debugger.jdi.StackFrameProxyImpl;
23 import com.intellij.openapi.diagnostic.Logger;
24 import com.intellij.openapi.editor.Document;
25 import com.intellij.openapi.project.IndexNotReadyException;
26 import com.intellij.openapi.util.Comparing;
27 import com.intellij.openapi.util.Key;
28 import com.intellij.psi.*;
29 import com.intellij.util.IncorrectOperationException;
30 import com.intellij.util.StringBuilderSpinAllocator;
31 import com.sun.jdi.Location;
32 import org.jetbrains.annotations.Nullable;
34 import java.util.List;
36 public class ContextUtil {
37 public static final Key<Boolean> IS_JSP_IMPLICIT = new Key<Boolean>("JspImplicit");
38 private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.PositionUtil");
40 @Nullable
41 public static SourcePosition getSourcePosition(final StackFrameContext context) {
42 DebugProcessImpl debugProcess = (DebugProcessImpl)context.getDebugProcess();
43 if(debugProcess == null) {
44 return null;
46 final StackFrameProxy frameProxy = context.getFrameProxy();
47 if(frameProxy == null) {
48 return null;
50 Location location = null;
51 try {
52 location = frameProxy.location();
54 catch (Throwable th) {
55 LOG.debug(th);
57 final CompoundPositionManager positionManager = debugProcess.getPositionManager();
58 if (positionManager == null) {
59 // process already closed
60 return null;
62 try {
63 return positionManager.getSourcePosition(location);
64 } catch (IndexNotReadyException e) {
65 return null;
69 @Nullable
70 public static PsiElement getContextElement(final StackFrameContext context) {
71 return getContextElement(context, getSourcePosition(context));
74 @Nullable
75 protected static PsiElement getContextElement(final StackFrameContext context, final SourcePosition position) {
76 if(LOG.isDebugEnabled()) {
77 final SourcePosition sourcePosition = getSourcePosition(context);
78 LOG.assertTrue(Comparing.equal(sourcePosition, position));
81 final PsiElement element = getContextElement(position);
83 if(element == null) {
84 return null;
87 final StackFrameProxyImpl frameProxy = (StackFrameProxyImpl)context.getFrameProxy();
89 if(frameProxy == null) {
90 return element;
93 final StringBuilder buf = StringBuilderSpinAllocator.alloc();
94 try {
95 List<LocalVariableProxyImpl> list = frameProxy.visibleVariables();
97 PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(element.getProject()).getResolveHelper();
98 buf.append('{');
99 for (LocalVariableProxyImpl localVariable : list) {
100 final String varName = localVariable.name();
101 if (resolveHelper.resolveReferencedVariable(varName, element) == null) {
102 buf.append(localVariable.getVariable().typeName()).append(" ").append(varName).append(";");
105 buf.append('}');
107 if (buf.length() <= 2) {
108 return element;
110 final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(element.getProject()).getElementFactory();
111 final PsiCodeBlock codeBlockFromText = elementFactory.createCodeBlockFromText(buf.toString(), element);
113 final PsiStatement[] statements = codeBlockFromText.getStatements();
114 for (PsiStatement statement : statements) {
115 if (statement instanceof PsiDeclarationStatement) {
116 PsiDeclarationStatement declStatement = (PsiDeclarationStatement)statement;
117 PsiElement[] declaredElements = declStatement.getDeclaredElements();
118 for (PsiElement declaredElement : declaredElements) {
119 declaredElement.putUserData(IS_JSP_IMPLICIT, Boolean.TRUE);
123 return codeBlockFromText;
125 catch (IncorrectOperationException e) {
126 return element;
128 catch (EvaluateException e) {
129 return element;
131 finally {
132 StringBuilderSpinAllocator.dispose(buf);
136 @Nullable
137 public static PsiElement getContextElement(final SourcePosition position) {
138 if(position == null) {
139 return null;
142 return getContextElementInText(position.getFile(), position.getLine());
145 @Nullable
146 private static PsiElement getContextElementInText(PsiFile psiFile, int lineNumber) {
147 if(lineNumber < 0) {
148 return psiFile;
151 final Document document = PsiDocumentManager.getInstance(psiFile.getProject()).getDocument(psiFile);
152 if (document == null) {
153 return null;
155 if (lineNumber >= document.getLineCount()) {
156 return psiFile;
158 int startOffset = document.getLineStartOffset(lineNumber);
159 if(startOffset == -1) {
160 return null;
163 PsiElement element;
164 final PsiElement rootElement = JspPsiUtil.isInJspFile(psiFile) ? (JspPsiUtil.getJspFile(psiFile)).getJavaClass() : psiFile;
165 while(true) {
166 final CharSequence charsSequence = document.getCharsSequence();
167 for (; startOffset < charsSequence.length(); startOffset++) {
168 char c = charsSequence.charAt(startOffset);
169 if (c != ' ' && c != '\t') {
170 break;
173 element = rootElement.findElementAt(startOffset);
175 if(element instanceof PsiComment) {
176 startOffset = element.getTextRange().getEndOffset() + 1;
178 else{
179 break;
183 if (element != null && element.getParent() instanceof PsiForStatement) {
184 return ((PsiForStatement)element.getParent()).getInitialization();
186 else {
187 return element;
191 public static boolean isJspImplicit(PsiElement element) {
192 return Boolean.TRUE.equals(element.getUserData(IS_JSP_IMPLICIT));