blob: eac093207b030d6001df3a8e2bca2ce18177301b [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* 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.jetbrains.idea.devkit.actions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessorEx;
import com.intellij.openapi.command.UndoConfirmationPolicy;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import gnu.trove.THashMap;
import java.util.*;
/**
* @author gregsh
*/
public class ShuffleNamesAction extends AnAction {
@Override
public void update(AnActionEvent e) {
Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
PsiFile file = CommonDataKeys.PSI_FILE.getData(e.getDataContext());
e.getPresentation().setEnabled(editor != null && file != null);
}
@Override
public void actionPerformed(AnActionEvent e) {
final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
PsiFile file = CommonDataKeys.PSI_FILE.getData(e.getDataContext());
if (editor == null || file == null) return;
final Project project = file.getProject();
CommandProcessorEx commandProcessor = (CommandProcessorEx)CommandProcessorEx.getInstance();
Object commandToken = commandProcessor.startCommand(project, e.getPresentation().getText(), e.getPresentation().getText(), UndoConfirmationPolicy.DEFAULT);
AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(getClass());
try {
shuffleIds(file, editor);
}
finally {
token.finish();
commandProcessor.finishCommand(project, commandToken, null);
}
}
private static boolean shuffleIds(PsiFile file, Editor editor) {
final Map<String, String> map = new THashMap<String, String>();
final StringBuilder sb = new StringBuilder();
final StringBuilder quote = new StringBuilder();
final ArrayList<String> split = new ArrayList<String>(100);
file.acceptChildren(new PsiRecursiveElementWalkingVisitor() {
@Override
public void visitElement(PsiElement element) {
if (element instanceof LeafPsiElement) {
String type = ((LeafPsiElement)element).getElementType().toString();
String text = element.getText();
if (text.isEmpty()) return;
for (int i=0, len=text.length(); i<len/2; i++) {
char c = text.charAt(i);
if (c == text.charAt(len-i-1) && !Character.isLetter(c)) {
quote.append(c);
}
else break;
}
boolean isQuoted = quote.length() > 0;
boolean isNumber = false;
if (isQuoted || type.equals("ID") || type.contains("IDENT") && !"ts".equals(text) ||
(isNumber = text.matches("[0-9]+"))) {
String replacement = map.get(text);
if (replacement == null) {
split.addAll(Arrays.asList((isQuoted? text.substring(quote.length(), text.length()-quote.length()).replace("''", "") : text).split("")));
if (!isNumber) {
for (ListIterator<String> it = split.listIterator(); it.hasNext(); ) {
String s = it.next();
if (s.isEmpty()) {
it.remove();
continue;
}
int c = s.charAt(0);
int cap = c & 32;
c &= ~cap;
c = (char) ((c >= 'A') && (c <= 'Z') ? ((c - 'A' + 7) % 26 + 'A') : c) | cap;
it.set(String.valueOf((char)c));
}
}
Collections.shuffle(split);
if (isNumber && "0".equals(split.get(0))) {
split.set(0, "1");
}
replacement = StringUtil.join(split, "");
if (isQuoted) {
replacement = quote + replacement + quote.reverse();
}
map.put(text, replacement);
}
text = replacement;
}
sb.append(text);
quote.setLength(0);
split.clear();
}
super.visitElement(element);
}
});
editor.getDocument().setText(sb.toString());
return true;
}
}