update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / refactoring / introduceField / ElementToWorkOn.java
blob26f2a212b2047197fc73a54bf46558b44341286f
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.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;
34 /**
35 * @author dsl
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;
47 myExpression = expr;
50 public PsiExpression getExpression() {
51 return myExpression;
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();
77 } else {
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();
84 } else {
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);
92 else {
93 IntroduceVariableBase.showChooser(editor, expressions, new Pass<PsiExpression>() {
94 @Override
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) {
98 var = variable;
100 processor.pass(getElementToWorkOn(editor, file, refactoringName, helpId, project, var, selectedValue));
103 return;
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,
115 final String helpId,
116 final Project project, PsiLocalVariable localVar, PsiExpression expr) {
117 int startOffset = 0;
118 int endOffset = 0;
119 if (localVar == null && expr == null) {
120 startOffset = editor.getSelectionModel().getSelectionStart();
121 endOffset = editor.getSelectionModel().getSelectionEnd();
122 expr = CodeInsightUtil.findExpressionInRange(file, startOffset, endOffset);
123 if (expr == null) {
124 PsiIdentifier ident = CodeInsightUtil.findElementInRange(file, startOffset, endOffset, PsiIdentifier.class);
125 if (ident != null) {
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);
151 return null;
153 return new ElementToWorkOn(localVar, expr);