GrExpression (GrExpression oldExpr, GrExpression newExpr, boolean removeUnnecessaryParentheses) { PsiElement oldParent = oldExpr.getParent(); if (oldParent == null) throw new PsiInvalidElementAccessException(oldExpr); if (convertToMethodCall(oldExpr)) { newExpr = ApplicationStatementUtil.convertToMethodCallExpression(newExpr); } // Remove unnecessary parentheses if (removeUnnecessaryParentheses && oldParent instanceof GrParenthesizedExpression && !(oldParent.getParent() instanceof GrArgumentLabel)) { return ((GrExpression)oldParent).replaceWithExpression(newExpr, true); } //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 { GrClosableBlock block = factory.createClosureFromText("{foo}"); oldParent.getNode().replaceChild(oldExpr.getNode(), block.getNode()); GrStatement[] statements = block.getStatements(); return ((GrExpression)statements[0]).replaceWithExpression(newExpr, removeUnnecessaryParentheses); } } if (PsiTreeUtil.getParentOfType(oldExpr, GrStringInjection.class, false, GrCodeBlock.class) != null) { final GrStringInjection stringInjection = PsiTreeUtil.getParentOfType(oldExpr, GrStringInjection.class); assert stringInjection != null; GrStringUtil.wrapInjection(stringInjection); return oldExpr.replaceWithExpression(newExpr, removeUnnecessaryParentheses); } //check priorities if (oldParent instanceof GrExpression && !(oldParent instanceof GrParenthesizedExpression)) { GrExpression addedParenth = checkPrecedence(newExpr, oldExpr) ? parenthesize(newExpr, oldExpr.getContext()) : newExpr; if (newExpr != addedParenth) { return oldExpr.replaceWithExpression(addedParenth, removeUnnecessaryParentheses); } } if (oldParent instanceof GrForInClause) { return (GrExpression) oldExpr.replace(parenthesize(newExpr, oldExpr.getContext())); } //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 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 commandArgList) { 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++) { assert result != null; result = PsiUtil.skipWhitespacesAndComments(result.getFirstChild(), true); } LOG.assertTrue(result instanceof GrParenthesizedExpression); return (GrExpression)result; } } return newExpr; }