private static PsiStatement addInitializationToConstructors( PsiLocalVariable local, PsiField field, PsiMethod enclosingConstructor, PsiElementFactory factory) throws IncorrectOperationException { PsiClass aClass = field.getContainingClass(); PsiMethod[] constructors = aClass.getConstructors(); PsiStatement assignment = createAssignment(local, field.getName(), factory); boolean added = false; for (PsiMethod constructor : constructors) { if (constructor == enclosingConstructor) continue; PsiCodeBlock body = constructor.getBody(); if (body == null) continue; PsiStatement[] statements = body.getStatements(); if (statements.length > 0) { PsiStatement first = statements[0]; if (first instanceof PsiExpressionStatement) { PsiExpression expression = ((PsiExpressionStatement) first).getExpression(); if (expression instanceof PsiMethodCallExpression) { @NonNls String text = ((PsiMethodCallExpression) expression).getMethodExpression().getText(); if ("this".equals(text)) { continue; } if ("super".equals(text) && enclosingConstructor == null && PsiTreeUtil.isAncestor(constructor, local, false)) { local.delete(); return (PsiStatement) body.addAfter(assignment, first); } } } if (enclosingConstructor == null && PsiTreeUtil.isAncestor(constructor, local, false)) { local.delete(); return (PsiStatement) body.addBefore(assignment, first); } } assignment = (PsiStatement) body.add(assignment); added = true; } if (!added && enclosingConstructor == null) { if (aClass instanceof PsiAnonymousClass) { final PsiClassInitializer classInitializer = (PsiClassInitializer) aClass.addAfter(factory.createClassInitializer(), field); assignment = (PsiStatement) classInitializer.getBody().add(assignment); } else { PsiMethod constructor = (PsiMethod) aClass.add(factory.createConstructor()); assignment = (PsiStatement) constructor.getBody().add(assignment); } } if (enclosingConstructor == null) local.delete(); return assignment; }
public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { final PsiLocalVariable variable = (PsiLocalVariable) element; final PsiReference[] references = ReferencesSearch.search(variable, variable.getUseScope(), false) .toArray(PsiReference.EMPTY_ARRAY); final PsiCodeBlock tightestBlock = MoveDeclarationPredicate.getTightestBlock(references); assert tightestBlock != null; final PsiDeclarationStatement declaration = (PsiDeclarationStatement) variable.getParent(); final PsiReference firstReference = references[0]; final PsiElement referenceElement = firstReference.getElement(); PsiDeclarationStatement newDeclaration; if (tightestBlock.equals(PsiTreeUtil.getParentOfType(referenceElement, PsiCodeBlock.class))) { // containing block of first reference is the same as the common // block of all. newDeclaration = moveDeclarationToReference(referenceElement, variable, tightestBlock); } else { // declaration must be moved to common block (first reference block // is too deep) final PsiElement child = MoveDeclarationPredicate.getChildWhichContainsElement(tightestBlock, referenceElement); newDeclaration = createNewDeclaration(variable, null); newDeclaration = (PsiDeclarationStatement) tightestBlock.addBefore(newDeclaration, child); } assert declaration != null; if (declaration.getDeclaredElements().length == 1) { declaration.delete(); } else { variable.delete(); } highlightElement(newDeclaration); }
private static PsiStatement addInitializationToSetUp( final PsiLocalVariable local, final PsiField field, final PsiElementFactory factory) throws IncorrectOperationException { PsiMethod inClass = TestFrameworks.getInstance().findOrCreateSetUpMethod(field.getContainingClass()); assert inClass != null; PsiStatement assignment = createAssignment(local, field.getName(), factory); final PsiCodeBlock body = inClass.getBody(); assert body != null; if (PsiTreeUtil.isAncestor(body, local, false)) { assignment = (PsiStatement) body.addBefore(assignment, PsiTreeUtil.getParentOfType(local, PsiStatement.class)); } else { assignment = (PsiStatement) body.add(assignment); } local.delete(); return assignment; }
public void run() { try { final boolean rebindNeeded2 = !myVariableName.equals(myFieldName) || myRebindNeeded; final PsiReference[] refs; if (rebindNeeded2) { refs = ReferencesSearch.search(myLocal, GlobalSearchScope.projectScope(myProject), false) .toArray(new PsiReference[0]); } else { refs = null; } final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); PsiVariable psiVariable = facade.getResolveHelper().resolveAccessibleReferencedVariable(myFieldName, myLocal); if (psiVariable != null && (!psiVariable.equals(myLocal))) { CommonRefactoringUtil.showErrorMessage( GosuIntroduceFieldHandler.REFACTORING_NAME, LOCAL_VARIABLE_WITH_THIS_NAME_ALREADY_EXISTS, HelpID.INTRODUCE_FIELD, myProject); return; } if (refs != null) { for (PsiReference occur : refs) { psiVariable = facade .getResolveHelper() .resolveAccessibleReferencedVariable(myFieldName, (PsiElement) occur); if (psiVariable != null && (psiVariable.getName().equals(myFieldName))) { CommonRefactoringUtil.showErrorMessage( GosuIntroduceFieldHandler.REFACTORING_NAME, LOCAL_VARIABLE_WITH_THIS_NAME_ALREADY_EXISTS, HelpID.INTRODUCE_FIELD, myProject); return; } } } final PsiMethod enclosingConstructor = GosuBaseExpressionToFieldHandler.getEnclosingConstructor(myDestinationClass, myLocal); myField = mySettings.isIntroduceEnumConstant() ? EnumConstantsUtil.createEnumConstant(myDestinationClass, myLocal, myFieldName) : createField( myLocal, mySettings.getForcedType(), myFieldName, myInitializerPlace == IN_FIELD_DECLARATION); myField = (PsiField) myDestinationClass.add(myField); GosuBaseExpressionToFieldHandler.setModifiers(myField, mySettings); if (!mySettings.isIntroduceEnumConstant()) { VisibilityUtil.fixVisibility(myOccurences, myField, mySettings.getFieldVisibility()); } myLocal.normalizeDeclaration(); // PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement) // myLocal.getParent(); final GosuBaseExpressionToFieldHandler.InitializationPlace finalInitializerPlace; if (myLocal.getInitializer() == null) { finalInitializerPlace = IN_FIELD_DECLARATION; } else { finalInitializerPlace = myInitializerPlace; } final PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory(); switch (finalInitializerPlace) { case IN_FIELD_DECLARATION: // declarationStatement.delete(); myLocal.delete(); break; case IN_CURRENT_METHOD: PsiStatement statement = createAssignment(myLocal, myFieldName, null); // myAssignmentStatement = (PsiStatement) // declarationStatement.replace(statement); myAssignmentStatement = (PsiStatement) myLocal.replace(statement); GeneratedMarkerVisitor.markGenerated(myAssignmentStatement); break; case IN_CONSTRUCTOR: myAssignmentStatement = addInitializationToConstructors(myLocal, myField, enclosingConstructor, factory); GeneratedMarkerVisitor.markGenerated(myAssignmentStatement); break; case IN_SETUP_METHOD: // myAssignmentStatement = addInitializationToSetUp(myLocal, myField, // factory); } if (enclosingConstructor != null && myInitializerPlace == IN_CONSTRUCTOR) { PsiStatement statement = createAssignment(myLocal, myFieldName, null); // myAssignmentStatement = (PsiStatement) // declarationStatement.replace(statement); myAssignmentStatement = (PsiStatement) myLocal.replace(statement); GeneratedMarkerVisitor.markGenerated(myAssignmentStatement); } if (rebindNeeded2) { for (final PsiReference reference : refs) { if (reference != null) { // expr = GosuRefactoringUtil.outermostParenthesizedExpression(expr); GosuRefactoringUtil.replaceOccurenceWithFieldRef( (PsiExpression) reference, myField, myDestinationClass); // replaceOccurenceWithFieldRef((PsiExpression)reference, field, aaClass); } } // GosuRefactoringUtil.renameVariableReferences(local, pPrefix + fieldName, // GlobalSearchScope.projectScope(myProject)); } ClassLord.doImportAndStick( mySettings.getForcedType().getCanonicalText(), myDestinationClass.getContainingFile()); } catch (IncorrectOperationException e) { LOG.error(e); } }
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { LOG.assertTrue(myOutOfScopeVariable != null); PsiManager manager = file.getManager(); myOutOfScopeVariable.normalizeDeclaration(); PsiUtil.setModifierProperty(myOutOfScopeVariable, PsiModifier.FINAL, false); PsiElement commonParent = PsiTreeUtil.findCommonParent(myOutOfScopeVariable, myUnresolvedReference); LOG.assertTrue(commonParent != null); PsiElement child = myOutOfScopeVariable.getTextRange().getStartOffset() < myUnresolvedReference.getTextRange().getStartOffset() ? myOutOfScopeVariable : myUnresolvedReference; while (child.getParent() != commonParent) child = child.getParent(); PsiDeclarationStatement newDeclaration = (PsiDeclarationStatement) JavaPsiFacade.getInstance(manager.getProject()) .getElementFactory() .createStatementFromText("int i = 0", null); PsiVariable variable = (PsiVariable) newDeclaration.getDeclaredElements()[0].replace(myOutOfScopeVariable); if (variable.getInitializer() != null) { variable.getInitializer().delete(); } while (!(child instanceof PsiStatement) || !(child.getParent() instanceof PsiCodeBlock)) { child = child.getParent(); commonParent = commonParent.getParent(); } LOG.assertTrue(commonParent != null); PsiDeclarationStatement added = (PsiDeclarationStatement) commonParent.addBefore(newDeclaration, child); PsiLocalVariable addedVar = (PsiLocalVariable) added.getDeclaredElements()[0]; manager.getCodeStyleManager().reformat(commonParent); // Leave initializer assignment PsiExpression initializer = myOutOfScopeVariable.getInitializer(); if (initializer != null) { PsiExpressionStatement assignment = (PsiExpressionStatement) JavaPsiFacade.getInstance(manager.getProject()) .getElementFactory() .createStatementFromText(myOutOfScopeVariable.getName() + "= e;", null); ((PsiAssignmentExpression) assignment.getExpression()).getRExpression().replace(initializer); assignment = (PsiExpressionStatement) manager.getCodeStyleManager().reformat(assignment); PsiDeclarationStatement declStatement = PsiTreeUtil.getParentOfType(myOutOfScopeVariable, PsiDeclarationStatement.class); LOG.assertTrue(declStatement != null); PsiElement parent = declStatement.getParent(); if (parent instanceof PsiForStatement) { declStatement.replace(assignment); } else { parent.addAfter(assignment, declStatement); } } if (myOutOfScopeVariable.isValid()) { myOutOfScopeVariable.delete(); } if (HighlightControlFlowUtil.checkVariableInitializedBeforeUsage( myUnresolvedReference, addedVar, new THashMap<PsiElement, Collection<PsiReferenceExpression>>()) != null) { initialize(addedVar); } DaemonCodeAnalyzer.getInstance(project).updateVisibleHighlighters(editor); }