| /* |
| * Copyright 2000-2009 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.rename; |
| |
| import com.intellij.lang.java.JavaLanguage; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.psi.*; |
| import com.intellij.psi.codeStyle.JavaCodeStyleManager; |
| import com.intellij.psi.codeStyle.NameUtil; |
| import com.intellij.psi.codeStyle.SuggestedNameInfo; |
| import com.intellij.psi.codeStyle.VariableKind; |
| import com.intellij.psi.util.PropertyUtil; |
| import com.intellij.psi.util.PsiTreeUtil; |
| import com.intellij.usageView.UsageViewUtil; |
| import com.intellij.util.ArrayUtil; |
| import com.intellij.util.containers.ContainerUtil; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.util.*; |
| |
| public class JavaNameSuggestionProvider implements NameSuggestionProvider { |
| @Nullable |
| public SuggestedNameInfo getSuggestedNames(final PsiElement element, final PsiElement nameSuggestionContext, Set<String> result) { |
| if (!element.getLanguage().isKindOf(JavaLanguage.INSTANCE)) return null; |
| String initialName = UsageViewUtil.getShortName(element); |
| SuggestedNameInfo info = suggestNamesForElement(element, nameSuggestionContext); |
| if (info != null) { |
| info = JavaCodeStyleManager.getInstance(element.getProject()).suggestUniqueVariableName(info, element, true, true); |
| } |
| |
| String parameterName = null; |
| String superMethodName = null; |
| if (nameSuggestionContext instanceof PsiParameter) { |
| final PsiElement nameSuggestionContextParent = nameSuggestionContext.getParent(); |
| if (nameSuggestionContextParent instanceof PsiParameterList) { |
| final PsiElement parentOfParent = nameSuggestionContextParent.getParent(); |
| if (parentOfParent instanceof PsiMethod) { |
| final String propName = PropertyUtil.getPropertyName((PsiMethod)parentOfParent); |
| if (propName != null) { |
| parameterName = propName; |
| } |
| superMethodName = getSuperMethodName((PsiParameter) nameSuggestionContext, (PsiMethod) parentOfParent); |
| } |
| } |
| } |
| final String[] strings = info != null ? info.names : ArrayUtil.EMPTY_STRING_ARRAY; |
| final ArrayList<String> list = new ArrayList<String>(Arrays.asList(strings)); |
| final String[] properlyCased = suggestProperlyCasedName(element); |
| if (properlyCased != null) { |
| Collections.addAll(list, properlyCased); |
| } |
| if (parameterName != null && !list.contains(parameterName)) { |
| list.add(parameterName); |
| } |
| if (superMethodName != null && !list.contains(superMethodName)) { |
| list.add(0, superMethodName); |
| } |
| if (!list.contains(initialName)) { |
| list.add(initialName); |
| } |
| else { |
| int i = list.indexOf(initialName); |
| list.remove(i); |
| list.add(initialName); |
| } |
| ContainerUtil.removeDuplicates(list); |
| result.addAll(list); |
| return info; |
| } |
| |
| @Nullable |
| private static String getSuperMethodName(final PsiParameter psiParameter, final PsiMethod method) { |
| final int index = method.getParameterList().getParameterIndex(psiParameter); |
| final PsiMethod[] superMethods = method.findSuperMethods(); |
| for (PsiMethod superMethod : superMethods) { |
| final PsiParameterList superParameters = superMethod.getParameterList(); |
| if (index < superParameters.getParametersCount()) { |
| return superParameters.getParameters() [index].getName(); |
| } |
| } |
| return null; |
| } |
| |
| @Nullable |
| private static String[] suggestProperlyCasedName(PsiElement psiElement) { |
| if (!(psiElement instanceof PsiNamedElement)) return null; |
| if (psiElement instanceof PsiFile) return null; |
| String name = ((PsiNamedElement)psiElement).getName(); |
| if (name == null) return null; |
| String prefix = ""; |
| if (psiElement instanceof PsiVariable) { |
| final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(psiElement.getProject()); |
| final VariableKind kind = codeStyleManager.getVariableKind((PsiVariable)psiElement); |
| prefix = codeStyleManager.getPrefixByVariableKind(kind); |
| if (kind == VariableKind.STATIC_FINAL_FIELD) { |
| final String[] words = NameUtil.splitNameIntoWords(name); |
| StringBuilder buffer = new StringBuilder(); |
| for (int i = 0; i < words.length; i++) { |
| String word = words[i]; |
| if (i > 0) buffer.append('_'); |
| buffer.append(StringUtil.toUpperCase(word)); |
| } |
| return new String[] {buffer.toString()}; |
| } |
| } |
| final List<String> result = new ArrayList<String>(); |
| result.add(suggestProperlyCasedName(prefix, NameUtil.splitNameIntoWords(name))); |
| if (name.startsWith(prefix)) { |
| name = name.substring(prefix.length()); |
| result.add(suggestProperlyCasedName(prefix, NameUtil.splitNameIntoWords(name))); |
| } |
| result.add(suggestProperlyCasedName(prefix, NameUtil.splitNameIntoWords(name.toLowerCase()))); |
| return ArrayUtil.toStringArray(result); |
| } |
| |
| private static String suggestProperlyCasedName(String prefix, String[] words) { |
| StringBuilder buffer = new StringBuilder(prefix); |
| for (int i = 0; i < words.length; i++) { |
| String word = words[i]; |
| final boolean prefixRequiresCapitalization = prefix.length() > 0 && !StringUtil.endsWithChar(prefix, '_'); |
| if (i > 0 || prefixRequiresCapitalization) { |
| buffer.append(StringUtil.capitalize(word)); |
| } |
| else { |
| buffer.append(StringUtil.decapitalize(word)); |
| } |
| } |
| return buffer.toString(); |
| } |
| |
| @Nullable |
| private static SuggestedNameInfo suggestNamesForElement(final PsiElement element, PsiElement nameSuggestionContext) { |
| PsiVariable var = null; |
| if (element instanceof PsiVariable) { |
| var = (PsiVariable)element; |
| } |
| else if (element instanceof PsiIdentifier) { |
| PsiIdentifier identifier = (PsiIdentifier)element; |
| if (identifier.getParent() instanceof PsiVariable) { |
| var = (PsiVariable)identifier.getParent(); |
| } |
| } |
| |
| if (var == null) return null; |
| |
| JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(element.getProject()); |
| VariableKind variableKind = codeStyleManager.getVariableKind(var); |
| final SuggestedNameInfo nameInfo = codeStyleManager.suggestVariableName(variableKind, null, var.getInitializer(), var.getType()); |
| final PsiExpression expression = PsiTreeUtil.getParentOfType(nameSuggestionContext, PsiExpression.class, false); |
| if (expression != null) { |
| return new SuggestedNameInfo.Delegate(codeStyleManager.suggestVariableName(variableKind, null, expression, var.getType()).names, nameInfo); |
| |
| } |
| return nameInfo; |
| } |
| |
| } |