blob: c83a0ba2a51cf0f44807d9718c957271cb31e7b5 [file] [log] [blame]
/*
* Copyright 2000-2014 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 com.intellij.refactoring.changeSignature;
import com.intellij.lang.LanguageRefactoringSupport;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType;
import com.intellij.psi.impl.source.tree.Factory;
import com.intellij.psi.impl.source.tree.SharedImplUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.CharTable;
import com.intellij.util.IncorrectOperationException;
import java.util.ArrayList;
import java.util.List;
/**
* @author dsl
*/
public class ChangeSignatureUtil {
private ChangeSignatureUtil() { }
public interface ChildrenGenerator<Parent extends PsiElement, Child extends PsiElement> {
List<Child> getChildren(Parent parent);
}
public static <Parent extends PsiElement, Child extends PsiElement> void synchronizeList(
Parent list,
List<Child> newElements,
ChildrenGenerator<Parent, Child> generator,
boolean[] shouldRemoveChild) throws IncorrectOperationException
{
List<Child> elementsToRemove = null;
List<Child> elements;
int index = 0;
while (true) {
elements = generator.getChildren(list);
if (index == newElements.size()) break;
if (elementsToRemove == null) {
elementsToRemove = new ArrayList<Child>();
for (int i = 0; i < shouldRemoveChild.length; i++) {
if (shouldRemoveChild[i] && i < elements.size()) {
elementsToRemove.add(elements.get(i));
}
}
}
Child oldElement = index < elements.size() ? elements.get(index) : null;
Child newElement = newElements.get(index);
if (newElement != null) {
if (!newElement.equals(oldElement)) {
if (oldElement != null && elementsToRemove.contains(oldElement)) {
oldElement.delete();
index--;
}
else {
assert list.isWritable() : PsiUtilCore.getVirtualFile(list);
list.addBefore(newElement, oldElement);
if (list.equals(newElement.getParent())) {
newElement.delete();
}
}
}
}
else {
if (newElements.size() > 1 && (!elements.isEmpty() || index < newElements.size() - 1)) {
PsiElement anchor;
if (index == 0) {
anchor = list.getFirstChild();
}
else {
anchor = index - 1 < elements.size() ? elements.get(index - 1) : null;
}
CharTable charTable = SharedImplUtil.findCharTableByTree(list.getNode());
PsiElement psi = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, charTable, list.getManager()).getPsi();
if (anchor != null) {
list.addAfter(psi, anchor);
}
else {
list.add(psi);
}
}
}
index++;
}
for (int i = newElements.size(); i < elements.size(); i++) {
Child element = elements.get(i);
element.delete();
}
}
public static void invokeChangeSignatureOn(PsiMethod method, Project project) {
ChangeSignatureHandler handler = LanguageRefactoringSupport.INSTANCE.forLanguage(method.getLanguage()).getChangeSignatureHandler();
if (handler != null) {
handler.invoke(project, new PsiElement[]{method}, null);
}
}
public static boolean deepTypeEqual(PsiType type1, PsiType type2) {
if (type1 == type2) return true;
if (type1 == null || !type1.equals(type2)) return false;
return Comparing.equal(type1.getCanonicalText(true), type2.getCanonicalText(true));
}
}