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 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); }