IDEA-66777 (Pasting escapes quotes too eagerly) tests will follow

This commit is contained in:
Bas Leijdekkers
2011-03-25 22:06:42 +01:00
parent c2d64fd03a
commit 50599de70d
@@ -15,10 +15,12 @@
*/
package com.intellij.codeInsight.editorActions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RawText;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.LineTokenizer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
@@ -26,17 +28,13 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
public String preprocessOnCopy(final PsiFile file, final int[] startOffsets, final int[] endOffsets, final String text) {
boolean isLiteral = true;
for (int i = 0; i < startOffsets.length && isLiteral; i++) {
final int startOffset = startOffsets[i];
final PsiElement elementAtCaret = file.findElementAt(startOffset);
if (!(elementAtCaret instanceof PsiJavaToken &&
(((PsiJavaToken) elementAtCaret)).getTokenType() == JavaTokenType.STRING_LITERAL &&
startOffset >= elementAtCaret.getTextRange().getStartOffset() &&
endOffsets[i] <= elementAtCaret.getTextRange().getEndOffset())) {
if (findLiteralTokenType(file, startOffsets[i], endOffsets[i]) == null) {
isLiteral = false;
}
}
@@ -47,28 +45,54 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
public String preprocessOnPaste(final Project project, final PsiFile file, final Editor editor, String text, final RawText rawText) {
final Document document = editor.getDocument();
PsiDocumentManager.getInstance(project).commitDocument(document);
int caretOffset = editor.getCaretModel().getOffset();
PsiElement elementAtCaret = file.findElementAt(caretOffset);
if (elementAtCaret instanceof PsiJavaToken && caretOffset > elementAtCaret.getTextOffset()) {
final IElementType tokenType = ((PsiJavaToken)elementAtCaret).getTokenType();
if (tokenType == JavaTokenType.STRING_LITERAL) {
if (rawText != null && rawText.rawText != null) return rawText.rawText; // Copied from the string literal. Copy as is.
final SelectionModel selectionModel = editor.getSelectionModel();
StringBuilder buffer = new StringBuilder(text.length());
CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
@NonNls String breaker = codeStyleSettings.BINARY_OPERATION_SIGN_ON_NEXT_LINE ? "\\n\"\n+ \"" : "\\n\" +\n\"";
final String[] lines = LineTokenizer.tokenize(text.toCharArray(), false, true);
for (int i = 0; i < lines.length; i++) {
String line = lines[i];
buffer.append(StringUtil.escapeStringCharacters(line));
if (i != lines.length - 1) buffer.append(breaker);
}
text = buffer.toString();
}
else if (tokenType == JavaTokenType.CHARACTER_LITERAL) {
if (rawText != null && rawText.rawText != null) return rawText.rawText; // Copied from the string literal. Copy as is.
// pastes in block selection mode (column mode) are not handled by a CopyPasteProcessor
final int selectionStart = selectionModel.getSelectionStart();
final int selectionEnd = selectionModel.getSelectionEnd();
IElementType tokenType = findLiteralTokenType(file, selectionStart, selectionEnd);
if (tokenType == JavaTokenType.STRING_LITERAL) {
if (rawText != null && rawText.rawText != null) return rawText.rawText; // Copied from the string literal. Copy as is.
StringBuilder buffer = new StringBuilder(text.length());
CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
@NonNls String breaker = codeStyleSettings.BINARY_OPERATION_SIGN_ON_NEXT_LINE ? "\\n\"\n+ \"" : "\\n\" +\n\"";
final String[] lines = LineTokenizer.tokenize(text.toCharArray(), false, true);
for (int i = 0; i < lines.length; i++) {
String line = lines[i];
buffer.append(StringUtil.escapeStringCharacters(line));
if (i != lines.length - 1) buffer.append(breaker);
}
text = buffer.toString();
}
else if (tokenType == JavaTokenType.CHARACTER_LITERAL) {
if (rawText != null && rawText.rawText != null) return rawText.rawText; // Copied from the string literal. Copy as is.
return escapeCharCharacters(text);
}
return text;
}
private static IElementType findLiteralTokenType(PsiFile file, int selectionStart, int selectionEnd) {
final PsiElement elementAtSelection = file.findElementAt(selectionStart);
if (!(elementAtSelection instanceof PsiJavaToken)) {
return null;
}
final IElementType tokenType = ((PsiJavaToken)elementAtSelection).getTokenType();
if ((tokenType != JavaTokenType.STRING_LITERAL && tokenType != JavaTokenType.CHARACTER_LITERAL)) {
return null;
}
final TextRange textRange = elementAtSelection.getTextRange();
if (selectionStart <= textRange.getStartOffset() || selectionEnd >= textRange.getEndOffset()) {
return null;
}
return tokenType;
}
@NotNull
public static String escapeCharCharacters(@NotNull String s) {
StringBuilder buffer = new StringBuilder();
StringUtil.escapeStringCharacters(s.length(), s, "\'", buffer);
return buffer.toString();
}
}