mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 06:05:01 +07:00
Merge branch 'master' into upsource-master
This commit is contained in:
File diff suppressed because it is too large
Load Diff
+194
-194
@@ -1,194 +1,194 @@
|
||||
/*
|
||||
* 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.codeInspection.defaultFileTemplateUsage;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightUtil;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.ide.fileTemplates.FileTemplate;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.JavaRecursiveElementWalkingVisitor;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author Alexey
|
||||
*/
|
||||
public class FileHeaderChecker {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.defaultFileTemplateUsage.FileHeaderChecker");
|
||||
|
||||
static ProblemDescriptor checkFileHeader(final PsiFile file, final InspectionManager manager, boolean onTheFly) {
|
||||
FileTemplate template = FileTemplateManager.getInstance().getDefaultTemplate(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME);
|
||||
TIntObjectHashMap<String> offsetToProperty = new TIntObjectHashMap<String>();
|
||||
String templateText = template.getText().trim();
|
||||
String regex = templateToRegex(templateText, offsetToProperty);
|
||||
regex = StringUtil.replace(regex, "with", "(?:with|by)");
|
||||
regex = ".*("+regex+").*";
|
||||
String fileText = file.getText();
|
||||
Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
|
||||
Matcher matcher = pattern.matcher(fileText);
|
||||
if (matcher.matches()) {
|
||||
final int startOffset = matcher.start(1);
|
||||
final int endOffset = matcher.end(1);
|
||||
final Ref<PsiDocComment> docComment = new Ref<PsiDocComment>();
|
||||
file.accept(new JavaRecursiveElementWalkingVisitor(){
|
||||
@Override public void visitElement(PsiElement element) {
|
||||
if (docComment.get() != null) return;
|
||||
TextRange range = element.getTextRange();
|
||||
if (!range.contains(startOffset) && !range.contains(endOffset)) return;
|
||||
super.visitElement(element);
|
||||
}
|
||||
@Override public void visitDocComment(PsiDocComment comment) {
|
||||
docComment.set(comment);
|
||||
}
|
||||
});
|
||||
PsiDocComment element = docComment.get();
|
||||
if (element == null) return null;
|
||||
LocalQuickFix[] quickFix = createQuickFix(matcher, offsetToProperty);
|
||||
final String description = InspectionsBundle.message("default.file.template.description");
|
||||
return manager.createProblemDescriptor(element, description, onTheFly, quickFix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Properties computeProperties(final Matcher matcher, final TIntObjectHashMap<String> offsetToProperty) {
|
||||
Properties properties = new Properties(FileTemplateManager.getInstance().getDefaultProperties());
|
||||
int[] offsets = offsetToProperty.keys();
|
||||
Arrays.sort(offsets);
|
||||
|
||||
for (int i = 0; i < offsets.length; i++) {
|
||||
final int offset = offsets[i];
|
||||
String propName = offsetToProperty.get(offset);
|
||||
int groupNum = i + 2; // first group is whole doc comment
|
||||
String propValue = matcher.group(groupNum);
|
||||
properties.put(propName, propValue);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static LocalQuickFix[] createQuickFix(final Matcher matcher,
|
||||
final TIntObjectHashMap<String> offsetToProperty) {
|
||||
final FileTemplate template = FileTemplateManager.getInstance().getPattern(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME);
|
||||
|
||||
final ReplaceWithFileTemplateFix replaceTemplateFix = new ReplaceWithFileTemplateFix() {
|
||||
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
|
||||
PsiElement element = descriptor.getPsiElement();
|
||||
if (element == null || !element.isValid()) return;
|
||||
if (!CodeInsightUtil.preparePsiElementsForWrite(element)) return;
|
||||
String newText;
|
||||
try {
|
||||
newText = template.getText(computeProperties(matcher, offsetToProperty));
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
int offset = element.getTextRange().getStartOffset();
|
||||
PsiFile psiFile = element.getContainingFile();
|
||||
if (psiFile == null) return;
|
||||
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(psiFile.getProject());
|
||||
Document document = documentManager.getDocument(psiFile);
|
||||
if (document == null) return;
|
||||
|
||||
element.delete();
|
||||
documentManager.doPostponedOperationsAndUnblockDocument(document);
|
||||
documentManager.commitDocument(document);
|
||||
|
||||
document.insertString(offset, newText);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
LOG.error("Cannot create doc comment from text: '" + newText + "'", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
final LocalQuickFix editFileTemplateFix = DefaultFileTemplateUsageInspection.createEditFileTemplateFix(template, replaceTemplateFix);
|
||||
if (template.isDefault()) {
|
||||
return new LocalQuickFix[]{editFileTemplateFix};
|
||||
}
|
||||
return new LocalQuickFix[]{replaceTemplateFix,editFileTemplateFix};
|
||||
}
|
||||
|
||||
private static String templateToRegex(final String text, TIntObjectHashMap<String> offsetToProperty) {
|
||||
String regex = text;
|
||||
@NonNls Collection<String> properties = new ArrayList<String>((Collection)FileTemplateManager.getInstance().getDefaultProperties().keySet());
|
||||
properties.add("PACKAGE_NAME");
|
||||
|
||||
regex = escapeRegexChars(regex);
|
||||
// first group is a whole file header
|
||||
int groupNumber = 1;
|
||||
for (String name : properties) {
|
||||
String escaped = escapeRegexChars("${"+name+"}");
|
||||
boolean first = true;
|
||||
for (int i = regex.indexOf(escaped); i!=-1 && i<regex.length(); i = regex.indexOf(escaped,i+1)) {
|
||||
String replacement = first ? "(.*)" : "\\" + groupNumber;
|
||||
final int delta = escaped.length() - replacement.length();
|
||||
int[] offs = offsetToProperty.keys();
|
||||
for (int off : offs) {
|
||||
if (off > i) {
|
||||
String prop = offsetToProperty.remove(off);
|
||||
offsetToProperty.put(off - delta, prop);
|
||||
}
|
||||
}
|
||||
offsetToProperty.put(i, name);
|
||||
regex = regex.substring(0,i) + replacement + regex.substring(i+escaped.length());
|
||||
if (first) {
|
||||
groupNumber++;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return regex;
|
||||
}
|
||||
|
||||
private static String escapeRegexChars(String regex) {
|
||||
regex = StringUtil.replace(regex,"|", "\\|");
|
||||
regex = StringUtil.replace(regex,".", "\\.");
|
||||
regex = StringUtil.replace(regex,"*", "\\*");
|
||||
regex = StringUtil.replace(regex,"+", "\\+");
|
||||
regex = StringUtil.replace(regex,"?", "\\?");
|
||||
regex = StringUtil.replace(regex,"$", "\\$");
|
||||
regex = StringUtil.replace(regex,"(", "\\(");
|
||||
regex = StringUtil.replace(regex,")", "\\)");
|
||||
regex = StringUtil.replace(regex,"[", "\\[");
|
||||
regex = StringUtil.replace(regex,"]", "\\]");
|
||||
regex = StringUtil.replace(regex,"{", "\\{");
|
||||
regex = StringUtil.replace(regex,"}", "\\}");
|
||||
return regex;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.codeInspection.defaultFileTemplateUsage;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightUtil;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.ide.fileTemplates.FileTemplate;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.JavaRecursiveElementWalkingVisitor;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author Alexey
|
||||
*/
|
||||
public class FileHeaderChecker {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.defaultFileTemplateUsage.FileHeaderChecker");
|
||||
|
||||
static ProblemDescriptor checkFileHeader(@NotNull final PsiFile file, final InspectionManager manager, boolean onTheFly) {
|
||||
FileTemplate template = FileTemplateManager.getInstance().getDefaultTemplate(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME);
|
||||
TIntObjectHashMap<String> offsetToProperty = new TIntObjectHashMap<String>();
|
||||
String templateText = template.getText().trim();
|
||||
String regex = templateToRegex(templateText, offsetToProperty, file.getProject());
|
||||
regex = StringUtil.replace(regex, "with", "(?:with|by)");
|
||||
regex = ".*("+regex+").*";
|
||||
String fileText = file.getText();
|
||||
Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
|
||||
Matcher matcher = pattern.matcher(fileText);
|
||||
if (matcher.matches()) {
|
||||
final int startOffset = matcher.start(1);
|
||||
final int endOffset = matcher.end(1);
|
||||
final Ref<PsiDocComment> docComment = new Ref<PsiDocComment>();
|
||||
file.accept(new JavaRecursiveElementWalkingVisitor(){
|
||||
@Override public void visitElement(PsiElement element) {
|
||||
if (docComment.get() != null) return;
|
||||
TextRange range = element.getTextRange();
|
||||
if (!range.contains(startOffset) && !range.contains(endOffset)) return;
|
||||
super.visitElement(element);
|
||||
}
|
||||
@Override public void visitDocComment(PsiDocComment comment) {
|
||||
docComment.set(comment);
|
||||
}
|
||||
});
|
||||
PsiDocComment element = docComment.get();
|
||||
if (element == null) return null;
|
||||
LocalQuickFix[] quickFix = createQuickFix(matcher, offsetToProperty);
|
||||
final String description = InspectionsBundle.message("default.file.template.description");
|
||||
return manager.createProblemDescriptor(element, description, onTheFly, quickFix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Properties computeProperties(final Matcher matcher, final TIntObjectHashMap<String> offsetToProperty) {
|
||||
Properties properties = new Properties(FileTemplateManager.getInstance().getDefaultProperties());
|
||||
int[] offsets = offsetToProperty.keys();
|
||||
Arrays.sort(offsets);
|
||||
|
||||
for (int i = 0; i < offsets.length; i++) {
|
||||
final int offset = offsets[i];
|
||||
String propName = offsetToProperty.get(offset);
|
||||
int groupNum = i + 2; // first group is whole doc comment
|
||||
String propValue = matcher.group(groupNum);
|
||||
properties.put(propName, propValue);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static LocalQuickFix[] createQuickFix(final Matcher matcher,
|
||||
final TIntObjectHashMap<String> offsetToProperty) {
|
||||
final FileTemplate template = FileTemplateManager.getInstance().getPattern(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME);
|
||||
|
||||
final ReplaceWithFileTemplateFix replaceTemplateFix = new ReplaceWithFileTemplateFix() {
|
||||
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
|
||||
PsiElement element = descriptor.getPsiElement();
|
||||
if (element == null || !element.isValid()) return;
|
||||
if (!CodeInsightUtil.preparePsiElementsForWrite(element)) return;
|
||||
String newText;
|
||||
try {
|
||||
newText = template.getText(computeProperties(matcher, offsetToProperty));
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
int offset = element.getTextRange().getStartOffset();
|
||||
PsiFile psiFile = element.getContainingFile();
|
||||
if (psiFile == null) return;
|
||||
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(psiFile.getProject());
|
||||
Document document = documentManager.getDocument(psiFile);
|
||||
if (document == null) return;
|
||||
|
||||
element.delete();
|
||||
documentManager.doPostponedOperationsAndUnblockDocument(document);
|
||||
documentManager.commitDocument(document);
|
||||
|
||||
document.insertString(offset, newText);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
LOG.error("Cannot create doc comment from text: '" + newText + "'", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
final LocalQuickFix editFileTemplateFix = DefaultFileTemplateUsageInspection.createEditFileTemplateFix(template, replaceTemplateFix);
|
||||
if (template.isDefault()) {
|
||||
return new LocalQuickFix[]{editFileTemplateFix};
|
||||
}
|
||||
return new LocalQuickFix[]{replaceTemplateFix,editFileTemplateFix};
|
||||
}
|
||||
|
||||
private static String templateToRegex(final String text, TIntObjectHashMap<String> offsetToProperty, Project project) {
|
||||
String regex = text;
|
||||
@NonNls Collection<String> properties = new ArrayList<String>((Collection)FileTemplateManager.getInstance().getDefaultProperties(project).keySet());
|
||||
properties.add("PACKAGE_NAME");
|
||||
|
||||
regex = escapeRegexChars(regex);
|
||||
// first group is a whole file header
|
||||
int groupNumber = 1;
|
||||
for (String name : properties) {
|
||||
String escaped = escapeRegexChars("${"+name+"}");
|
||||
boolean first = true;
|
||||
for (int i = regex.indexOf(escaped); i!=-1 && i<regex.length(); i = regex.indexOf(escaped,i+1)) {
|
||||
String replacement = first ? "(.*)" : "\\" + groupNumber;
|
||||
final int delta = escaped.length() - replacement.length();
|
||||
int[] offs = offsetToProperty.keys();
|
||||
for (int off : offs) {
|
||||
if (off > i) {
|
||||
String prop = offsetToProperty.remove(off);
|
||||
offsetToProperty.put(off - delta, prop);
|
||||
}
|
||||
}
|
||||
offsetToProperty.put(i, name);
|
||||
regex = regex.substring(0,i) + replacement + regex.substring(i+escaped.length());
|
||||
if (first) {
|
||||
groupNumber++;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return regex;
|
||||
}
|
||||
|
||||
private static String escapeRegexChars(String regex) {
|
||||
regex = StringUtil.replace(regex,"|", "\\|");
|
||||
regex = StringUtil.replace(regex,".", "\\.");
|
||||
regex = StringUtil.replace(regex,"*", "\\*");
|
||||
regex = StringUtil.replace(regex,"+", "\\+");
|
||||
regex = StringUtil.replace(regex,"?", "\\?");
|
||||
regex = StringUtil.replace(regex,"$", "\\$");
|
||||
regex = StringUtil.replace(regex,"(", "\\(");
|
||||
regex = StringUtil.replace(regex,")", "\\)");
|
||||
regex = StringUtil.replace(regex,"[", "\\[");
|
||||
regex = StringUtil.replace(regex,"]", "\\]");
|
||||
regex = StringUtil.replace(regex,"{", "\\{");
|
||||
regex = StringUtil.replace(regex,"}", "\\}");
|
||||
return regex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,206 +1,206 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
package com.intellij.psi.impl.file;
|
||||
|
||||
import com.intellij.core.CoreJavaDirectoryService;
|
||||
import com.intellij.ide.fileTemplates.FileTemplate;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateUtil;
|
||||
import com.intellij.ide.fileTemplates.JavaTemplateUtil;
|
||||
import com.intellij.ide.fileTemplates.ui.CreateFromTemplateDialog;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.module.LanguageLevelUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
public class JavaDirectoryServiceImpl extends CoreJavaDirectoryService {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.file.JavaDirectoryServiceImpl");
|
||||
|
||||
@Override
|
||||
public PsiPackage getPackage(@NotNull PsiDirectory dir) {
|
||||
ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(dir.getProject()).getFileIndex();
|
||||
String packageName = projectFileIndex.getPackageNameByDirectory(dir.getVirtualFile());
|
||||
if (packageName == null) return null;
|
||||
return JavaPsiFacade.getInstance(dir.getProject()).findPackage(packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass createClass(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
return createClassFromTemplate(dir, name, JavaTemplateUtil.INTERNAL_CLASS_TEMPLATE_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass createClass(@NotNull PsiDirectory dir, @NotNull String name, @NotNull String templateName) throws IncorrectOperationException {
|
||||
return createClassFromTemplate(dir, name, templateName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiClass createClass(@NotNull PsiDirectory dir,
|
||||
@NotNull String name,
|
||||
@NotNull String templateName,
|
||||
boolean askForUndefinedVariables) throws IncorrectOperationException {
|
||||
return createClassFromTemplate(dir, name, templateName, askForUndefinedVariables);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass createInterface(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
String templateName = JavaTemplateUtil.INTERNAL_INTERFACE_TEMPLATE_NAME;
|
||||
PsiClass someClass = createClassFromTemplate(dir, name, templateName);
|
||||
if (!someClass.isInterface()) {
|
||||
throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName));
|
||||
}
|
||||
return someClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass createEnum(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
String templateName = JavaTemplateUtil.INTERNAL_ENUM_TEMPLATE_NAME;
|
||||
PsiClass someClass = createClassFromTemplate(dir, name, templateName);
|
||||
if (!someClass.isEnum()) {
|
||||
throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName));
|
||||
}
|
||||
return someClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass createAnnotationType(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
String templateName = JavaTemplateUtil.INTERNAL_ANNOTATION_TYPE_TEMPLATE_NAME;
|
||||
PsiClass someClass = createClassFromTemplate(dir, name, templateName);
|
||||
if (!someClass.isAnnotationType()) {
|
||||
throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName));
|
||||
}
|
||||
return someClass;
|
||||
}
|
||||
|
||||
private static PsiClass createClassFromTemplate(@NotNull PsiDirectory dir, String name, String templateName) throws IncorrectOperationException {
|
||||
return createClassFromTemplate(dir, name, templateName, false);
|
||||
}
|
||||
|
||||
private static PsiClass createClassFromTemplate(@NotNull PsiDirectory dir,
|
||||
String name,
|
||||
String templateName,
|
||||
boolean askToDefineVariables) throws IncorrectOperationException {
|
||||
//checkCreateClassOrInterface(dir, name);
|
||||
|
||||
FileTemplate template = FileTemplateManager.getInstance().getInternalTemplate(templateName);
|
||||
|
||||
Properties defaultProperties = FileTemplateManager.getInstance().getDefaultProperties();
|
||||
Properties properties = new Properties(defaultProperties);
|
||||
properties.setProperty(FileTemplate.ATTRIBUTE_NAME, name);
|
||||
|
||||
String ext = StdFileTypes.JAVA.getDefaultExtension();
|
||||
String fileName = name + "." + ext;
|
||||
|
||||
PsiElement element;
|
||||
try {
|
||||
element = askToDefineVariables ? new CreateFromTemplateDialog(dir.getProject(), dir, template, null, properties).create()
|
||||
: FileTemplateUtil.createFromTemplate(template, fileName, properties, dir);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
return null;
|
||||
}
|
||||
if (element == null) return null;
|
||||
final PsiJavaFile file = (PsiJavaFile)element.getContainingFile();
|
||||
PsiClass[] classes = file.getClasses();
|
||||
if (classes.length < 1) {
|
||||
throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName));
|
||||
}
|
||||
return classes[0];
|
||||
}
|
||||
|
||||
private static String getIncorrectTemplateMessage(String templateName) {
|
||||
return PsiBundle.message("psi.error.incorroect.class.template.message",
|
||||
FileTemplateManager.getInstance().internalTemplateToSubject(templateName), templateName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCreateClass(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
checkCreateClassOrInterface(dir, name);
|
||||
}
|
||||
|
||||
public static void checkCreateClassOrInterface(@NotNull PsiDirectory directory, String name) throws IncorrectOperationException {
|
||||
PsiUtil.checkIsIdentifier(directory.getManager(), name);
|
||||
|
||||
String fileName = name + "." + StdFileTypes.JAVA.getDefaultExtension();
|
||||
directory.checkCreateFile(fileName);
|
||||
|
||||
PsiNameHelper helper = JavaPsiFacade.getInstance(directory.getProject()).getNameHelper();
|
||||
PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(directory);
|
||||
String qualifiedName = aPackage == null ? null : aPackage.getQualifiedName();
|
||||
if (!StringUtil.isEmpty(qualifiedName) && !helper.isQualifiedName(qualifiedName)) {
|
||||
throw new IncorrectOperationException("Cannot create class in invalid package: '"+qualifiedName+"'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSourceRoot(@NotNull PsiDirectory dir) {
|
||||
final VirtualFile file = dir.getVirtualFile();
|
||||
final VirtualFile sourceRoot = ProjectRootManager.getInstance(dir.getProject()).getFileIndex().getSourceRootForFile(file);
|
||||
return file.equals(sourceRoot);
|
||||
}
|
||||
|
||||
private static final Key<LanguageLevel> LANG_LEVEL_IN_DIRECTORY = new Key<LanguageLevel>("LANG_LEVEL_IN_DIRECTORY");
|
||||
@Override
|
||||
public LanguageLevel getLanguageLevel(@NotNull PsiDirectory dir) {
|
||||
synchronized (PsiLock.LOCK) {
|
||||
LanguageLevel level = dir.getUserData(LANG_LEVEL_IN_DIRECTORY);
|
||||
if (level == null) {
|
||||
level = getLanguageLevelInner(dir);
|
||||
dir.putUserData(LANG_LEVEL_IN_DIRECTORY, level);
|
||||
}
|
||||
return level;
|
||||
}
|
||||
}
|
||||
|
||||
private static LanguageLevel getLanguageLevelInner(@NotNull PsiDirectory dir) {
|
||||
final VirtualFile virtualFile = dir.getVirtualFile();
|
||||
final Project project = dir.getProject();
|
||||
final Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(virtualFile);
|
||||
if (module != null) {
|
||||
return LanguageLevelUtil.getEffectiveLanguageLevel(module);
|
||||
}
|
||||
|
||||
return LanguageLevelProjectExtension.getInstance(project).getLanguageLevel();
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
package com.intellij.psi.impl.file;
|
||||
|
||||
import com.intellij.core.CoreJavaDirectoryService;
|
||||
import com.intellij.ide.fileTemplates.FileTemplate;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateUtil;
|
||||
import com.intellij.ide.fileTemplates.JavaTemplateUtil;
|
||||
import com.intellij.ide.fileTemplates.ui.CreateFromTemplateDialog;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.module.LanguageLevelUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
public class JavaDirectoryServiceImpl extends CoreJavaDirectoryService {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.file.JavaDirectoryServiceImpl");
|
||||
|
||||
@Override
|
||||
public PsiPackage getPackage(@NotNull PsiDirectory dir) {
|
||||
ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(dir.getProject()).getFileIndex();
|
||||
String packageName = projectFileIndex.getPackageNameByDirectory(dir.getVirtualFile());
|
||||
if (packageName == null) return null;
|
||||
return JavaPsiFacade.getInstance(dir.getProject()).findPackage(packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass createClass(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
return createClassFromTemplate(dir, name, JavaTemplateUtil.INTERNAL_CLASS_TEMPLATE_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass createClass(@NotNull PsiDirectory dir, @NotNull String name, @NotNull String templateName) throws IncorrectOperationException {
|
||||
return createClassFromTemplate(dir, name, templateName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiClass createClass(@NotNull PsiDirectory dir,
|
||||
@NotNull String name,
|
||||
@NotNull String templateName,
|
||||
boolean askForUndefinedVariables) throws IncorrectOperationException {
|
||||
return createClassFromTemplate(dir, name, templateName, askForUndefinedVariables);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass createInterface(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
String templateName = JavaTemplateUtil.INTERNAL_INTERFACE_TEMPLATE_NAME;
|
||||
PsiClass someClass = createClassFromTemplate(dir, name, templateName);
|
||||
if (!someClass.isInterface()) {
|
||||
throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName));
|
||||
}
|
||||
return someClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass createEnum(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
String templateName = JavaTemplateUtil.INTERNAL_ENUM_TEMPLATE_NAME;
|
||||
PsiClass someClass = createClassFromTemplate(dir, name, templateName);
|
||||
if (!someClass.isEnum()) {
|
||||
throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName));
|
||||
}
|
||||
return someClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass createAnnotationType(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
String templateName = JavaTemplateUtil.INTERNAL_ANNOTATION_TYPE_TEMPLATE_NAME;
|
||||
PsiClass someClass = createClassFromTemplate(dir, name, templateName);
|
||||
if (!someClass.isAnnotationType()) {
|
||||
throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName));
|
||||
}
|
||||
return someClass;
|
||||
}
|
||||
|
||||
private static PsiClass createClassFromTemplate(@NotNull PsiDirectory dir, String name, String templateName) throws IncorrectOperationException {
|
||||
return createClassFromTemplate(dir, name, templateName, false);
|
||||
}
|
||||
|
||||
private static PsiClass createClassFromTemplate(@NotNull PsiDirectory dir,
|
||||
String name,
|
||||
String templateName,
|
||||
boolean askToDefineVariables) throws IncorrectOperationException {
|
||||
//checkCreateClassOrInterface(dir, name);
|
||||
|
||||
FileTemplate template = FileTemplateManager.getInstance().getInternalTemplate(templateName);
|
||||
|
||||
Properties defaultProperties = FileTemplateManager.getInstance().getDefaultProperties(dir.getProject());
|
||||
Properties properties = new Properties(defaultProperties);
|
||||
properties.setProperty(FileTemplate.ATTRIBUTE_NAME, name);
|
||||
|
||||
String ext = StdFileTypes.JAVA.getDefaultExtension();
|
||||
String fileName = name + "." + ext;
|
||||
|
||||
PsiElement element;
|
||||
try {
|
||||
element = askToDefineVariables ? new CreateFromTemplateDialog(dir.getProject(), dir, template, null, properties).create()
|
||||
: FileTemplateUtil.createFromTemplate(template, fileName, properties, dir);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
return null;
|
||||
}
|
||||
if (element == null) return null;
|
||||
final PsiJavaFile file = (PsiJavaFile)element.getContainingFile();
|
||||
PsiClass[] classes = file.getClasses();
|
||||
if (classes.length < 1) {
|
||||
throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName));
|
||||
}
|
||||
return classes[0];
|
||||
}
|
||||
|
||||
private static String getIncorrectTemplateMessage(String templateName) {
|
||||
return PsiBundle.message("psi.error.incorroect.class.template.message",
|
||||
FileTemplateManager.getInstance().internalTemplateToSubject(templateName), templateName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCreateClass(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
checkCreateClassOrInterface(dir, name);
|
||||
}
|
||||
|
||||
public static void checkCreateClassOrInterface(@NotNull PsiDirectory directory, String name) throws IncorrectOperationException {
|
||||
PsiUtil.checkIsIdentifier(directory.getManager(), name);
|
||||
|
||||
String fileName = name + "." + StdFileTypes.JAVA.getDefaultExtension();
|
||||
directory.checkCreateFile(fileName);
|
||||
|
||||
PsiNameHelper helper = JavaPsiFacade.getInstance(directory.getProject()).getNameHelper();
|
||||
PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(directory);
|
||||
String qualifiedName = aPackage == null ? null : aPackage.getQualifiedName();
|
||||
if (!StringUtil.isEmpty(qualifiedName) && !helper.isQualifiedName(qualifiedName)) {
|
||||
throw new IncorrectOperationException("Cannot create class in invalid package: '"+qualifiedName+"'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSourceRoot(@NotNull PsiDirectory dir) {
|
||||
final VirtualFile file = dir.getVirtualFile();
|
||||
final VirtualFile sourceRoot = ProjectRootManager.getInstance(dir.getProject()).getFileIndex().getSourceRootForFile(file);
|
||||
return file.equals(sourceRoot);
|
||||
}
|
||||
|
||||
private static final Key<LanguageLevel> LANG_LEVEL_IN_DIRECTORY = new Key<LanguageLevel>("LANG_LEVEL_IN_DIRECTORY");
|
||||
@Override
|
||||
public LanguageLevel getLanguageLevel(@NotNull PsiDirectory dir) {
|
||||
synchronized (PsiLock.LOCK) {
|
||||
LanguageLevel level = dir.getUserData(LANG_LEVEL_IN_DIRECTORY);
|
||||
if (level == null) {
|
||||
level = getLanguageLevelInner(dir);
|
||||
dir.putUserData(LANG_LEVEL_IN_DIRECTORY, level);
|
||||
}
|
||||
return level;
|
||||
}
|
||||
}
|
||||
|
||||
private static LanguageLevel getLanguageLevelInner(@NotNull PsiDirectory dir) {
|
||||
final VirtualFile virtualFile = dir.getVirtualFile();
|
||||
final Project project = dir.getProject();
|
||||
final Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(virtualFile);
|
||||
if (module != null) {
|
||||
return LanguageLevelUtil.getEffectiveLanguageLevel(module);
|
||||
}
|
||||
|
||||
return LanguageLevelProjectExtension.getInstance(project).getLanguageLevel();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,246 +1,246 @@
|
||||
/*
|
||||
* 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.psi.util;
|
||||
|
||||
import com.intellij.ide.fileTemplates.FileTemplate;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.ide.fileTemplates.JavaCreateFromTemplateHandler;
|
||||
import com.intellij.ide.util.DirectoryChooserUtil;
|
||||
import com.intellij.ide.util.PackageUtil;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.impl.DirectoryIndex;
|
||||
import com.intellij.openapi.roots.impl.DirectoryInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.text.StringTokenizer;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* author: lesya
|
||||
*/
|
||||
public class CreateClassUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.j2ee.CreateClassUtil");
|
||||
|
||||
@NonNls public static final String DEFAULT_CLASS_TEMPLATE = "#DEFAULT_CLASS_TEMPLATE";
|
||||
@NonNls private static final String DO_NOT_CREATE_CLASS_TEMPLATE = "#DO_NOT_CREATE_CLASS_TEMPLATE";
|
||||
@NonNls private static final String CLASS_NAME_PROPERTY = "Class_Name";
|
||||
@NonNls private static final String INTERFACE_NAME_PROPERTY = "Interface_Name";
|
||||
|
||||
private CreateClassUtil() {}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass createClassFromTemplate(@NotNull final Properties attributes, @Nullable final String templateName,
|
||||
@NotNull final PsiDirectory directoryRoot,
|
||||
@NotNull final String className) throws IncorrectOperationException {
|
||||
if (templateName == null) return null;
|
||||
if (templateName.equals(DO_NOT_CREATE_CLASS_TEMPLATE)) return null;
|
||||
|
||||
final Project project = directoryRoot.getProject();
|
||||
try {
|
||||
final PsiDirectory directory = createParentDirectories(directoryRoot, className);
|
||||
final PsiFile psiFile = directory.findFile(className + "." + StdFileTypes.JAVA.getDefaultExtension());
|
||||
if (psiFile != null) {
|
||||
psiFile.delete();
|
||||
}
|
||||
|
||||
final String rawClassName = extractClassName(className);
|
||||
final PsiFile existing = directory.findFile(rawClassName + ".java");
|
||||
if (existing instanceof PsiJavaFile) {
|
||||
final PsiClass[] classes = ((PsiJavaFile)existing).getClasses();
|
||||
if (classes.length > 0) {
|
||||
return classes[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiClass aClass;
|
||||
if (templateName.equals(DEFAULT_CLASS_TEMPLATE)) {
|
||||
aClass = JavaDirectoryService.getInstance().createClass(directory, rawClassName);
|
||||
}
|
||||
else {
|
||||
final FileTemplateManager fileTemplateManager = FileTemplateManager.getInstance();
|
||||
FileTemplate fileTemplate = fileTemplateManager.getJ2eeTemplate(templateName);
|
||||
LOG.assertTrue(fileTemplate != null, templateName + " not found");
|
||||
final String text = fileTemplate.getText(attributes);
|
||||
aClass = JavaCreateFromTemplateHandler.createClassOrInterface(project, directory, text, true, fileTemplate.getExtension());
|
||||
}
|
||||
return (PsiClass)JavaCodeStyleManager.getInstance(project).shortenClassReferences(aClass);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IncorrectOperationException(e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiDirectory createParentDirectories(@NotNull PsiDirectory directoryRoot, @NotNull String className) throws IncorrectOperationException {
|
||||
final PsiPackage currentPackage = JavaDirectoryService.getInstance().getPackage(directoryRoot);
|
||||
final String packagePrefix = currentPackage == null? null : currentPackage.getQualifiedName() + ".";
|
||||
final String packageName = extractPackage(packagePrefix != null && className.startsWith(packagePrefix)?
|
||||
className.substring(packagePrefix.length()) : className);
|
||||
final StringTokenizer tokenizer = new StringTokenizer(packageName, ".");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
String packagePart = tokenizer.nextToken();
|
||||
PsiDirectory subdirectory = directoryRoot.findSubdirectory(packagePart);
|
||||
if (subdirectory == null) {
|
||||
directoryRoot.checkCreateSubdirectory(packagePart);
|
||||
subdirectory = directoryRoot.createSubdirectory(packagePart);
|
||||
}
|
||||
directoryRoot = subdirectory;
|
||||
}
|
||||
return directoryRoot;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiDirectory getRootDirectory(PsiClass aClass) {
|
||||
return getSourceRootDirectory(aClass.getContainingFile().getContainingDirectory());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiDirectory getSourceRootDirectory(PsiDirectory directory) {
|
||||
PsiManager manager = directory.getManager();
|
||||
DirectoryIndex directoryIndex = DirectoryIndex.getInstance(manager.getProject());
|
||||
DirectoryInfo info = directoryIndex.getInfoForDirectory(directory.getVirtualFile());
|
||||
if (info == null || info.sourceRoot == null) return null;
|
||||
return manager.findDirectory(info.sourceRoot);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiDirectory obtainDirectoryRootForPackage(final Module module, final String packageName) {
|
||||
final Project project = module.getProject();
|
||||
GlobalSearchScope scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module);
|
||||
final PsiPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(packageName);
|
||||
if (aPackage != null) {
|
||||
PsiDirectory[] directories = aPackage.getDirectories(scope);
|
||||
if (directories.length == 1) return getSourceRootDirectory(directories[0]);
|
||||
}
|
||||
|
||||
final VirtualFile[] sourceRoots = ModuleRootManager.getInstance(module).getSourceRoots();
|
||||
List<PsiDirectory> directoryList = new ArrayList<PsiDirectory>();
|
||||
for (VirtualFile sourceRoot : sourceRoots) {
|
||||
final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(sourceRoot);
|
||||
directoryList.add(directory);
|
||||
}
|
||||
PsiDirectory[] sourceDirectories = directoryList.toArray(new PsiDirectory[directoryList.size()]);
|
||||
|
||||
return DirectoryChooserUtil.selectDirectory(project, sourceDirectories, null, File.separatorChar + packageName.replace('.', File.separatorChar));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiDirectory getRoot(Module module, String className) {
|
||||
String aPackage = extractPackage(className);
|
||||
PsiManager psiManager = PsiManager.getInstance(module.getProject());
|
||||
PsiPackage psiPackage = JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(aPackage);
|
||||
if (psiPackage == null) return null;
|
||||
PsiDirectory[] directories = psiPackage.getDirectories(GlobalSearchScope.moduleScope(module));
|
||||
if (directories.length == 0) return null;
|
||||
|
||||
return directories[0];
|
||||
}
|
||||
|
||||
public static String extractClassName(String fqName) {
|
||||
return StringUtil.getShortName(fqName);
|
||||
}
|
||||
|
||||
public static String extractPackage(String fqName) {
|
||||
int i = fqName.lastIndexOf('.');
|
||||
return i == -1 ? "" : fqName.substring(0, i);
|
||||
}
|
||||
|
||||
public static String makeFQName(String aPackage, String className) {
|
||||
String fq = aPackage;
|
||||
if (!"".equals(aPackage)) {
|
||||
fq += ".";
|
||||
}
|
||||
fq += className;
|
||||
return fq;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiClass createClassNamed(String newClassName, String templateName, PsiDirectory directory) throws IncorrectOperationException {
|
||||
return createClassNamed(newClassName, new Properties(FileTemplateManager.getInstance().getDefaultProperties()), templateName, directory);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiClass createClassNamed(String newClassName, Map classProperties, String templateName, PsiDirectory directory)
|
||||
throws IncorrectOperationException {
|
||||
Properties defaultProperties = FileTemplateManager.getInstance().getDefaultProperties();
|
||||
Properties properties = new Properties(defaultProperties);
|
||||
properties.putAll(classProperties);
|
||||
|
||||
return createClassNamed(newClassName, properties, templateName, directory);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass createClassNamed(@Nullable String newClassName,
|
||||
@NotNull Properties properties,
|
||||
String templateName,
|
||||
@NotNull PsiDirectory directory) throws IncorrectOperationException {
|
||||
if (newClassName == null) {
|
||||
return null;
|
||||
}
|
||||
final String className = extractClassName(newClassName);
|
||||
properties.setProperty(CLASS_NAME_PROPERTY, className);
|
||||
properties.setProperty(INTERFACE_NAME_PROPERTY, className);
|
||||
|
||||
return createClassFromTemplate(properties, templateName, directory, newClassName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiClass createClassFromCustomTemplate(@Nullable PsiDirectory classDirectory,
|
||||
@Nullable final Module module,
|
||||
final String className,
|
||||
final String templateName) {
|
||||
if (classDirectory == null && module != null) {
|
||||
try {
|
||||
classDirectory = PackageUtil.findOrCreateDirectoryForPackage(module, "", null, false);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (classDirectory == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
final Properties properties = ApplicationManager.getApplication().isUnitTestMode() ?
|
||||
new Properties() :
|
||||
FileTemplateManager.getInstance().getDefaultProperties();
|
||||
return createClassNamed(className, new Properties(properties), templateName, classDirectory);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.psi.util;
|
||||
|
||||
import com.intellij.ide.fileTemplates.FileTemplate;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.ide.fileTemplates.JavaCreateFromTemplateHandler;
|
||||
import com.intellij.ide.util.DirectoryChooserUtil;
|
||||
import com.intellij.ide.util.PackageUtil;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.impl.DirectoryIndex;
|
||||
import com.intellij.openapi.roots.impl.DirectoryInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.text.StringTokenizer;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* author: lesya
|
||||
*/
|
||||
public class CreateClassUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.j2ee.CreateClassUtil");
|
||||
|
||||
@NonNls public static final String DEFAULT_CLASS_TEMPLATE = "#DEFAULT_CLASS_TEMPLATE";
|
||||
@NonNls private static final String DO_NOT_CREATE_CLASS_TEMPLATE = "#DO_NOT_CREATE_CLASS_TEMPLATE";
|
||||
@NonNls private static final String CLASS_NAME_PROPERTY = "Class_Name";
|
||||
@NonNls private static final String INTERFACE_NAME_PROPERTY = "Interface_Name";
|
||||
|
||||
private CreateClassUtil() {}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass createClassFromTemplate(@NotNull final Properties attributes, @Nullable final String templateName,
|
||||
@NotNull final PsiDirectory directoryRoot,
|
||||
@NotNull final String className) throws IncorrectOperationException {
|
||||
if (templateName == null) return null;
|
||||
if (templateName.equals(DO_NOT_CREATE_CLASS_TEMPLATE)) return null;
|
||||
|
||||
final Project project = directoryRoot.getProject();
|
||||
try {
|
||||
final PsiDirectory directory = createParentDirectories(directoryRoot, className);
|
||||
final PsiFile psiFile = directory.findFile(className + "." + StdFileTypes.JAVA.getDefaultExtension());
|
||||
if (psiFile != null) {
|
||||
psiFile.delete();
|
||||
}
|
||||
|
||||
final String rawClassName = extractClassName(className);
|
||||
final PsiFile existing = directory.findFile(rawClassName + ".java");
|
||||
if (existing instanceof PsiJavaFile) {
|
||||
final PsiClass[] classes = ((PsiJavaFile)existing).getClasses();
|
||||
if (classes.length > 0) {
|
||||
return classes[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiClass aClass;
|
||||
if (templateName.equals(DEFAULT_CLASS_TEMPLATE)) {
|
||||
aClass = JavaDirectoryService.getInstance().createClass(directory, rawClassName);
|
||||
}
|
||||
else {
|
||||
final FileTemplateManager fileTemplateManager = FileTemplateManager.getInstance();
|
||||
FileTemplate fileTemplate = fileTemplateManager.getJ2eeTemplate(templateName);
|
||||
LOG.assertTrue(fileTemplate != null, templateName + " not found");
|
||||
final String text = fileTemplate.getText(attributes);
|
||||
aClass = JavaCreateFromTemplateHandler.createClassOrInterface(project, directory, text, true, fileTemplate.getExtension());
|
||||
}
|
||||
return (PsiClass)JavaCodeStyleManager.getInstance(project).shortenClassReferences(aClass);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IncorrectOperationException(e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiDirectory createParentDirectories(@NotNull PsiDirectory directoryRoot, @NotNull String className) throws IncorrectOperationException {
|
||||
final PsiPackage currentPackage = JavaDirectoryService.getInstance().getPackage(directoryRoot);
|
||||
final String packagePrefix = currentPackage == null? null : currentPackage.getQualifiedName() + ".";
|
||||
final String packageName = extractPackage(packagePrefix != null && className.startsWith(packagePrefix)?
|
||||
className.substring(packagePrefix.length()) : className);
|
||||
final StringTokenizer tokenizer = new StringTokenizer(packageName, ".");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
String packagePart = tokenizer.nextToken();
|
||||
PsiDirectory subdirectory = directoryRoot.findSubdirectory(packagePart);
|
||||
if (subdirectory == null) {
|
||||
directoryRoot.checkCreateSubdirectory(packagePart);
|
||||
subdirectory = directoryRoot.createSubdirectory(packagePart);
|
||||
}
|
||||
directoryRoot = subdirectory;
|
||||
}
|
||||
return directoryRoot;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiDirectory getRootDirectory(PsiClass aClass) {
|
||||
return getSourceRootDirectory(aClass.getContainingFile().getContainingDirectory());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiDirectory getSourceRootDirectory(PsiDirectory directory) {
|
||||
PsiManager manager = directory.getManager();
|
||||
DirectoryIndex directoryIndex = DirectoryIndex.getInstance(manager.getProject());
|
||||
DirectoryInfo info = directoryIndex.getInfoForDirectory(directory.getVirtualFile());
|
||||
if (info == null || info.sourceRoot == null) return null;
|
||||
return manager.findDirectory(info.sourceRoot);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiDirectory obtainDirectoryRootForPackage(final Module module, final String packageName) {
|
||||
final Project project = module.getProject();
|
||||
GlobalSearchScope scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module);
|
||||
final PsiPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(packageName);
|
||||
if (aPackage != null) {
|
||||
PsiDirectory[] directories = aPackage.getDirectories(scope);
|
||||
if (directories.length == 1) return getSourceRootDirectory(directories[0]);
|
||||
}
|
||||
|
||||
final VirtualFile[] sourceRoots = ModuleRootManager.getInstance(module).getSourceRoots();
|
||||
List<PsiDirectory> directoryList = new ArrayList<PsiDirectory>();
|
||||
for (VirtualFile sourceRoot : sourceRoots) {
|
||||
final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(sourceRoot);
|
||||
directoryList.add(directory);
|
||||
}
|
||||
PsiDirectory[] sourceDirectories = directoryList.toArray(new PsiDirectory[directoryList.size()]);
|
||||
|
||||
return DirectoryChooserUtil.selectDirectory(project, sourceDirectories, null, File.separatorChar + packageName.replace('.', File.separatorChar));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiDirectory getRoot(Module module, String className) {
|
||||
String aPackage = extractPackage(className);
|
||||
PsiManager psiManager = PsiManager.getInstance(module.getProject());
|
||||
PsiPackage psiPackage = JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(aPackage);
|
||||
if (psiPackage == null) return null;
|
||||
PsiDirectory[] directories = psiPackage.getDirectories(GlobalSearchScope.moduleScope(module));
|
||||
if (directories.length == 0) return null;
|
||||
|
||||
return directories[0];
|
||||
}
|
||||
|
||||
public static String extractClassName(String fqName) {
|
||||
return StringUtil.getShortName(fqName);
|
||||
}
|
||||
|
||||
public static String extractPackage(String fqName) {
|
||||
int i = fqName.lastIndexOf('.');
|
||||
return i == -1 ? "" : fqName.substring(0, i);
|
||||
}
|
||||
|
||||
public static String makeFQName(String aPackage, String className) {
|
||||
String fq = aPackage;
|
||||
if (!"".equals(aPackage)) {
|
||||
fq += ".";
|
||||
}
|
||||
fq += className;
|
||||
return fq;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiClass createClassNamed(String newClassName, String templateName, @NotNull PsiDirectory directory) throws IncorrectOperationException {
|
||||
return createClassNamed(newClassName, FileTemplateManager.getInstance().getDefaultProperties(directory.getProject()), templateName, directory);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiClass createClassNamed(String newClassName, Map classProperties, String templateName, @NotNull PsiDirectory directory)
|
||||
throws IncorrectOperationException {
|
||||
Properties defaultProperties = FileTemplateManager.getInstance().getDefaultProperties(directory.getProject());
|
||||
Properties properties = new Properties(defaultProperties);
|
||||
properties.putAll(classProperties);
|
||||
|
||||
return createClassNamed(newClassName, properties, templateName, directory);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass createClassNamed(@Nullable String newClassName,
|
||||
@NotNull Properties properties,
|
||||
String templateName,
|
||||
@NotNull PsiDirectory directory) throws IncorrectOperationException {
|
||||
if (newClassName == null) {
|
||||
return null;
|
||||
}
|
||||
final String className = extractClassName(newClassName);
|
||||
properties.setProperty(CLASS_NAME_PROPERTY, className);
|
||||
properties.setProperty(INTERFACE_NAME_PROPERTY, className);
|
||||
|
||||
return createClassFromTemplate(properties, templateName, directory, newClassName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiClass createClassFromCustomTemplate(@Nullable PsiDirectory classDirectory,
|
||||
@Nullable final Module module,
|
||||
final String className,
|
||||
final String templateName) {
|
||||
if (classDirectory == null && module != null) {
|
||||
try {
|
||||
classDirectory = PackageUtil.findOrCreateDirectoryForPackage(module, "", null, false);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (classDirectory == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
final Properties properties = ApplicationManager.getApplication().isUnitTestMode() ?
|
||||
new Properties() :
|
||||
FileTemplateManager.getInstance().getDefaultProperties(classDirectory.getProject());
|
||||
return createClassNamed(className, new Properties(properties), templateName, classDirectory);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+358
-358
@@ -1,358 +1,358 @@
|
||||
/*
|
||||
* 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.ide.util.SuperMethodWarningUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pass;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiElementProcessor;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch;
|
||||
import com.intellij.psi.search.searches.MethodReferencesSearch;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.listeners.RefactoringElementListener;
|
||||
import com.intellij.refactoring.util.ConflictsUtil;
|
||||
import com.intellij.refactoring.util.MoveRenameUsageInfo;
|
||||
import com.intellij.refactoring.util.RefactoringUIUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class RenameJavaMethodProcessor extends RenameJavaMemberProcessor {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenameJavaMethodProcessor");
|
||||
|
||||
public boolean canProcessElement(@NotNull final PsiElement element) {
|
||||
return element instanceof PsiMethod;
|
||||
}
|
||||
|
||||
public void renameElement(final PsiElement psiElement,
|
||||
final String newName,
|
||||
final UsageInfo[] usages, final RefactoringElementListener listener) throws IncorrectOperationException {
|
||||
PsiMethod method = (PsiMethod) psiElement;
|
||||
Set<PsiMethod> methodAndOverriders = new HashSet<PsiMethod>();
|
||||
Set<PsiClass> containingClasses = new HashSet<PsiClass>();
|
||||
List<PsiElement> renamedReferences = new ArrayList<PsiElement>();
|
||||
List<MemberHidesOuterMemberUsageInfo> outerHides = new ArrayList<MemberHidesOuterMemberUsageInfo>();
|
||||
List<MemberHidesStaticImportUsageInfo> staticImportHides = new ArrayList<MemberHidesStaticImportUsageInfo>();
|
||||
|
||||
methodAndOverriders.add(method);
|
||||
containingClasses.add(method.getContainingClass());
|
||||
|
||||
// do actual rename of overriding/implementing methods and of references to all them
|
||||
for (UsageInfo usage : usages) {
|
||||
PsiElement element = usage.getElement();
|
||||
if (element == null) continue;
|
||||
|
||||
if (usage instanceof MemberHidesStaticImportUsageInfo) {
|
||||
staticImportHides.add((MemberHidesStaticImportUsageInfo)usage);
|
||||
} else if (usage instanceof MemberHidesOuterMemberUsageInfo) {
|
||||
PsiJavaCodeReferenceElement collidingRef = (PsiJavaCodeReferenceElement)element;
|
||||
PsiMethod resolved = (PsiMethod)collidingRef.resolve();
|
||||
outerHides.add(new MemberHidesOuterMemberUsageInfo(element, resolved));
|
||||
}
|
||||
else if (!(element instanceof PsiMethod)) {
|
||||
final PsiReference ref;
|
||||
if (usage instanceof MoveRenameUsageInfo) {
|
||||
ref = usage.getReference();
|
||||
}
|
||||
else {
|
||||
ref = element.getReference();
|
||||
}
|
||||
if (ref != null) {
|
||||
PsiElement e = processRef(ref, newName);
|
||||
if (e != null) {
|
||||
renamedReferences.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
PsiMethod overrider = (PsiMethod)element;
|
||||
methodAndOverriders.add(overrider);
|
||||
containingClasses.add(overrider.getContainingClass());
|
||||
}
|
||||
}
|
||||
|
||||
// do actual rename of method
|
||||
method.setName(newName);
|
||||
for (UsageInfo usage : usages) {
|
||||
PsiElement element = usage.getElement();
|
||||
if (element instanceof PsiMethod) {
|
||||
((PsiMethod)element).setName(newName);
|
||||
}
|
||||
}
|
||||
listener.elementRenamed(method);
|
||||
|
||||
for (PsiElement element: renamedReferences) {
|
||||
fixNameCollisionsWithInnerClassMethod(element, newName, methodAndOverriders, containingClasses,
|
||||
method.hasModifierProperty(PsiModifier.STATIC));
|
||||
}
|
||||
qualifyOuterMemberReferences(outerHides);
|
||||
qualifyStaticImportReferences(staticImportHides);
|
||||
}
|
||||
|
||||
/**
|
||||
* handles rename of refs
|
||||
* @param ref
|
||||
* @param newName
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
protected PsiElement processRef(PsiReference ref, String newName) {
|
||||
return ref.handleElementRename(newName);
|
||||
}
|
||||
|
||||
private static void fixNameCollisionsWithInnerClassMethod(final PsiElement element, final String newName,
|
||||
final Set<PsiMethod> methodAndOverriders, final Set<PsiClass> containingClasses,
|
||||
final boolean isStatic) throws IncorrectOperationException {
|
||||
if (!(element instanceof PsiReferenceExpression)) return;
|
||||
PsiElement elem = ((PsiReferenceExpression)element).resolve();
|
||||
|
||||
if (elem instanceof PsiMethod) {
|
||||
PsiMethod actualMethod = (PsiMethod) elem;
|
||||
if (!methodAndOverriders.contains(actualMethod)) {
|
||||
PsiClass outerClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
while (outerClass != null) {
|
||||
if (containingClasses.contains(outerClass)) {
|
||||
qualifyMember(element, newName, outerClass, isStatic);
|
||||
break;
|
||||
}
|
||||
outerClass = PsiTreeUtil.getParentOfType(outerClass, PsiClass.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<PsiReference> findReferences(final PsiElement element) {
|
||||
GlobalSearchScope projectScope = GlobalSearchScope.projectScope(element.getProject());
|
||||
return MethodReferencesSearch.search((PsiMethod)element, projectScope, true).findAll();
|
||||
}
|
||||
|
||||
public void findCollisions(final PsiElement element, final String newName, final Map<? extends PsiElement, String> allRenames,
|
||||
final List<UsageInfo> result) {
|
||||
final PsiMethod methodToRename = (PsiMethod)element;
|
||||
findSubmemberHidesMemberCollisions(methodToRename, newName, result);
|
||||
findMemberHidesOuterMemberCollisions((PsiMethod) element, newName, result);
|
||||
findCollisionsAgainstNewName(methodToRename, newName, result);
|
||||
findHidingMethodWithOtherSignature(methodToRename, newName, result);
|
||||
final PsiClass containingClass = methodToRename.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final PsiMethod patternMethod = (PsiMethod)methodToRename.copy();
|
||||
try {
|
||||
patternMethod.setName(newName);
|
||||
final PsiMethod methodInBaseClass = containingClass.findMethodBySignature(patternMethod, true);
|
||||
if (methodInBaseClass != null && methodInBaseClass.getContainingClass() != containingClass) {
|
||||
if (methodInBaseClass.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
result.add(new UnresolvableCollisionUsageInfo(methodInBaseClass, methodToRename) {
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Renaming method will override final \"" + RefactoringUIUtil.getDescription(methodInBaseClass, true) + "\"";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void findHidingMethodWithOtherSignature(final PsiMethod methodToRename, final String newName, final List<UsageInfo> result) {
|
||||
final PsiClass containingClass = methodToRename.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final PsiMethod prototype = getPrototypeWithNewName(methodToRename, newName);
|
||||
if (prototype == null || containingClass.findMethodBySignature(prototype, true) != null) return;
|
||||
|
||||
final PsiMethod[] methodsByName = containingClass.findMethodsByName(newName, true);
|
||||
if (methodsByName.length > 0) {
|
||||
|
||||
for (UsageInfo info : result) {
|
||||
final PsiElement element = info.getElement();
|
||||
if (element instanceof PsiReferenceExpression) {
|
||||
if (((PsiReferenceExpression)element).resolve() == methodToRename) {
|
||||
final PsiMethodCallExpression copy = (PsiMethodCallExpression)JavaPsiFacade.getElementFactory(element.getProject())
|
||||
.createExpressionFromText(element.getParent().getText(), element);
|
||||
final PsiReferenceExpression expression = (PsiReferenceExpression)processRef(copy.getMethodExpression(), newName);
|
||||
if (expression == null) continue;
|
||||
final JavaResolveResult resolveResult = expression.advancedResolve(true);
|
||||
final PsiMember resolveResultElement = (PsiMember)resolveResult.getElement();
|
||||
if (resolveResult.isValidResult() && resolveResultElement != null) {
|
||||
result.add(new UnresolvableCollisionUsageInfo(element, methodToRename) {
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Method call would be linked to \"" + RefactoringUIUtil.getDescription(resolveResultElement, true) +
|
||||
"\" after rename";
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiMethod getPrototypeWithNewName(PsiMethod methodToRename, String newName) {
|
||||
final PsiMethod prototype = (PsiMethod)methodToRename.copy();
|
||||
try {
|
||||
prototype.setName(newName);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
return null;
|
||||
}
|
||||
return prototype;
|
||||
}
|
||||
|
||||
public void findExistingNameConflicts(final PsiElement element, final String newName, final MultiMap<PsiElement, String> conflicts) {
|
||||
if (element instanceof PsiCompiledElement) return;
|
||||
final PsiMethod refactoredMethod = (PsiMethod)element;
|
||||
if (newName.equals(refactoredMethod.getName())) return;
|
||||
final PsiMethod prototype = getPrototypeWithNewName(refactoredMethod, newName);
|
||||
if (prototype == null) return;
|
||||
|
||||
ConflictsUtil.checkMethodConflicts(
|
||||
refactoredMethod.getContainingClass(),
|
||||
refactoredMethod,
|
||||
prototype,
|
||||
conflicts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareRenaming(PsiElement element, final String newName, final Map<PsiElement, String> allRenames, SearchScope scope) {
|
||||
final PsiMethod method = (PsiMethod) element;
|
||||
OverridingMethodsSearch.search(method, scope, true).forEach(new Processor<PsiMethod>() {
|
||||
public boolean process(PsiMethod overrider) {
|
||||
final String overriderName = overrider.getName();
|
||||
final String baseName = method.getName();
|
||||
final String newOverriderName = RefactoringUtil.suggestNewOverriderName(overriderName, baseName, newName);
|
||||
if (newOverriderName != null) {
|
||||
RenameProcessor.assertNonCompileElement(overrider);
|
||||
allRenames.put(overrider, newOverriderName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NonNls
|
||||
public String getHelpID(final PsiElement element) {
|
||||
return HelpID.RENAME_METHOD;
|
||||
}
|
||||
|
||||
public boolean isToSearchInComments(final PsiElement psiElement) {
|
||||
return JavaRefactoringSettings.getInstance().RENAME_SEARCH_IN_COMMENTS_FOR_METHOD;
|
||||
}
|
||||
|
||||
public void setToSearchInComments(final PsiElement element, final boolean enabled) {
|
||||
JavaRefactoringSettings.getInstance().RENAME_SEARCH_IN_COMMENTS_FOR_METHOD = enabled;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement substituteElementToRename(PsiElement element, Editor editor) {
|
||||
PsiMethod psiMethod = (PsiMethod)element;
|
||||
if (psiMethod.isConstructor()) {
|
||||
PsiClass containingClass = psiMethod.getContainingClass();
|
||||
if (containingClass == null) return null;
|
||||
if (Comparing.strEqual(psiMethod.getName(), containingClass.getName())) {
|
||||
element = containingClass;
|
||||
if (!PsiElementRenameHandler.canRename(element.getProject(), editor, element)) {
|
||||
return null;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
}
|
||||
return SuperMethodWarningUtil.checkSuperMethod(psiMethod, RefactoringBundle.message("to.rename"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void substituteElementToRename(@NotNull PsiElement element,
|
||||
@NotNull final Editor editor,
|
||||
@NotNull final Pass<PsiElement> renameCallback) {
|
||||
final PsiMethod psiMethod = (PsiMethod)element;
|
||||
if (psiMethod.isConstructor()) {
|
||||
final PsiClass containingClass = psiMethod.getContainingClass();
|
||||
if (containingClass == null) return;
|
||||
if (!Comparing.strEqual(psiMethod.getName(), containingClass.getName())) {
|
||||
renameCallback.pass(psiMethod);
|
||||
return;
|
||||
}
|
||||
super.substituteElementToRename(element, editor, renameCallback);
|
||||
}
|
||||
else {
|
||||
SuperMethodWarningUtil.checkSuperMethod(psiMethod, "Rename", new PsiElementProcessor<PsiMethod>() {
|
||||
@Override
|
||||
public boolean execute(@NotNull PsiMethod method) {
|
||||
if (!PsiElementRenameHandler.canRename(method.getProject(), editor, method)) return false;
|
||||
renameCallback.pass(method);
|
||||
return false;
|
||||
}
|
||||
}, editor);
|
||||
}
|
||||
}
|
||||
|
||||
private static void findSubmemberHidesMemberCollisions(final PsiMethod method, final String newName, final List<UsageInfo> result) {
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass == null) return;
|
||||
if (method.hasModifierProperty(PsiModifier.PRIVATE)) return;
|
||||
Collection<PsiClass> inheritors = ClassInheritorsSearch.search(containingClass, true).findAll();
|
||||
|
||||
MethodSignature oldSignature = method.getSignature(PsiSubstitutor.EMPTY);
|
||||
MethodSignature newSignature = MethodSignatureUtil.createMethodSignature(newName, oldSignature.getParameterTypes(),
|
||||
oldSignature.getTypeParameters(),
|
||||
oldSignature.getSubstitutor(),
|
||||
method.isConstructor());
|
||||
for (PsiClass inheritor : inheritors) {
|
||||
PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(containingClass, inheritor, PsiSubstitutor.EMPTY);
|
||||
final PsiMethod[] methodsByName = inheritor.findMethodsByName(newName, false);
|
||||
for (PsiMethod conflictingMethod : methodsByName) {
|
||||
if (newSignature.equals(conflictingMethod.getSignature(superSubstitutor))) {
|
||||
result.add(new SubmemberHidesMemberUsageInfo(conflictingMethod, method));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isToSearchForTextOccurrences(final PsiElement element) {
|
||||
return JavaRefactoringSettings.getInstance().RENAME_SEARCH_FOR_TEXT_FOR_METHOD;
|
||||
}
|
||||
|
||||
public void setToSearchForTextOccurrences(final PsiElement element, final boolean enabled) {
|
||||
JavaRefactoringSettings.getInstance().RENAME_SEARCH_FOR_TEXT_FOR_METHOD = enabled;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.ide.util.SuperMethodWarningUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pass;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiElementProcessor;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch;
|
||||
import com.intellij.psi.search.searches.MethodReferencesSearch;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.listeners.RefactoringElementListener;
|
||||
import com.intellij.refactoring.util.ConflictsUtil;
|
||||
import com.intellij.refactoring.util.MoveRenameUsageInfo;
|
||||
import com.intellij.refactoring.util.RefactoringUIUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class RenameJavaMethodProcessor extends RenameJavaMemberProcessor {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenameJavaMethodProcessor");
|
||||
|
||||
public boolean canProcessElement(@NotNull final PsiElement element) {
|
||||
return element instanceof PsiMethod;
|
||||
}
|
||||
|
||||
public void renameElement(final PsiElement psiElement,
|
||||
final String newName,
|
||||
final UsageInfo[] usages, final RefactoringElementListener listener) throws IncorrectOperationException {
|
||||
PsiMethod method = (PsiMethod) psiElement;
|
||||
Set<PsiMethod> methodAndOverriders = new HashSet<PsiMethod>();
|
||||
Set<PsiClass> containingClasses = new HashSet<PsiClass>();
|
||||
LinkedHashSet<PsiElement> renamedReferences = new LinkedHashSet<PsiElement>();
|
||||
List<MemberHidesOuterMemberUsageInfo> outerHides = new ArrayList<MemberHidesOuterMemberUsageInfo>();
|
||||
List<MemberHidesStaticImportUsageInfo> staticImportHides = new ArrayList<MemberHidesStaticImportUsageInfo>();
|
||||
|
||||
methodAndOverriders.add(method);
|
||||
containingClasses.add(method.getContainingClass());
|
||||
|
||||
// do actual rename of overriding/implementing methods and of references to all them
|
||||
for (UsageInfo usage : usages) {
|
||||
PsiElement element = usage.getElement();
|
||||
if (element == null) continue;
|
||||
|
||||
if (usage instanceof MemberHidesStaticImportUsageInfo) {
|
||||
staticImportHides.add((MemberHidesStaticImportUsageInfo)usage);
|
||||
} else if (usage instanceof MemberHidesOuterMemberUsageInfo) {
|
||||
PsiJavaCodeReferenceElement collidingRef = (PsiJavaCodeReferenceElement)element;
|
||||
PsiMethod resolved = (PsiMethod)collidingRef.resolve();
|
||||
outerHides.add(new MemberHidesOuterMemberUsageInfo(element, resolved));
|
||||
}
|
||||
else if (!(element instanceof PsiMethod)) {
|
||||
final PsiReference ref;
|
||||
if (usage instanceof MoveRenameUsageInfo) {
|
||||
ref = usage.getReference();
|
||||
}
|
||||
else {
|
||||
ref = element.getReference();
|
||||
}
|
||||
if (ref != null) {
|
||||
PsiElement e = processRef(ref, newName);
|
||||
if (e != null) {
|
||||
renamedReferences.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
PsiMethod overrider = (PsiMethod)element;
|
||||
methodAndOverriders.add(overrider);
|
||||
containingClasses.add(overrider.getContainingClass());
|
||||
}
|
||||
}
|
||||
|
||||
// do actual rename of method
|
||||
method.setName(newName);
|
||||
for (UsageInfo usage : usages) {
|
||||
PsiElement element = usage.getElement();
|
||||
if (element instanceof PsiMethod) {
|
||||
((PsiMethod)element).setName(newName);
|
||||
}
|
||||
}
|
||||
listener.elementRenamed(method);
|
||||
|
||||
for (PsiElement element: renamedReferences) {
|
||||
fixNameCollisionsWithInnerClassMethod(element, newName, methodAndOverriders, containingClasses,
|
||||
method.hasModifierProperty(PsiModifier.STATIC));
|
||||
}
|
||||
qualifyOuterMemberReferences(outerHides);
|
||||
qualifyStaticImportReferences(staticImportHides);
|
||||
}
|
||||
|
||||
/**
|
||||
* handles rename of refs
|
||||
* @param ref
|
||||
* @param newName
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
protected PsiElement processRef(PsiReference ref, String newName) {
|
||||
return ref.handleElementRename(newName);
|
||||
}
|
||||
|
||||
private static void fixNameCollisionsWithInnerClassMethod(final PsiElement element, final String newName,
|
||||
final Set<PsiMethod> methodAndOverriders, final Set<PsiClass> containingClasses,
|
||||
final boolean isStatic) throws IncorrectOperationException {
|
||||
if (!(element instanceof PsiReferenceExpression)) return;
|
||||
PsiElement elem = ((PsiReferenceExpression)element).resolve();
|
||||
|
||||
if (elem instanceof PsiMethod) {
|
||||
PsiMethod actualMethod = (PsiMethod) elem;
|
||||
if (!methodAndOverriders.contains(actualMethod)) {
|
||||
PsiClass outerClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
while (outerClass != null) {
|
||||
if (containingClasses.contains(outerClass)) {
|
||||
qualifyMember(element, newName, outerClass, isStatic);
|
||||
break;
|
||||
}
|
||||
outerClass = PsiTreeUtil.getParentOfType(outerClass, PsiClass.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<PsiReference> findReferences(final PsiElement element) {
|
||||
GlobalSearchScope projectScope = GlobalSearchScope.projectScope(element.getProject());
|
||||
return MethodReferencesSearch.search((PsiMethod)element, projectScope, true).findAll();
|
||||
}
|
||||
|
||||
public void findCollisions(final PsiElement element, final String newName, final Map<? extends PsiElement, String> allRenames,
|
||||
final List<UsageInfo> result) {
|
||||
final PsiMethod methodToRename = (PsiMethod)element;
|
||||
findSubmemberHidesMemberCollisions(methodToRename, newName, result);
|
||||
findMemberHidesOuterMemberCollisions((PsiMethod) element, newName, result);
|
||||
findCollisionsAgainstNewName(methodToRename, newName, result);
|
||||
findHidingMethodWithOtherSignature(methodToRename, newName, result);
|
||||
final PsiClass containingClass = methodToRename.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final PsiMethod patternMethod = (PsiMethod)methodToRename.copy();
|
||||
try {
|
||||
patternMethod.setName(newName);
|
||||
final PsiMethod methodInBaseClass = containingClass.findMethodBySignature(patternMethod, true);
|
||||
if (methodInBaseClass != null && methodInBaseClass.getContainingClass() != containingClass) {
|
||||
if (methodInBaseClass.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
result.add(new UnresolvableCollisionUsageInfo(methodInBaseClass, methodToRename) {
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Renaming method will override final \"" + RefactoringUIUtil.getDescription(methodInBaseClass, true) + "\"";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void findHidingMethodWithOtherSignature(final PsiMethod methodToRename, final String newName, final List<UsageInfo> result) {
|
||||
final PsiClass containingClass = methodToRename.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final PsiMethod prototype = getPrototypeWithNewName(methodToRename, newName);
|
||||
if (prototype == null || containingClass.findMethodBySignature(prototype, true) != null) return;
|
||||
|
||||
final PsiMethod[] methodsByName = containingClass.findMethodsByName(newName, true);
|
||||
if (methodsByName.length > 0) {
|
||||
|
||||
for (UsageInfo info : result) {
|
||||
final PsiElement element = info.getElement();
|
||||
if (element instanceof PsiReferenceExpression) {
|
||||
if (((PsiReferenceExpression)element).resolve() == methodToRename) {
|
||||
final PsiMethodCallExpression copy = (PsiMethodCallExpression)JavaPsiFacade.getElementFactory(element.getProject())
|
||||
.createExpressionFromText(element.getParent().getText(), element);
|
||||
final PsiReferenceExpression expression = (PsiReferenceExpression)processRef(copy.getMethodExpression(), newName);
|
||||
if (expression == null) continue;
|
||||
final JavaResolveResult resolveResult = expression.advancedResolve(true);
|
||||
final PsiMember resolveResultElement = (PsiMember)resolveResult.getElement();
|
||||
if (resolveResult.isValidResult() && resolveResultElement != null) {
|
||||
result.add(new UnresolvableCollisionUsageInfo(element, methodToRename) {
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Method call would be linked to \"" + RefactoringUIUtil.getDescription(resolveResultElement, true) +
|
||||
"\" after rename";
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiMethod getPrototypeWithNewName(PsiMethod methodToRename, String newName) {
|
||||
final PsiMethod prototype = (PsiMethod)methodToRename.copy();
|
||||
try {
|
||||
prototype.setName(newName);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
return null;
|
||||
}
|
||||
return prototype;
|
||||
}
|
||||
|
||||
public void findExistingNameConflicts(final PsiElement element, final String newName, final MultiMap<PsiElement, String> conflicts) {
|
||||
if (element instanceof PsiCompiledElement) return;
|
||||
final PsiMethod refactoredMethod = (PsiMethod)element;
|
||||
if (newName.equals(refactoredMethod.getName())) return;
|
||||
final PsiMethod prototype = getPrototypeWithNewName(refactoredMethod, newName);
|
||||
if (prototype == null) return;
|
||||
|
||||
ConflictsUtil.checkMethodConflicts(
|
||||
refactoredMethod.getContainingClass(),
|
||||
refactoredMethod,
|
||||
prototype,
|
||||
conflicts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareRenaming(PsiElement element, final String newName, final Map<PsiElement, String> allRenames, SearchScope scope) {
|
||||
final PsiMethod method = (PsiMethod) element;
|
||||
OverridingMethodsSearch.search(method, scope, true).forEach(new Processor<PsiMethod>() {
|
||||
public boolean process(PsiMethod overrider) {
|
||||
final String overriderName = overrider.getName();
|
||||
final String baseName = method.getName();
|
||||
final String newOverriderName = RefactoringUtil.suggestNewOverriderName(overriderName, baseName, newName);
|
||||
if (newOverriderName != null) {
|
||||
RenameProcessor.assertNonCompileElement(overrider);
|
||||
allRenames.put(overrider, newOverriderName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NonNls
|
||||
public String getHelpID(final PsiElement element) {
|
||||
return HelpID.RENAME_METHOD;
|
||||
}
|
||||
|
||||
public boolean isToSearchInComments(final PsiElement psiElement) {
|
||||
return JavaRefactoringSettings.getInstance().RENAME_SEARCH_IN_COMMENTS_FOR_METHOD;
|
||||
}
|
||||
|
||||
public void setToSearchInComments(final PsiElement element, final boolean enabled) {
|
||||
JavaRefactoringSettings.getInstance().RENAME_SEARCH_IN_COMMENTS_FOR_METHOD = enabled;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement substituteElementToRename(PsiElement element, Editor editor) {
|
||||
PsiMethod psiMethod = (PsiMethod)element;
|
||||
if (psiMethod.isConstructor()) {
|
||||
PsiClass containingClass = psiMethod.getContainingClass();
|
||||
if (containingClass == null) return null;
|
||||
if (Comparing.strEqual(psiMethod.getName(), containingClass.getName())) {
|
||||
element = containingClass;
|
||||
if (!PsiElementRenameHandler.canRename(element.getProject(), editor, element)) {
|
||||
return null;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
}
|
||||
return SuperMethodWarningUtil.checkSuperMethod(psiMethod, RefactoringBundle.message("to.rename"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void substituteElementToRename(@NotNull PsiElement element,
|
||||
@NotNull final Editor editor,
|
||||
@NotNull final Pass<PsiElement> renameCallback) {
|
||||
final PsiMethod psiMethod = (PsiMethod)element;
|
||||
if (psiMethod.isConstructor()) {
|
||||
final PsiClass containingClass = psiMethod.getContainingClass();
|
||||
if (containingClass == null) return;
|
||||
if (!Comparing.strEqual(psiMethod.getName(), containingClass.getName())) {
|
||||
renameCallback.pass(psiMethod);
|
||||
return;
|
||||
}
|
||||
super.substituteElementToRename(element, editor, renameCallback);
|
||||
}
|
||||
else {
|
||||
SuperMethodWarningUtil.checkSuperMethod(psiMethod, "Rename", new PsiElementProcessor<PsiMethod>() {
|
||||
@Override
|
||||
public boolean execute(@NotNull PsiMethod method) {
|
||||
if (!PsiElementRenameHandler.canRename(method.getProject(), editor, method)) return false;
|
||||
renameCallback.pass(method);
|
||||
return false;
|
||||
}
|
||||
}, editor);
|
||||
}
|
||||
}
|
||||
|
||||
private static void findSubmemberHidesMemberCollisions(final PsiMethod method, final String newName, final List<UsageInfo> result) {
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass == null) return;
|
||||
if (method.hasModifierProperty(PsiModifier.PRIVATE)) return;
|
||||
Collection<PsiClass> inheritors = ClassInheritorsSearch.search(containingClass, true).findAll();
|
||||
|
||||
MethodSignature oldSignature = method.getSignature(PsiSubstitutor.EMPTY);
|
||||
MethodSignature newSignature = MethodSignatureUtil.createMethodSignature(newName, oldSignature.getParameterTypes(),
|
||||
oldSignature.getTypeParameters(),
|
||||
oldSignature.getSubstitutor(),
|
||||
method.isConstructor());
|
||||
for (PsiClass inheritor : inheritors) {
|
||||
PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(containingClass, inheritor, PsiSubstitutor.EMPTY);
|
||||
final PsiMethod[] methodsByName = inheritor.findMethodsByName(newName, false);
|
||||
for (PsiMethod conflictingMethod : methodsByName) {
|
||||
if (newSignature.equals(conflictingMethod.getSignature(superSubstitutor))) {
|
||||
result.add(new SubmemberHidesMemberUsageInfo(conflictingMethod, method));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isToSearchForTextOccurrences(final PsiElement element) {
|
||||
return JavaRefactoringSettings.getInstance().RENAME_SEARCH_FOR_TEXT_FOR_METHOD;
|
||||
}
|
||||
|
||||
public void setToSearchForTextOccurrences(final PsiElement element, final boolean enabled) {
|
||||
JavaRefactoringSettings.getInstance().RENAME_SEARCH_FOR_TEXT_FOR_METHOD = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user