3 * Copyright 2000-2009 JetBrains s.r.o.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 package com
.intellij
.codeInsight
.generation
.surroundWith
;
19 import com
.intellij
.openapi
.diagnostic
.Logger
;
20 import com
.intellij
.openapi
.util
.TextRange
;
21 import com
.intellij
.psi
.*;
22 import com
.intellij
.psi
.codeStyle
.CodeStyleManager
;
23 import com
.intellij
.psi
.search
.GlobalSearchScope
;
24 import com
.intellij
.psi
.search
.searches
.ReferencesSearch
;
25 import com
.intellij
.psi
.util
.PsiTypesUtil
;
26 import com
.intellij
.util
.IncorrectOperationException
;
28 import java
.util
.ArrayList
;
30 public class SurroundWithUtil
{
31 private static final Logger LOG
= Logger
.getInstance("#com.intellij.codeInsight.generation.surroundWith.SurroundWithUtil");
32 static PsiElement
[] moveDeclarationsOut(PsiElement block
, PsiElement
[] statements
, boolean generateInitializers
) {
34 PsiManager psiManager
= block
.getManager();
35 PsiElementFactory factory
= JavaPsiFacade
.getInstance(psiManager
.getProject()).getElementFactory();
36 ArrayList
<PsiElement
> array
= new ArrayList
<PsiElement
>();
37 for (PsiElement statement
: statements
) {
38 if (statement
instanceof PsiDeclarationStatement
) {
39 PsiDeclarationStatement declaration
= (PsiDeclarationStatement
)statement
;
40 if (needToDeclareOut(block
, statements
, declaration
)) {
41 PsiElement
[] elements
= declaration
.getDeclaredElements();
42 for (PsiElement element
: elements
) {
43 PsiVariable var
= (PsiVariable
)element
;
44 PsiExpression initializer
= var
.getInitializer();
45 if (initializer
!= null) {
46 String name
= var
.getName();
47 PsiExpressionStatement assignment
= (PsiExpressionStatement
)factory
.createStatementFromText(name
+ "=x;", null);
48 assignment
= (PsiExpressionStatement
)CodeStyleManager
.getInstance(psiManager
.getProject()).reformat(assignment
);
49 PsiAssignmentExpression expr
= (PsiAssignmentExpression
)assignment
.getExpression();
50 expr
.getRExpression().replace(initializer
);
51 assignment
= (PsiExpressionStatement
)block
.addAfter(assignment
, declaration
);
52 array
.add(assignment
);
55 PsiDeclarationStatement newDeclaration
;
56 if (!array
.isEmpty()) {
57 PsiElement firstStatement
= array
.get(0);
58 newDeclaration
= (PsiDeclarationStatement
)block
.addBefore(declaration
, firstStatement
);
62 newDeclaration
= declaration
;
64 elements
= newDeclaration
.getDeclaredElements();
65 for (PsiElement element1
: elements
) {
66 PsiVariable var
= (PsiVariable
)element1
;
67 PsiExpression initializer
= var
.getInitializer();
68 if (initializer
!= null) {
69 if (!generateInitializers
|| var
.hasModifierProperty(PsiModifier
.FINAL
)) {
73 String defaultValue
= PsiTypesUtil
.getDefaultValueOfType(var
.getType());
74 PsiExpression expr
= factory
.createExpressionFromText(defaultValue
, null);
75 initializer
.replace(expr
);
84 return array
.toArray(new PsiElement
[array
.size()]);
86 catch(IncorrectOperationException e
){
92 private static boolean needToDeclareOut(PsiElement block
, PsiElement
[] statements
, PsiDeclarationStatement statement
) {
93 PsiElement
[] elements
= statement
.getDeclaredElements();
94 PsiElement lastStatement
= statements
[statements
.length
- 1];
95 int endOffset
= lastStatement
.getTextRange().getEndOffset();
96 for (PsiElement element
: elements
) {
97 if (element
instanceof PsiVariable
) {
98 GlobalSearchScope projectScope
= GlobalSearchScope
.projectScope(element
.getProject());
99 PsiReference
[] refs
= ReferencesSearch
.search(element
, projectScope
, false).toArray(PsiReference
.EMPTY_ARRAY
);
100 if (refs
.length
> 0) {
101 PsiReference lastRef
= refs
[refs
.length
- 1];
102 if (lastRef
.getElement().getTextOffset() > endOffset
) {
111 public static TextRange
getRangeToSelect (PsiCodeBlock block
) {
112 PsiElement first
= block
.getFirstBodyElement();
113 if (first
instanceof PsiWhiteSpace
) {
114 first
= first
.getNextSibling();
117 int offset
= block
.getTextRange().getStartOffset() + 1;
118 return new TextRange(offset
, offset
);
120 PsiElement last
= block
.getRBrace().getPrevSibling();
121 if (last
instanceof PsiWhiteSpace
) {
122 last
= last
.getPrevSibling();
124 return new TextRange(first
.getTextRange().getStartOffset(), last
.getTextRange().getEndOffset());