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");
41 public static SourcePosition
getSourcePosition(final StackFrameContext context
) {
42 DebugProcessImpl debugProcess
= (DebugProcessImpl
)context
.getDebugProcess();
43 if(debugProcess
== null) {
46 final StackFrameProxy frameProxy
= context
.getFrameProxy();
47 if(frameProxy
== null) {
50 Location location
= null;
52 location
= frameProxy
.location();
54 catch (Throwable th
) {
57 final CompoundPositionManager positionManager
= debugProcess
.getPositionManager();
58 if (positionManager
== null) {
59 // process already closed
63 return positionManager
.getSourcePosition(location
);
64 } catch (IndexNotReadyException e
) {
70 public static PsiElement
getContextElement(final StackFrameContext context
) {
71 return getContextElement(context
, getSourcePosition(context
));
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
);
87 final StackFrameProxyImpl frameProxy
= (StackFrameProxyImpl
)context
.getFrameProxy();
89 if(frameProxy
== null) {
93 final StringBuilder buf
= StringBuilderSpinAllocator
.alloc();
95 List
<LocalVariableProxyImpl
> list
= frameProxy
.visibleVariables();
97 PsiResolveHelper resolveHelper
= JavaPsiFacade
.getInstance(element
.getProject()).getResolveHelper();
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(";");
107 if (buf
.length() <= 2) {
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
) {
128 catch (EvaluateException e
) {
132 StringBuilderSpinAllocator
.dispose(buf
);
137 public static PsiElement
getContextElement(final SourcePosition position
) {
138 if(position
== null) {
142 return getContextElementInText(position
.getFile(), position
.getLine());
146 private static PsiElement
getContextElementInText(PsiFile psiFile
, int lineNumber
) {
151 final Document document
= PsiDocumentManager
.getInstance(psiFile
.getProject()).getDocument(psiFile
);
152 if (document
== null) {
155 if (lineNumber
>= document
.getLineCount()) {
158 int startOffset
= document
.getLineStartOffset(lineNumber
);
159 if(startOffset
== -1) {
164 final PsiElement rootElement
= JspPsiUtil
.isInJspFile(psiFile
) ?
(JspPsiUtil
.getJspFile(psiFile
)).getJavaClass() : psiFile
;
166 final CharSequence charsSequence
= document
.getCharsSequence();
167 for (; startOffset
< charsSequence
.length(); startOffset
++) {
168 char c
= charsSequence
.charAt(startOffset
);
169 if (c
!= ' ' && c
!= '\t') {
173 element
= rootElement
.findElementAt(startOffset
);
175 if(element
instanceof PsiComment
) {
176 startOffset
= element
.getTextRange().getEndOffset() + 1;
183 if (element
!= null && element
.getParent() instanceof PsiForStatement
) {
184 return ((PsiForStatement
)element
.getParent()).getInitialization();
191 public static boolean isJspImplicit(PsiElement element
) {
192 return Boolean
.TRUE
.equals(element
.getUserData(IS_JSP_IMPLICIT
));