2 * Copyright 2000-2016 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.refactoring.changeSignature;
18 import com.intellij.ide.highlighter.JavaFileType;
19 import com.intellij.openapi.diagnostic.Logger;
20 import com.intellij.openapi.fileTypes.FileType;
21 import com.intellij.openapi.project.Project;
22 import com.intellij.openapi.util.TextRange;
23 import com.intellij.openapi.util.text.StringUtil;
24 import com.intellij.psi.*;
25 import com.intellij.psi.util.PsiTreeUtil;
26 import com.intellij.refactoring.changeSignature.inplace.LanguageChangeSignatureDetector;
27 import com.intellij.refactoring.util.CanonicalTypes;
28 import com.intellij.util.ObjectUtils;
29 import com.intellij.util.VisibilityUtil;
30 import org.jetbrains.annotations.NotNull;
32 import java.util.List;
38 public class JavaChangeSignatureDetector implements LanguageChangeSignatureDetector<DetectedJavaChangeInfo> {
39 private static final Logger LOG = Logger.getInstance("#" + JavaChangeSignatureDetector.class.getName());
43 public DetectedJavaChangeInfo createInitialChangeInfo(final @NotNull PsiElement element) {
44 return DetectedJavaChangeInfo.createFromMethod(PsiTreeUtil.getParentOfType(element, PsiMethod.class), false);
48 public void performChange(final DetectedJavaChangeInfo changeInfo, @NotNull final String oldText) {
49 changeInfo.perform(changeInfo, oldText, true);
53 public boolean isChangeSignatureAvailableOnElement(@NotNull PsiElement element, DetectedJavaChangeInfo currentInfo) {
54 final PsiMethod method = currentInfo.getMethod();
55 TextRange range = method.getTextRange();
56 PsiCodeBlock body = method.getBody();
58 range = new TextRange(range.getStartOffset(), body.getTextOffset());
60 return element.getContainingFile() == method.getContainingFile() && range.contains(element.getTextRange());
64 public boolean ignoreChanges(PsiElement element) {
65 if (element instanceof PsiMethod) return true;
66 return PsiTreeUtil.getParentOfType(element, PsiImportList.class) != null;
70 public TextRange getHighlightingRange(@NotNull DetectedJavaChangeInfo changeInfo) {
71 PsiElement method = changeInfo.getMethod();
72 return method != null ? getSignatureRange((PsiMethod)method) : null;
76 public String getMethodSignaturePreview(DetectedJavaChangeInfo initialChangeInfo,
77 final List<TextRange> deleteRanges,
78 final List<TextRange> newRanges) {
79 StringBuilder buf = new StringBuilder();
80 String visibility = VisibilityUtil.getVisibilityString(initialChangeInfo.getNewVisibility());
81 buf.append(visibility);
82 if (!StringUtil.isEmptyOrSpaces(visibility)) {
85 CanonicalTypes.Type returnType = initialChangeInfo.getNewReturnType();
86 if (returnType != null) {
87 buf.append(returnType.getTypeText()).append(" ");
89 buf.append(initialChangeInfo.getNewName()).append("(");
91 JavaParameterInfo[] newParameters = initialChangeInfo.getNewParameters();
93 boolean[] toRemove = initialChangeInfo.toRemoveParm();
94 for (int i = 0; i < toRemove.length; i++) {
103 String deletedParam = initialChangeInfo.getOldParameterTypes()[i] + " " + initialChangeInfo.getOldParameterNames()[i];
104 deleteRanges.add(new TextRange(buf.length(), buf.length() + deletedParam.length()));
105 buf.append(deletedParam);
108 for (JavaParameterInfo parameter : newParameters) {
109 if (parameter.getOldIndex() == i) {
110 buf.append(parameter.getTypeText()).append(" ").append(parameter.getName());
117 for (JavaParameterInfo param : newParameters) {
118 if (param.getOldIndex() == -1) {
125 String paramPresentation = param.getTypeText() + " " + ObjectUtils.notNull(param.getName(), "");
126 newRanges.add(new TextRange(buf.length(), buf.length() + paramPresentation.length()));
127 buf.append(paramPresentation);
131 return buf.toString();
135 public FileType getFileType() {
136 return JavaFileType.INSTANCE;
140 public DetectedJavaChangeInfo createNextChangeInfo(String signature, @NotNull final DetectedJavaChangeInfo currentInfo, boolean delegate) {
141 final PsiElement currentInfoMethod = currentInfo.getMethod();
142 if (currentInfoMethod == null) {
145 final Project project = currentInfoMethod.getProject();
147 final PsiMethod oldMethod = currentInfo.getMethod();
148 String visibility = "";
149 PsiClass containingClass = oldMethod.getContainingClass();
150 if (containingClass != null && containingClass.isInterface()) {
151 visibility = PsiModifier.PUBLIC + " ";
153 PsiMethod method = JavaPsiFacade.getElementFactory(project).createMethodFromText((visibility + signature).trim(), oldMethod);
154 return currentInfo.createNextInfo(method, delegate);
157 public static TextRange getSignatureRange(PsiMethod method) {
158 int endOffset = method.getThrowsList().getTextRange().getEndOffset();
159 int startOffset = method.getTextRange().getStartOffset();
160 return new TextRange(startOffset, endOffset);