blob: 3d01eb2031843a89455d64d23c7a5d3a9266cebe [file] [log] [blame]
/*
* Copyright 2006 Sascha Weinreuter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.intellij.lang.regexp.surroundWith;
import com.intellij.lang.ASTNode;
import com.intellij.lang.surroundWith.Surrounder;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.intellij.lang.regexp.RegExpFileType;
import org.intellij.lang.regexp.psi.RegExpAtom;
import org.intellij.lang.regexp.psi.RegExpPattern;
import org.intellij.lang.regexp.psi.impl.RegExpElementImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
class GroupSurrounder implements Surrounder {
private final String myTitle;
private final String myGroupStart;
public GroupSurrounder(String title, String groupStart) {
myTitle = title;
myGroupStart = groupStart;
}
public String getTemplateDescription() {
return myTitle;
}
public boolean isApplicable(@NotNull PsiElement[] elements) {
return elements.length == 1 || PsiTreeUtil.findCommonParent(elements) == elements[0].getParent();
}
@Nullable
public TextRange surroundElements(@NotNull Project project, @NotNull Editor editor, @NotNull PsiElement[] elements) throws IncorrectOperationException {
assert elements.length == 1 || PsiTreeUtil.findCommonParent(elements) == elements[0].getParent();
final PsiElement e = elements[0];
final ASTNode node = e.getNode();
assert node != null;
final ASTNode parent = node.getTreeParent();
final StringBuilder s = new StringBuilder();
for (int i = 0; i < elements.length; i++) {
final PsiElement element = elements[i];
if (element instanceof RegExpElementImpl) {
s.append(((RegExpElementImpl)element).getUnescapedText());
} else {
s.append(element.getText());
}
if (i > 0) {
final ASTNode child = element.getNode();
assert child != null;
parent.removeChild(child);
}
}
final PsiFileFactory factory = PsiFileFactory.getInstance(project);
final PsiFile f = factory.createFileFromText("dummy.regexp", RegExpFileType.INSTANCE, makeReplacement(s));
final RegExpPattern pattern = PsiTreeUtil.getChildOfType(f, RegExpPattern.class);
assert pattern != null;
final RegExpAtom element = pattern.getBranches()[0].getAtoms()[0];
if (isInsideStringLiteral(e)) {
final Document doc = editor.getDocument();
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(doc);
final TextRange tr = e.getTextRange();
doc.replaceString(tr.getStartOffset(), tr.getEndOffset(),
StringUtil.escapeStringCharacters(element.getText()));
return TextRange.from(e.getTextRange().getEndOffset(), 0);
} else {
final PsiElement n = e.replace(element);
return TextRange.from(n.getTextRange().getEndOffset(), 0);
}
}
private static boolean isInsideStringLiteral(PsiElement context) {
while (context != null) {
if (RegExpElementImpl.isLiteralExpression(context)) {
return true;
}
context = context.getContext();
}
return false;
}
protected String makeReplacement(StringBuilder s) {
return myGroupStart + s + ")";
}
}