public GrLiteralImpl handleContentChange(GrLiteral expr, TextRange range, String newContent) throws IncorrectOperationException { if (!(expr.getValue() instanceof String)) throw new IncorrectOperationException("cannot handle content change"); LOG.assertTrue(expr instanceof GrLiteralImpl); String oldText = expr.getText(); final String quote = GrStringUtil.getStartQuote(oldText); if (quote.startsWith("'")) { newContent = GrStringUtil.escapeSymbolsForString(newContent, !quote.equals("'''"), false); } else if (quote.startsWith("\"")) { newContent = GrStringUtil.escapeSymbolsForGString(newContent, !quote.equals("\"\"\""), true); } else if ("/".equals(quote)) { newContent = GrStringUtil.escapeSymbolsForSlashyStrings(newContent); } else if ("$/".equals(quote)) { newContent = GrStringUtil.escapeSymbolsForDollarSlashyStrings(newContent); } String newText = oldText.substring(0, range.getStartOffset()) + newContent + oldText.substring(range.getEndOffset()); return ((GrLiteralImpl) expr).updateText(newText); }
@Override public String getValue() { final String text = getText(); StringBuilder chars = new StringBuilder(text.length()); boolean result = GrStringUtil.parseStringCharacters(text, chars, null); return result ? chars.toString() : null; }
public static void appendName(@NotNull final StringBuilder buffer, @NotNull final String name) { if (GroovyNamesUtil.isIdentifier(name)) { buffer.append(name); } else { buffer.append("'"); buffer.append(GrStringUtil.escapeSymbolsForString(name, true, false)); buffer.append("'"); } }
/** @return leading regex or null if it does not exist */ @Nullable private static GrLiteral getRegexAtTheBeginning(PsiElement expr) { PsiElement fchild = expr; while (fchild != null) { if (fchild instanceof GrLiteral && GrStringUtil.isRegex((GrLiteral) fchild)) return (GrLiteral) fchild; fchild = fchild.getFirstChild(); } return null; }
@NotNull public static String getName(@NotNull GrNamedElement namedElement) { PsiElement nameElement = namedElement.getNameIdentifierGroovy(); ASTNode node = nameElement.getNode(); LOG.assertTrue(node != null); if (node.getElementType() == mIDENT) { return nameElement.getText(); } if (node.getElementType() == mSTRING_LITERAL || node.getElementType() == mGSTRING_LITERAL) { final Object value = GrLiteralImpl.getLiteralValue(nameElement); if (value instanceof String) { return (String) value; } else { return GrStringUtil.removeQuotes(nameElement.getText()); } } throw new IncorrectOperationException( "incorrect name element: " + node.getElementType() + ", named element: " + namedElement); }
@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; }