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
.refactoring
.introduceField
;
18 import com
.intellij
.codeInsight
.CodeInsightUtil
;
19 import com
.intellij
.codeInsight
.TargetElementUtilBase
;
20 import com
.intellij
.openapi
.editor
.Editor
;
21 import com
.intellij
.openapi
.editor
.RangeMarker
;
22 import com
.intellij
.openapi
.project
.Project
;
23 import com
.intellij
.openapi
.util
.Key
;
24 import com
.intellij
.openapi
.util
.Pass
;
25 import com
.intellij
.psi
.*;
26 import com
.intellij
.psi
.util
.PsiTreeUtil
;
27 import com
.intellij
.psi
.util
.PsiUtil
;
28 import com
.intellij
.refactoring
.RefactoringBundle
;
29 import com
.intellij
.refactoring
.introduceVariable
.IntroduceVariableBase
;
30 import com
.intellij
.refactoring
.util
.CommonRefactoringUtil
;
32 import java
.util
.List
;
37 public class ElementToWorkOn
{
38 public static final Key
<PsiElement
> PARENT
= Key
.create("PARENT");
39 private final PsiExpression myExpression
;
40 private final PsiLocalVariable myLocalVariable
;
41 public static final Key
<String
> PREFIX
= Key
.create("prefix");
42 public static final Key
<String
> SUFFIX
= Key
.create("suffix");
43 public static final Key
<RangeMarker
> TEXT_RANGE
= Key
.create("range");
45 private ElementToWorkOn(PsiLocalVariable localVariable
, PsiExpression expr
) {
46 myLocalVariable
= localVariable
;
50 public PsiExpression
getExpression() {
54 public PsiLocalVariable
getLocalVariable() {
55 return myLocalVariable
;
58 public boolean isInvokedOnDeclaration() {
59 return myExpression
== null;
62 public static void processElementToWorkOn(final Editor editor
, final PsiFile file
, final String refactoringName
, final String helpId
, final Project project
, final Pass
<ElementToWorkOn
> processor
) {
63 PsiLocalVariable localVar
= null;
64 PsiExpression expr
= null;
66 if (!editor
.getSelectionModel().hasSelection()) {
67 PsiElement element
= TargetElementUtilBase
.findTargetElement(editor
, TargetElementUtilBase
68 .ELEMENT_NAME_ACCEPTED
| TargetElementUtilBase
69 .REFERENCED_ELEMENT_ACCEPTED
| TargetElementUtilBase
70 .LOOKUP_ITEM_ACCEPTED
);
71 if (element
instanceof PsiLocalVariable
) {
72 localVar
= (PsiLocalVariable
) element
;
73 final PsiElement elementAt
= file
.findElementAt(editor
.getCaretModel().getOffset());
74 if (elementAt
instanceof PsiIdentifier
&& elementAt
.getParent() instanceof PsiReferenceExpression
) {
75 expr
= (PsiExpression
) elementAt
.getParent();
78 final PsiLocalVariable variable
= PsiTreeUtil
.getParentOfType(file
.findElementAt(editor
.getCaretModel().getOffset()), PsiLocalVariable
.class);
80 final int offset
= editor
.getCaretModel().getOffset();
81 final PsiElement
[] statementsInRange
= IntroduceVariableBase
.findStatementsAtOffset(editor
, file
, offset
);
82 if (statementsInRange
.length
== 1 && PsiUtil
.hasErrorElementChild(statementsInRange
[0])) {
83 editor
.getSelectionModel().selectLineAtCaret();
85 final List
<PsiExpression
> expressions
= IntroduceVariableBase
.collectExpressions(file
, editor
, offset
, statementsInRange
);
86 if (expressions
.isEmpty()) {
87 editor
.getSelectionModel().selectLineAtCaret();
89 else if (expressions
.size() == 1) {
90 expr
= expressions
.get(0);
93 IntroduceVariableBase
.showChooser(editor
, expressions
, new Pass
<PsiExpression
>() {
95 public void pass(final PsiExpression selectedValue
) {
96 PsiLocalVariable var
= null; //replace var if selected expression == var initializer
97 if (variable
!= null && variable
.getInitializer() == selectedValue
) {
100 processor
.pass(getElementToWorkOn(editor
, file
, refactoringName
, helpId
, project
, var
, selectedValue
));
110 processor
.pass(getElementToWorkOn(editor
, file
, refactoringName
, helpId
, project
, localVar
, expr
));
113 private static ElementToWorkOn
getElementToWorkOn(final Editor editor
, final PsiFile file
,
114 final String refactoringName
,
116 final Project project
, PsiLocalVariable localVar
, PsiExpression expr
) {
119 if (localVar
== null && expr
== null) {
120 startOffset
= editor
.getSelectionModel().getSelectionStart();
121 endOffset
= editor
.getSelectionModel().getSelectionEnd();
122 expr
= CodeInsightUtil
.findExpressionInRange(file
, startOffset
, endOffset
);
124 PsiIdentifier ident
= CodeInsightUtil
.findElementInRange(file
, startOffset
, endOffset
, PsiIdentifier
.class);
126 localVar
= PsiTreeUtil
.getParentOfType(ident
, PsiLocalVariable
.class);
131 if (expr
== null && localVar
== null) {
132 PsiElement
[] statements
= CodeInsightUtil
.findStatementsInRange(file
, startOffset
, endOffset
);
133 if (statements
.length
== 1 && statements
[0] instanceof PsiExpressionStatement
) {
134 expr
= ((PsiExpressionStatement
)statements
[0]).getExpression();
136 else if (statements
.length
== 1 && statements
[0] instanceof PsiDeclarationStatement
) {
137 PsiDeclarationStatement decl
= (PsiDeclarationStatement
)statements
[0];
138 PsiElement
[] declaredElements
= decl
.getDeclaredElements();
139 if (declaredElements
.length
== 1 && declaredElements
[0] instanceof PsiLocalVariable
) {
140 localVar
= (PsiLocalVariable
)declaredElements
[0];
144 if (localVar
== null && expr
== null) {
145 expr
= IntroduceVariableBase
.getSelectedExpression(project
, file
, startOffset
, endOffset
);
148 if (localVar
== null && expr
== null) {
149 String message
= RefactoringBundle
.getCannotRefactorMessage(RefactoringBundle
.message("error.wrong.caret.position.local.or.expression.name"));
150 CommonRefactoringUtil
.showErrorHint(project
, editor
, message
, refactoringName
, helpId
);
153 return new ElementToWorkOn(localVar
, expr
);