Merge branch 'master' into changeSignature
[idea/community.git] / java / java-impl / src / com / intellij / refactoring / changeSignature / ChangeSignatureUtil.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.refactoring.changeSignature;
17
18 import com.intellij.psi.PsiElement;
19 import com.intellij.psi.util.PsiUtilBase;
20 import com.intellij.util.IncorrectOperationException;
21
22 import java.util.ArrayList;
23 import java.util.List;
24
25 /**
26  * @author dsl
27  */
28 public class ChangeSignatureUtil {
29   private ChangeSignatureUtil() {
30   }
31
32   public static <Parent extends PsiElement, Child extends PsiElement> void synchronizeList(Parent list,
33                                                                                            final List<Child> newElements,
34                                                                                            ChildrenGenerator<Parent, Child> generator,
35                                                                                            final boolean[] shouldRemoveChild)
36     throws IncorrectOperationException {
37
38     ArrayList<Child> elementsToRemove = null;
39     List<Child> elements;
40
41     int index = 0;
42     while (true) {
43       elements = generator.getChildren(list);
44       if (index == newElements.size()) break;
45
46       if (elementsToRemove == null) {
47         elementsToRemove = new ArrayList<Child>();
48         for (int i = 0; i < shouldRemoveChild.length; i++) {
49           if (shouldRemoveChild[i] && i < elements.size()) {
50             elementsToRemove.add(elements.get(i));
51           }
52         }
53       }
54
55       Child oldElement = index < elements.size() ? elements.get(index) : null;
56       Child newElement = newElements.get(index);
57       if (!newElement.equals(oldElement)) {
58         if (oldElement != null && elementsToRemove.contains(oldElement)) {
59           oldElement.delete();
60           index--;
61         }
62         else {
63           assert list.isWritable() : PsiUtilBase.getVirtualFile(list);
64           list.addBefore(newElement, oldElement);
65           if (list.equals(newElement.getParent())) {
66             newElement.delete();
67           }
68         }
69       }
70       index++;
71     }
72     for (int i = newElements.size(); i < elements.size(); i++) {
73       Child element = elements.get(i);
74       element.delete();
75     }
76   }
77
78   public interface ChildrenGenerator<Parent extends PsiElement, Child extends PsiElement> {
79     List<Child> getChildren(Parent parent);
80   }
81 }