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.editor.Editor;
21 import com.intellij.openapi.fileTypes.FileType;
22 import com.intellij.openapi.project.Project;
23 import com.intellij.openapi.util.TextRange;
24 import com.intellij.openapi.util.text.StringUtil;
25 import com.intellij.psi.*;
26 import com.intellij.psi.util.PsiTreeUtil;
27 import com.intellij.refactoring.changeSignature.inplace.LanguageChangeSignatureDetector;
28 import com.intellij.refactoring.util.CanonicalTypes;
29 import com.intellij.util.ObjectUtils;
30 import com.intellij.util.VisibilityUtil;
31 import org.jetbrains.annotations.NotNull;
33 import java.util.List;
39 public class JavaChangeSignatureDetector implements LanguageChangeSignatureDetector<DetectedJavaChangeInfo> {
40 private static final Logger LOG = Logger.getInstance("#" + JavaChangeSignatureDetector.class.getName());
44 public DetectedJavaChangeInfo createInitialChangeInfo(final @NotNull PsiElement element) {
45 return DetectedJavaChangeInfo.createFromMethod(PsiTreeUtil.getParentOfType(element, PsiMethod.class), false);
49 public void performChange(final DetectedJavaChangeInfo changeInfo, Editor editor, @NotNull final String oldText) {
50 changeInfo.perform(oldText, editor, true);
54 public boolean isChangeSignatureAvailableOnElement(@NotNull PsiElement element, DetectedJavaChangeInfo currentInfo) {
55 final PsiMethod method = currentInfo.getMethod();
56 TextRange range = method.getTextRange();
57 PsiCodeBlock body = method.getBody();
59 range = new TextRange(range.getStartOffset(), body.getTextOffset());
61 return element.getContainingFile() == method.getContainingFile() && range.contains(element.getTextRange());
65 public boolean ignoreChanges(PsiElement element) {
66 if (element instanceof PsiMethod) return true;
67 return PsiTreeUtil.getParentOfType(element, PsiImportList.class) != null;
71 public TextRange getHighlightingRange(@NotNull DetectedJavaChangeInfo changeInfo) {
72 PsiElement method = changeInfo.getMethod();
73 return method != null ? getSignatureRange((PsiMethod)method) : null;
77 public String getMethodSignaturePreview(DetectedJavaChangeInfo initialChangeInfo,
78 final List<TextRange> deleteRanges,
79 final List<TextRange> newRanges) {
80 StringBuilder buf = new StringBuilder();
81 String visibility = VisibilityUtil.getVisibilityString(initialChangeInfo.getNewVisibility());
82 buf.append(visibility);
83 if (!StringUtil.isEmptyOrSpaces(visibility)) {
86 CanonicalTypes.Type returnType = initialChangeInfo.getNewReturnType();
87 if (returnType != null) {
88 buf.append(returnType.getTypeText()).append(" ");
90 buf.append(initialChangeInfo.getNewName()).append("(");
92 JavaParameterInfo[] newParameters = initialChangeInfo.getNewParameters();
94 boolean[] toRemove = initialChangeInfo.toRemoveParm();
95 for (int i = 0; i < toRemove.length; i++) {
104 String deletedParam = initialChangeInfo.getOldParameterTypes()[i] + " " + initialChangeInfo.getOldParameterNames()[i];
105 deleteRanges.add(new TextRange(buf.length(), buf.length() + deletedParam.length()));
106 buf.append(deletedParam);
109 for (JavaParameterInfo parameter : newParameters) {
110 if (parameter.getOldIndex() == i) {
111 buf.append(parameter.getTypeText()).append(" ").append(parameter.getName());
118 for (JavaParameterInfo param : newParameters) {
119 if (param.getOldIndex() == -1) {
126 String paramPresentation = param.getTypeText() + " " + ObjectUtils.notNull(param.getName(), "");
127 newRanges.add(new TextRange(buf.length(), buf.length() + paramPresentation.length()));
128 buf.append(paramPresentation);
132 return buf.toString();
136 public FileType getFileType() {
137 return JavaFileType.INSTANCE;
141 public DetectedJavaChangeInfo createNextChangeInfo(String signature, @NotNull final DetectedJavaChangeInfo currentInfo, boolean delegate) {
142 final PsiElement currentInfoMethod = currentInfo.getMethod();
143 if (currentInfoMethod == null) {
146 final Project project = currentInfoMethod.getProject();
148 final PsiMethod oldMethod = currentInfo.getMethod();
149 String visibility = "";
150 PsiClass containingClass = oldMethod.getContainingClass();
151 if (containingClass != null && containingClass.isInterface()) {
152 visibility = PsiModifier.PUBLIC + " ";
154 PsiMethod method = JavaPsiFacade.getElementFactory(project).createMethodFromText((visibility + signature).trim(), oldMethod);
155 return currentInfo.createNextInfo(method, delegate);
158 public static TextRange getSignatureRange(PsiMethod method) {
159 int endOffset = method.getThrowsList().getTextRange().getEndOffset();
160 int startOffset = method.getTextRange().getStartOffset();
161 return new TextRange(startOffset, endOffset);