@Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); if (!(element instanceof PsiReferenceExpression)) { return; } final PsiElement parent = PsiUtil.skipParenthesizedExprUp(element.getParent()); if (parent instanceof PsiVariable) { element.delete(); } if (!(parent instanceof PsiAssignmentExpression)) { return; } final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) parent; final PsiExpression lhs = assignmentExpression.getLExpression(); final PsiExpression rhs = assignmentExpression.getRExpression(); if (PsiTreeUtil.isAncestor(lhs, element, false)) { if (rhs != null) { assignmentExpression.replace(rhs); } else { assignmentExpression.delete(); } } else { final PsiElement grandParent = assignmentExpression.getParent(); if (grandParent instanceof PsiExpressionStatement) { grandParent.delete(); } else { assignmentExpression.replace(element); } } }
/** * Allows to check if static import may be performed for the given element. * * @param element element to check * @return target class that may be statically imported if any; <code>null</code> otherwise */ @Nullable public static PsiClass getClassToPerformStaticImport(@NotNull PsiElement element) { if (!PsiUtil.isLanguageLevel5OrHigher(element)) return null; if (!(element instanceof PsiIdentifier) || !(element.getParent() instanceof PsiJavaCodeReferenceElement)) { return null; } PsiJavaCodeReferenceElement refExpr = (PsiJavaCodeReferenceElement) element.getParent(); if (refExpr instanceof PsiMethodReferenceExpression) return null; final PsiElement gParent = refExpr.getParent(); if (gParent instanceof PsiMethodReferenceExpression) return null; if (!(gParent instanceof PsiJavaCodeReferenceElement) || isParameterizedReference((PsiJavaCodeReferenceElement) gParent)) return null; PsiElement resolved = refExpr.resolve(); if (!(resolved instanceof PsiClass)) { return null; } PsiClass psiClass = (PsiClass) resolved; if (PsiUtil.isFromDefaultPackage(psiClass) || psiClass.hasModifierProperty(PsiModifier.PRIVATE) || psiClass.getQualifiedName() == null) return null; final PsiElement ggParent = gParent.getParent(); if (ggParent instanceof PsiMethodCallExpression) { final PsiMethodCallExpression call = (PsiMethodCallExpression) ggParent.copy(); final PsiElement qualifier = call.getMethodExpression().getQualifier(); if (qualifier == null) return null; qualifier.delete(); final PsiMethod method = call.resolveMethod(); if (method != null && method.getContainingClass() != psiClass) return null; } else { final PsiJavaCodeReferenceElement copy = (PsiJavaCodeReferenceElement) gParent.copy(); final PsiElement qualifier = copy.getQualifier(); if (qualifier == null) return null; qualifier.delete(); final PsiElement target = copy.resolve(); if (target != null && PsiTreeUtil.getParentOfType(target, PsiClass.class) != psiClass) return null; } PsiFile file = refExpr.getContainingFile(); if (!(file instanceof PsiJavaFile)) return null; PsiImportList importList = ((PsiJavaFile) file).getImportList(); if (importList == null) return null; return psiClass; }
private void changeParameter( int parameterIndex, JetParameter parameter, JetParameterInfo parameterInfo) { ASTNode valOrVarAstNode = parameter.getValOrVarNode(); PsiElement valOrVarNode = valOrVarAstNode != null ? valOrVarAstNode.getPsi() : null; JetValVar valOrVar = parameterInfo.getValOrVar(); JetPsiFactory psiFactory = JetPsiFactory(getProject()); if (valOrVarNode != null) { if (valOrVar == JetValVar.None) { valOrVarNode.delete(); } else { valOrVarNode.replace(psiFactory.createValOrVarNode(valOrVar.toString()).getPsi()); } } else if (valOrVar != JetValVar.None) { PsiElement firstChild = parameter.getFirstChild(); parameter.addBefore(psiFactory.createValOrVarNode(valOrVar.toString()).getPsi(), firstChild); parameter.addBefore(psiFactory.createWhiteSpace(), firstChild); } if (parameterInfo.getIsTypeChanged() && parameter.getTypeReference() != null) { String renderedType = parameterInfo.renderType(parameterIndex, this); parameter.setTypeReference(psiFactory.createType(renderedType)); } PsiElement identifier = parameter.getNameIdentifier(); if (identifier != null) { //noinspection unchecked String newName = parameterInfo.getInheritedName((JetFunctionDefinitionUsage<PsiElement>) this); identifier.replace(psiFactory.createIdentifier(newName)); } }
public static void removeVariable(GrVariable variable) { final GrVariableDeclaration varDecl = (GrVariableDeclaration) variable.getParent(); final List<GrVariable> variables = Arrays.asList(varDecl.getVariables()); if (!variables.contains(variable)) { throw new IllegalArgumentException(); } final PsiElement parent = varDecl.getParent(); final ASTNode owner = parent.getNode(); if (variables.size() == 1 && owner != null) { PsiElement next = varDecl.getNextSibling(); // remove redundant semicolons //noinspection ConstantConditions while (next != null && next.getNode() != null && next.getNode().getElementType() == mSEMI) { PsiElement tmpNext = next.getNextSibling(); //noinspection ConstantConditions next.delete(); next = tmpNext; } removeNewLineAfter(varDecl); varDecl.delete(); return; } variable.delete(); }
@Override public boolean flip(PsiElement left, PsiElement right) { if (left instanceof PsiVariable && right instanceof PsiVariable) { final PsiElement first = left.getFirstChild(); if (!(first instanceof PsiModifierList)) { return false; } final PsiElement child = PsiTreeUtil.skipSiblingsForward(first, PsiWhiteSpace.class); if (!(child instanceof PsiTypeElement)) { return false; } final PsiElement last = child.getNextSibling(); if (!(last instanceof PsiWhiteSpace)) { return false; } final PsiElement anchor = right.getFirstChild(); if (!(anchor instanceof PsiIdentifier)) { return false; } final PsiElement semiColon = right.getLastChild(); if (!(semiColon instanceof PsiJavaToken)) { return false; } right.addRangeBefore(first, last, anchor); left.deleteChildRange(first, last); left.add(semiColon); semiColon.delete(); final PsiElement copy = left.copy(); left.replace(right); right.replace(copy); return true; } return false; }
@Override protected void performRefactoring(@NotNull UsageInfo[] usages) { try { for (UsageInfo usage : usages) { if (usage instanceof SafeDeleteCustomUsageInfo) { ((SafeDeleteCustomUsageInfo) usage).performRefactoring(); } } DumbService.allowStartingDumbModeInside( DumbModePermission.MAY_START_MODAL, () -> { for (PsiElement element : myElements) { for (SafeDeleteProcessorDelegate delegate : Extensions.getExtensions(SafeDeleteProcessorDelegate.EP_NAME)) { if (delegate.handlesElement(element)) { delegate.prepareForDeletion(element); } } element.delete(); } }); } catch (IncorrectOperationException e) { RefactoringUIUtil.processIncorrectOperation(myProject, e); } }
private static PsiDeclarationStatement moveDeclarationToReference( @NotNull PsiElement referenceElement, @NotNull PsiLocalVariable variable, @NotNull PsiCodeBlock block) throws IncorrectOperationException { PsiStatement statement = PsiTreeUtil.getParentOfType(referenceElement, PsiStatement.class); assert statement != null; if (statement.getParent() instanceof PsiForStatement) { statement = (PsiStatement) statement.getParent(); } final PsiElement referenceParent = referenceElement.getParent(); if (referenceParent instanceof PsiAssignmentExpression) { final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) referenceParent; if (referenceElement.equals(assignmentExpression.getLExpression())) { PsiDeclarationStatement newDeclaration = createNewDeclaration(variable, assignmentExpression.getRExpression()); newDeclaration = (PsiDeclarationStatement) block.addBefore(newDeclaration, statement); final PsiElement parent = assignmentExpression.getParent(); assert parent != null; parent.delete(); return newDeclaration; } } return createNewDeclaration(variable, null); }
private static XmlTag createTag( @NotNull XmlTag contextTag, @NotNull XmlElementDescriptor descriptor) { String namespace = getNamespace(descriptor); XmlTag tag = contextTag.createChildTag(descriptor.getName(), namespace, null, false); PsiElement lastChild = tag.getLastChild(); assert lastChild != null; lastChild.delete(); // remove XML_EMPTY_ELEMENT_END return tag; }
private static void fixCommaIfNeeded(@NotNull PsiElement element, boolean willBeLast) { PsiElement comma = getComma(element); if (willBeLast && comma != null) { comma.delete(); } else if (!willBeLast && comma == null) { PsiElement parent = element.getParent(); assert parent != null; parent.addAfter(JetPsiFactory(parent.getProject()).createComma(), element); } }
public static PsiElement[] move( @NotNull PsiElement container, @NotNull PsiElement[] statements, boolean generateDefaultInitializers) { if (statements.length == 0) { return statements; } Project project = container.getProject(); List<PsiElement> resultStatements = new ArrayList<PsiElement>(); List<KtProperty> propertiesDeclarations = new ArrayList<KtProperty>(); // Dummy element to add new declarations at the beginning KtPsiFactory psiFactory = KtPsiFactoryKt.KtPsiFactory(project); PsiElement dummyFirstStatement = container.addBefore(psiFactory.createExpression("dummyStatement"), statements[0]); try { SearchScope scope = new LocalSearchScope(container); int lastStatementOffset = statements[statements.length - 1].getTextRange().getEndOffset(); for (PsiElement statement : statements) { if (needToDeclareOut(statement, lastStatementOffset, scope)) { if (statement instanceof KtProperty && ((KtProperty) statement).getInitializer() != null) { KtProperty property = (KtProperty) statement; KtProperty declaration = createVariableDeclaration(property, generateDefaultInitializers); declaration = (KtProperty) container.addBefore(declaration, dummyFirstStatement); propertiesDeclarations.add(declaration); container.addAfter(psiFactory.createNewLine(), declaration); KtBinaryExpression assignment = createVariableAssignment(property); resultStatements.add(property.replace(assignment)); } else { PsiElement newStatement = container.addBefore(statement, dummyFirstStatement); container.addAfter(psiFactory.createNewLine(), newStatement); container.deleteChildRange(statement, statement); } } else { resultStatements.add(statement); } } } finally { dummyFirstStatement.delete(); } ShortenReferences.DEFAULT.process(propertiesDeclarations); return PsiUtilCore.toPsiElementArray(resultStatements); }
private static void deleteOverrideAnnotationIfFound(PsiMethod oMethod) { final PsiAnnotation annotation = AnnotationUtil.findAnnotation(oMethod, CommonClassNames.JAVA_LANG_OVERRIDE); if (annotation != null) { PsiElement prev = annotation.getPrevSibling(); PsiElement next = annotation.getNextSibling(); if ((prev == null || org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLineFeed(prev)) && org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLineFeed(next)) { next.delete(); } annotation.delete(); } }
static void deleteWholeStatement(PsiElement element, PsiElementFactory factory) throws IncorrectOperationException { // just delete it altogether if (element.getParent() instanceof PsiExpressionStatement) { PsiExpressionStatement parent = (PsiExpressionStatement) element.getParent(); if (parent.getParent() instanceof PsiCodeBlock) { parent.delete(); } else { // replace with empty statement (to handle with 'if (..) i=0;' ) parent.replace(createStatementIfNeeded(null, factory, element)); } } else { element.delete(); } }
public void setInitializer(@Nullable PsiExpression psiExpression) throws IncorrectOperationException { GrExpression oldInitializer = getInitializerGroovy(); if (psiExpression == null) { if (oldInitializer != null) { oldInitializer.delete(); PsiElement assign = findChildByType(GroovyTokenTypes.mASSIGN); if (assign != null) { assign.delete(); } } return; } GrExpression newInitializer = GroovyPsiElementFactory.getInstance(getProject()) .createExpressionFromText(psiExpression.getText()); if (oldInitializer != null) { oldInitializer.replaceWithExpression(newInitializer, true); } else { getNode().addLeaf(GroovyTokenTypes.mASSIGN, "=", getNode().getLastChildNode()); addAfter(newInitializer, getLastChild()); } }
private void setModifierPropertyInternal(String name, boolean doSet) { if (doSet) { PsiElement modifier = GroovyPsiElementFactory.getInstance(getProject()).createModifierFromText(name); PsiElement anchor = findAnchor(name); addAfter(modifier, anchor); } else { final PsiElement[] modifiers = findChildrenByType(TokenSets.MODIFIERS, PsiElement.class); for (PsiElement modifier : modifiers) { if (name.equals(modifier.getText())) { deleteChildRange(modifier, modifier); break; } } if (getTextLength() == 0) { final PsiElement nextSibling = getNextSibling(); if (nextSibling != null && TokenSets.WHITE_SPACES_SET.contains(nextSibling.getNode().getElementType())) { nextSibling.delete(); } } } }
public void deletePropertyIfExist(String key, PropertiesFile file) { final IProperty property = file.findPropertyByKey(key); if (property != null && myKeysOrder != null) { boolean keyExistInOtherPropertiesFiles = false; for (PropertiesFile propertiesFile : myResourceBundle.getPropertiesFiles()) { if (!propertiesFile.equals(file) && propertiesFile.findPropertyByKey(key) != null) { keyExistInOtherPropertiesFiles = true; break; } } if (!keyExistInOtherPropertiesFiles) { myKeysOrder.remove(key); } } if (property != null) { PsiElement anElement = property.getPsiElement(); if (anElement instanceof PomTargetPsiElement) { final PomTarget xmlProperty = ((PomTargetPsiElement) anElement).getTarget(); LOG.assertTrue(xmlProperty instanceof XmlProperty); anElement = ((XmlProperty) xmlProperty).getNavigationElement(); } anElement.delete(); } }
private static void processMethodUsage( PsiElement element, JavaChangeInfo changeInfo, boolean toChangeArguments, boolean toCatchExceptions, GrClosureSignatureUtil.ArgInfo<PsiElement>[] map, PsiSubstitutor substitutor) { if (map == null) return; if (changeInfo.isNameChanged()) { if (element instanceof GrReferenceElement) { element = ((GrReferenceElement) element).handleElementRename(changeInfo.getNewName()); } } if (toChangeArguments) { JavaParameterInfo[] parameters = changeInfo.getNewParameters(); GrArgumentList argumentList = PsiUtil.getArgumentsList(element); GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(element.getProject()); if (argumentList == null) { if (element instanceof GrEnumConstant) { argumentList = factory.createArgumentList(); argumentList = (GrArgumentList) element.add(argumentList); } else { return; } } Set<PsiElement> argsToDelete = new HashSet<PsiElement>(map.length * 2); for (GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo : map) { argsToDelete.addAll(argInfo.args); } for (JavaParameterInfo parameter : parameters) { int index = parameter.getOldIndex(); if (index >= 0) { argsToDelete.removeAll(map[index].args); } } for (PsiElement arg : argsToDelete) { arg.delete(); } boolean skipOptionals = false; PsiElement anchor = null; // PsiTreeUtil.getChildOfAnyType(argumentList, GrExpression.class, // GrNamedArgument.class); for (int i = 0; i < parameters.length; i++) { JavaParameterInfo parameter = parameters[i]; int index = parameter.getOldIndex(); if (index >= 0) { GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo = map[index]; List<PsiElement> arguments = argInfo.args; if (argInfo.isMultiArg) { // arguments for Map and varArg if ((i != 0 || !(!arguments.isEmpty() && arguments.iterator().next() instanceof GrNamedArgument)) && (i != parameters.length - 1 || !parameter.isVarargType())) { final PsiType type = parameter.createType( changeInfo.getMethod().getParameterList(), argumentList.getManager()); final GrExpression arg = GroovyRefactoringUtil.generateArgFromMultiArg( substitutor, arguments, type, element.getProject()); for (PsiElement argument : arguments) { argument.delete(); } anchor = argumentList.addAfter(arg, anchor); JavaCodeStyleManager.getInstance(anchor.getProject()).shortenClassReferences(anchor); } } else { // arguments for simple parameters if (arguments.size() == 1) { // arg exists PsiElement arg = arguments.iterator().next(); if (i == parameters.length - 1 && parameter.isVarargType()) { if (arg instanceof GrSafeCastExpression) { PsiElement expr = ((GrSafeCastExpression) arg).getOperand(); if (expr instanceof GrListOrMap && !((GrListOrMap) expr).isMap()) { final PsiElement copy = expr.copy(); PsiElement[] newVarargs = ((GrListOrMap) copy).getInitializers(); for (PsiElement vararg : newVarargs) { anchor = argumentList.addAfter(vararg, anchor); } arg.delete(); continue; } } } PsiElement curArg = getNextOfType(argumentList, anchor, GrExpression.class); if (curArg == arg) { anchor = arg; } else { final PsiElement copy = arg.copy(); anchor = argumentList.addAfter(copy, anchor); arg.delete(); } } else { // arg is skipped. Parameter is optional skipOptionals = true; } } } else { if (skipOptionals && isParameterOptional(parameter)) continue; if (forceOptional(parameter)) { skipOptionals = true; continue; } try { GrExpression value = createDefaultValue(factory, changeInfo, parameter, argumentList); if (i > 0 && (value == null || anchor == null)) { PsiElement comma = Factory.createSingleLeafElement( GroovyTokenTypes.mCOMMA, ",", 0, 1, SharedImplUtil.findCharTableByTree(argumentList.getNode()), argumentList.getManager()) .getPsi(); if (anchor == null) anchor = argumentList.getLeftParen(); anchor = argumentList.addAfter(comma, anchor); } if (value != null) { anchor = argumentList.addAfter(value, anchor); } } catch (IncorrectOperationException e) { LOG.error(e.getMessage()); } } } GrCall call = GroovyRefactoringUtil.getCallExpressionByMethodReference(element); if (argumentList.getText().trim().isEmpty() && (call == null || !PsiImplUtil.hasClosureArguments(call))) { argumentList = argumentList.replaceWithArgumentList(factory.createArgumentList()); } CodeStyleManager.getInstance(argumentList.getProject()).reformat(argumentList); } if (toCatchExceptions) { final ThrownExceptionInfo[] exceptionInfos = changeInfo.getNewExceptions(); PsiClassType[] exceptions = getExceptions(exceptionInfos, element, element.getManager()); fixExceptions(element, exceptions); } }
// Delete element if it doesn't contain children of a given type public static <T extends PsiElement> void deleteChildlessElement( PsiElement element, Class<T> childClass) { if (PsiTreeUtil.getChildrenOfType(element, childClass) == null) { element.delete(); } }
/** * @param sideEffects if null, delete usages, otherwise collect side effects * @return true if there are at least one unrecoverable side effect found, false if no side * effects, null if read usage found (may happen if interval between fix creation in invoke() * call was long enough) * @throws com.intellij.util.IncorrectOperationException */ static Boolean processUsage( PsiElement element, PsiVariable variable, List<PsiElement> sideEffects, int deleteMode) throws IncorrectOperationException { if (!element.isValid()) return null; PsiElementFactory factory = JavaPsiFacade.getInstance(variable.getProject()).getElementFactory(); while (element != null) { if (element instanceof PsiAssignmentExpression) { PsiAssignmentExpression expression = (PsiAssignmentExpression) element; PsiExpression lExpression = expression.getLExpression(); // there should not be read access to the variable, otherwise it is not unused if (!(lExpression instanceof PsiReferenceExpression) || variable != ((PsiReferenceExpression) lExpression).resolve()) { return null; } PsiExpression rExpression = expression.getRExpression(); rExpression = PsiUtil.deparenthesizeExpression(rExpression); if (rExpression == null) return true; // replace assignment with expression and resimplify boolean sideEffectFound = checkSideEffects(rExpression, variable, sideEffects); if (!(element.getParent() instanceof PsiExpressionStatement) || PsiUtil.isStatement(rExpression)) { if (deleteMode == MAKE_STATEMENT || deleteMode == DELETE_ALL && !(element.getParent() instanceof PsiExpressionStatement)) { element = replaceElementWithExpression(rExpression, factory, element); while (element.getParent() instanceof PsiParenthesizedExpression) { element = element.getParent().replace(element); } List<PsiElement> references = new ArrayList<PsiElement>(); collectReferences(element, variable, references); deleteReferences(variable, references, deleteMode); } else if (deleteMode == DELETE_ALL) { deleteWholeStatement(element, factory); } return true; } else { if (deleteMode != CANCEL) { deleteWholeStatement(element, factory); } return !sideEffectFound; } } else if (element instanceof PsiExpressionStatement && deleteMode != CANCEL) { final PsiElement parent = element.getParent(); if (parent instanceof PsiIfStatement || parent instanceof PsiLoopStatement && ((PsiLoopStatement) parent).getBody() == element) { element.replace( JavaPsiFacade.getElementFactory(element.getProject()) .createStatementFromText(";", element)); } else { element.delete(); } break; } else if (element instanceof PsiVariable && element == variable) { PsiExpression expression = variable.getInitializer(); if (expression != null) { expression = PsiUtil.deparenthesizeExpression(expression); } boolean sideEffectsFound = checkSideEffects(expression, variable, sideEffects); if (expression != null && PsiUtil.isStatement(expression) && variable instanceof PsiLocalVariable && !(variable.getParent() instanceof PsiDeclarationStatement && ((PsiDeclarationStatement) variable.getParent()).getDeclaredElements().length > 1)) { if (deleteMode == MAKE_STATEMENT) { element = element.replace(createStatementIfNeeded(expression, factory, element)); List<PsiElement> references = new ArrayList<PsiElement>(); collectReferences(element, variable, references); deleteReferences(variable, references, deleteMode); } else if (deleteMode == DELETE_ALL) { element.delete(); } return true; } else { if (deleteMode != CANCEL) { if (element instanceof PsiField) { ((PsiField) element).normalizeDeclaration(); } element.delete(); } return !sideEffectsFound; } } element = element.getParent(); } return true; }
public void replace(final ReplacementInfo info, ReplaceOptions options) { PsiElement elementToReplace = info.getMatch(0); PsiElement elementParent = elementToReplace.getParent(); String replacementToMake = info.getReplacement(); Project project = myContext.getProject(); PsiElement el = findRealSubstitutionElement(elementToReplace); boolean listContext = isListContext(el); if (el instanceof PsiAnnotation && !StringUtil.startsWithChar(replacementToMake, '@')) { replacementToMake = "@" + replacementToMake; } PsiElement[] statements = ReplacerUtil.createTreeForReplacement( replacementToMake, el instanceof PsiMember && !isSymbolReplacement(el) ? PatternTreeContext.Class : PatternTreeContext.Block, myContext); if (listContext) { if (statements.length > 1) { elementParent.addRangeBefore( statements[0], statements[statements.length - 1], elementToReplace); } else if (statements.length == 1) { PsiElement replacement = getMatchExpr(statements[0], elementToReplace); handleModifierList(el, replacement); replacement = handleSymbolReplacement(replacement, el); if (replacement instanceof PsiTryStatement) { final List<PsiCatchSection> unmatchedCatchSections = el.getUserData(JavaMatchingVisitor.UNMATCHED_CATCH_SECTION_CONTENT_VAR_KEY); final PsiCatchSection[] catches = ((PsiTryStatement) replacement).getCatchSections(); if (unmatchedCatchSections != null) { for (int i = unmatchedCatchSections.size() - 1; i >= 0; --i) { final PsiParameter parameter = unmatchedCatchSections.get(i).getParameter(); final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); final PsiCatchSection catchSection = elementFactory.createCatchSection(parameter.getType(), parameter.getName(), null); catchSection.getCatchBlock().replace(unmatchedCatchSections.get(i).getCatchBlock()); replacement.addAfter(catchSection, catches[catches.length - 1]); replacement.addBefore(createWhiteSpace(replacement), replacement.getLastChild()); } } } try { final PsiElement inserted = elementParent.addBefore(replacement, elementToReplace); if (replacement instanceof PsiComment && (elementParent instanceof PsiIfStatement || elementParent instanceof PsiLoopStatement)) { elementParent.addAfter(createSemicolon(replacement), inserted); } } catch (IncorrectOperationException e) { elementToReplace.replace(replacement); } } } else if (statements.length > 0) { PsiElement replacement = ReplacerUtil.copySpacesAndCommentsBefore( elementToReplace, statements, replacementToMake, elementParent); replacement = getMatchExpr(replacement, elementToReplace); if (replacement instanceof PsiStatement && !(replacement.getLastChild() instanceof PsiJavaToken) && !(replacement.getLastChild() instanceof PsiComment)) { // assert w/o ; final PsiElement prevLastChildInParent = replacement.getLastChild().getPrevSibling(); if (prevLastChildInParent != null) { elementParent.addRangeBefore(replacement.getFirstChild(), prevLastChildInParent, el); } else { elementParent.addBefore(replacement.getFirstChild(), el); } el.getNode().getTreeParent().removeChild(el.getNode()); } else { // preserve comments handleModifierList(el, replacement); if (replacement instanceof PsiClass) { // modifier list final PsiStatement[] searchStatements = getCodeBlock().getStatements(); if (searchStatements.length > 0 && searchStatements[0] instanceof PsiDeclarationStatement && ((PsiDeclarationStatement) searchStatements[0]).getDeclaredElements()[0] instanceof PsiClass) { final PsiClass replaceClazz = (PsiClass) replacement; final PsiClass queryClazz = (PsiClass) ((PsiDeclarationStatement) searchStatements[0]).getDeclaredElements()[0]; final PsiClass clazz = (PsiClass) el; if (replaceClazz.getExtendsList().getTextLength() == 0 && queryClazz.getExtendsList().getTextLength() == 0 && clazz.getExtendsList().getTextLength() != 0) { replaceClazz.addBefore( clazz.getExtendsList().getPrevSibling(), replaceClazz.getExtendsList()); // whitespace replaceClazz .getExtendsList() .addRange( clazz.getExtendsList().getFirstChild(), clazz.getExtendsList().getLastChild()); } if (replaceClazz.getImplementsList().getTextLength() == 0 && queryClazz.getImplementsList().getTextLength() == 0 && clazz.getImplementsList().getTextLength() != 0) { replaceClazz.addBefore( clazz.getImplementsList().getPrevSibling(), replaceClazz.getImplementsList()); // whitespace replaceClazz .getImplementsList() .addRange( clazz.getImplementsList().getFirstChild(), clazz.getImplementsList().getLastChild()); } if (replaceClazz.getTypeParameterList().getTextLength() == 0 && queryClazz.getTypeParameterList().getTextLength() == 0 && clazz.getTypeParameterList().getTextLength() != 0) { // skip < and > replaceClazz.getTypeParameterList().replace(clazz.getTypeParameterList()); } } } replacement = handleSymbolReplacement(replacement, el); el.replace(replacement); } } else { final PsiElement nextSibling = el.getNextSibling(); el.delete(); if (nextSibling instanceof PsiWhiteSpace && nextSibling.isValid()) { nextSibling.delete(); } } if (listContext) { final int matchSize = info.getMatchesCount(); for (int i = 0; i < matchSize; ++i) { PsiElement matchElement = info.getMatch(i); PsiElement element = findRealSubstitutionElement(matchElement); if (element == null) continue; PsiElement firstToDelete = element; PsiElement lastToDelete = element; PsiElement prevSibling = element.getPrevSibling(); PsiElement nextSibling = element.getNextSibling(); if (prevSibling instanceof PsiWhiteSpace) { firstToDelete = prevSibling; prevSibling = prevSibling != null ? prevSibling.getPrevSibling() : null; } else if (prevSibling == null && nextSibling instanceof PsiWhiteSpace) { lastToDelete = nextSibling; } if (nextSibling instanceof XmlText && i + 1 < matchSize) { final PsiElement next = info.getMatch(i + 1); if (next != null && next == nextSibling.getNextSibling()) { lastToDelete = nextSibling; } } if (element instanceof PsiExpression) { final PsiElement parent = element.getParent().getParent(); if ((parent instanceof PsiCall || parent instanceof PsiAnonymousClass) && prevSibling instanceof PsiJavaToken && ((PsiJavaToken) prevSibling).getTokenType() == JavaTokenType.COMMA) { firstToDelete = prevSibling; } } else if (element instanceof PsiParameter && prevSibling instanceof PsiJavaToken && ((PsiJavaToken) prevSibling).getTokenType() == JavaTokenType.COMMA) { firstToDelete = prevSibling; } element.getParent().deleteChildRange(firstToDelete, lastToDelete); } } }
@Override public void invoke(@NotNull Project project, Editor editor, JetFile file) throws IncorrectOperationException { element.delete(); }
private void tryToMoveInitializers( PsiMethod constructor, HashSet<PsiMethod> subConstructors, LinkedHashSet<PsiField> movedFields) throws IncorrectOperationException { final LinkedHashMap<PsiField, Initializer> fieldsToInitializers = new LinkedHashMap<PsiField, Initializer>(); boolean anyFound = false; for (PsiField field : movedFields) { PsiStatement commonInitializer = null; final ArrayList<PsiElement> fieldInitializersToRemove = new ArrayList<PsiElement>(); for (PsiMethod subConstructor : subConstructors) { commonInitializer = hasCommonInitializer( commonInitializer, subConstructor, field, fieldInitializersToRemove); if (commonInitializer == null) break; } if (commonInitializer != null) { final ParametersAndMovedFieldsUsedCollector visitor = new ParametersAndMovedFieldsUsedCollector(movedFields); commonInitializer.accept(visitor); fieldsToInitializers.put( field, new Initializer( commonInitializer, visitor.getUsedFields(), visitor.getUsedParameters(), fieldInitializersToRemove)); anyFound = true; } } if (!anyFound) return; { final Set<PsiField> initializedFields = fieldsToInitializers.keySet(); Set<PsiField> unmovable = RefactoringUtil.transitiveClosure( new RefactoringUtil.Graph<PsiField>() { public Set<PsiField> getVertices() { return initializedFields; } public Set<PsiField> getTargets(PsiField source) { return fieldsToInitializers.get(source).movedFieldsUsed; } }, new Condition<PsiField>() { public boolean value(PsiField object) { return !initializedFields.contains(object); } }); for (PsiField psiField : unmovable) { fieldsToInitializers.remove(psiField); } } final PsiElementFactory factory = JavaPsiFacade.getElementFactory(myProject); if (constructor == null) { constructor = (PsiMethod) myTargetSuperClass.add(factory.createConstructor()); final String visibilityModifier = VisibilityUtil.getVisibilityModifier(myTargetSuperClass.getModifierList()); PsiUtil.setModifierProperty(constructor, visibilityModifier, true); } ArrayList<PsiField> initializedFields = new ArrayList<PsiField>(fieldsToInitializers.keySet()); Collections.sort( initializedFields, new Comparator<PsiField>() { public int compare(PsiField field1, PsiField field2) { Initializer i1 = fieldsToInitializers.get(field1); Initializer i2 = fieldsToInitializers.get(field2); if (i1.movedFieldsUsed.contains(field2)) return 1; if (i2.movedFieldsUsed.contains(field1)) return -1; return 0; } }); for (final PsiField initializedField : initializedFields) { Initializer initializer = fieldsToInitializers.get(initializedField); // correct constructor parameters and subConstructors super calls final PsiParameterList parameterList = constructor.getParameterList(); for (final PsiParameter parameter : initializer.usedParameters) { parameterList.add(parameter); } for (final PsiMethod subConstructor : subConstructors) { modifySuperCall(subConstructor, initializer.usedParameters); } PsiStatement assignmentStatement = (PsiStatement) constructor.getBody().add(initializer.initializer); PsiManager manager = PsiManager.getInstance(myProject); ChangeContextUtil.decodeContextInfo( assignmentStatement, myTargetSuperClass, RefactoringChangeUtil.createThisExpression(manager, null)); for (PsiElement psiElement : initializer.statementsToRemove) { psiElement.delete(); } } }