@Override protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { if (!(element instanceof GrConditionalExpression)) { throw new IncorrectOperationException("Not invoked on a conditional"); } GroovyPsiElementFactory groovyPsiElementFactory = GroovyPsiElementFactory.getInstance(project); GrConditionalExpression condExp = (GrConditionalExpression) element; GrExpression thenBranch = condExp.getThenBranch(); GrExpression elseBranch = condExp.getElseBranch(); Object thenVal = GroovyConstantExpressionEvaluator.evaluate(thenBranch); if (Boolean.TRUE.equals(thenVal) && elseBranch != null) { // aaa ? true : bbb -> aaa || bbb GrExpression conditionExp = condExp.getCondition(); String conditionExpText = getStringToPutIntoOrExpression(conditionExp); String elseExpText = getStringToPutIntoOrExpression(elseBranch); String newExp = conditionExpText + "||" + elseExpText; int caretOffset = conditionExpText.length() + 2; // after "||" GrExpression expressionFromText = groovyPsiElementFactory.createExpressionFromText(newExp, condExp.getContext()); expressionFromText = (GrExpression) condExp.replace(expressionFromText); editor .getCaretModel() .moveToOffset(expressionFromText.getTextOffset() + caretOffset); // just past "||" return; } Object elseVal = GroovyConstantExpressionEvaluator.evaluate(elseBranch); if (Boolean.FALSE.equals(elseVal) && thenBranch != null) { // aaa ? bbb : false -> aaa && bbb GrExpression conditionExp = condExp.getCondition(); String conditionExpText = getStringToPutIntoAndExpression(conditionExp); String thenExpText = getStringToPutIntoAndExpression(thenBranch); String newExp = conditionExpText + "&&" + thenExpText; int caretOffset = conditionExpText.length() + 2; // after "&&" GrExpression expressionFromText = groovyPsiElementFactory.createExpressionFromText(newExp, condExp.getContext()); expressionFromText = (GrExpression) condExp.replace(expressionFromText); editor .getCaretModel() .moveToOffset(expressionFromText.getTextOffset() + caretOffset); // just past "&&" } }
private static GrMethodCallExpression createMethodCall(ExtractInfoHelper helper) { StringBuilder buffer = new StringBuilder(); buffer.append(helper.getName()).append("("); int number = 0; for (ParameterInfo info : helper.getParameterInfos()) { if (info.passAsParameter()) number++; } int i = 0; String[] argumentNames = helper.getArgumentNames(); for (String argName : argumentNames) { if (argName.length() > 0) { buffer.append(argName); if (i < number - 1) { buffer.append(","); } i++; } } buffer.append(")"); String callText = buffer.toString(); GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(helper.getProject()); GrExpression expr = factory.createExpressionFromText(callText); LOG.assertTrue(expr instanceof GrMethodCallExpression, callText); return ((GrMethodCallExpression) expr); }
@Override public void visitReferenceExpression(GrReferenceExpression expression) { super.visitReferenceExpression(expression); if (expression.getCopyableUserData(SUPER_REF) != null) { expression.putCopyableUserData(SUPER_REF, null); final GrExpression qualifier = expression.getQualifier(); if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression) qualifier).isReferenceTo(mySourceClass)) { try { GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject); GrExpression newExpr = factory.createExpressionFromText(myTargetSuperClass.getName() + ".this", null); expression.replace(newExpr); } catch (IncorrectOperationException e) { LOG.error(e); } } } else if (expression.getCopyableUserData(THIS_REF) != null) { expression.putCopyableUserData(THIS_REF, null); final GrExpression qualifier = expression.getQualifier(); if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression) qualifier).isReferenceTo(mySourceClass)) { try { ((GrReferenceExpression) qualifier).bindToElement(myTargetSuperClass); GroovyChangeContextUtil.clearContextInfo(qualifier); } catch (IncorrectOperationException e) { LOG.error(e); } } } }
private void fixReferencesToStatic(GroovyPsiElement classMember, Set<PsiMember> movedMembers) throws IncorrectOperationException { final StaticReferencesCollector collector = new StaticReferencesCollector(movedMembers); classMember.accept(collector); ArrayList<GrReferenceElement> refs = collector.getReferences(); ArrayList<PsiElement> members = collector.getReferees(); ArrayList<PsiClass> classes = collector.getRefereeClasses(); GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject); for (int i = 0; i < refs.size(); i++) { GrReferenceElement ref = refs.get(i); PsiElement namedElement = members.get(i); PsiClass aClass = classes.get(i); if (namedElement instanceof PsiNamedElement) { GrReferenceExpression newRef = (GrReferenceExpression) factory.createExpressionFromText( "a." + ((PsiNamedElement) namedElement).getName(), null); GrExpression qualifier = newRef.getQualifierExpression(); assert qualifier != null; qualifier = (GrExpression) qualifier.replace( factory.createReferenceExpressionFromText(aClass.getQualifiedName())); qualifier.putCopyableUserData(PRESERVE_QUALIFIER, ref.isQualified()); PsiElement replaced = ref.replace(newRef); JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(replaced); } } }
@Override protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { PsiElement parent = element.getParent(); if (!"if".equals(element.getText()) || !(parent instanceof GrIfStatement)) { throw new IncorrectOperationException("Not invoked on an if"); } GrIfStatement parentIf = (GrIfStatement) parent; GroovyPsiElementFactory groovyPsiElementFactory = GroovyPsiElementFactory.getInstance(project); GrExpression condition = parentIf.getCondition(); if (condition == null) { throw new IncorrectOperationException("Invoked on an if with empty condition"); } GrExpression negatedCondition = null; if (condition instanceof GrUnaryExpression) { GrUnaryExpression unaryCondition = (GrUnaryExpression) condition; if ("!".equals(unaryCondition.getOperationToken().getText())) { negatedCondition = stripParenthesis(unaryCondition.getOperand()); } } if (negatedCondition == null) { // Now check whether this is a simple expression condition = stripParenthesis(condition); String negatedExpressionText; if (condition instanceof GrCallExpression || condition instanceof GrReferenceExpression) { negatedExpressionText = "!" + condition.getText(); } else { negatedExpressionText = "!(" + condition.getText() + ")"; } negatedCondition = groovyPsiElementFactory.createExpressionFromText(negatedExpressionText, parentIf); } GrStatement thenBranch = parentIf.getThenBranch(); final boolean thenIsNotEmpty = isNotEmpty(thenBranch); String newIfText = "if (" + negatedCondition.getText() + ") {}"; if (thenIsNotEmpty) { newIfText += " else {}"; } GrIfStatement newIf = (GrIfStatement) groovyPsiElementFactory.createStatementFromText(newIfText, parentIf.getContext()); generateElseBranchTextAndRemoveTailStatements(parentIf, newIf); if (thenIsNotEmpty) { final GrStatement elseBranch = newIf.getElseBranch(); assert elseBranch != null; elseBranch.replaceWithStatement(thenBranch); } parentIf.replace(newIf); }
@Override protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrMethodCallExpression expression = (GrMethodCallExpression) element; final GrClosableBlock block = expression.getClosureArguments()[0]; final GrParameterList parameterList = block.getParameterList(); final GrParameter[] parameters = parameterList.getParameters(); String var; if (parameters.length == 1) { var = parameters[0].getText(); var = StringUtil.replace(var, GrModifier.DEF, ""); } else { var = "it"; } final GrExpression invokedExpression = expression.getInvokedExpression(); GrExpression qualifier = ((GrReferenceExpression) invokedExpression).getQualifierExpression(); final GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(element.getProject()); if (qualifier == null) { qualifier = elementFactory.createExpressionFromText("this"); } StringBuilder builder = new StringBuilder(); builder.append("for (").append(var).append(" in ").append(qualifier.getText()).append(") {\n"); String text = block.getText(); final PsiElement blockArrow = block.getArrow(); int index; if (blockArrow != null) { index = blockArrow.getStartOffsetInParent() + blockArrow.getTextLength(); } else { index = 1; } while (index < text.length() && Character.isWhitespace(text.charAt(index))) index++; text = text.substring(index, text.length() - 1); builder.append(text); builder.append("}"); final GrStatement statement = elementFactory.createStatementFromText(builder.toString()); GrForStatement forStatement = (GrForStatement) expression.replaceWithStatement(statement); final GrForClause clause = forStatement.getClause(); GrVariable variable = clause.getDeclaredVariable(); forStatement = updateReturnStatements(forStatement); if (variable == null) return; if (ApplicationManager.getApplication().isUnitTestMode()) return; final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); final Document doc = documentManager.getDocument(element.getContainingFile()); if (doc == null) return; documentManager.doPostponedOperationsAndUnblockDocument(doc); editor.getCaretModel().moveToOffset(variable.getTextOffset()); new VariableInplaceRenamer(variable, editor).performInplaceRename(); }
private static GrExpression genRefForGetter(GrMethodCall call, String accessorName) { String name = GroovyPropertyUtils.getPropertyNameByGetterName(accessorName, true); GrReferenceExpression refExpr = (GrReferenceExpression) call.getInvokedExpression(); String oldNameStr = refExpr.getReferenceNameElement().getText(); String newRefExpr = StringUtil.trimEnd(refExpr.getText(), oldNameStr) + name; final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(call.getProject()); return factory.createExpressionFromText(newRefExpr, call); }
public static GrReferenceExpression qualifyReference( GrReferenceExpression referenceExpression, final PsiMember member, @Nullable final PsiClass qualifyingClass) throws IncorrectOperationException { PsiManager manager = referenceExpression.getManager(); GrReferenceExpression expressionFromText; final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(referenceExpression.getProject()); if (qualifyingClass == null) { PsiClass parentClass = PsiTreeUtil.getParentOfType(referenceExpression, PsiClass.class); final PsiClass containingClass = member.getContainingClass(); if (parentClass != null && !InheritanceUtil.isInheritorOrSelf(parentClass, containingClass, true)) { while (parentClass != null && !InheritanceUtil.isInheritorOrSelf(parentClass, containingClass, true)) { parentClass = PsiTreeUtil.getParentOfType(parentClass, PsiClass.class, true); } LOG.assertTrue(parentClass != null); expressionFromText = factory.createReferenceExpressionFromText("A.this." + member.getName()); //noinspection ConstantConditions ((GrReferenceExpression) expressionFromText.getQualifier()) .getQualifier() .replace(factory.createReferenceElementForClass(parentClass)); } else { expressionFromText = (GrReferenceExpression) factory.createExpressionFromText("this." + member.getName()); } } else { expressionFromText = (GrReferenceExpression) factory.createExpressionFromText("A." + member.getName()); expressionFromText.setQualifier(factory.createReferenceElementForClass(qualifyingClass)); } CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); expressionFromText = (GrReferenceExpression) codeStyleManager.reformat(expressionFromText); return (GrReferenceExpression) referenceExpression.replace(expressionFromText); }
public void fixSupers() throws IncorrectOperationException { final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject); GrReferenceExpression thisExpression = (GrReferenceExpression) factory.createExpressionFromText("this", null); for (GrExpression expression : mySupersToDelete) { if (expression.getParent() instanceof GrReferenceExpression) { ((GrReferenceExpression) expression.getParent()).setQualifier(null); } } for (GrReferenceExpression superExpression : mySupersToChangeToThis) { superExpression.replace(thisExpression); } }
public static void processChangedMethodCall( PsiElement element, GrIntroduceParameterSettings settings, Project project) { if (!(element.getParent() instanceof GrMethodCallExpression)) { LOG.error(element.getParent()); return; } GrMethodCallExpression methodCall = (GrMethodCallExpression) element.getParent(); GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project); final String name = settings.getName(); LOG.assertTrue(name != null); GrExpression expression = factory.createExpressionFromText(name, null); final GrArgumentList argList = methodCall.getArgumentList(); final PsiElement[] exprs = argList.getAllArguments(); if (exprs.length > 0) { argList.addAfter(expression, exprs[exprs.length - 1]); } else { argList.add(expression); } removeParametersFromCall(methodCall, settings); }
@Nullable public static GrExpression replaceExpression( GrExpression oldExpr, GrExpression newExpr, boolean removeUnnecessaryParentheses) { PsiElement oldParent = oldExpr.getParent(); if (oldParent == null) throw new PsiInvalidElementAccessException(oldExpr); if (!(oldExpr instanceof GrApplicationStatement)) { newExpr = ApplicationStatementUtil.convertToMethodCallExpression(newExpr); } // Remove unnecessary parentheses if (removeUnnecessaryParentheses && oldParent instanceof GrParenthesizedExpression && !(oldParent.getParent() instanceof GrArgumentLabel)) { return ((GrExpression) oldParent) .replaceWithExpression(newExpr, removeUnnecessaryParentheses); } // regexes cannot be after identifier , try to replace it with simple string if (getRegexAtTheBeginning(newExpr) != null && isAfterIdentifier(oldExpr)) { final PsiElement copy = newExpr.copy(); final GrLiteral regex = getRegexAtTheBeginning(copy); LOG.assertTrue(regex != null); final GrLiteral stringLiteral = GrStringUtil.createStringFromRegex(regex); if (regex == copy) { return oldExpr.replaceWithExpression(stringLiteral, removeUnnecessaryParentheses); } else { regex.replace(stringLiteral); return oldExpr.replaceWithExpression((GrExpression) copy, removeUnnecessaryParentheses); } } GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(oldExpr.getProject()); if (oldParent instanceof GrStringInjection) { if (newExpr instanceof GrString || newExpr instanceof GrLiteral && ((GrLiteral) newExpr).getValue() instanceof String) { return GrStringUtil.replaceStringInjectionByLiteral( (GrStringInjection) oldParent, (GrLiteral) newExpr); } else { newExpr = factory.createExpressionFromText("{" + newExpr.getText() + "}"); oldParent.getNode().replaceChild(oldExpr.getNode(), newExpr.getNode()); return newExpr; } } if (PsiTreeUtil.getParentOfType(oldExpr, GrStringInjection.class, false, GrCodeBlock.class) != null) { final PsiElement replaced = oldExpr.replace(newExpr); final GrStringInjection stringInjection = PsiTreeUtil.getParentOfType(replaced, GrStringInjection.class); GrStringUtil.wrapInjection(stringInjection); assert stringInjection != null; return stringInjection.getClosableBlock(); } // check priorities if (oldParent instanceof GrExpression && !(oldParent instanceof GrParenthesizedExpression)) { GrExpression addedParenth = addParenthesesIfNeeded(newExpr, oldExpr, (GrExpression) oldParent); if (newExpr != addedParenth) { return oldExpr.replaceWithExpression(addedParenth, removeUnnecessaryParentheses); } } // if replace closure argument with expression // we should add the expression in arg list if (oldExpr instanceof GrClosableBlock && !(newExpr instanceof GrClosableBlock) && oldParent instanceof GrMethodCallExpression && ArrayUtil.contains( oldExpr, ((GrMethodCallExpression) oldParent).getClosureArguments())) { return ((GrMethodCallExpression) oldParent) .replaceClosureArgument((GrClosableBlock) oldExpr, newExpr); } newExpr = (GrExpression) oldExpr.replace(newExpr); // if newExpr is the first grand child of command argument list we should replace command arg // list with parenthesised arg list. // In other case the code will be broken. So we try to find wrapping command arg list counting // levels. After arg list replace we go inside it // to find target parenthesised expression. if (newExpr instanceof GrParenthesizedExpression && isFirstChild(newExpr)) { int parentCount = 0; PsiElement element = oldParent; while (element != null && !(element instanceof GrCommandArgumentList)) { if (element instanceof GrCodeBlock || element instanceof GrParenthesizedExpression) break; if (element instanceof PsiFile) break; final PsiElement parent = element.getParent(); if (parent == null) break; if (!isFirstChild(element)) break; element = parent; parentCount++; } if (element instanceof GrCommandArgumentList) { final GrCommandArgumentList commandArgList = (GrCommandArgumentList) element; final PsiElement parent = commandArgList.getParent(); LOG.assertTrue(parent instanceof GrApplicationStatement); final GrMethodCall methodCall = factory.createMethodCallByAppCall((GrApplicationStatement) parent); final GrMethodCall newCall = (GrMethodCall) parent.replace(methodCall); PsiElement result = newCall.getArgumentList().getAllArguments()[0]; for (int i = 0; i < parentCount; i++) { result = PsiUtil.skipWhitespacesAndComments(result.getFirstChild(), true); } LOG.assertTrue(result instanceof GrParenthesizedExpression); return (GrExpression) result; } } return newExpr; }
@Override protected void performRefactoring(UsageInfo[] usages) { GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject); PsiType initializerType = mySettings.getSelectedType(); // Changing external occurrences (the tricky part) IntroduceParameterUtil.processUsages(usages, this); final GrMethod toReplaceIn = (GrMethod) mySettings.getToReplaceIn(); final PsiMethod toSearchFor = (PsiMethod) mySettings.getToSearchFor(); final boolean methodsToProcessAreDifferent = toReplaceIn != toSearchFor; if (mySettings.generateDelegate()) { GroovyIntroduceParameterUtil.generateDelegate(toReplaceIn, myParameterInitializer, myProject); if (methodsToProcessAreDifferent) { final GrMethod method = GroovyIntroduceParameterUtil.generateDelegate( toSearchFor, myParameterInitializer, myProject); final PsiClass containingClass = method.getContainingClass(); if (containingClass != null && containingClass.isInterface()) { final GrOpenBlock block = method.getBlock(); if (block != null) { block.delete(); } } } } // Changing signature of initial method // (signature of myMethodToReplaceIn will be either changed now or have already been changed) LOG.assertTrue(initializerType == null || initializerType.isValid()); final FieldConflictsResolver fieldConflictsResolver = new FieldConflictsResolver(mySettings.getName(), toReplaceIn.getBlock()); IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts( new UsageInfo(toReplaceIn), usages, this); if (methodsToProcessAreDifferent) { IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts( new UsageInfo(toSearchFor), usages, this); } // Replacing expression occurrences for (UsageInfo usage : usages) { if (usage instanceof ChangedMethodCallInfo) { PsiElement element = usage.getElement(); GroovyIntroduceParameterUtil.processChangedMethodCall(element, mySettings, myProject); } else if (usage instanceof InternalUsageInfo) { PsiElement element = usage.getElement(); if (element == null) continue; GrExpression newExpr = factory.createExpressionFromText(mySettings.getName()); if (element instanceof GrExpression) { ((GrExpression) element).replaceWithExpression(newExpr, true); } else { element.replace(newExpr); } } } final StringPartInfo stringPartInfo = mySettings.getStringPartInfo(); if (stringPartInfo != null) { final GrExpression expr = GrIntroduceHandlerBase.processLiteral( mySettings.getName(), mySettings.getStringPartInfo(), mySettings.getProject()); final Editor editor = PsiUtilBase.findEditor(expr); if (editor != null) { editor.getSelectionModel().removeSelection(); editor.getCaretModel().moveToOffset(expr.getTextRange().getEndOffset()); } } final GrVariable var = mySettings.getVar(); if (var != null && mySettings.removeLocalVariable()) { var.delete(); } fieldConflictsResolver.fix(); }
@Nullable private static GrExpression createDefaultValue( GroovyPsiElementFactory factory, JavaChangeInfo changeInfo, JavaParameterInfo info, final GrArgumentList list) { if (info.isUseAnySingleVariable()) { final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper(); final PsiType type = info.getTypeWrapper().getType(changeInfo.getMethod(), list.getManager()); final VariablesProcessor processor = new VariablesProcessor(false) { @Override protected boolean check(PsiVariable var, ResolveState state) { if (var instanceof PsiField && !resolveHelper.isAccessible((PsiField) var, list, null)) return false; if (var instanceof GrVariable && PsiUtil.isLocalVariable(var) && list.getTextRange().getStartOffset() <= var.getTextRange().getStartOffset()) { return false; } if (PsiTreeUtil.isAncestor(var, list, false)) return false; final PsiType _type = var instanceof GrVariable ? ((GrVariable) var).getTypeGroovy() : var.getType(); final PsiType varType = state.get(PsiSubstitutor.KEY).substitute(_type); return type.isAssignableFrom(varType); } @Override public boolean execute(@NotNull PsiElement pe, @NotNull ResolveState state) { super.execute(pe, state); return size() < 2; } }; ResolveUtil.treeWalkUp(list, processor, false); if (processor.size() == 1) { final PsiVariable result = processor.getResult(0); return factory.createExpressionFromText(result.getName(), list); } if (processor.size() == 0) { final PsiClass parentClass = PsiTreeUtil.getParentOfType(list, PsiClass.class); if (parentClass != null) { PsiClass containingClass = parentClass; final Set<PsiClass> containingClasses = new HashSet<PsiClass>(); final PsiElementFactory jfactory = JavaPsiFacade.getElementFactory(list.getProject()); while (containingClass != null) { if (type.isAssignableFrom(jfactory.createType(containingClass, PsiSubstitutor.EMPTY))) { containingClasses.add(containingClass); } containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class); } if (containingClasses.size() == 1) { return factory.createThisExpression( containingClasses.contains(parentClass) ? null : containingClasses.iterator().next()); } } } } final String value = info.getDefaultValue(); return !StringUtil.isEmpty(value) ? factory.createExpressionFromText(value, list) : null; }