Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
irengrig
2010-06-08 16:56:28 +04:00
970 changed files with 26067 additions and 11180 deletions
+18
View File
@@ -0,0 +1,18 @@
<component name="libraryTable">
<library name="Mocks">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/dev/easymock.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-1.0.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-cglib-1.0.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/easymockclassextension.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-junit4-2.3.0-RC2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-2.3.0-RC2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/objenesis-1.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/mockobjects-core-0.09.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-library-1.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-api-1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
+30 -25
View File
@@ -2,12 +2,12 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/plugins/InspectionGadgets/InspectionGadgetsPlugin.iml" filepath="$PROJECT_DIR$/plugins/InspectionGadgets/InspectionGadgetsPlugin.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/InspectionGadgets/InspectionGadgetsPlugin.iml" filepath="$PROJECT_DIR$/plugins/InspectionGadgets/InspectionGadgetsPlugin.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-java.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-java.iml" group="plugins/IntelliLang" />
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-javaee.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-javaee.iml" group="plugins/IntelliLang" />
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-xml.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-xml.iml" group="plugins/IntelliLang" />
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLangJava.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLangJava.iml" group="plugins/IntelliLang" />
<module fileurl="file://$PROJECT_DIR$/plugins/IntentionPowerPak/IntentionPowerPackPlugin.iml" filepath="$PROJECT_DIR$/plugins/IntentionPowerPak/IntentionPowerPackPlugin.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/IntentionPowerPak/IntentionPowerPackPlugin.iml" filepath="$PROJECT_DIR$/plugins/IntentionPowerPak/IntentionPowerPackPlugin.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/RegExpSupport/RegExpSupport.iml" filepath="$PROJECT_DIR$/RegExpSupport/RegExpSupport.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/annotations/annotations.iml" filepath="$PROJECT_DIR$/platform/annotations/annotations.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/plugins/ant/ant.iml" filepath="$PROJECT_DIR$/plugins/ant/ant.iml" group="plugins" />
@@ -20,45 +20,50 @@
<module fileurl="file://$PROJECT_DIR$/java/compiler/impl/compiler-impl.iml" filepath="$PROJECT_DIR$/java/compiler/impl/compiler-impl.iml" group="java/compiler" />
<module fileurl="file://$PROJECT_DIR$/java/compiler/openapi/compiler-openapi.iml" filepath="$PROJECT_DIR$/java/compiler/openapi/compiler-openapi.iml" group="java/compiler" />
<module fileurl="file://$PROJECT_DIR$/plugins/copyright/copyright.iml" filepath="$PROJECT_DIR$/plugins/copyright/copyright.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/cvs/cvs-core/cvs-core.iml" filepath="$PROJECT_DIR$/plugins/cvs/cvs-core/cvs-core.iml" group="plugins/cvs" />
<module fileurl="file://$PROJECT_DIR$/plugins/cvs/cvs-plugin/cvs-plugin.iml" filepath="$PROJECT_DIR$/plugins/cvs/cvs-plugin/cvs-plugin.iml" group="plugins/cvs" />
<module fileurl="file://$PROJECT_DIR$/plugins/cvs/cvs-core/cvs-core.iml" filepath="$PROJECT_DIR$/plugins/cvs/cvs-core/cvs-core.iml" group="plugins/VCS/cvs" />
<module fileurl="file://$PROJECT_DIR$/plugins/cvs/cvs-plugin/cvs-plugin.iml" filepath="$PROJECT_DIR$/plugins/cvs/cvs-plugin/cvs-plugin.iml" group="plugins/VCS/cvs" />
<module fileurl="file://$PROJECT_DIR$/java/debugger/impl/debugger-impl.iml" filepath="$PROJECT_DIR$/java/debugger/impl/debugger-impl.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/java/debugger/openapi/debugger-openapi.iml" filepath="$PROJECT_DIR$/java/debugger/openapi/debugger-openapi.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/plugins/devkit/devkit.iml" filepath="$PROJECT_DIR$/plugins/devkit/devkit.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/devkit/devkit.iml" filepath="$PROJECT_DIR$/plugins/devkit/devkit.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/xml/dom-impl/dom-impl.iml" filepath="$PROJECT_DIR$/xml/dom-impl/dom-impl.iml" group="xml" />
<module fileurl="file://$PROJECT_DIR$/xml/dom-openapi/dom-openapi.iml" filepath="$PROJECT_DIR$/xml/dom-openapi/dom-openapi.iml" group="xml" />
<module fileurl="file://$PROJECT_DIR$/plugins/eclipse/eclipse.iml" filepath="$PROJECT_DIR$/plugins/eclipse/eclipse.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/eclipse/eclipse.iml" filepath="$PROJECT_DIR$/plugins/eclipse/eclipse.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/java/execution/impl/execution-impl.iml" filepath="$PROJECT_DIR$/java/execution/impl/execution-impl.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/java/execution/openapi/execution-openapi.iml" filepath="$PROJECT_DIR$/java/execution/openapi/execution-openapi.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/platform/extensions/extensions.iml" filepath="$PROJECT_DIR$/platform/extensions/extensions.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/java/compiler/forms-compiler/forms-compiler.iml" filepath="$PROJECT_DIR$/java/compiler/forms-compiler/forms-compiler.iml" group="java/compiler" />
<module fileurl="file://$PROJECT_DIR$/platform/forms_rt/forms_rt.iml" filepath="$PROJECT_DIR$/platform/forms_rt/forms_rt.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/plugins/generate-tostring/generate-tostring.iml" filepath="$PROJECT_DIR$/plugins/generate-tostring/generate-tostring.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/git4idea/git4idea.iml" filepath="$PROJECT_DIR$/plugins/git4idea/git4idea.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/groovy/rt/groovy-rt.iml" filepath="$PROJECT_DIR$/plugins/groovy/rt/groovy-rt.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/groovy/groovypp/groovypp.iml" filepath="$PROJECT_DIR$/plugins/groovy/groovypp/groovypp.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/generate-tostring/generate-tostring.iml" filepath="$PROJECT_DIR$/plugins/generate-tostring/generate-tostring.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/git4idea/git4idea.iml" filepath="$PROJECT_DIR$/plugins/git4idea/git4idea.iml" group="plugins/VCS" />
<module fileurl="file://$PROJECT_DIR$/plugins/groovy/grape/grape.iml" filepath="$PROJECT_DIR$/plugins/groovy/grape/grape.iml" group="plugins/Groovy" />
<module fileurl="file://$PROJECT_DIR$/plugins/groovy/grape/grape-rt.iml" filepath="$PROJECT_DIR$/plugins/groovy/grape/grape-rt.iml" group="plugins/Groovy" />
<module fileurl="file://$PROJECT_DIR$/plugins/groovy/hotswap/groovy-hotswap.iml" filepath="$PROJECT_DIR$/plugins/groovy/hotswap/groovy-hotswap.iml" group="plugins/Groovy" />
<module fileurl="file://$PROJECT_DIR$/plugins/groovy/rt/groovy-rt.iml" filepath="$PROJECT_DIR$/plugins/groovy/rt/groovy-rt.iml" group="plugins/Groovy" />
<module fileurl="file://$PROJECT_DIR$/plugins/groovy/groovypp/groovypp.iml" filepath="$PROJECT_DIR$/plugins/groovy/groovypp/groovypp.iml" group="plugins/Groovy" />
<module fileurl="file://$PROJECT_DIR$/plugins/hg4idea/hg4idea.iml" filepath="$PROJECT_DIR$/plugins/hg4idea/hg4idea.iml" group="plugins/VCS" />
<module fileurl="file://$PROJECT_DIR$/platform/icons/icons.iml" filepath="$PROJECT_DIR$/platform/icons/icons.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/java/idea-ui/idea-ui.iml" filepath="$PROJECT_DIR$/java/idea-ui/idea-ui.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/images/images.iml" filepath="$PROJECT_DIR$/images/images.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/java-i18n/java-i18n.iml" filepath="$PROJECT_DIR$/plugins/java-i18n/java-i18n.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/java/java-impl/java-impl.iml" filepath="$PROJECT_DIR$/java/java-impl/java-impl.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/java/java-runtime/java-runtime.iml" filepath="$PROJECT_DIR$/java/java-runtime/java-runtime.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/java/java-tests/java-tests.iml" filepath="$PROJECT_DIR$/java/java-tests/java-tests.iml" />
<module fileurl="file://$PROJECT_DIR$/java/java-tests/java-tests.iml" filepath="$PROJECT_DIR$/java/java-tests/java-tests.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/java/compiler/javac2/javac2.iml" filepath="$PROJECT_DIR$/java/compiler/javac2/javac2.iml" group="java/compiler" />
<module fileurl="file://$PROJECT_DIR$/plugins/cvs/javacvs-src/javacvs-src.iml" filepath="$PROJECT_DIR$/plugins/cvs/javacvs-src/javacvs-src.iml" group="plugins/cvs" />
<module fileurl="file://$PROJECT_DIR$/plugins/groovy/jetgroovy.iml" filepath="$PROJECT_DIR$/plugins/groovy/jetgroovy.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/groovy/jetgroovy-tests.iml" filepath="$PROJECT_DIR$/plugins/groovy/jetgroovy-tests.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/cvs/javacvs-src/javacvs-src.iml" filepath="$PROJECT_DIR$/plugins/cvs/javacvs-src/javacvs-src.iml" group="plugins/VCS/cvs" />
<module fileurl="file://$PROJECT_DIR$/plugins/groovy/jetgroovy.iml" filepath="$PROJECT_DIR$/plugins/groovy/jetgroovy.iml" group="plugins/Groovy" />
<module fileurl="file://$PROJECT_DIR$/plugins/groovy/jetgroovy-tests.iml" filepath="$PROJECT_DIR$/plugins/groovy/jetgroovy-tests.iml" group="plugins/Groovy" />
<module fileurl="file://$PROJECT_DIR$/java/jsp-base-openapi/jsp-base-openapi.iml" filepath="$PROJECT_DIR$/java/jsp-base-openapi/jsp-base-openapi.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/java/jsp-openapi/jsp-openapi.iml" filepath="$PROJECT_DIR$/java/jsp-openapi/jsp-openapi.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/java/jsp-spi/jsp-spi.iml" filepath="$PROJECT_DIR$/java/jsp-spi/jsp-spi.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/plugins/junit/junit.iml" filepath="$PROJECT_DIR$/plugins/junit/junit.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/junit_rt/junit_rt.iml" filepath="$PROJECT_DIR$/plugins/junit_rt/junit_rt.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/junit/junit.iml" filepath="$PROJECT_DIR$/plugins/junit/junit.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/junit_rt/junit_rt.iml" filepath="$PROJECT_DIR$/plugins/junit_rt/junit_rt.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/platform/lang-api/lang-api.iml" filepath="$PROJECT_DIR$/platform/lang-api/lang-api.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/lang-impl/lang-impl.iml" filepath="$PROJECT_DIR$/platform/lang-impl/lang-impl.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/lvcs-api/lvcs-api.iml" filepath="$PROJECT_DIR$/platform/lvcs-api/lvcs-api.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/lvcs-impl/lvcs-impl.iml" filepath="$PROJECT_DIR$/platform/lvcs-impl/lvcs-impl.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven.iml" filepath="$PROJECT_DIR$/plugins/maven/maven.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven-facade.iml" filepath="$PROJECT_DIR$/plugins/maven/maven-facade.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven.iml" filepath="$PROJECT_DIR$/plugins/maven/maven.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/facade-api/maven-facade-api.iml" filepath="$PROJECT_DIR$/plugins/maven/facade-api/maven-facade-api.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/facade-impl/maven-facade-impl.iml" filepath="$PROJECT_DIR$/plugins/maven/facade-impl/maven-facade-impl.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/java/compiler/notNull/notNull.iml" filepath="$PROJECT_DIR$/java/compiler/notNull/notNull.iml" group="java/compiler" />
<module fileurl="file://$PROJECT_DIR$/java/openapi/openapi.iml" filepath="$PROJECT_DIR$/java/openapi/openapi.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/platform/platform-api/platform-api.iml" filepath="$PROJECT_DIR$/platform/platform-api/platform-api.iml" group="platform" />
@@ -70,15 +75,15 @@
<module fileurl="file://$PROJECT_DIR$/resources/resources.iml" filepath="$PROJECT_DIR$/resources/resources.iml" />
<module fileurl="file://$PROJECT_DIR$/resources-en/resources-en.iml" filepath="$PROJECT_DIR$/resources-en/resources-en.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/smRunner/smRunner.iml" filepath="$PROJECT_DIR$/platform/smRunner/smRunner.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/plugins/cvs/smartcvs-src/smartcvs-src.iml" filepath="$PROJECT_DIR$/plugins/cvs/smartcvs-src/smartcvs-src.iml" group="plugins/cvs" />
<module fileurl="file://$PROJECT_DIR$/plugins/cvs/smartcvs-src/smartcvs-src.iml" filepath="$PROJECT_DIR$/plugins/cvs/smartcvs-src/smartcvs-src.iml" group="plugins/VCS/cvs" />
<module fileurl="file://$PROJECT_DIR$/plugins/spellchecker/spellchecker.iml" filepath="$PROJECT_DIR$/plugins/spellchecker/spellchecker.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/svn4idea/svn4idea.iml" filepath="$PROJECT_DIR$/plugins/svn4idea/svn4idea.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/svn4idea/svn4idea-tests.iml" filepath="$PROJECT_DIR$/plugins/svn4idea/svn4idea-tests.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/svn4idea/svn4idea.iml" filepath="$PROJECT_DIR$/plugins/svn4idea/svn4idea.iml" group="plugins/VCS" />
<module fileurl="file://$PROJECT_DIR$/plugins/svn4idea/svn4idea-tests.iml" filepath="$PROJECT_DIR$/plugins/svn4idea/svn4idea-tests.iml" group="plugins/VCS" />
<module fileurl="file://$PROJECT_DIR$/platform/testFramework/testFramework.iml" filepath="$PROJECT_DIR$/platform/testFramework/testFramework.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/java/testFramework/testFramework-java.iml" filepath="$PROJECT_DIR$/java/testFramework/testFramework-java.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/platform/testRunner/testRunner.iml" filepath="$PROJECT_DIR$/platform/testRunner/testRunner.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/plugins/testng/testng.iml" filepath="$PROJECT_DIR$/plugins/testng/testng.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/testng_rt/testng_rt.iml" filepath="$PROJECT_DIR$/plugins/testng_rt/testng_rt.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/testng/testng.iml" filepath="$PROJECT_DIR$/plugins/testng/testng.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/testng_rt/testng_rt.iml" filepath="$PROJECT_DIR$/plugins/testng_rt/testng_rt.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/platform/testFramework/bootstrap/tests_bootstrap.iml" filepath="$PROJECT_DIR$/platform/testFramework/bootstrap/tests_bootstrap.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/plugins/ui-designer/ui-designer.iml" filepath="$PROJECT_DIR$/plugins/ui-designer/ui-designer.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/platform/usageView/usageView.iml" filepath="$PROJECT_DIR$/platform/usageView/usageView.iml" group="platform" />
@@ -89,8 +94,8 @@
<module fileurl="file://$PROJECT_DIR$/platform/xdebugger-impl/xdebugger-impl.iml" filepath="$PROJECT_DIR$/platform/xdebugger-impl/xdebugger-impl.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/xml/impl/xml.iml" filepath="$PROJECT_DIR$/xml/impl/xml.iml" group="xml" />
<module fileurl="file://$PROJECT_DIR$/xml/openapi/xml-openapi.iml" filepath="$PROJECT_DIR$/xml/openapi/xml-openapi.iml" group="xml" />
<module fileurl="file://$PROJECT_DIR$/plugins/xpath/xpath.iml" filepath="$PROJECT_DIR$/plugins/xpath/xpath.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/xpath/xslt-rt/xslt-rt.iml" filepath="$PROJECT_DIR$/plugins/xpath/xslt-rt/xslt-rt.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/xpath/xpath.iml" filepath="$PROJECT_DIR$/plugins/xpath/xpath.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/xpath/xslt-rt/xslt-rt.iml" filepath="$PROJECT_DIR$/plugins/xpath/xslt-rt/xslt-rt.iml" group="plugins" />
</modules>
</component>
</project>
+7 -3
View File
@@ -174,10 +174,14 @@ def layoutFull(String home, String targetDirectory) {
layoutPlugin("maven") {
jar("maven-facade.jar") {
module("maven-facade")
jar("maven-facade-api.jar") {
module("maven-facade-api")
}
fileset(dir: "$home/plugins/maven/lib")
jar("maven-facade-impl.jar") {
module("maven-facade-impl")
}
fileset(dir: "$home/plugins/maven/facade-impl/lib")
fileset(dir: "$home/plugins/maven/facade-api/lib")
}
+1 -1
View File
@@ -65,7 +65,7 @@ binding.setVariable("guessHome", {
})
binding.setVariable("loadProject", {
requireProperty("jdk", requireProperty("jdk15.home", guessJdk()))
requireProperty("jdk", requireProperty("jdk16.home", guessJdk()))
new IdeaProjectLoader().loadFromPath(project, "${home}")
binding.ant.patternset(id: "idea.compiler.resources") {
@@ -66,7 +66,10 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.packageDependencies.DependenciesBuilder;
import com.intellij.packageDependencies.ForwardDependenciesBuilder;
import com.intellij.pom.java.LanguageLevel;
@@ -482,7 +482,7 @@ public class Javac2 extends Javac {
return container;
}
}
InputStream resourceStream = myLoader.getResourceAsStream("/" + formFileName + ".form");
InputStream resourceStream = myLoader.getResourceAsStream(formFileName);
if (resourceStream != null) {
final LwRootContainer container = Utils.getRootContainer(resourceStream, null);
myFormCache.put(formFileName, container);
@@ -99,7 +99,8 @@ public class AbstractRerunFailedTestsAction extends AnAction {
final Executor executor = isDebug ? DefaultDebugExecutor.getDebugExecutorInstance() : DefaultRunExecutor.getRunExecutorInstance();
final ProgramRunner runner = RunnerRegistry.getInstance().getRunner(executor.getId(), profile);
assert runner != null;
runner.execute(executor, new ExecutionEnvironment(profile, myRunnerSettings, myConfigurationPerRunnerSettings, dataContext));
runner.execute(executor, new ExecutionEnvironment(profile, profile.getProject(), myRunnerSettings, myConfigurationPerRunnerSettings,
null));
}
catch (ExecutionException e1) {
LOG.error(e1);
@@ -20,18 +20,18 @@ import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.filters.Filter;
import com.intellij.execution.filters.TextConsoleBuilder;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.util.ExecutionErrorDialog;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiClassUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiClassUtil;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -54,7 +54,7 @@ public class JavaExecutionUtil {
final DefaultRunProfile profile = new DefaultRunProfile(project, cmdLine, contentName, icon, filters);
final ProgramRunner runner = RunnerRegistry.getInstance().getRunner(DefaultRunExecutor.EXECUTOR_ID, profile);
if (runner != null) {
runner.execute(DefaultRunExecutor.getRunExecutorInstance(), new ExecutionEnvironment(profile, dataContext));
runner.execute(DefaultRunExecutor.getRunExecutorInstance(), new ExecutionEnvironment(profile, project, null, null, null));
return true;
}
@@ -157,6 +157,7 @@ public class CodeInsightUtil {
public static PsiExpression[] findExpressionOccurrences(PsiElement scope, PsiExpression expr) {
List<PsiExpression> array = new ArrayList<PsiExpression>();
addExpressionOccurrences(RefactoringUtil.unparenthesizeExpression(expr), array, scope);
if (!array.contains(expr)) array.add(expr);
return array.toArray(new PsiExpression[array.size()]);
}
@@ -38,33 +38,30 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
public void handleInsert(InsertionContext context, LookupElementDecorator<LookupItem> item) {
@SuppressWarnings({"unchecked"}) final LookupItem<PsiClass> delegate = item.getDelegate();
final PsiElement position = SmartCompletionDecorator.getPosition(context, delegate);
final PsiExpression enclosing = PsiTreeUtil.getContextOfType(position, PsiExpression.class, true);
final PsiAnonymousClass anonymousClass = PsiTreeUtil.getParentOfType(position, PsiAnonymousClass.class);
final boolean inAnonymous = anonymousClass != null && anonymousClass.getParent() == enclosing;
insertParentheses(context, delegate, delegate.getObject());
DefaultInsertHandler.addImportForItem(context.getFile(), context.getStartOffset(), delegate);
final PsiElement position = SmartCompletionDecorator.getPosition(context, delegate);
final PsiExpression enclosing = PsiTreeUtil.getContextOfType(position, PsiExpression.class, true);
if (item.getUserData(LookupItem.BRACKETS_COUNT_ATTR) == null) {
final PsiAnonymousClass anonymousClass = PsiTreeUtil.getParentOfType(position, PsiAnonymousClass.class);
if (anonymousClass == null || anonymousClass.getParent() != enclosing) {
if (item.getUserData(LookupItem.BRACKETS_COUNT_ATTR) == null && !inAnonymous) {
if (((PsiClass)item.getObject()).hasModifierProperty(PsiModifier.ABSTRACT)) {
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.smarttype.anonymous");
final PsiClass psiClass = (PsiClass)item.getObject();
PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting(context.getFile().getViewProvider());
if (psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface()) {
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.smarttype.anonymous");
PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting(context.getFile().getViewProvider());
final Editor editor = context.getEditor();
final int offset = context.getTailOffset();
editor.getDocument().insertString(offset, " {}");
editor.getCaretModel().moveToOffset(offset + 2);
context.setLaterRunnable(generateAnonymousBody(editor, context.getFile()));
}
else {
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.smarttype.afternew");
}
final Editor editor = context.getEditor();
final int offset = context.getTailOffset();
editor.getDocument().insertString(offset, " {}");
editor.getCaretModel().moveToOffset(offset + 2);
context.setLaterRunnable(generateAnonymousBody(editor, context.getFile()));
}
else {
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.smarttype.afternew");
}
}
}
@@ -15,7 +15,10 @@
*/
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.*;
import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.codeInsight.TailType;
import com.intellij.codeInsight.TailTypes;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupItem;
import com.intellij.featureStatistics.FeatureUsageTracker;
@@ -37,21 +40,14 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class DefaultInsertHandler extends TemplateInsertHandler implements Cloneable {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.DefaultInsertHandler");
protected InsertionContext myContext;
private LookupItem<?> myLookupItem;
private Project myProject;
private PsiFile myFile;
private Editor myEditor;
protected Document myDocument;
private InsertHandlerState myState;
public static final DefaultInsertHandler NO_TAIL_HANDLER = new DefaultInsertHandler(){
@Override
protected TailType getTailType(char completionChar) {
protected TailType getTailType(char completionChar, LookupItem item) {
return TailType.NONE;
}
};
@@ -64,107 +60,105 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
private void handleInsertInner(InsertionContext context, LookupItem item, final char completionChar) {
LOG.assertTrue(CommandProcessor.getInstance().getCurrentCommand() != null);
PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getEditor().getDocument());
myContext = context;
myLookupItem = item;
final Project project = context.getProject();
final Editor editor = context.getEditor();
final Document document = editor.getDocument();
PsiDocumentManager.getInstance(project).commitDocument(document);
myProject = myContext.getProject();
myFile = myContext.getFile();
myEditor = myContext.getEditor();
myDocument = myEditor.getDocument();
final PsiFile file = context.getFile();
TailType tailType = getTailType(completionChar);
TailType tailType = getTailType(completionChar, item);
myState = new InsertHandlerState(myContext.getSelectionEndOffset(), myContext.getSelectionEndOffset());
InsertHandlerState state = new InsertHandlerState(context.getSelectionEndOffset(), context.getSelectionEndOffset());
final boolean needLeftParenth = isToInsertParenth();
final boolean hasParams = needLeftParenth && hasParams();
final boolean needLeftParenth = isToInsertParenth(context, item);
final boolean hasParams = needLeftParenth && hasParams(context, item);
if (CompletionUtil.isOverwrite(item, completionChar)) {
removeEndOfIdentifier(needLeftParenth && hasParams);
removeEndOfIdentifier(needLeftParenth && hasParams, context);
}
else if(myContext.getOffsetMap().getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET) != myContext.getSelectionEndOffset()) {
else if(context.getOffsetMap().getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET) != context.getSelectionEndOffset()) {
JavaCompletionUtil.resetParensInfo(context.getOffsetMap());
}
handleParenses(hasParams, needLeftParenth, tailType);
handleBrackets();
handleParentheses(hasParams, needLeftParenth, tailType, context, state);
handleBrackets(item, document, state);
if (myLookupItem.getObject() instanceof PsiVariable) {
if (completionChar == '!' && PsiType.BOOLEAN.isAssignableFrom(((PsiVariable) myLookupItem.getObject()).getType())) {
PsiDocumentManager.getInstance(myProject).commitDocument(myDocument);
if (item.getObject() instanceof PsiVariable) {
if (completionChar == '!' && PsiType.BOOLEAN.isAssignableFrom(((PsiVariable) item.getObject()).getType())) {
PsiDocumentManager.getInstance(project).commitDocument(document);
final PsiReferenceExpression ref =
PsiTreeUtil.findElementOfClassAtOffset(myFile, myState.tailOffset - 1, PsiReferenceExpression.class, false);
PsiTreeUtil.findElementOfClassAtOffset(file, state.tailOffset - 1, PsiReferenceExpression.class, false);
if (ref != null) {
FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EXCLAMATION_FINISH);
myDocument.insertString(ref.getTextRange().getStartOffset(), "!");
myState.caretOffset++;
myState.tailOffset++;
document.insertString(ref.getTextRange().getStartOffset(), "!");
state.caretOffset++;
state.tailOffset++;
}
}
}
myContext.setTailOffset(myState.tailOffset);
myState.caretOffset = processTail(tailType, myState.caretOffset, myState.tailOffset);
myEditor.getSelectionModel().removeSelection();
context.setTailOffset(state.tailOffset);
state.caretOffset = processTail(tailType, state.caretOffset, state.tailOffset, editor);
editor.getSelectionModel().removeSelection();
qualifyIfNeeded();
qualifyIfNeeded(context, item);
if (needLeftParenth && hasParams){
// Invoke parameters popup
AutoPopupController.getInstance(myProject).autoPopupParameterInfo(myEditor, null);
AutoPopupController.getInstance(project).autoPopupParameterInfo(editor, null);
}
if (tailType == TailType.DOT){
AutoPopupController.getInstance(myProject).autoPopupMemberLookup(myEditor, null);
AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, null);
}
if (completionChar == '#') {
context.setLaterRunnable(new Runnable() {
public void run() {
new CodeCompletionHandlerBase(CompletionType.BASIC) {
}.invoke(myProject, myEditor, myFile);
new CodeCompletionHandlerBase(CompletionType.BASIC).invoke(project, editor, file);
}
});
}
if (insertingAnnotation()) {
if (insertingAnnotation(context, item)) {
// Check if someone inserts annotation class that require @
PsiElement elementAt = myFile.findElementAt(myContext.getStartOffset());
PsiElement elementAt = file.findElementAt(context.getStartOffset());
final PsiElement parentElement = elementAt != null ? elementAt.getParent():null;
if (elementAt instanceof PsiIdentifier &&
(PsiTreeUtil.getParentOfType(elementAt, PsiAnnotationParameterList.class) != null ||
parentElement instanceof PsiErrorElement && parentElement.getParent() instanceof PsiJavaFile // top level annotation without @
)
&& isAtTokenNeeded()) {
&& isAtTokenNeeded(context)) {
int expectedOffsetForAtToken = elementAt.getTextRange().getStartOffset();
myDocument.insertString(expectedOffsetForAtToken, "@");
document.insertString(expectedOffsetForAtToken, "@");
}
}
}
private void qualifyIfNeeded() {
private static void qualifyIfNeeded(InsertionContext context, LookupElement item) {
try{
if (myLookupItem.getObject() instanceof PsiField) {
PsiDocumentManager.getInstance(myFile.getProject()).commitAllDocuments();
PsiReference reference = myFile.findReferenceAt(myContext.getStartOffset());
final PsiFile file = context.getFile();
if (item.getObject() instanceof PsiField) {
PsiDocumentManager.getInstance(file.getProject()).commitAllDocuments();
PsiReference reference = file.findReferenceAt(context.getStartOffset());
if (reference instanceof PsiReferenceExpression && !((PsiReferenceExpression) reference).isQualified()) {
final PsiField member = (PsiField)myLookupItem.getObject();
final PsiField member = (PsiField)item.getObject();
final PsiVariable target =
JavaPsiFacade.getInstance(myProject).getResolveHelper().resolveReferencedVariable(member.getName(), (PsiElement)reference);
JavaPsiFacade.getInstance(context.getProject()).getResolveHelper().resolveReferencedVariable(member.getName(), (PsiElement)reference);
if (member.getManager().areElementsEquivalent(target, JavaCompletionUtil.getOriginalElement(member))) return;
final PsiClass psiClass = member.getContainingClass();
if (psiClass != null && StringUtil.isNotEmpty(psiClass.getName())) {
myDocument.insertString(myContext.getStartOffset(), psiClass.getName() + ".");
context.getEditor().getDocument().insertString(context.getStartOffset(), psiClass.getName() + ".");
}
}
}
addImportForItem(myFile, myContext.getStartOffset(), myLookupItem);
if (myContext.getTailOffset() < 0) { //hack, hack, hack. ideally the tail offset just should survive after the importing stuff
myContext.setTailOffset(myEditor.getCaretModel().getOffset());
addImportForItem(file, context.getStartOffset(), item);
if (context.getTailOffset() < 0) { //hack, hack, hack. ideally the tail offset just should survive after the importing stuff
context.setTailOffset(context.getEditor().getCaretModel().getOffset());
}
}
catch(IncorrectOperationException e){
@@ -172,7 +166,7 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
}
}
private boolean isAtTokenNeeded() {
private static boolean isAtTokenNeeded(InsertionContext myContext) {
HighlighterIterator iterator = ((EditorEx)myContext.getEditor()).getHighlighter().createIterator(myContext.getStartOffset());
LOG.assertTrue(iterator.getTokenType() == JavaTokenType.IDENTIFIER);
iterator.retreat();
@@ -180,53 +174,54 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
return iterator.getTokenType() != JavaTokenType.AT && iterator.getTokenType() != JavaTokenType.DOT;
}
private void handleBrackets(){
private static void handleBrackets(LookupElement item, Document document, InsertHandlerState myState){
// brackets
final Integer bracketsAttr = (Integer)myLookupItem.getUserData(LookupItem.BRACKETS_COUNT_ATTR);
final Integer bracketsAttr = (Integer)item.getUserData(LookupItem.BRACKETS_COUNT_ATTR);
if (bracketsAttr != null){
int count = bracketsAttr.intValue();
if(count > 0)
myState.caretOffset = myState.tailOffset + 1;
for(int i = 0; i < count; i++){
myDocument.insertString(myState.tailOffset, "[]");
document.insertString(myState.tailOffset, "[]");
myState.tailOffset += 2;
}
}
}
private void handleParenses(final boolean hasParams, final boolean needParenth, TailType tailType){
private static void handleParentheses(final boolean hasParams, final boolean needParenth, TailType tailType, InsertionContext context, InsertHandlerState myState){
final Document document = context.getEditor().getDocument();
boolean insertRightParenth = tailType != TailType.SMART_COMPLETION;
if (needParenth){
if (myContext.getOffsetMap().getOffset(JavaCompletionUtil.LPAREN_OFFSET) >= 0 && myContext.getOffsetMap().getOffset(JavaCompletionUtil.ARG_LIST_END_OFFSET) >= 0){
myState.tailOffset = myContext.getOffsetMap().getOffset(JavaCompletionUtil.ARG_LIST_END_OFFSET);
if (myContext.getOffsetMap().getOffset(JavaCompletionUtil.RPAREN_OFFSET) < 0 && insertRightParenth){
myDocument.insertString(myState.tailOffset, ")");
if (context.getOffsetMap().getOffset(JavaCompletionUtil.LPAREN_OFFSET) >= 0 && context.getOffsetMap().getOffset(JavaCompletionUtil.ARG_LIST_END_OFFSET) >= 0){
myState.tailOffset = context.getOffsetMap().getOffset(JavaCompletionUtil.ARG_LIST_END_OFFSET);
if (context.getOffsetMap().getOffset(JavaCompletionUtil.RPAREN_OFFSET) < 0 && insertRightParenth){
document.insertString(myState.tailOffset, ")");
myState.tailOffset += 1;
}
if (hasParams){
myState.caretOffset = myContext.getOffsetMap().getOffset(JavaCompletionUtil.LPAREN_OFFSET) + 1;
myState.caretOffset = context.getOffsetMap().getOffset(JavaCompletionUtil.LPAREN_OFFSET) + 1;
}
else{
myState.caretOffset = myContext.getOffsetMap().getOffset(JavaCompletionUtil.ARG_LIST_END_OFFSET);
myState.caretOffset = context.getOffsetMap().getOffset(JavaCompletionUtil.ARG_LIST_END_OFFSET);
}
}
else{
final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(myProject);
myState.tailOffset = myContext.getSelectionEndOffset();
myState.caretOffset = myContext.getSelectionEndOffset();
final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(context.getProject());
myState.tailOffset = context.getSelectionEndOffset();
myState.caretOffset = context.getSelectionEndOffset();
if(styleSettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES){
myDocument.insertString(myState.tailOffset++, " ");
document.insertString(myState.tailOffset++, " ");
myState.caretOffset ++;
}
if (insertRightParenth) {
final CharSequence charsSequence = myDocument.getCharsSequence();
final CharSequence charsSequence = document.getCharsSequence();
if (charsSequence.length() <= myState.tailOffset || charsSequence.charAt(myState.tailOffset) != '(') {
myDocument.insertString(myState.tailOffset, "(");
document.insertString(myState.tailOffset, "(");
}
myDocument.insertString(myState.tailOffset + 1, ")");
document.insertString(myState.tailOffset + 1, ")");
if (hasParams){
myState.tailOffset += 2;
myState.caretOffset++;
@@ -243,26 +238,26 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
}
}
else{
myDocument.insertString(myState.tailOffset++, "(");
document.insertString(myState.tailOffset++, "(");
myState.caretOffset ++;
}
if(hasParams && styleSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES){
myDocument.insertString(myState.caretOffset++, " ");
document.insertString(myState.caretOffset++, " ");
myState.tailOffset++;
}
}
}
}
protected boolean isToInsertParenth(){
return insertingAnnotationWithParameters();
protected static boolean isToInsertParenth(InsertionContext context, LookupElement item){
return insertingAnnotationWithParameters(context, item);
}
private boolean hasParams(){
final String lookupString = myLookupItem.getLookupString();
private static boolean hasParams(InsertionContext context, LookupElement item){
final String lookupString = item.getLookupString();
if (PsiKeyword.SYNCHRONIZED.equals(lookupString)) {
final PsiElement place = myFile.findElementAt(myContext.getStartOffset());
final PsiElement place = context.getFile().findElementAt(context.getStartOffset());
return PsiTreeUtil.getParentOfType(place, PsiMember.class, PsiCodeBlock.class) instanceof PsiCodeBlock;
}
else if(PsiKeyword.CATCH.equals(lookupString) ||
@@ -270,21 +265,21 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
PsiKeyword.WHILE.equals(lookupString) ||
PsiKeyword.FOR.equals(lookupString))
return true;
else if (insertingAnnotationWithParameters()) {
else if (insertingAnnotationWithParameters(context, item)) {
return true;
}
return false;
}
private boolean insertingAnnotationWithParameters() {
if(insertingAnnotation()) {
final Document document = myContext.getEditor().getDocument();
PsiDocumentManager.getInstance(myContext.getProject()).commitDocument(document);
PsiElement elementAt = myFile.findElementAt(myContext.getStartOffset());
private static boolean insertingAnnotationWithParameters(InsertionContext context, LookupElement item) {
if(insertingAnnotation(context, item)) {
final Document document = context.getEditor().getDocument();
PsiDocumentManager.getInstance(context.getProject()).commitDocument(document);
PsiElement elementAt = context.getFile().findElementAt(context.getStartOffset());
if (elementAt instanceof PsiIdentifier) {
final PsiModifierListOwner parent = PsiTreeUtil.getParentOfType(elementAt, PsiModifierListOwner.class, false, PsiCodeBlock.class);
if (parent != null) {
for (PsiMethod m : ((PsiClass)myLookupItem.getObject()).getMethods()) {
for (PsiMethod m : ((PsiClass)item.getObject()).getMethods()) {
if (!(m instanceof PsiAnnotationMethod)) continue;
final PsiAnnotationMemberValue defaultValue = ((PsiAnnotationMethod)m).getDefaultValue();
if (defaultValue == null) return true;
@@ -295,35 +290,38 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
return false;
}
private boolean insertingAnnotation() {
final Object obj = myLookupItem.getObject();
private static boolean insertingAnnotation(InsertionContext context, LookupElement item) {
final Object obj = item.getObject();
if (!(obj instanceof PsiClass) || !((PsiClass)obj).isAnnotationType()) return false;
final Document document = myEditor.getDocument();
PsiDocumentManager.getInstance(myFile.getProject()).commitDocument(document);
final int offset = myContext.getStartOffset();
final Document document = context.getEditor().getDocument();
PsiDocumentManager.getInstance(context.getProject()).commitDocument(document);
final int offset = context.getStartOffset();
if (PsiTreeUtil.findElementOfClassAtOffset(myFile, offset, PsiImportStatement.class, false) != null) return false;
final PsiFile file = context.getFile();
if (PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiImportStatement.class, false) != null) return false;
//outside of any class: we are surely inserting an annotation
if (PsiTreeUtil.findElementOfClassAtOffset(myFile, offset, PsiClass.class, false) == null) return true;
if (PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiClass.class, false) == null) return true;
//the easiest check that there's a @ before the identifier
return PsiTreeUtil.findElementOfClassAtOffset(myFile, offset, PsiAnnotation.class, false) != null;
return PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiAnnotation.class, false) != null;
}
protected void removeEndOfIdentifier(boolean needParenth){
JavaCompletionUtil.initOffsets(myContext.getFile(), myContext.getProject(), myContext.getOffsetMap());
myDocument.deleteString(myContext.getSelectionEndOffset(), myContext.getOffsetMap().getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET));
if(myContext.getOffsetMap().getOffset(JavaCompletionUtil.LPAREN_OFFSET) > 0 && !needParenth){
myDocument.deleteString(myContext.getOffsetMap().getOffset(JavaCompletionUtil.LPAREN_OFFSET),
myContext.getOffsetMap().getOffset(JavaCompletionUtil.ARG_LIST_END_OFFSET));
JavaCompletionUtil.resetParensInfo(myContext.getOffsetMap());
protected static void removeEndOfIdentifier(boolean needParenth, InsertionContext context){
final Document document = context.getEditor().getDocument();
JavaCompletionUtil.initOffsets(context.getFile(), context.getProject(), context.getOffsetMap());
document.deleteString(context.getSelectionEndOffset(), context.getOffsetMap().getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET));
if(context.getOffsetMap().getOffset(JavaCompletionUtil.LPAREN_OFFSET) > 0 && !needParenth){
document.deleteString(context.getOffsetMap().getOffset(JavaCompletionUtil.LPAREN_OFFSET),
context.getOffsetMap().getOffset(JavaCompletionUtil.ARG_LIST_END_OFFSET));
JavaCompletionUtil.resetParensInfo(context.getOffsetMap());
}
}
protected TailType getTailType(final char completionChar){
protected TailType getTailType(final char completionChar, LookupItem item){
switch(completionChar){
case '.': return TailType.DOT;
case ',': return TailType.COMMA;
@@ -337,14 +335,14 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
case '\"':
case '[': return TailType.createSimpleTailType(completionChar);
}
final TailType attr = myLookupItem.getTailType();
final TailType attr = item.getTailType();
return attr == TailType.UNKNOWN ? TailType.NONE : attr;
}
private int processTail(TailType tailType, int caretOffset, int tailOffset) {
myEditor.getCaretModel().moveToOffset(caretOffset);
tailType.processTail(myEditor, tailOffset);
return myEditor.getCaretModel().getOffset();
private static int processTail(TailType tailType, int caretOffset, int tailOffset, Editor editor) {
editor.getCaretModel().moveToOffset(caretOffset);
tailType.processTail(editor, tailOffset);
return editor.getCaretModel().getOffset();
}
@Override
@@ -392,6 +390,7 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
private static void shortenReference(final PsiFile file, final int offset) throws IncorrectOperationException {
final PsiDocumentManager manager = PsiDocumentManager.getInstance(file.getProject());
final Document document = manager.getDocument(file);
assert document != null;
manager.commitDocument(document);
final PsiReference ref = file.findReferenceAt(offset);
if (ref instanceof PsiJavaCodeReferenceElement) {
@@ -480,6 +479,7 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
return toDelete;
}
@Nullable
static PsiElement resolveReference(final PsiReference psiReference) {
if (psiReference instanceof PsiPolyVariantReference) {
final ResolveResult[] results = ((PsiPolyVariantReference)psiReference).multiResolve(true);
@@ -28,7 +28,8 @@ public class JavaChangeLocalityDetector implements ChangeLocalityDetector {
public PsiElement getChangeHighlightingDirtyScopeFor(final PsiElement element) {
PsiElement parent = element.getParent();
if (element instanceof PsiCodeBlock && parent instanceof PsiMethod && !((PsiMethod)parent).isConstructor() &&
parent.getParent()instanceof PsiClass && !(parent.getParent()instanceof PsiAnonymousClass)) {
parent.getParent() instanceof PsiClass && !(parent.getParent() instanceof PsiAnonymousClass)) {
// for changes inside method, rehighlight codeblock only
// do not use this optimization for constructors and class initializers - to update non-initialized fields
return parent;
}
@@ -529,6 +529,7 @@ public class HighlightMethodUtil {
return containingClass == null ? method.getContainingFile().getName() : HighlightUtil.formatClass(containingClass, false);
}
@Language("HTML")
private static String createAmbiguousMethodHtmlTooltipMethodRow(final MethodCandidateInfo methodCandidate) {
PsiMethod method = methodCandidate.getElement();
PsiParameter[] parameters = method.getParameterList().getParameters();
@@ -565,6 +566,7 @@ public class HighlightMethodUtil {
PsiExpression[] expressions = list.getExpressions();
int cols = Math.max(parameters.length, expressions.length);
@Language("HTML")
@NonNls String parensizedName = methodName + (parameters.length == 0 ? "(&nbsp;)&nbsp;" : "");
return JavaErrorMessages.message(
"argument.mismatch.html.tooltip",
@@ -576,7 +578,7 @@ public class HighlightMethodUtil {
}
private static String esctrim(@NotNull String s) {
return StringUtil.first(XmlStringUtil.escapeString(s), 40, true);
return XmlStringUtil.escapeString(StringUtil.first(s, 40, true));
}
private static String createMismatchedArgumentsHtmlTooltip(PsiExpressionList list,
@@ -592,6 +594,7 @@ public class HighlightMethodUtil {
}
}
@Language("HTML")
private static String createLongMismatchedArgumentsHtmlTooltip(PsiExpressionList list,
PsiParameter[] parameters,
String methodName,
@@ -599,22 +602,21 @@ public class HighlightMethodUtil {
PsiClass aClass) {
PsiExpression[] expressions = list.getExpressions();
@NonNls @Language("HTML")
@NonNls
String s = "<html><body><table border=0>" +
" <caption align=top><nobr><b>" + methodName + "() </b> in <b>" + HighlightUtil.formatClass(aClass, false) +"</b> cannot be applied to:</nobr></caption>"+
" <tr><th colspan=2 align=left>Expected<br>Parameters:</th><th align=left>Actual<br>Arguments:</th></tr>"
+" <tr><td colspan=3><hr></td></tr>"
"<tr><td colspan=3>" +
"<nobr><b>" + methodName + "()</b> in <b>" + HighlightUtil.formatClass(aClass, false) +"</b> cannot be applied to:</nobr>" +
"</td></tr>"+
"<tr><td colspan=2 align=left>Expected<br>Parameters:</td><td align=left>Actual<br>Arguments:</td></tr>"+
"<tr><td colspan=3><hr></td></tr>"
;
for (int i = 0; i < Math.max(parameters.length,expressions.length); i++) {
PsiParameter parameter = i < parameters.length ? parameters[i] : null;
PsiExpression expression = i < expressions.length ? expressions[i] : null;
@NonNls String mismatchColor = showShortType(i, parameters, expressions, substitutor) ? null : "red";
s += "<tr" +
(i%2 == 0 ? " style='background-color: #eeeeee'" : "") +
">";
s += "<tr" + (i % 2 == 0 ? " style='background-color: #eeeeee'" : "") + ">";
s += "<td><b><nobr>";
if (parameter != null) {
String name = parameter.getName();
@@ -651,10 +653,11 @@ public class HighlightMethodUtil {
s += "</tr>";
}
s+= " </table></body></html>";
s+= "</table></body></html>";
return s;
}
@Language("HTML")
private static String createMismatchedArgsHtmlTooltipArgumentsRow(final PsiExpression[] expressions, final PsiParameter[] parameters,
final PsiSubstitutor substitutor, final int cols) {
@NonNls String ms = "";
@@ -678,6 +681,7 @@ public class HighlightMethodUtil {
return ms;
}
@Language("HTML")
private static String createMismatchedArgsHtmlTooltipParamsRow(final PsiParameter[] parameters,
final PsiSubstitutor substitutor,
final PsiExpression[] expressions) {
@@ -109,20 +109,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
LOG.assertTrue(element.isValid());
}
element.accept(this);
if (myRefCountHolder != null) {
instantiateInjections(element);
}
}
private void instantiateInjections(final PsiElement element) {
InjectedLanguageUtil.enumerate(element, myFile, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
public void visit(@NotNull final PsiFile injectedPsi, @NotNull final List<PsiLanguageInjectionHost.Shred> places) {
// no op
}
}, false);
}
private void registerReferencesFromInjectedFragments(final PsiElement element) {
InjectedLanguageUtil.enumerate(element, myFile, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
public void visit(@NotNull final PsiFile injectedPsi, @NotNull final List<PsiLanguageInjectionHost.Shred> places) {
@@ -34,8 +34,8 @@ import com.intellij.find.findUsages.FindUsagesHandler;
import com.intellij.find.findUsages.FindUsagesManager;
import com.intellij.find.findUsages.FindUsagesOptions;
import com.intellij.find.impl.FindManagerImpl;
import com.intellij.ide.util.SuperMethodWarningUtil;
import com.intellij.ide.DataManager;
import com.intellij.ide.util.SuperMethodWarningUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.undo.UndoUtil;
import com.intellij.openapi.editor.Editor;
@@ -95,7 +95,7 @@ public class ChangeMethodSignatureFromUsageFix implements IntentionAction {
String result = "";
try {
for (ParameterInfoImpl info : infos) {
PsiType type = info.getTypeWrapper().getType(context, context.getManager());
PsiType type = info.createType(context, context.getManager());
if (result.length() != 0) {
result += ", ";
}
@@ -25,7 +25,6 @@ import com.intellij.psi.*;
import com.intellij.psi.controlFlow.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
/**
@@ -39,8 +39,6 @@ import java.util.*;
public class RemoveUnusedVariableFix implements IntentionAction {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableFix");
private final PsiVariable myVariable;
@NonNls private static final String JAVA_LANG_PCKG = "java.lang";
@NonNls private static final String JAVA_IO_PCKG = "java.io";
public RemoveUnusedVariableFix(PsiVariable variable) {
myVariable = variable;
@@ -356,10 +354,10 @@ public class RemoveUnusedVariableFix implements IntentionAction {
PsiFile file = aClass.getContainingFile();
PsiDirectory directory = file.getContainingDirectory();
PsiPackage classPackage = JavaDirectoryService.getInstance().getPackage(directory);
String packageName = classPackage.getQualifiedName();
String packageName = classPackage == null ? null : classPackage.getQualifiedName();
// all Throwable descendants from java.lang are side effects free
if (JAVA_LANG_PCKG.equals(packageName) || JAVA_IO_PCKG.equals(packageName)) {
if ("java.lang".equals(packageName) || "java.io".equals(packageName)) {
PsiClass throwableClass = JavaPsiFacade.getInstance(aClass.getProject()).findClass("java.lang.Throwable", aClass.getResolveScope());
if (throwableClass != null && InheritanceUtil.isInheritorOrSelf(aClass, throwableClass, true)) {
return true;
@@ -22,8 +22,8 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.UndoConfirmationPolicy;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.EditorModificationUtil;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.fileTypes.FileType;
@@ -27,7 +27,6 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class AddDeprecationAnnotationFix extends AddAnnotationFix {
public AddDeprecationAnnotationFix() {
@@ -28,7 +28,6 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class AddNullableNotNullAnnotationFix extends AddAnnotationFix {
public AddNullableNotNullAnnotationFix(final String annotation, final String annotationToRemove) {
@@ -31,7 +31,6 @@ import com.intellij.util.IncorrectOperationException;
import gnu.trove.TIntArrayList;
import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author ven
@@ -32,7 +32,6 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class AddSingleMemberStaticImportAction extends PsiElementBaseIntentionAction {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.intention.impl.AddSingleMemberStaticImportAction");
@@ -34,7 +34,6 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.ui.ColorChooser;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
@@ -38,7 +38,6 @@ import com.intellij.psi.controlFlow.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -36,7 +36,6 @@ import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -26,7 +26,6 @@ import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author max
@@ -27,7 +27,6 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author mike
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.impl.ProjectRootUtil;
@@ -270,8 +271,9 @@ public class PackageUtil {
return false;
}
private static PsiDirectory getWritableDirectory(Query<VirtualFile> vFiles, PsiManager manager) {
private static PsiDirectory getWritableModuleDirectory(@NotNull Query<VirtualFile> vFiles, @NotNull Module module, PsiManager manager) {
for (VirtualFile vFile : vFiles) {
if (ModuleUtil.findModuleForFile(vFile, module.getProject()) != module) continue;
PsiDirectory directory = manager.findDirectory(vFile);
if (directory != null && directory.isValid() && directory.isWritable()) {
return directory;
@@ -286,7 +288,7 @@ public class PackageUtil {
String nameToMatch = packageName;
while (true) {
Query<VirtualFile> vFiles = ModulePackageIndex.getInstance(module).getDirsByPackageName(nameToMatch, false);
PsiDirectory directory = getWritableDirectory(vFiles, manager);
PsiDirectory directory = getWritableModuleDirectory(vFiles, module, manager);
if (directory != null) return JavaDirectoryService.getInstance().getPackage(directory);
int lastDotIndex = nameToMatch.lastIndexOf('.');
@@ -23,7 +23,6 @@ import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.util.ExecutionErrorDialog;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
@@ -61,12 +60,12 @@ public final class JavadocGenerationManager extends AbstractProjectComponent imp
return myConfiguration;
}
public void generateJavadoc(AnalysisScope scope, DataContext dataContext) {
public void generateJavadoc(AnalysisScope scope) {
myConfiguration.setGenerationScope(scope);
try {
final ProgramRunner runner = RunnerRegistry.getInstance().getRunner(DefaultRunExecutor.EXECUTOR_ID, myConfiguration);
assert runner != null;
runner.execute(DefaultRunExecutor.getRunExecutorInstance(), new ExecutionEnvironment(myConfiguration, dataContext));
runner.execute(DefaultRunExecutor.getRunExecutorInstance(), new ExecutionEnvironment(myConfiguration, myProject, null, null, null));
}
catch (ExecutionException e) {
ExecutionErrorDialog.show(e, CommonBundle.getErrorTitle(), myProject);
@@ -18,7 +18,6 @@ package com.intellij.javadoc.actions;
import com.intellij.analysis.AnalysisScope;
import com.intellij.analysis.BaseAnalysisAction;
import com.intellij.analysis.BaseAnalysisActionDialog;
import com.intellij.ide.DataManager;
import com.intellij.javadoc.JavadocBundle;
import com.intellij.javadoc.JavadocConfigurable;
import com.intellij.javadoc.JavadocGenerationManager;
@@ -37,7 +36,7 @@ public final class GenerateJavadocAction extends BaseAnalysisAction{
@Override
protected void analyze(@NotNull Project project, AnalysisScope scope) {
myConfigurable.apply();
JavadocGenerationManager.getInstance(project).generateJavadoc(scope, DataManager.getInstance().getDataContext());
JavadocGenerationManager.getInstance(project).generateJavadoc(scope);
dispose();
}
@@ -22,6 +22,8 @@ import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.RefactoringActionHandler;
import com.intellij.refactoring.changeSignature.ChangeSignatureHandler;
import com.intellij.refactoring.changeSignature.JavaChangeSignatureHandler;
import com.intellij.refactoring.extractInterface.ExtractInterfaceHandler;
import com.intellij.refactoring.extractMethod.ExtractMethodHandler;
import com.intellij.refactoring.extractSuperclass.ExtractSuperclassHandler;
@@ -84,6 +86,11 @@ public class JavaRefactoringSupportProvider extends DefaultRefactoringSupportPro
return new ExtractSuperclassHandler();
}
@Override
public ChangeSignatureHandler getChangeSignatureHandler() {
return new JavaChangeSignatureHandler();
}
public static boolean mayRenameInplace(PsiElement elementToRename, final PsiElement nameSuggestionContext) {
if (!(elementToRename instanceof PsiVariable)) return false;
if (nameSuggestionContext != null && nameSuggestionContext.getContainingFile() != elementToRename.getContainingFile()) return false;
@@ -301,12 +301,9 @@ public class PsiSuperMethodImplUtil {
CachedValue<Map<MethodSignature, HierarchicalMethodSignature>> value = aClass.getUserData(SIGNATURES_KEY);
if (value == null) {
BySignaturesCachedValueProvider provider = new BySignaturesCachedValueProvider(aClass);
value = CachedValuesManager.getManager(aClass.getProject()).createCachedValue(provider, false);
//Do not cache for nonphysical elements
if (aClass.isPhysical()) {
UserDataHolderEx dataHolder = (UserDataHolderEx)aClass;
value = dataHolder.putUserDataIfAbsent(SIGNATURES_KEY, value);
}
UserDataHolderEx dataHolder = (UserDataHolderEx)aClass;
value = dataHolder.putUserDataIfAbsent(SIGNATURES_KEY,
CachedValuesManager.getManager(aClass.getProject()).createCachedValue(provider, false));
}
return value.getValue();
@@ -496,7 +496,9 @@ public class PsiPackageImpl extends PsiElementBase implements PsiPackage, Querya
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclaractionKind.CLASS)) {
NameHint nameHint = processor.getHint(NameHint.KEY);
if (nameHint != null) {
if (processClassesByName(processor, state, place, scope, nameHint.getName(state))) return false;
final String shortName = nameHint.getName(state);
if ((migration != null || containsClassNamed(shortName))
&& processClassesByName(processor, state, place, scope, shortName)) return false;
}
else if (prefixMatcher != null && migration == null) {
for (String className : getClassNamesCache()) {
@@ -138,7 +138,9 @@ public class PsiClassReferenceType extends PsiClassType {
return factory.createType(aClass, rawSubstitutor, getLanguageLevel(), getAnnotations());
}
String qualifiedName = myReference.getQualifiedName();
LightClassReference reference = new LightClassReference(myReference.getManager(), myReference.getReferenceName(), qualifiedName, myReference.getResolveScope());
String name = myReference.getReferenceName();
if (name==null) name="";
LightClassReference reference = new LightClassReference(myReference.getManager(), name, qualifiedName, myReference.getResolveScope());
return new PsiClassReferenceType(reference, null,getAnnotations());
}
@@ -31,7 +31,10 @@ import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.jsp.jspJava.JspxImportStatement;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.statistics.JavaStatisticsManager;
import com.intellij.psi.util.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashSet;
@@ -567,18 +570,21 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
String methodName = methodExpr.getReferenceName();
if (methodName != null) {
String[] words = NameUtil.nameToWords(methodName);
if (words.length > 1) {
String firstWord = words[0];
if (words.length > 0) {
final String firstWord = words[0];
if (GET_PREFIX.equals(firstWord)
|| IS_PREFIX.equals(firstWord)
|| FIND_PREFIX.equals(firstWord)
|| CREATE_PREFIX.equals(firstWord)) {
final String propertyName = methodName.substring(firstWord.length());
final String[] names = getSuggestionsByName(propertyName, variableKind, false);
return new NamesByExprInfo(propertyName, names);
if (words.length > 1) {
final String propertyName = methodName.substring(firstWord.length());
final String[] names = getSuggestionsByName(propertyName, variableKind, false);
return new NamesByExprInfo(propertyName, names);
}
}
else if (words.length == 1) {
return new NamesByExprInfo(methodName, getSuggestionsByName(methodName, variableKind, false));
}
} else {
return new NamesByExprInfo(methodName, getSuggestionsByName(methodName, variableKind, false));
}
}
}
@@ -15,13 +15,19 @@
*/
package com.intellij.refactoring.actions;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageRefactoringSupport;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.refactoring.RefactoringActionHandler;
import com.intellij.refactoring.changeSignature.ChangeSignatureHandler;
import com.intellij.refactoring.changeSignature.ChangeSignatureTargetUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ChangeSignatureAction extends BaseRefactoringAction {
public boolean isAvailableInEditorOnly() {
@@ -35,13 +41,71 @@ public class ChangeSignatureAction extends BaseRefactoringAction {
protected boolean isAvailableOnElementInEditor(final PsiElement element, final Editor editor) {
final Document document = editor.getDocument();
final PsiFile file = PsiDocumentManager.getInstance(element.getProject()).getPsiFile(document);
if (file != null && ChangeSignatureTargetUtil.findTargetMember(file, editor) != null) {
return true;
if (file == null) return false;
PsiElement targetMember = findTargetMember(file, editor);
if (targetMember == null) return false;
final ChangeSignatureHandler targetHandler = getChangeSignatureHandler(targetMember.getLanguage());
if (targetHandler == null) return false;
return true;
}
@Nullable
private static PsiElement findTargetMember(PsiFile file, Editor editor) {
final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
final PsiElement targetMember = findTargetMember(element);
if (targetMember != null) return targetMember;
final PsiReference reference = file.findReferenceAt(editor.getCaretModel().getOffset());
if (reference == null) return null;
return reference.resolve();
}
@Nullable
private static PsiElement findTargetMember(@Nullable PsiElement element) {
if (element == null) return null;
final ChangeSignatureHandler fileHandler = getChangeSignatureHandler(element.getLanguage());
if (fileHandler != null) {
final PsiElement targetMember = fileHandler.findTargetMember(element);
if (targetMember != null) return targetMember;
}
return element instanceof PsiMethod || element instanceof PsiClass;
final PsiReference reference = element.getReference();
if (reference == null) return null;
return reference.resolve();
}
public RefactoringActionHandler getHandler(DataContext dataContext) {
return new ChangeSignatureHandler();
final Language language = LangDataKeys.LANGUAGE.getData(dataContext);
if (language != null) {
return new RefactoringActionHandler() {
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
final PsiElement targetMember = findTargetMember(file, editor);
if (targetMember == null) return;
final ChangeSignatureHandler handler = getChangeSignatureHandler(targetMember.getLanguage());
if (handler == null) return;
handler.invoke(project, new PsiElement[]{targetMember}, dataContext);
}
public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
if (elements.length != 1) return;
final PsiElement targetMember = findTargetMember(elements[0]);
if (targetMember == null) return;
final ChangeSignatureHandler handler = getChangeSignatureHandler(targetMember.getLanguage());
if (handler == null) return;
handler.invoke(project, new PsiElement[]{targetMember}, dataContext);
}
};
}
return null;
}
@Override
protected boolean isAvailableForLanguage(Language language) {
return getChangeSignatureHandler(language) != null;
}
@Nullable
private static ChangeSignatureHandler getChangeSignatureHandler(Language language) {
return LanguageRefactoringSupport.INSTANCE.forLanguage(language).getChangeSignatureHandler();
}
}
@@ -282,8 +282,12 @@ public class ChangeSignatureDialog extends RefactoringDialog {
panel.add(subPanel, BorderLayout.CENTER);
JPanel subPanel1 = new JPanel(new GridBagLayout());
subPanel1.add(createExceptionsPanel(), new GridBagConstraints(0, 0, 1, 1, 0.5, 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(4,4,4,0), 0, 0));
subPanel1.add(createSignaturePanel(), new GridBagConstraints(1, 0, 1, 1, 0.5, 0.0, GridBagConstraints.EAST, GridBagConstraints.BOTH, new Insets(4,0,4,4), 0, 0));
subPanel1.add(createExceptionsPanel(),
new GridBagConstraints(0, 0, 1, 1, 0.5, 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(4, 4, 4, 0), 0,
0));
subPanel1.add(createSignaturePanel(),
new GridBagConstraints(1, 0, 1, 1, 0.5, 0.0, GridBagConstraints.EAST, GridBagConstraints.BOTH, new Insets(4, 0, 4, 4), 0,
0));
panel.add(subPanel1, BorderLayout.SOUTH);
return panel;
@@ -453,7 +457,7 @@ public class ChangeSignatureDialog extends RefactoringDialog {
final PsiClassType[] types = myMethod.getThrowsList().getReferencedTypes();
if (thrownExceptions.length <= types.length) return false;
for (int i = 0; i < types.length; i++) {
if (thrownExceptions[i].oldIndex != i) return false;
if (thrownExceptions[i].getOldIndex() != i) return false;
}
return true;
}
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2010 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.changeSignature;
import com.intellij.psi.PsiElement;
import com.intellij.usageView.UsageInfo;
/**
* @author Maxim.Medvedev
*/
public class ChangeSignatureParameterUsageInfo extends UsageInfo {
public final String oldParameterName;
public final String newParameterName;
public ChangeSignatureParameterUsageInfo(PsiElement element, String oldParameterName, String newParameterName) {
super(element);
this.oldParameterName = oldParameterName;
this.newParameterName = newParameterName;
}
}
@@ -1,78 +0,0 @@
/*
* 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.
*/
/*
* User: anna
* Date: 24-Nov-2009
*/
package com.intellij.refactoring.changeSignature;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
public class ChangeSignatureTargetUtil {
private ChangeSignatureTargetUtil() {}
@Nullable
public static PsiMember findTargetMember(PsiFile file, Editor editor) {
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
if (PsiTreeUtil.getParentOfType(element, PsiParameterList.class) != null) {
return PsiTreeUtil.getParentOfType(element, PsiMethod.class);
}
final PsiCallExpression expression = PsiTreeUtil.getParentOfType(element, PsiCallExpression.class);
if (expression != null) {
assert element != null;
final PsiExpression qualifierExpression = expression instanceof PsiMethodCallExpression ? ((PsiMethodCallExpression)expression).getMethodExpression().getQualifierExpression()
: expression instanceof PsiNewExpression ? ((PsiNewExpression)expression).getQualifier() : null;
if (PsiTreeUtil.isAncestor(qualifierExpression, element, false)) {
final PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(qualifierExpression, PsiExpressionList.class);
if (expressionList != null) {
final PsiElement parent = expressionList.getParent();
if (parent instanceof PsiMethodCallExpression) {
return ((PsiMethodCallExpression)parent).resolveMethod();
}
}
} else {
return expression.resolveMethod();
}
}
final PsiTypeParameterList typeParameterList = PsiTreeUtil.getParentOfType(element, PsiTypeParameterList.class);
if (typeParameterList != null) {
return PsiTreeUtil.getParentOfType(typeParameterList, PsiMember.class);
}
final PsiReferenceParameterList referenceParameterList = PsiTreeUtil.getParentOfType(element, PsiReferenceParameterList.class);
if (referenceParameterList != null) {
final PsiJavaCodeReferenceElement referenceElement =
PsiTreeUtil.getParentOfType(referenceParameterList, PsiJavaCodeReferenceElement.class);
if (referenceElement != null) {
final PsiElement resolved = referenceElement.resolve();
if (resolved instanceof PsiClass) {
return (PsiMember)resolved;
}
else if (resolved instanceof PsiMethod) {
return (PsiMember)resolved;
}
}
}
return null;
}
}
@@ -26,10 +26,13 @@ import java.util.List;
* @author dsl
*/
public class ChangeSignatureUtil {
private ChangeSignatureUtil() {}
private ChangeSignatureUtil() {
}
public static <Parent extends PsiElement, Child extends PsiElement>
void synchronizeList(Parent list, final List<Child> newElements, ChildrenGenerator<Parent, Child> generator, final boolean[] shouldRemoveChild)
public static <Parent extends PsiElement, Child extends PsiElement> void synchronizeList(Parent list,
final List<Child> newElements,
ChildrenGenerator<Parent, Child> generator,
final boolean[] shouldRemoveChild)
throws IncorrectOperationException {
ArrayList<Child> elementsToRemove = null;
@@ -20,16 +20,16 @@
*/
package com.intellij.refactoring.changeSignature;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.usageView.UsageViewBundle;
import com.intellij.usageView.UsageViewDescriptor;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
class ChangeSignatureViewDescriptor implements UsageViewDescriptor {
public class ChangeSignatureViewDescriptor implements UsageViewDescriptor {
private final PsiMethod myMethod;
private final String myProcessedElementsHeader;
@@ -29,7 +29,7 @@ import java.util.List;
/**
* @author ven
*/
class ExceptionsTableModel extends AbstractTableModel implements RowEditableTableModel {
public class ExceptionsTableModel extends AbstractTableModel implements RowEditableTableModel {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ParameterTableModel");
private List<PsiTypeCodeFragment> myTypeCodeFraments;
@@ -45,7 +45,7 @@ class ExceptionsTableModel extends AbstractTableModel implements RowEditableTabl
}
public void addRow() {
myExceptionInfos.add(new ThrownExceptionInfo());
myExceptionInfos.add(new JavaThrownExceptionInfo());
myTypeCodeFraments.add(createParameterTypeCodeFragment("", myContext));
fireTableRowsInserted(myTypeCodeFraments.size() - 1, myTypeCodeFraments.size() - 1);
}
@@ -102,22 +102,6 @@ class ExceptionsTableModel extends AbstractTableModel implements RowEditableTabl
}
}
PsiType getTypeByRow(int row) {
Object typeValueAt = getValueAt(row, 0);
LOG.assertTrue(typeValueAt instanceof PsiTypeCodeFragment);
PsiType type;
try {
type = ((PsiTypeCodeFragment)typeValueAt).getType();
}
catch (PsiTypeCodeFragment.TypeSyntaxException e1) {
type = null;
}
catch (PsiTypeCodeFragment.NoTypeException e1) {
type = null;
}
return type;
}
public void setTypeInfos(PsiMethod method) {
PsiClassType[] referencedTypes = method.getThrowsList().getReferencedTypes();
myTypeCodeFraments = new ArrayList<PsiTypeCodeFragment>(referencedTypes.length);
@@ -127,17 +111,17 @@ class ExceptionsTableModel extends AbstractTableModel implements RowEditableTabl
final PsiTypeCodeFragment typeCodeFragment = createParameterTypeCodeFragment(typeWrapper.getTypeText(), method.getThrowsList());
typeWrapper.addImportsTo(typeCodeFragment);
myTypeCodeFraments.add(typeCodeFragment);
myExceptionInfos.add(new ThrownExceptionInfo(i, referencedTypes[i]));
myExceptionInfos.add(new JavaThrownExceptionInfo(i, referencedTypes[i]));
}
}
PsiTypeCodeFragment createParameterTypeCodeFragment(final String typeText, PsiElement context) {
public PsiTypeCodeFragment createParameterTypeCodeFragment(final String typeText, PsiElement context) {
return JavaPsiFacade.getInstance(myContext.getProject()).getElementFactory().createTypeCodeFragment(
typeText, context, false, true, true
);
}
PsiTypeCodeFragment[] getTypeCodeFragments() {
public PsiTypeCodeFragment[] getTypeCodeFragments() {
return myTypeCodeFraments.toArray(new PsiTypeCodeFragment[myTypeCodeFraments.size()]);
}
@@ -0,0 +1,67 @@
/*
* Copyright 2000-2010 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.changeSignature;
import com.intellij.psi.*;
import com.intellij.refactoring.util.CanonicalTypes;
import org.jetbrains.annotations.NotNull;
/**
* @author Maxim.Medvedev
*/
public interface JavaChangeInfo extends ChangeInfo {
boolean isVisibilityChanged();
boolean isExceptionSetChanged();
boolean isExceptionSetOrOrderChanged();
PsiMethod getMethod();
CanonicalTypes.Type getNewReturnType();
@NotNull
JavaParameterInfo[] getNewParameters();
@Modifier
String getNewVisibility();
@NotNull
String[] getOldParameterNames();
@NotNull
String[] getOldParameterTypes();
ThrownExceptionInfo[] getNewExceptions();
boolean isRetainsVarargs();
boolean isObtainsVarags();
boolean isArrayToVarargs();
PsiIdentifier getNewNameIdentifier();
String getOldName();
boolean wasVararg();
boolean[] toRemoveParm();
PsiExpression getValue(int i, PsiCallExpression callExpression);
void updateMethod(PsiMethod psiMethod);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2010 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.
@@ -20,6 +20,8 @@
*/
package com.intellij.refactoring.changeSignature;
import com.intellij.lang.Language;
import com.intellij.lang.StdLanguages;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.refactoring.util.CanonicalTypes;
@@ -30,10 +32,12 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
class ChangeInfoImpl implements ChangeInfo {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ChangeInfoImpl");
class JavaChangeInfoImpl implements JavaChangeInfo {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.JavaChangeInfoImpl");
@Modifier
final String newVisibility;
private PsiMethod method;
final String oldName;
@@ -59,18 +63,25 @@ class ChangeInfoImpl implements ChangeInfo {
final boolean obtainsVarags;
final boolean arrayToVarargs;
PsiIdentifier newNameIdentifier;
PsiType newTypeElement;
// PsiType newTypeElement;
final PsiExpression[] defaultValues;
final boolean isGenerateDelegate;
final Set<PsiMethod> propagateParametersMethods;
final Set<PsiMethod> propagateExceptionsMethods;
/**
* @param newExceptions null if not changed
*/
public ChangeInfoImpl(@Modifier String newVisibility,
public JavaChangeInfoImpl(@Modifier String newVisibility,
PsiMethod method,
String newName,
CanonicalTypes.Type newType,
@NotNull ParameterInfoImpl[] newParms,
ThrownExceptionInfo[] newExceptions) {
ThrownExceptionInfo[] newExceptions,
boolean generateDelegate,
Set<PsiMethod> propagateParametersMethods,
Set<PsiMethod> propagateExceptionsMethods) {
this.newVisibility = newVisibility;
this.method = method;
this.newName = newName;
@@ -78,6 +89,10 @@ class ChangeInfoImpl implements ChangeInfo {
this.newParms = newParms;
wasVararg = method.isVarArgs();
this.isGenerateDelegate =generateDelegate;
this.propagateExceptionsMethods=propagateExceptionsMethods;
this.propagateParametersMethods=propagateParametersMethods;
oldName = method.getName();
final PsiManager manager = method.getManager();
if (!method.isConstructor()){
@@ -175,13 +190,23 @@ class ChangeInfoImpl implements ChangeInfo {
arrayToVarargs = false;
}
}
if (isNameChanged) {
newNameIdentifier = factory.createIdentifier(newName);
}
}
@NotNull
public ParameterInfo[] getNewParameters() {
public JavaParameterInfo[] getNewParameters() {
return newParms;
}
@Modifier
public String getNewVisibility() {
return newVisibility;
}
public boolean isParameterSetOrOrderChanged() {
return isParameterSetOrOrderChanged;
}
@@ -196,7 +221,7 @@ class ChangeInfoImpl implements ChangeInfo {
if (!isExceptionSetChanged) {
for (int i = 0; i < newExceptions.length; i++) {
try {
if (newExceptions[i].oldIndex < 0 || !types[i].equals(newExceptions[i].myType.getType(method, method.getManager()))) {
if (newExceptions[i].getOldIndex() < 0 || !types[i].equals(newExceptions[i].createType(method, method.getManager()))) {
isExceptionSetChanged = true;
break;
}
@@ -204,7 +229,7 @@ class ChangeInfoImpl implements ChangeInfo {
catch (IncorrectOperationException e) {
isExceptionSetChanged = true;
}
if (newExceptions[i].oldIndex != i) isExceptionSetOrOrderChanged = true;
if (newExceptions[i].getOldIndex() != i) isExceptionSetOrOrderChanged = true;
}
}
@@ -231,7 +256,7 @@ class ChangeInfoImpl implements ChangeInfo {
PsiClassType[] types = method.getThrowsList().getReferencedTypes();
ThrownExceptionInfo[] result = new ThrownExceptionInfo[types.length];
for (int i = 0; i < result.length; i++) {
result[i] = new ThrownExceptionInfo(i, types[i]);
result[i] = new JavaThrownExceptionInfo(i, types[i]);
}
return result;
}
@@ -240,6 +265,10 @@ class ChangeInfoImpl implements ChangeInfo {
return method;
}
public CanonicalTypes.Type getNewReturnType() {
return newReturnType;
}
public void updateMethod(PsiMethod method) {
this.method = method;
}
@@ -259,4 +288,86 @@ class ChangeInfoImpl implements ChangeInfo {
if (defaultValues[i] != null) return defaultValues[i];
return newParms[i].getValue(expr);
}
public boolean isVisibilityChanged() {
return isVisibilityChanged;
}
public boolean isNameChanged() {
return isNameChanged;
}
public boolean isReturnTypeChanged() {
return isReturnTypeChanged;
}
public String getNewName() {
return newName;
}
public Language getLanguage() {
return StdLanguages.JAVA;
}
public boolean isExceptionSetChanged() {
return isExceptionSetChanged;
}
public boolean isExceptionSetOrOrderChanged() {
return isExceptionSetOrOrderChanged;
}
public boolean isParameterNamesChanged() {
return isParameterNamesChanged;
}
public boolean isParameterTypesChanged() {
return isParameterTypesChanged;
}
public boolean isGenerateDelegate() {
return isGenerateDelegate;
}
@NotNull
public String[] getOldParameterNames() {
return oldParameterNames;
}
@NotNull
public String[] getOldParameterTypes() {
return oldParameterTypes;
}
public ThrownExceptionInfo[] getNewExceptions() {
return newExceptions;
}
public boolean isRetainsVarargs() {
return retainsVarargs;
}
public boolean isObtainsVarags() {
return obtainsVarags;
}
public boolean isArrayToVarargs() {
return arrayToVarargs;
}
public PsiIdentifier getNewNameIdentifier() {
return newNameIdentifier;
}
public String getOldName() {
return oldName;
}
public boolean wasVararg() {
return wasVararg;
}
public boolean[] toRemoveParm() {
return toRemoveParm;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2010 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.
@@ -24,20 +24,19 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.RefactoringActionHandler;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.changeClassSignature.ChangeClassSignatureDialog;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ChangeSignatureHandler implements RefactoringActionHandler {
public static final String REFACTORING_NAME = RefactoringBundle.message("changeSignature.refactoring.name");
public class JavaChangeSignatureHandler implements ChangeSignatureHandler {
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
PsiElement element = ChangeSignatureTargetUtil.findTargetMember(file, editor);
PsiElement element = findTargetMember(file, editor);
if (element == null) {
element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
}
@@ -77,10 +76,6 @@ public class ChangeSignatureHandler implements RefactoringActionHandler {
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, method)) return;
final PsiClass containingClass = method.getContainingClass();
if (containingClass != null && containingClass.isAnnotationType()) {
CommonRefactoringUtil.showErrorHint(project, editor, REFACTORING_NAME + " is not supported for annotation types", REFACTORING_NAME, HelpID.CHANGE_SIGNATURE);
return;
}
final PsiReferenceExpression refExpr = editor != null ? TargetElementUtil.findReferenceExpression(editor) : null;
final ChangeSignatureDialog dialog = new ChangeSignatureDialog(project, method, containingClass != null && !containingClass.isInterface(),
refExpr);
@@ -100,4 +95,59 @@ public class ChangeSignatureHandler implements RefactoringActionHandler {
ChangeClassSignatureDialog dialog = new ChangeClassSignatureDialog(aClass);
dialog.show();
}
@Nullable
public PsiElement findTargetMember(PsiFile file, Editor editor) {
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
return findTargetMember(element);
}
public PsiElement findTargetMember(PsiElement element) {
if (PsiTreeUtil.getParentOfType(element, PsiParameterList.class) != null) {
return PsiTreeUtil.getParentOfType(element, PsiMethod.class);
}
if (element.getParent() instanceof PsiMethod && ((PsiMethod)element.getParent()).getNameIdentifier()==element) {
return element.getParent();
}
final PsiMethodCallExpression expression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (expression != null) {
assert element != null;
final PsiExpression qualifierExpression = expression.getMethodExpression().getQualifierExpression();
if (PsiTreeUtil.isAncestor(qualifierExpression, element, false)) {
final PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(qualifierExpression, PsiExpressionList.class);
if (expressionList != null) {
final PsiElement parent = expressionList.getParent();
if (parent instanceof PsiMethodCallExpression) {
return ((PsiMethodCallExpression)parent).resolveMethod();
}
}
}
else {
return expression.resolveMethod();
}
}
final PsiTypeParameterList typeParameterList = PsiTreeUtil.getParentOfType(element, PsiTypeParameterList.class);
if (typeParameterList != null) {
return PsiTreeUtil.getParentOfType(typeParameterList, PsiMember.class);
}
final PsiReferenceParameterList referenceParameterList = PsiTreeUtil.getParentOfType(element, PsiReferenceParameterList.class);
if (referenceParameterList != null) {
final PsiJavaCodeReferenceElement referenceElement =
PsiTreeUtil.getParentOfType(referenceParameterList, PsiJavaCodeReferenceElement.class);
if (referenceElement != null) {
final PsiElement resolved = referenceElement.resolve();
if (resolved instanceof PsiClass) {
return resolved;
}
else if (resolved instanceof PsiMethod) {
return resolved;
}
}
}
return null;
}
}
@@ -0,0 +1,884 @@
/*
* Copyright 2000-2010 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.changeSignature;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.lang.StdLanguages;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.scope.processor.VariablesProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.rename.RenameUtil;
import com.intellij.refactoring.util.*;
import com.intellij.refactoring.util.usageInfo.DefaultConstructorImplicitUsageInfo;
import com.intellij.refactoring.util.usageInfo.NoConstructorClassUsageInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
import com.intellij.util.containers.HashSet;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* @author Maxim.Medvedev
*/
public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsageProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.JavaChangeSignatureUsageProcessor");
private static boolean isJavaUsage(UsageInfo info) {
final PsiElement element = info.getElement();
if (element == null) return false;
return element.getLanguage() == StdLanguages.JAVA;
}
public UsageInfo[] findUsages(ChangeInfo info) {
if (info instanceof JavaChangeInfo) {
return new JavaChangeSignatureUsageSearcher((JavaChangeInfo)info).findUsages();
}
else {
return UsageInfo.EMPTY_ARRAY;
}
}
public MultiMap<PsiElement, String> findConflicts(ChangeInfo info, Ref<UsageInfo[]> refUsages) {
if (info instanceof JavaChangeInfo) {
return new ConflictSearcher((JavaChangeInfo)info).findConflicts(refUsages);
}
else {
return new MultiMap<PsiElement, String>();
}
}
public boolean processUsage(ChangeInfo changeInfo, UsageInfo usage, boolean beforeMethodChange, UsageInfo[] usages) {
if (!isJavaUsage(usage)) return false;
if (!(changeInfo instanceof JavaChangeInfo)) return false;
if (beforeMethodChange) {
if (usage instanceof CallerUsageInfo) {
final CallerUsageInfo callerUsageInfo = (CallerUsageInfo)usage;
processCallerMethod((JavaChangeInfo)changeInfo, callerUsageInfo.getMethod(), null, callerUsageInfo.isToInsertParameter(),
callerUsageInfo.isToInsertException());
return true;
}
else if (usage instanceof OverriderUsageInfo) {
OverriderUsageInfo info = (OverriderUsageInfo)usage;
final PsiMethod method = info.getElement();
final PsiMethod baseMethod = info.getBaseMethod();
if (info.isOriginalOverrider()) {
processPrimaryMethod((JavaChangeInfo)changeInfo, method, baseMethod, false);
}
else {
processCallerMethod((JavaChangeInfo)changeInfo, method, baseMethod, info.isToInsertArgs(), info.isToCatchExceptions());
}
return true;
}
}
else {
PsiElement element = usage.getElement();
LOG.assertTrue(element != null);
if (usage instanceof DefaultConstructorImplicitUsageInfo) {
final DefaultConstructorImplicitUsageInfo defConstructorUsage = (DefaultConstructorImplicitUsageInfo)usage;
PsiMethod constructor = defConstructorUsage.getConstructor();
if (!constructor.isPhysical()) {
final boolean toPropagate =
changeInfo instanceof JavaChangeInfoImpl && ((JavaChangeInfoImpl)changeInfo).propagateParametersMethods.remove(constructor);
final PsiClass containingClass = defConstructorUsage.getContainingClass();
constructor = (PsiMethod)containingClass.add(constructor);
PsiUtil.setModifierProperty(constructor, VisibilityUtil.getVisibilityModifier(containingClass.getModifierList()), true);
if (toPropagate) {
((JavaChangeInfoImpl)changeInfo).propagateParametersMethods.add(constructor);
}
}
addSuperCall((JavaChangeInfo)changeInfo, constructor, defConstructorUsage.getBaseConstructor(), usages);
return true;
}
else if (usage instanceof NoConstructorClassUsageInfo) {
addDefaultConstructor(((JavaChangeInfo)changeInfo), ((NoConstructorClassUsageInfo)usage).getPsiClass(), usages);
return true;
}
else if (usage instanceof MethodCallUsageInfo) {
final MethodCallUsageInfo methodCallInfo = (MethodCallUsageInfo)usage;
processMethodUsage(methodCallInfo.getElement(), (JavaChangeInfo)changeInfo, methodCallInfo.isToChangeArguments(),
methodCallInfo.isToCatchExceptions(), methodCallInfo.getReferencedMethod(), methodCallInfo.getSubstitutor(), usages);
return true;
}
else if (usage instanceof ChangeSignatureParameterUsageInfo) {
String newName = ((ChangeSignatureParameterUsageInfo)usage).newParameterName;
String oldName = ((ChangeSignatureParameterUsageInfo)usage).oldParameterName;
processParameterUsage((PsiReferenceExpression)element, oldName, newName);
return true;
}
else if (usage instanceof CallReferenceUsageInfo) {
((CallReferenceUsageInfo)usage).getReference().handleChangeSignature(changeInfo);
return true;
}
else if (element instanceof PsiEnumConstant) {
fixActualArgumentsList(((PsiEnumConstant)element).getArgumentList(), (JavaChangeInfo)changeInfo, true, PsiSubstitutor.EMPTY);
return true;
}
else if (!(usage instanceof OverriderUsageInfo)) {
PsiReference reference = usage instanceof MoveRenameUsageInfo ? usage.getReference() : element.getReference();
if (reference != null) {
PsiElement target = changeInfo.getMethod();
if (target != null) {
reference.bindToElement(target);
}
}
}
}
return false;
}
private static void processParameterUsage(PsiReferenceExpression ref, String oldName, String newName)
throws IncorrectOperationException {
PsiElement last = ref.getReferenceNameElement();
if (last instanceof PsiIdentifier && last.getText().equals(oldName)) {
PsiElementFactory factory = JavaPsiFacade.getInstance(ref.getProject()).getElementFactory();
PsiIdentifier newNameIdentifier = factory.createIdentifier(newName);
last.replace(newNameIdentifier);
}
}
private static void addDefaultConstructor(JavaChangeInfo changeInfo, PsiClass aClass, final UsageInfo[] usages)
throws IncorrectOperationException {
if (!(aClass instanceof PsiAnonymousClass)) {
PsiElementFactory factory = JavaPsiFacade.getElementFactory(aClass.getProject());
PsiMethod defaultConstructor = factory.createMethodFromText(aClass.getName() + "(){}", aClass);
defaultConstructor = (PsiMethod)CodeStyleManager.getInstance(aClass.getProject()).reformat(defaultConstructor);
defaultConstructor = (PsiMethod)aClass.add(defaultConstructor);
PsiUtil.setModifierProperty(defaultConstructor, VisibilityUtil.getVisibilityModifier(aClass.getModifierList()), true);
addSuperCall(changeInfo, defaultConstructor, null, usages);
}
else {
final PsiElement parent = aClass.getParent();
if (parent instanceof PsiNewExpression) {
final PsiExpressionList argumentList = ((PsiNewExpression)parent).getArgumentList();
final PsiClass baseClass = changeInfo.getMethod().getContainingClass();
final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY);
fixActualArgumentsList(argumentList, changeInfo, true, substitutor);
}
}
}
private static void addSuperCall(JavaChangeInfo changeInfo, PsiMethod constructor, PsiMethod callee, final UsageInfo[] usages)
throws IncorrectOperationException {
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(constructor.getProject());
PsiExpressionStatement superCall = (PsiExpressionStatement)factory.createStatementFromText("super();", constructor);
PsiCodeBlock body = constructor.getBody();
assert body != null;
PsiStatement[] statements = body.getStatements();
if (statements.length > 0) {
superCall = (PsiExpressionStatement)body.addBefore(superCall, statements[0]);
}
else {
superCall = (PsiExpressionStatement)body.add(superCall);
}
PsiMethodCallExpression callExpression = (PsiMethodCallExpression)superCall.getExpression();
final PsiClass aClass = constructor.getContainingClass();
final PsiClass baseClass = changeInfo.getMethod().getContainingClass();
final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY);
processMethodUsage(callExpression.getMethodExpression(), changeInfo, true, false, callee, substitutor, usages);
}
private static void processMethodUsage(PsiElement ref,
JavaChangeInfo changeInfo,
boolean toChangeArguments,
boolean toCatchExceptions,
PsiMethod callee, PsiSubstitutor subsitutor, final UsageInfo[] usages) throws IncorrectOperationException {
if (changeInfo.isNameChanged()) {
if (ref instanceof PsiJavaCodeReferenceElement) {
PsiElement last = ((PsiJavaCodeReferenceElement)ref).getReferenceNameElement();
if (last instanceof PsiIdentifier && last.getText().equals(changeInfo.getOldName())) {
last.replace(changeInfo.getNewNameIdentifier());
}
}
}
final PsiMethod caller = RefactoringUtil.getEnclosingMethod(ref);
if (toChangeArguments) {
final PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(ref);
boolean toInsertDefaultValue = !(changeInfo instanceof JavaChangeInfoImpl) || !((JavaChangeInfoImpl)changeInfo).propagateParametersMethods.contains(caller);
if (toInsertDefaultValue && ref instanceof PsiReferenceExpression) {
final PsiExpression qualifierExpression = ((PsiReferenceExpression)ref).getQualifierExpression();
if (qualifierExpression instanceof PsiSuperExpression && callerSignatureIsAboutToChangeToo(caller, usages)) {
toInsertDefaultValue = false;
}
}
fixActualArgumentsList(list, changeInfo, toInsertDefaultValue, subsitutor);
}
if (toCatchExceptions) {
if (!(ref instanceof PsiReferenceExpression &&
((PsiReferenceExpression)ref).getQualifierExpression() instanceof PsiSuperExpression)) {
if (needToCatchExceptions(changeInfo, caller)) {
PsiClassType[] newExceptions =
callee != null ? getCalleeChangedExceptionInfo(callee) : getPrimaryChangedExceptionInfo(changeInfo);
fixExceptions(ref, newExceptions);
}
}
}
}
private static boolean callerSignatureIsAboutToChangeToo(final PsiMethod caller, final UsageInfo[] usages) {
for (UsageInfo usage : usages) {
if (usage instanceof MethodCallUsageInfo &&
MethodSignatureUtil.isSuperMethod(((MethodCallUsageInfo)usage).getReferencedMethod(), caller)) {
return true;
}
}
return false;
}
private static PsiClassType[] getCalleeChangedExceptionInfo(final PsiMethod callee) {
return callee.getThrowsList().getReferencedTypes(); //Callee method's throws list is already modified!
}
private static void fixExceptions(PsiElement ref, PsiClassType[] newExceptions) throws IncorrectOperationException {
//methods' throws lists are already modified, may use ExceptionUtil.collectUnhandledExceptions
newExceptions = filterCheckedExceptions(newExceptions);
PsiElement context = PsiTreeUtil.getParentOfType(ref, PsiTryStatement.class, PsiMethod.class);
if (context instanceof PsiTryStatement) {
PsiTryStatement tryStatement = (PsiTryStatement)context;
PsiCodeBlock tryBlock = tryStatement.getTryBlock();
//Remove unused catches
Collection<PsiClassType> classes = ExceptionUtil.collectUnhandledExceptions(tryBlock, tryBlock);
PsiParameter[] catchParameters = tryStatement.getCatchBlockParameters();
for (PsiParameter parameter : catchParameters) {
final PsiType caughtType = parameter.getType();
if (!(caughtType instanceof PsiClassType)) continue;
if (ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType)caughtType)) continue;
if (!isCatchParameterRedundant((PsiClassType)caughtType, classes)) continue;
parameter.getParent().delete(); //delete catch section
}
PsiClassType[] exceptionsToAdd = filterUnhandledExceptions(newExceptions, tryBlock);
addExceptions(exceptionsToAdd, tryStatement);
adjustPossibleEmptyTryStatement(tryStatement);
}
else {
newExceptions = filterUnhandledExceptions(newExceptions, ref);
if (newExceptions.length > 0) {
//Add new try statement
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(ref.getProject());
PsiTryStatement tryStatement = (PsiTryStatement)elementFactory.createStatementFromText("try {} catch (Exception e) {}", null);
PsiStatement anchor = PsiTreeUtil.getParentOfType(ref, PsiStatement.class);
LOG.assertTrue(anchor != null);
tryStatement.getTryBlock().add(anchor);
tryStatement = (PsiTryStatement)anchor.getParent().addAfter(tryStatement, anchor);
addExceptions(newExceptions, tryStatement);
anchor.delete();
tryStatement.getCatchSections()[0].delete(); //Delete dummy catch section
}
}
}
private static PsiClassType[] filterCheckedExceptions(PsiClassType[] exceptions) {
List<PsiClassType> result = new ArrayList<PsiClassType>();
for (PsiClassType exceptionType : exceptions) {
if (!ExceptionUtil.isUncheckedException(exceptionType)) result.add(exceptionType);
}
return result.toArray(new PsiClassType[result.size()]);
}
private static void adjustPossibleEmptyTryStatement(PsiTryStatement tryStatement) throws IncorrectOperationException {
PsiCodeBlock tryBlock = tryStatement.getTryBlock();
if (tryBlock != null) {
if (tryStatement.getCatchSections().length == 0 &&
tryStatement.getFinallyBlock() == null) {
PsiElement firstBodyElement = tryBlock.getFirstBodyElement();
if (firstBodyElement != null) {
tryStatement.getParent().addRangeAfter(firstBodyElement, tryBlock.getLastBodyElement(), tryStatement);
}
tryStatement.delete();
}
}
}
private static void addExceptions(PsiClassType[] exceptionsToAdd, PsiTryStatement tryStatement) throws IncorrectOperationException {
for (PsiClassType type : exceptionsToAdd) {
final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(tryStatement.getProject());
String name = styleManager.suggestVariableName(VariableKind.PARAMETER, null, null, type).names[0];
name = styleManager.suggestUniqueVariableName(name, tryStatement, false);
PsiCatchSection catchSection =
JavaPsiFacade.getInstance(tryStatement.getProject()).getElementFactory().createCatchSection(type, name, tryStatement);
tryStatement.add(catchSection);
}
}
private static PsiClassType[] filterUnhandledExceptions(PsiClassType[] exceptions, PsiElement place) {
List<PsiClassType> result = new ArrayList<PsiClassType>();
for (PsiClassType exception : exceptions) {
if (!ExceptionUtil.isHandled(exception, place)) result.add(exception);
}
return result.toArray(new PsiClassType[result.size()]);
}
private static boolean isCatchParameterRedundant(PsiClassType catchParamType, Collection<PsiClassType> thrownTypes) {
for (PsiType exceptionType : thrownTypes) {
if (exceptionType.isConvertibleFrom(catchParamType)) return false;
}
return true;
}
//This methods works equally well for primary usages as well as for propagated callers' usages
private static void fixActualArgumentsList(PsiExpressionList list,
JavaChangeInfo changeInfo,
boolean toInsertDefaultValue, PsiSubstitutor substitutor) throws IncorrectOperationException {
final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory();
if (changeInfo.isParameterSetOrOrderChanged()) {
if (changeInfo instanceof JavaChangeInfoImpl && ((JavaChangeInfoImpl)changeInfo).isPropagationEnabled) {
final ParameterInfoImpl[] createdParmsInfo = ((JavaChangeInfoImpl)changeInfo).getCreatedParmsInfoWithoutVarargs();
for (ParameterInfoImpl info : createdParmsInfo) {
PsiExpression newArg;
if (toInsertDefaultValue) {
newArg = createDefaultValue(changeInfo, factory, info, list);
}
else {
newArg = factory.createExpressionFromText(info.getName(), list);
}
list.add(newArg);
}
}
else {
final PsiExpression[] args = list.getExpressions();
final int nonVarargCount = getNonVarargCount(changeInfo, args);
final int varargCount = args.length - nonVarargCount;
PsiExpression[] newVarargInitializers = null;
final int newArgsLength;
final int newNonVarargCount;
final JavaParameterInfo[] newParms = changeInfo.getNewParameters();
if (changeInfo.isArrayToVarargs()) {
newNonVarargCount = newParms.length - 1;
final JavaParameterInfo lastNewParm = newParms[newParms.length - 1];
final PsiExpression arrayToConvert = args[lastNewParm.getOldIndex()];
if (arrayToConvert instanceof PsiNewExpression) {
final PsiNewExpression expression = (PsiNewExpression)arrayToConvert;
final PsiArrayInitializerExpression arrayInitializer = expression.getArrayInitializer();
if (arrayInitializer != null) {
newVarargInitializers = arrayInitializer.getInitializers();
}
}
newArgsLength = newVarargInitializers == null ? newParms.length : newNonVarargCount + newVarargInitializers.length;
}
else if (changeInfo.isRetainsVarargs()) {
newNonVarargCount = newParms.length - 1;
newArgsLength = newNonVarargCount + varargCount;
}
else if (changeInfo.isObtainsVarags()) {
newNonVarargCount = newParms.length - 1;
newArgsLength = newNonVarargCount;
}
else {
newNonVarargCount = newParms.length;
newArgsLength = newParms.length;
}
String[] oldVarargs = null;
if (changeInfo.wasVararg() && !changeInfo.isRetainsVarargs()) {
oldVarargs = new String[varargCount];
for (int i = nonVarargCount; i < args.length; i++) {
oldVarargs[i - nonVarargCount] = args[i].getText();
}
}
final PsiExpression[] newArgs = new PsiExpression[newArgsLength];
for (int i = 0; i < newNonVarargCount; i++) {
if (newParms[i].getOldIndex() == nonVarargCount && oldVarargs != null) {
PsiType type = newParms[i].createType(changeInfo.getMethod(), list.getManager());
if (type instanceof PsiArrayType) {
type = substitutor.substitute(type);
type = TypeConversionUtil.erasure(type);
String typeText = type.getCanonicalText();
if (type instanceof PsiEllipsisType) {
typeText = typeText.replace("...", "[]");
}
String text = "new " + typeText + "{" + StringUtil.join(oldVarargs, ",") + "}";
newArgs[i] = factory.createExpressionFromText(text, changeInfo.getMethod());
continue;
}
}
newArgs[i] = createActualArgument(changeInfo, list, newParms[i], toInsertDefaultValue, args);
}
if (changeInfo.isArrayToVarargs()) {
if (newVarargInitializers == null) {
newArgs[newNonVarargCount] =
createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args);
}
else {
System.arraycopy(newVarargInitializers, 0, newArgs, newNonVarargCount, newVarargInitializers.length);
}
}
else {
final int newVarargCount = newArgsLength - newNonVarargCount;
LOG.assertTrue(newVarargCount == 0 || newVarargCount == varargCount);
System.arraycopy(args, nonVarargCount, newArgs, newNonVarargCount, newVarargCount);
}
ChangeSignatureUtil.synchronizeList(list, Arrays.asList(newArgs), ExpressionList.INSTANCE, changeInfo.toRemoveParm());
}
}
}
private static int getNonVarargCount(JavaChangeInfo changeInfo, PsiExpression[] args) {
if (!changeInfo.wasVararg()) return args.length;
return changeInfo.getOldParameterTypes().length - 1;
}
@Nullable
private static PsiExpression createActualArgument(JavaChangeInfo changeInfo,
final PsiExpressionList list,
final JavaParameterInfo info,
final boolean toInsertDefaultValue,
final PsiExpression[] args) throws IncorrectOperationException {
final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory();
final int index = info.getOldIndex();
if (index >= 0) {
return args[index];
}
else {
if (toInsertDefaultValue) {
return createDefaultValue(changeInfo, factory, info, list);
}
else {
return factory.createExpressionFromText(info.getName(), list);
}
}
}
@Nullable
private static PsiExpression createDefaultValue(JavaChangeInfo changeInfo,
final PsiElementFactory factory,
final JavaParameterInfo info,
final PsiExpressionList list)
throws IncorrectOperationException {
if (info.isUseAnySingleVariable()) {
final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper();
final PsiType type = info.getTypeWrapper().getType(changeInfo.getMethod(), list.getManager());
final VariablesProcessor processor = new VariablesProcessor(false) {
protected boolean check(PsiVariable var, ResolveState state) {
if (var instanceof PsiField && !resolveHelper.isAccessible((PsiField)var, list, null)) return false;
final PsiType varType = state.get(PsiSubstitutor.KEY).substitute(var.getType());
return type.isAssignableFrom(varType);
}
public boolean execute(PsiElement pe, ResolveState state) {
super.execute(pe, state);
return size() < 2;
}
};
PsiScopesUtil.treeWalkUp(processor, list, null);
if (processor.size() == 1) {
final PsiVariable result = processor.getResult(0);
return factory.createExpressionFromText(result.getName(), list);
}
}
final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(list, PsiCallExpression.class);
return callExpression != null ? info.getValue(callExpression) : factory.createExpressionFromText(info.getDefaultValue(), list);
}
public boolean processPrimaryMethod(ChangeInfo changeInfo) {
if (!StdLanguages.JAVA.equals(changeInfo.getLanguage()) || !(changeInfo instanceof JavaChangeInfo)) return false;
final PsiElement element = changeInfo.getMethod();
LOG.assertTrue(element instanceof PsiMethod);
if (changeInfo.isGenerateDelegate()) {
generateDelegate((JavaChangeInfo)changeInfo);
}
processPrimaryMethod((JavaChangeInfo)changeInfo, (PsiMethod)element, null, true);
return true;
}
public boolean shouldPreviewUsages(ChangeInfo changeInfo, UsageInfo[] usages) {
return false;
}
private static void generateDelegate(JavaChangeInfo changeInfo) throws IncorrectOperationException {
final PsiMethod delegate = (PsiMethod)changeInfo.getMethod().copy();
final PsiClass targetClass = changeInfo.getMethod().getContainingClass();
LOG.assertTrue(!targetClass.isInterface());
PsiElementFactory factory = JavaPsiFacade.getElementFactory(targetClass.getProject());
ChangeSignatureProcessor.makeEmptyBody(factory, delegate);
final PsiCallExpression callExpression = ChangeSignatureProcessor.addDelegatingCallTemplate(delegate, changeInfo.getNewName());
addDelegateArguments(changeInfo, factory, callExpression);
targetClass.addBefore(delegate, changeInfo.getMethod());
}
private static void addDelegateArguments(JavaChangeInfo changeInfo, PsiElementFactory factory, final PsiCallExpression callExpression) throws IncorrectOperationException {
final JavaParameterInfo[] newParms = changeInfo.getNewParameters();
final String[] oldParameterNames = changeInfo.getOldParameterNames();
for (int i = 0; i < newParms.length; i++) {
JavaParameterInfo newParm = newParms[i];
final PsiExpression actualArg;
if (newParm.getOldIndex() >= 0) {
actualArg = factory.createExpressionFromText(oldParameterNames[newParm.getOldIndex()], callExpression);
}
else {
actualArg = changeInfo.getValue(i, callExpression);
}
callExpression.getArgumentList().add(actualArg);
}
}
private static void processPrimaryMethod(JavaChangeInfo changeInfo, PsiMethod method,
PsiMethod baseMethod,
boolean isOriginal) throws IncorrectOperationException {
PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();
if (changeInfo.isVisibilityChanged()) {
PsiModifierList modifierList = method.getModifierList();
final String highestVisibility = isOriginal
? changeInfo.getNewVisibility()
: VisibilityUtil.getHighestVisibility(changeInfo.getNewVisibility(),
VisibilityUtil.getVisibilityModifier(modifierList));
VisibilityUtil.setVisibility(modifierList, highestVisibility);
}
if (changeInfo.isNameChanged()) {
String newName = baseMethod == null ? changeInfo.getNewName() :
RefactoringUtil.suggestNewOverriderName(method.getName(), baseMethod.getName(), changeInfo.getNewName());
if (newName != null && !newName.equals(method.getName())) {
final PsiIdentifier nameId = method.getNameIdentifier();
assert nameId != null;
nameId.replace(JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createIdentifier(newName));
}
}
final PsiSubstitutor substitutor =
baseMethod == null ? PsiSubstitutor.EMPTY : ChangeSignatureProcessor.calculateSubstitutor(method, baseMethod);
if (changeInfo.isReturnTypeChanged()) {
PsiType newTypeElement = changeInfo.getNewReturnType().getType(changeInfo.getMethod().getParameterList(), method.getManager());
final PsiType returnType = substitutor.substitute(newTypeElement);
// don't modify return type for non-Java overriders (EJB)
if (method.getName().equals(changeInfo.getNewName())) {
final PsiTypeElement typeElement = method.getReturnTypeElement();
if (typeElement != null) {
typeElement.replace(factory.createTypeElement(returnType));
}
}
}
PsiParameterList list = method.getParameterList();
PsiParameter[] parameters = list.getParameters();
final JavaParameterInfo[] parameterInfos = changeInfo.getNewParameters();
PsiParameter[] newParms = new PsiParameter[parameterInfos.length -
(baseMethod != null ? baseMethod.getParameterList().getParametersCount() -
method.getParameterList().getParametersCount() : 0)];
final String[] oldParameterNames = changeInfo.getOldParameterNames();
final String[] oldParameterTypes = changeInfo.getOldParameterTypes();
for (int i = 0; i < newParms.length; i++) {
JavaParameterInfo info = parameterInfos[i];
int index = info.getOldIndex();
if (index >= 0) {
PsiParameter parameter = parameters[index];
newParms[i] = parameter;
String oldName = oldParameterNames[index];
if (!oldName.equals(info.getName()) && oldName.equals(parameter.getName())) {
PsiIdentifier newIdentifier = factory.createIdentifier(info.getName());
parameter.getNameIdentifier().replace(newIdentifier);
}
String oldType = oldParameterTypes[index];
if (!oldType.equals(info.getTypeText())) {
parameter.normalizeDeclaration();
PsiType newType = substitutor.substitute(info.createType(changeInfo.getMethod().getParameterList(), method.getManager()));
parameter.getTypeElement().replace(factory.createTypeElement(newType));
}
}
else {
newParms[i] = createNewParameter(changeInfo, info, substitutor);
}
}
resolveParameterVsFieldsConflicts(newParms, method, list, changeInfo.toRemoveParm());
fixJavadocsForChangedMethod(method, changeInfo, newParms.length);
if (changeInfo.isExceptionSetOrOrderChanged()) {
final PsiClassType[] newExceptions = getPrimaryChangedExceptionInfo(changeInfo);
fixPrimaryThrowsLists(method, newExceptions);
}
}
private static PsiClassType[] getPrimaryChangedExceptionInfo(JavaChangeInfo changeInfo) throws IncorrectOperationException {
final ThrownExceptionInfo[] newExceptionInfos = changeInfo.getNewExceptions();
PsiClassType[] newExceptions = new PsiClassType[newExceptionInfos.length];
final PsiMethod method = changeInfo.getMethod();
for (int i = 0; i < newExceptions.length; i++) {
newExceptions[i] =
(PsiClassType)newExceptionInfos[i].createType(method, method.getManager()); //context really does not matter here
}
return newExceptions;
}
private static void processCallerMethod(JavaChangeInfo changeInfo, PsiMethod caller,
PsiMethod baseMethod,
boolean toInsertParams,
boolean toInsertThrows) throws IncorrectOperationException {
LOG.assertTrue(toInsertParams || toInsertThrows);
if (toInsertParams) {
List<PsiParameter> newParameters = new ArrayList<PsiParameter>();
newParameters.addAll(Arrays.asList(caller.getParameterList().getParameters()));
final JavaParameterInfo[] primaryNewParms = changeInfo.getNewParameters();
PsiSubstitutor substitutor =
baseMethod == null ? PsiSubstitutor.EMPTY : ChangeSignatureProcessor.calculateSubstitutor(caller, baseMethod);
for (JavaParameterInfo info : primaryNewParms) {
if (info.getOldIndex() < 0) newParameters.add(createNewParameter(changeInfo, info, substitutor));
}
PsiParameter[] arrayed = newParameters.toArray(new PsiParameter[newParameters.size()]);
boolean[] toRemoveParm = new boolean[arrayed.length];
Arrays.fill(toRemoveParm, false);
resolveParameterVsFieldsConflicts(arrayed, caller, caller.getParameterList(), toRemoveParm);
}
if (toInsertThrows) {
List<PsiJavaCodeReferenceElement> newThrowns = new ArrayList<PsiJavaCodeReferenceElement>();
final PsiReferenceList throwsList = caller.getThrowsList();
newThrowns.addAll(Arrays.asList(throwsList.getReferenceElements()));
final ThrownExceptionInfo[] primaryNewExns = changeInfo.getNewExceptions();
for (ThrownExceptionInfo thrownExceptionInfo : primaryNewExns) {
if (thrownExceptionInfo.getOldIndex() < 0) {
final PsiClassType type = (PsiClassType)thrownExceptionInfo.createType(caller, caller.getManager());
final PsiJavaCodeReferenceElement ref =
JavaPsiFacade.getInstance(caller.getProject()).getElementFactory().createReferenceElementByType(type);
newThrowns.add(ref);
}
}
PsiJavaCodeReferenceElement[] arrayed = newThrowns.toArray(new PsiJavaCodeReferenceElement[newThrowns.size()]);
boolean[] toRemoveParm = new boolean[arrayed.length];
Arrays.fill(toRemoveParm, false);
ChangeSignatureUtil.synchronizeList(throwsList, Arrays.asList(arrayed), ThrowsList.INSTANCE, toRemoveParm);
}
}
private static void fixPrimaryThrowsLists(PsiMethod method, PsiClassType[] newExceptions) throws IncorrectOperationException {
PsiElementFactory elementFactory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();
PsiJavaCodeReferenceElement[] refs = new PsiJavaCodeReferenceElement[newExceptions.length];
for (int i = 0; i < refs.length; i++) {
refs[i] = elementFactory.createReferenceElementByType(newExceptions[i]);
}
PsiReferenceList throwsList = elementFactory.createReferenceList(refs);
PsiReferenceList methodThrowsList = (PsiReferenceList)method.getThrowsList().replace(throwsList);
methodThrowsList = (PsiReferenceList)JavaCodeStyleManager.getInstance(method.getProject()).shortenClassReferences(methodThrowsList);
method.getManager().getCodeStyleManager().reformatRange(method, method.getParameterList().getTextRange().getEndOffset(),
methodThrowsList.getTextRange().getEndOffset());
}
private static void fixJavadocsForChangedMethod(PsiMethod method, JavaChangeInfo changeInfo, int newParamsLength) throws IncorrectOperationException {
final PsiParameter[] parameters = method.getParameterList().getParameters();
final JavaParameterInfo[] newParms = changeInfo.getNewParameters();
LOG.assertTrue(parameters.length <= newParamsLength);
final Set<PsiParameter> newParameters = new HashSet<PsiParameter>();
final String[] oldParameterNames = changeInfo.getOldParameterNames();
for (int i = 0; i < newParamsLength; i++) {
JavaParameterInfo newParm = newParms[i];
if (newParm.getOldIndex() < 0 ||
!newParm.getName().equals(oldParameterNames[newParm.getOldIndex()])) {
newParameters.add(parameters[i]);
}
}
RefactoringUtil.fixJavadocsForParams(method, newParameters);
}
private static PsiParameter createNewParameter(JavaChangeInfo changeInfo, JavaParameterInfo newParm,
PsiSubstitutor substitutor) throws IncorrectOperationException {
final PsiParameterList list = changeInfo.getMethod().getParameterList();
final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory();
final PsiType type = substitutor.substitute(newParm.createType(list, list.getManager()));
return factory.createParameter(newParm.getName(), type);
}
private static void resolveParameterVsFieldsConflicts(final PsiParameter[] newParms,
final PsiMethod method,
final PsiParameterList list,
boolean[] toRemoveParm) throws IncorrectOperationException {
List<FieldConflictsResolver> conflictResolvers = new ArrayList<FieldConflictsResolver>();
for (PsiParameter parameter : newParms) {
conflictResolvers.add(new FieldConflictsResolver(parameter.getName(), method.getBody()));
}
ChangeSignatureUtil.synchronizeList(list, Arrays.asList(newParms), ParameterList.INSTANCE, toRemoveParm);
JavaCodeStyleManager.getInstance(list.getProject()).shortenClassReferences(list);
for (FieldConflictsResolver fieldConflictsResolver : conflictResolvers) {
fieldConflictsResolver.fix();
}
}
private static boolean needToCatchExceptions(JavaChangeInfo changeInfo, PsiMethod caller) {
return changeInfo.isExceptionSetOrOrderChanged() &&
!(changeInfo instanceof JavaChangeInfoImpl && ((JavaChangeInfoImpl)changeInfo).propagateExceptionsMethods.contains(caller));
}
private static class ParameterList implements ChangeSignatureUtil.ChildrenGenerator<PsiParameterList, PsiParameter> {
public static final ParameterList INSTANCE = new ParameterList();
public List<PsiParameter> getChildren(PsiParameterList psiParameterList) {
return Arrays.asList(psiParameterList.getParameters());
}
}
private static class ThrowsList implements ChangeSignatureUtil.ChildrenGenerator<PsiReferenceList, PsiJavaCodeReferenceElement> {
public static final ThrowsList INSTANCE = new ThrowsList();
public List<PsiJavaCodeReferenceElement> getChildren(PsiReferenceList throwsList) {
return Arrays.asList(throwsList.getReferenceElements());
}
}
private static class ConflictSearcher {
private final JavaChangeInfo myChangeInfo;
private ConflictSearcher(JavaChangeInfo changeInfo) {
this.myChangeInfo = changeInfo;
}
public MultiMap<PsiElement, String> findConflicts(Ref<UsageInfo[]> refUsages) {
MultiMap<PsiElement, String> conflictDescriptions = new MultiMap<PsiElement, String>();
addMethodConflicts(conflictDescriptions);
Set<UsageInfo> usagesSet = new HashSet<UsageInfo>(Arrays.asList(refUsages.get()));
RenameUtil.removeConflictUsages(usagesSet);
if (myChangeInfo.isVisibilityChanged()) {
try {
addInaccessibilityDescriptions(usagesSet, conflictDescriptions);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
return conflictDescriptions;
}
private boolean needToChangeCalls() {
return myChangeInfo.isNameChanged() || myChangeInfo.isParameterSetOrOrderChanged() || myChangeInfo.isExceptionSetOrOrderChanged();
}
private void addInaccessibilityDescriptions(Set<UsageInfo> usages, MultiMap<PsiElement, String> conflictDescriptions)
throws IncorrectOperationException {
PsiMethod method = myChangeInfo.getMethod();
PsiModifierList modifierList = (PsiModifierList)method.getModifierList().copy();
VisibilityUtil.setVisibility(modifierList, myChangeInfo.getNewVisibility());
for (Iterator<UsageInfo> iterator = usages.iterator(); iterator.hasNext();) {
UsageInfo usageInfo = iterator.next();
PsiElement element = usageInfo.getElement();
if (element != null && StdLanguages.JAVA.equals(element.getLanguage())) {
if (element instanceof PsiReferenceExpression) {
PsiClass accessObjectClass = null;
PsiExpression qualifier = ((PsiReferenceExpression)element).getQualifierExpression();
if (qualifier != null) {
accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement();
}
if (!JavaPsiFacade.getInstance(element.getProject()).getResolveHelper()
.isAccessible(method, modifierList, element, accessObjectClass, null)) {
String message =
RefactoringBundle.message("0.with.1.visibility.is.not.accesible.from.2",
RefactoringUIUtil.getDescription(method, true),
myChangeInfo.getNewVisibility(),
RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true));
conflictDescriptions.putValue(method, message);
if (!needToChangeCalls()) {
iterator.remove();
}
}
}
}
}
}
private void addMethodConflicts(MultiMap<PsiElement, String> conflicts) {
String newMethodName = myChangeInfo.getNewName();
if (!(myChangeInfo instanceof JavaChangeInfo)) {
return;
}
try {
PsiMethod prototype;
final PsiMethod method = myChangeInfo.getMethod();
if (!StdLanguages.JAVA.equals(method.getLanguage())) return;
PsiManager manager = PsiManager.getInstance(method.getProject());
PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
final CanonicalTypes.Type returnType = myChangeInfo.getNewReturnType();
if (returnType != null) {
prototype = factory.createMethod(newMethodName, returnType.getType(method, manager));
}
else {
prototype = factory.createConstructor();
prototype.setName(newMethodName);
}
JavaParameterInfo[] parameters = myChangeInfo.getNewParameters();
for (JavaParameterInfo info : parameters) {
PsiType parameterType = info.createType(method, manager);
if (parameterType == null) {
parameterType =
JavaPsiFacade.getElementFactory(method.getProject()).createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, method);
}
PsiParameter param = factory.createParameter(info.getName(), parameterType);
prototype.getParameterList().add(param);
}
ConflictsUtil.checkMethodConflicts(method.getContainingClass(), method, prototype, conflicts);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
}
private static class ExpressionList implements ChangeSignatureUtil.ChildrenGenerator<PsiExpressionList, PsiExpression> {
public static final ExpressionList INSTANCE = new ExpressionList();
public List<PsiExpression> getChildren(PsiExpressionList psiExpressionList) {
return Arrays.asList(psiExpressionList.getExpressions());
}
}
}
@@ -0,0 +1,317 @@
/*
* Copyright 2000-2010 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.changeSignature;
import com.intellij.lang.StdLanguages;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocTagValue;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.MethodReferencesSearch;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.xml.XmlElement;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.rename.JavaUnresolvableLocalCollisionDetector;
import com.intellij.refactoring.rename.UnresolvableCollisionUsageInfo;
import com.intellij.refactoring.util.MoveRenameUsageInfo;
import com.intellij.refactoring.util.RefactoringUIUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.refactoring.util.usageInfo.DefaultConstructorImplicitUsageInfo;
import com.intellij.refactoring.util.usageInfo.NoConstructorClassUsageInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.containers.HashSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Set;
/**
* @author Maxim.Medvedev
*/
class JavaChangeSignatureUsageSearcher {
private final JavaChangeInfo myChangeInfo;
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.JavaChangeSignatureUsageSearcher");
JavaChangeSignatureUsageSearcher(JavaChangeInfo changeInfo) {
this.myChangeInfo = changeInfo;
}
public UsageInfo[] findUsages() {
ArrayList<UsageInfo> result = new ArrayList<UsageInfo>();
final PsiElement element = myChangeInfo.getMethod();
if (element instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)element;
findSimpleUsages(method, result);
final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]);
return UsageViewUtil.removeDuplicatedUsages(usageInfos);
}
return UsageInfo.EMPTY_ARRAY;
}
private void findSimpleUsages(final PsiMethod method, final ArrayList<UsageInfo> result) {
PsiMethod[] overridingMethods = findSimpleUsagesWithoutParameters(method, result, true, true, true);
findUsagesInCallers(result);
//Parameter name changes are not propagated
findParametersUsage(method, result, overridingMethods);
}
private void findUsagesInCallers(final ArrayList<UsageInfo> usages) {
if (myChangeInfo instanceof JavaChangeInfoImpl) {
JavaChangeInfoImpl changeInfo = (JavaChangeInfoImpl)myChangeInfo;
for (PsiMethod caller : changeInfo.propagateParametersMethods) {
usages.add(new CallerUsageInfo(caller, true, changeInfo.propagateExceptionsMethods.contains(caller)));
}
for (PsiMethod caller : changeInfo.propagateExceptionsMethods) {
usages.add(new CallerUsageInfo(caller, changeInfo.propagateParametersMethods.contains(caller), true));
}
Set<PsiMethod> merged = new HashSet<PsiMethod>();
merged.addAll(changeInfo.propagateParametersMethods);
merged.addAll(changeInfo.propagateExceptionsMethods);
for (final PsiMethod method : merged) {
findSimpleUsagesWithoutParameters(method, usages, changeInfo.propagateParametersMethods.contains(method),
changeInfo.propagateExceptionsMethods.contains(method), false);
}
}
}
private void detectLocalsCollisionsInMethod(final PsiMethod method, final ArrayList<UsageInfo> result, boolean isOriginal) {
if (!StdLanguages.JAVA.equals(method.getLanguage())) return;
final PsiParameter[] parameters = method.getParameterList().getParameters();
final Set<PsiParameter> deletedOrRenamedParameters = new HashSet<PsiParameter>();
if (isOriginal) {
deletedOrRenamedParameters.addAll(Arrays.asList(parameters));
for (ParameterInfo parameterInfo : myChangeInfo.getNewParameters()) {
if (parameterInfo.getOldIndex() >= 0 && parameterInfo.getOldIndex() < parameters.length) {
final PsiParameter parameter = parameters[parameterInfo.getOldIndex()];
if (parameterInfo.getName().equals(parameter.getName())) {
deletedOrRenamedParameters.remove(parameter);
}
}
}
}
for (ParameterInfo parameterInfo : myChangeInfo.getNewParameters()) {
final int oldParameterIndex = parameterInfo.getOldIndex();
final String newName = parameterInfo.getName();
if (oldParameterIndex >= 0 && oldParameterIndex < parameters.length) {
if (isOriginal) { //Name changes take place only in primary method
final PsiParameter parameter = parameters[oldParameterIndex];
if (!newName.equals(parameter.getName())) {
JavaUnresolvableLocalCollisionDetector.visitLocalsCollisions(
parameter, newName, method.getBody(), null,
new JavaUnresolvableLocalCollisionDetector.CollidingVariableVisitor() {
public void visitCollidingElement(final PsiVariable collidingVariable) {
if (!deletedOrRenamedParameters.contains(collidingVariable)) {
result.add(new RenamedParameterCollidesWithLocalUsageInfo(parameter, collidingVariable, method));
}
}
});
}
}
}
else {
JavaUnresolvableLocalCollisionDetector.visitLocalsCollisions(
method, newName, method.getBody(), null,
new JavaUnresolvableLocalCollisionDetector.CollidingVariableVisitor() {
public void visitCollidingElement(PsiVariable collidingVariable) {
if (!deletedOrRenamedParameters.contains(collidingVariable)) {
result.add(new NewParameterCollidesWithLocalUsageInfo(
collidingVariable, collidingVariable, method));
}
}
});
}
}
}
private void findParametersUsage(final PsiMethod method, ArrayList<UsageInfo> result, PsiMethod[] overriders) {
if (StdLanguages.JAVA.equals(myChangeInfo.getLanguage())) {
PsiParameter[] parameters = method.getParameterList().getParameters();
for (ParameterInfo info : myChangeInfo.getNewParameters()) {
if (info.getOldIndex() >= 0) {
PsiParameter parameter = parameters[info.getOldIndex()];
if (!info.getName().equals(parameter.getName())) {
addParameterUsages(parameter, result, info);
for (PsiMethod overrider : overriders) {
PsiParameter parameter1 = overrider.getParameterList().getParameters()[info.getOldIndex()];
if (parameter.getName().equals(parameter1.getName())) {
addParameterUsages(parameter1, result, info);
}
}
}
}
}
}
}
private static boolean shouldPropagateToNonPhysicalMethod(PsiMethod method,
ArrayList<UsageInfo> result,
PsiClass containingClass,
final Set<PsiMethod> propagateMethods) {
for (PsiMethod psiMethod : propagateMethods) {
if (!psiMethod.isPhysical() && Comparing.strEqual(psiMethod.getName(), containingClass.getName())) {
result.add(new DefaultConstructorImplicitUsageInfo(psiMethod, containingClass, method));
return true;
}
}
return false;
}
private PsiMethod[] findSimpleUsagesWithoutParameters(final PsiMethod method,
final ArrayList<UsageInfo> result,
boolean isToModifyArgs,
boolean isToThrowExceptions,
boolean isOriginal) {
GlobalSearchScope projectScope = GlobalSearchScope.projectScope(method.getProject());
PsiMethod[] overridingMethods = OverridingMethodsSearch.search(method, method.getUseScope(), true).toArray(PsiMethod.EMPTY_ARRAY);
for (PsiMethod overridingMethod : overridingMethods) {
result.add(new OverriderUsageInfo(overridingMethod, method, isOriginal, isToModifyArgs, isToThrowExceptions));
}
boolean needToChangeCalls =
!myChangeInfo.isGenerateDelegate() && (myChangeInfo.isNameChanged() ||
myChangeInfo.isParameterSetOrOrderChanged() ||
myChangeInfo.isExceptionSetOrOrderChanged() ||
myChangeInfo.isVisibilityChanged()/*for checking inaccessible*/);
if (needToChangeCalls) {
int parameterCount = method.getParameterList().getParametersCount();
PsiReference[] refs = MethodReferencesSearch.search(method, projectScope, true).toArray(PsiReference.EMPTY_ARRAY);
for (PsiReference ref : refs) {
PsiElement element = ref.getElement();
boolean isToCatchExceptions = isToThrowExceptions && needToCatchExceptions(RefactoringUtil.getEnclosingMethod(element));
if (!isToCatchExceptions) {
if (RefactoringUtil.isMethodUsage(element)) {
PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(element);
if (!method.isVarArgs() && list.getExpressions().length != parameterCount) continue;
}
}
if (RefactoringUtil.isMethodUsage(element)) {
result.add(new MethodCallUsageInfo(element, isToModifyArgs, isToCatchExceptions));
}
else if (element instanceof PsiDocTagValue) {
result.add(new UsageInfo(element));
}
else if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) {
if (StdLanguages.JAVA.equals(element.getLanguage())) {
DefaultConstructorImplicitUsageInfo implicitUsageInfo =
new DefaultConstructorImplicitUsageInfo((PsiMethod)element, ((PsiMethod)element).getContainingClass(), method);
result.add(implicitUsageInfo);
}
}
else if (element instanceof PsiClass) {
LOG.assertTrue(method.isConstructor());
final PsiClass psiClass = (PsiClass)element;
if (StdLanguages.JAVA.equals(psiClass.getLanguage())) {
if (myChangeInfo instanceof JavaChangeInfoImpl) {
if (shouldPropagateToNonPhysicalMethod(method, result, psiClass,
((JavaChangeInfoImpl)myChangeInfo).propagateParametersMethods)) {
continue;
}
if (shouldPropagateToNonPhysicalMethod(method, result, psiClass,
((JavaChangeInfoImpl)myChangeInfo).propagateExceptionsMethods)) {
continue;
}
}
result.add(new NoConstructorClassUsageInfo(psiClass));
}
}
else if (ref instanceof PsiCallReference) {
result.add(new CallReferenceUsageInfo((PsiCallReference)ref));
}
else {
result.add(new MoveRenameUsageInfo(element, ref, method));
}
}
//if (method.isConstructor() && parameterCount == 0) {
// RefactoringUtil.visitImplicitConstructorUsages(method.getContainingClass(),
// new DefaultConstructorUsageCollector(result));
//}
}
else if (myChangeInfo.isParameterTypesChanged()) {
PsiReference[] refs = MethodReferencesSearch.search(method, projectScope, true).toArray(PsiReference.EMPTY_ARRAY);
for (PsiReference reference : refs) {
final PsiElement element = reference.getElement();
if (element instanceof PsiDocTagValue) {
result.add(new UsageInfo(reference));
}
else if (element instanceof XmlElement) {
result.add(new MoveRenameUsageInfo(reference, method));
}
}
}
// Conflicts
detectLocalsCollisionsInMethod(method, result, isOriginal);
for (final PsiMethod overridingMethod : overridingMethods) {
detectLocalsCollisionsInMethod(overridingMethod, result, isOriginal);
}
return overridingMethods;
}
private static void addParameterUsages(PsiParameter parameter, ArrayList<UsageInfo> results, ParameterInfo info) {
PsiManager manager = parameter.getManager();
GlobalSearchScope projectScope = GlobalSearchScope.projectScope(manager.getProject());
for (PsiReference psiReference : ReferencesSearch.search(parameter, projectScope, false)) {
PsiElement parmRef = psiReference.getElement();
UsageInfo usageInfo = new ChangeSignatureParameterUsageInfo(parmRef, parameter.getName(), info.getName());
results.add(usageInfo);
}
}
private boolean needToCatchExceptions(PsiMethod caller) {
if (myChangeInfo instanceof JavaChangeInfoImpl) {
return myChangeInfo.isExceptionSetOrOrderChanged() &&
!((JavaChangeInfoImpl)myChangeInfo).propagateExceptionsMethods.contains(caller);
}
else {
return myChangeInfo.isExceptionSetOrOrderChanged();
}
}
private static class RenamedParameterCollidesWithLocalUsageInfo extends UnresolvableCollisionUsageInfo {
private final PsiElement myCollidingElement;
private final PsiMethod myMethod;
public RenamedParameterCollidesWithLocalUsageInfo(PsiParameter parameter, PsiElement collidingElement, PsiMethod method) {
super(parameter, collidingElement);
myCollidingElement = collidingElement;
myMethod = method;
}
public String getDescription() {
return RefactoringBundle.message("there.is.already.a.0.in.the.1.it.will.conflict.with.the.renamed.parameter",
RefactoringUIUtil.getDescription(myCollidingElement, true),
RefactoringUIUtil.getDescription(myMethod, true));
}
}
}
@@ -0,0 +1,39 @@
/*
* Copyright 2000-2010 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.changeSignature;
import com.intellij.psi.*;
import com.intellij.refactoring.util.CanonicalTypes;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nullable;
/**
* @author Maxim.Medvedev
*/
public interface JavaParameterInfo extends ParameterInfo {
@Nullable
PsiType createType(PsiElement context, final PsiManager manager) throws IncorrectOperationException;
String getTypeText();
CanonicalTypes.Type getTypeWrapper();
PsiExpression getValue(PsiCallExpression callExpression);
boolean isVarargType();
boolean isUseAnySingleVariable();
}
@@ -0,0 +1,68 @@
/*
* Copyright 2000-2010 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.changeSignature;
import com.intellij.psi.*;
import com.intellij.refactoring.util.CanonicalTypes;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nullable;
/**
* @author Maxim.Medvedev
*/
public class JavaThrownExceptionInfo implements ThrownExceptionInfo {
private final int oldIndex;
private CanonicalTypes.Type myType;
public JavaThrownExceptionInfo() {
oldIndex = -1;
}
public JavaThrownExceptionInfo(int oldIndex) {
this.oldIndex = oldIndex;
}
public JavaThrownExceptionInfo(int oldIndex, PsiClassType type) {
this.oldIndex = oldIndex;
setType(type);
}
public void setType(PsiClassType type) {
myType = CanonicalTypes.createTypeWrapper(type);
}
@Nullable
public PsiType createType(PsiElement context, final PsiManager manager) throws IncorrectOperationException {
if (myType != null) {
return myType.getType(context, manager);
}
else {
return null;
}
}
public void updateFromMethod(PsiMethod method) {
if (myType != null) return;
PsiClassType[] types = method.getThrowsList().getReferencedTypes();
if (oldIndex >= 0) {
setType(types[oldIndex]);
}
}
public int getOldIndex() {
return oldIndex;
}
}
@@ -27,6 +27,7 @@ public class MethodCallUsageInfo extends UsageInfo {
private final boolean myToChangeArguments;
private final boolean myToCatchExceptions;
private final PsiMethod myReferencedMethod;
private final PsiSubstitutor mySubstitutor;
public boolean isToCatchExceptions() {
return myToCatchExceptions;
@@ -40,17 +41,19 @@ public class MethodCallUsageInfo extends UsageInfo {
super(ref);
myToChangeArguments = isToChangeArguments;
myToCatchExceptions = isToCatchExceptions;
myReferencedMethod = resolveMethod(ref);
final JavaResolveResult resolveResult = resolveMethod(ref);
myReferencedMethod = (PsiMethod)resolveResult.getElement();
mySubstitutor = resolveResult.getSubstitutor();
}
private static PsiMethod resolveMethod(final PsiElement ref) {
if (ref instanceof PsiEnumConstant) return ((PsiEnumConstant)ref).resolveConstructor();
private static JavaResolveResult resolveMethod(final PsiElement ref) {
if (ref instanceof PsiEnumConstant) return ((PsiEnumConstant)ref).resolveMethodGenerics();
PsiElement parent = ref.getParent();
if (parent instanceof PsiCall) {
return ((PsiCall)parent).resolveMethod();
return ((PsiCall)parent).resolveMethodGenerics();
}
else if (parent instanceof PsiAnonymousClass) {
return ((PsiNewExpression)parent.getParent()).resolveConstructor();
return ((PsiNewExpression)parent.getParent()).resolveMethodGenerics();
}
LOG.error("Unknown reference");
@@ -60,4 +63,8 @@ public class MethodCallUsageInfo extends UsageInfo {
public PsiMethod getReferencedMethod() {
return myReferencedMethod;
}
public PsiSubstitutor getSubstitutor() {
return mySubstitutor;
}
}
@@ -30,7 +30,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class ParameterInfoImpl implements ParameterInfo {
public class ParameterInfoImpl implements JavaParameterInfo {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ParameterInfoImpl");
public final int oldParameterIndex;
boolean useAnySingleVariable;
@@ -116,8 +116,7 @@ class ParameterTableModel extends AbstractTableModel implements RowEditableTable
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (rowIndex < 0 || rowIndex >= myParameterInfos.size()) return;
String s = aValue instanceof String ? (String)aValue : null;
if (s == null) s = "";
String s = aValue instanceof String ? (String)aValue : "";
s = s.trim();
ParameterInfoImpl info = myParameterInfos.get(rowIndex);
switch (columnIndex) {
@@ -186,8 +185,8 @@ class ParameterTableModel extends AbstractTableModel implements RowEditableTable
}
private JavaCodeFragment createDefaultValueCodeFragment(final String expressionText, final PsiType expectedType) {
PsiExpressionCodeFragment codeFragment = JavaPsiFacade.getInstance(myParameterList.getProject()).getElementFactory().createExpressionCodeFragment(expressionText,
myReferenceExpression, expectedType, true);
PsiExpressionCodeFragment codeFragment = JavaPsiFacade.getInstance(myParameterList.getProject()).getElementFactory()
.createExpressionCodeFragment(expressionText, myReferenceExpression, expectedType, true);
codeFragment.setVisibilityChecker(JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE);
return codeFragment;
}
@@ -16,59 +16,19 @@
package com.intellij.refactoring.changeSignature;
import com.intellij.psi.*;
import com.intellij.refactoring.util.CanonicalTypes;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nullable;
/**
* @author ven
*/
public class ThrownExceptionInfo {
int oldIndex;
CanonicalTypes.Type myType;
public interface ThrownExceptionInfo {
void setType(PsiClassType type);
public ThrownExceptionInfo() {
oldIndex = -1;
}
@Nullable
PsiType createType(PsiElement context, final PsiManager manager) throws IncorrectOperationException;
public ThrownExceptionInfo(int oldIndex) {
this.oldIndex = oldIndex;
}
void updateFromMethod(PsiMethod method);
public ThrownExceptionInfo(int oldIndex, PsiClassType type) {
this.oldIndex = oldIndex;
setType(type);
}
public void setType(PsiClassType type) {
myType = CanonicalTypes.createTypeWrapper(type);
}
public PsiType createType(PsiElement context, final PsiManager manager) throws IncorrectOperationException {
if (myType != null) {
return myType.getType(context, manager);
} else {
return null;
}
}
String getTypeText() {
if (myType != null) {
return myType.getTypeText();
}
else {
return "";
}
}
public void updateFromMethod(PsiMethod method) {
if (myType != null) return;
PsiClassType[] types = method.getThrowsList().getReferencedTypes();
if (oldIndex >= 0) {
setType(types[oldIndex]);
}
}
public int getOldIndex() {
return oldIndex;
}
int getOldIndex();
}
@@ -636,11 +636,7 @@ public class ExtractMethodProcessor implements MatchProvider {
if (myNullConditionalCheck) {
final String varName = myOutputVariable.getName();
if (isDeclaredInside(myOutputVariable)) {
PsiDeclarationStatement statement = (PsiDeclarationStatement)myElementFactory
.createStatementFromText(myOutputVariable.getType().getCanonicalText() + " " + varName + "=x;", null);
statement = (PsiDeclarationStatement)addToMethodCallLocation(statement);
myMethodCall =
(PsiMethodCallExpression)((PsiLocalVariable)statement.getDeclaredElements()[0]).getInitializer().replace(myMethodCall);
declareVariableAtMethodCallLocation(varName);
}
else {
PsiExpressionStatement assignmentExpression =
@@ -676,12 +672,7 @@ public class ExtractMethodProcessor implements MatchProvider {
myMethodCall = (PsiMethodCallExpression)assignment.getRExpression().replace(myMethodCall);
}
else {
PsiDeclarationStatement statement =
myElementFactory.createVariableDeclarationStatement(name, myOutputVariable.getType(), myMethodCall);
statement = (PsiDeclarationStatement)addToMethodCallLocation(statement);
PsiVariable var = (PsiVariable)statement.getDeclaredElements()[0];
myMethodCall = (PsiMethodCallExpression)var.getInitializer();
var.getModifierList().replace(myOutputVariable.getModifierList());
declareVariableAtMethodCallLocation(name);
}
}
else if (myHasReturnStatementOutput) {
@@ -737,6 +728,15 @@ public class ExtractMethodProcessor implements MatchProvider {
}
private void declareVariableAtMethodCallLocation(String name) {
PsiDeclarationStatement statement =
myElementFactory.createVariableDeclarationStatement(name, myOutputVariable.getType(), myMethodCall);
statement = (PsiDeclarationStatement)addToMethodCallLocation(statement);
PsiVariable var = (PsiVariable)statement.getDeclaredElements()[0];
myMethodCall = (PsiMethodCallExpression)var.getInitializer();
var.getModifierList().replace(myOutputVariable.getModifierList());
}
private void adjustFinalParameters(final PsiMethod method) throws IncorrectOperationException {
final IncorrectOperationException[] exc = new IncorrectOperationException[1];
exc[0] = null;
@@ -133,8 +133,8 @@ public class ExtractSuperclassHandler implements RefactoringActionHandler, Extra
else {
targetPackage = null;
}
MultiMap<PsiElement,String> conflicts =
PullUpConflictsUtil.checkConflicts(infos, mySubclass, null, targetPackage, targetDirectory, dialog.getContainmentVerifier());
final MultiMap<PsiElement,String> conflicts =
PullUpConflictsUtil.checkConflicts(infos, mySubclass, mySubclass.getSuperClass(), targetPackage, targetDirectory, dialog.getContainmentVerifier());
if (!conflicts.isEmpty()) {
ConflictsDialog conflictsDialog = new ConflictsDialog(myProject, conflicts);
conflictsDialog.show();
@@ -34,14 +34,16 @@ import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.ReferenceEditorComboWithBrowseButton;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.util.ArrayList;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;
import java.util.Map;
@SuppressWarnings({"OverridableMethodCallInConstructor"})
class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeListener<PsiMember, MemberInfo> {
@@ -53,6 +55,8 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
private final JTextField sourceClassTextField;
private JCheckBox myGenerateAccessorsCb;
private final VisibilityPanel myVisibilityPanel;
private JCheckBox extractAsEnum;
private List<MemberInfo> enumConstants = new ArrayList<MemberInfo>();
ExtractClassDialog(PsiClass sourceClass, PsiMember selectedMember) {
super(sourceClass.getProject(), true);
@@ -93,10 +97,19 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
}
};
memberInfo = MemberInfo.extractClassMembers(this.sourceClass, filter, false);
extractAsEnum = new JCheckBox("Extract as enum");
boolean hasConstants = false;
for (MemberInfo info : memberInfo) {
if (info.getMember().equals(selectedMember)) {
final PsiMember member = info.getMember();
if (member.equals(selectedMember)) {
info.setChecked(true);
}
if (!hasConstants && member instanceof PsiField && member.hasModifierProperty(PsiModifier.FINAL) && member.hasModifierProperty(PsiModifier.STATIC)) {
hasConstants = true;
}
}
if (!hasConstants) {
extractAsEnum.setVisible(false);
}
super.init();
sourceClassTextField.setText(sourceClass.getQualifiedName());
@@ -111,7 +124,13 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
final String newClassName = getClassName();
final String packageName = getPackageName();
final ExtractClassProcessor processor = new ExtractClassProcessor(sourceClass, fields, methods, classes, packageName, newClassName, myVisibilityPanel.getVisibility(), isGenerateAccessors());
Collections.sort(enumConstants, new Comparator<MemberInfo>() {
public int compare(MemberInfo o1, MemberInfo o2) {
return o1.getMember().getTextOffset() - o2.getMember().getTextOffset();
}
});
final ExtractClassProcessor processor = new ExtractClassProcessor(sourceClass, fields, methods, classes, packageName, newClassName, myVisibilityPanel.getVisibility(), isGenerateAccessors(),
isExtractAsEnum() ? enumConstants : Collections.<MemberInfo>emptyList());
invokeRefactoring(processor);
}
@@ -180,6 +199,10 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
return myGenerateAccessorsCb.isSelected();
}
public boolean isExtractAsEnum() {
return extractAsEnum.isVisible() && extractAsEnum.isEnabled() && extractAsEnum.isSelected();
}
protected String getDimensionServiceKey() {
return "RefactorJ.ExtractClass";
}
@@ -200,6 +223,7 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
final JPanel classNamePanel = new JPanel(new BorderLayout());
classNamePanel.add(classNameLabel, BorderLayout.NORTH);
classNamePanel.add(classNameField, BorderLayout.CENTER);
classNamePanel.add(extractAsEnum, BorderLayout.SOUTH);
box.add(classNamePanel);
box.add(Box.createVerticalStrut(5));
@@ -221,12 +245,40 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
protected JComponent createCenterPanel() {
final JPanel panel = new JPanel(new BorderLayout());
final MemberSelectionPanel memberSelectionPanel =
new MemberSelectionPanel(RefactorJBundle.message("members.to.extract.label"), memberInfo, null);
new MemberSelectionPanel(RefactorJBundle.message("members.to.extract.label"), memberInfo, "as enum"){
@Override
protected MemberSelectionTable createMemberSelectionTable(final List<MemberInfo> memberInfo, String abstractColumnHeader) {
return new MemberSelectionTable(memberInfo, abstractColumnHeader) {
@Nullable
@Override
protected Object getAbstractColumnValue(MemberInfo memberInfo) {
if (isExtractAsEnum()) {
final PsiMember member = memberInfo.getMember();
if (isConstantField(member)) {
return Boolean.valueOf(enumConstants.contains(memberInfo));
}
}
return null;
}
@Override
protected boolean isAbstractColumnEditable(int rowIndex) {
final MemberInfo info = memberInfo.get(rowIndex);
if (info.isChecked()) {
final PsiMember member = info.getMember();
if (isConstantField(member)) {
if (enumConstants.isEmpty()) return true;
final MemberInfo currentEnumConstant = enumConstants.get(0);
if (((PsiField)currentEnumConstant.getMember()).getType().equals(((PsiField)member).getType())) return true;
}
}
return false;
}
};
}
};
final MemberSelectionTable table = memberSelectionPanel.getTable();
table.setMemberInfoModel(new DelegatingMemberInfoModel<PsiMember, MemberInfo>(table.getMemberInfoModel()) {
public Boolean isFixedAbstract(MemberInfo member) {
return Boolean.TRUE;
}
@Override
public int checkForProblems(@NotNull final MemberInfo member) {
@@ -274,7 +326,11 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
});
panel.add(memberSelectionPanel, BorderLayout.CENTER);
table.addMemberInfoChangeListener(this);
extractAsEnum.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
table.repaint();
}
});
myGenerateAccessorsCb = new JCheckBox("Generate accessors");
myGenerateAccessorsCb.setMnemonic('G');
panel.add(myGenerateAccessorsCb, BorderLayout.SOUTH);
@@ -283,6 +339,13 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
return panel;
}
private static boolean isConstantField(PsiMember member) {
return member instanceof PsiField &&
member.hasModifierProperty(PsiModifier.STATIC) &&
member.hasModifierProperty(PsiModifier.FINAL) &&
((PsiField)member).hasInitializer();
}
public JComponent getPreferredFocusedComponent() {
return classNameField;
}
@@ -295,5 +358,34 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
public void memberInfoChanged(MemberInfoChange memberInfoChange) {
validateButtons();
myMember2CauseMap.clear();
if (extractAsEnum.isVisible()) {
for (Object info : memberInfoChange.getChangedMembers()) {
if (((MemberInfo)info).isToAbstract()) {
enumConstants.add((MemberInfo)info);
} else {
enumConstants.remove((MemberInfo)info);
}
}
extractAsEnum.setEnabled(canExtractEnum());
}
}
private boolean canExtractEnum() {
final List<PsiField> fields = new ArrayList<PsiField>();
final List<PsiClass> innerClasses = new ArrayList<PsiClass>();
final List<PsiMethod> methods = new ArrayList<PsiMethod>();
for (MemberInfo info : memberInfo) {
if (info.isChecked()) {
final PsiMember member = info.getMember();
if (member instanceof PsiField) {
fields.add((PsiField)member);
} else if (member instanceof PsiMethod) {
methods.add((PsiMethod)member);
} else if (member instanceof PsiClass) {
innerClasses.add((PsiClass)member);
}
}
}
return !new BackpointerUsageVisitor(fields, innerClasses, methods, sourceClass).backpointerRequired();
}
}
@@ -43,7 +43,9 @@ import com.intellij.refactoring.psi.MethodInheritanceUtils;
import com.intellij.refactoring.psi.TypeParametersVisitor;
import com.intellij.refactoring.util.FixableUsageInfo;
import com.intellij.refactoring.util.FixableUsagesRefactoringProcessor;
import com.intellij.refactoring.util.RefactoringUIUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.refactoring.util.classMembers.MemberInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import com.intellij.util.IncorrectOperationException;
@@ -66,6 +68,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
private final String newPackageName;
private final String myNewVisibility;
private final boolean myGenerateAccessors;
private final List<PsiField> enumConstants;
private final String newClassName;
private final String delegateFieldName;
private final boolean requiresBackpointer;
@@ -77,7 +80,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
List<PsiClass> innerClasses,
String newPackageName,
String newClassName) {
this(sourceClass, fields, methods, innerClasses, newPackageName, newClassName, null, false);
this(sourceClass, fields, methods, innerClasses, newPackageName, newClassName, null, false, Collections.<MemberInfo>emptyList());
}
public ExtractClassProcessor(PsiClass sourceClass,
@@ -87,12 +90,16 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
String packageName,
String newClassName,
String newVisibility,
boolean generateAccessors) {
boolean generateAccessors, List<MemberInfo> enumConstants) {
super(sourceClass.getProject());
this.sourceClass = sourceClass;
this.newPackageName = packageName;
myNewVisibility = newVisibility;
myGenerateAccessors = generateAccessors;
this.enumConstants = new ArrayList<PsiField>();
for (MemberInfo constant : enumConstants) {
this.enumConstants.add((PsiField)constant.getMember());
}
this.fields = new ArrayList<PsiField>(fields);
this.methods = new ArrayList<PsiMethod>(methods);
this.innerClasses = new ArrayList<PsiClass>(classes);
@@ -146,6 +153,21 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
conflicts.putValue(field, "Field \'" + field.getName() + "\' needs setter");
}
}
for (final PsiField enumConstant : enumConstants) {
final PsiExpression initializer = enumConstant.getInitializer();
assert initializer != null;
initializer.accept(new JavaRecursiveElementWalkingVisitor(){
@Override
public void visitReferenceExpression(PsiReferenceExpression expression) {
super.visitReferenceExpression(expression);
final PsiElement resolved = expression.resolve();
if (!enumConstants.contains(resolved) && fields.contains(resolved)) {
conflicts.putValue(initializer, "Enum constant " + RefactoringUIUtil.getDescription(enumConstant, false) +
" would forward reference on field " + RefactoringUIUtil.getDescription(resolved, false));
}
}
});
}
return showConflicts(conflicts, refUsages.get());
}
@@ -250,16 +272,14 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
if (moveInitializerToConstructor[0]) {
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
PsiMethod constructor;
final PsiMethod[] constructors = psiClass.getConstructors();
PsiMethod[] constructors = psiClass.getConstructors();
if (constructors.length == 0) {
constructor = elementFactory.createConstructor();
constructor.setName(psiClass.getName());
constructor = (PsiMethod)psiClass.add(constructor);
} else {
constructor = constructors[0];
final PsiMethod constructor = (PsiMethod)elementFactory.createConstructor().setName(psiClass.getName());
constructors = new PsiMethod[] {(PsiMethod)psiClass.add(constructor)};
}
for (PsiMethod constructor : constructors) {
MoveInstanceMembersUtil.moveInitializerToConstructor(elementFactory, constructor, member);
}
MoveInstanceMembersUtil.moveInitializerToConstructor(elementFactory, constructor, member);
}
}
}
@@ -607,7 +627,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
}
else {
usages.add(isStatic
? new ReplaceStaticVariableAccess(exp, qualifiedName)
? new ReplaceStaticVariableAccess(exp, qualifiedName, enumConstants.contains(field))
: new ReplaceInstanceVariableAccess(exp, delegateFieldName, getter, field.getName()));
}
@@ -630,6 +650,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
extractedClassBuilder.setPackageName(newPackageName);
extractedClassBuilder.setOriginalClassName(sourceClass.getQualifiedName());
extractedClassBuilder.setRequiresBackPointer(requiresBackpointer);
extractedClassBuilder.setExtractAsEnum(enumConstants);
for (PsiField field : fields) {
extractedClassBuilder.addField(field);
}
@@ -26,6 +26,7 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.psi.MethodInheritanceUtils;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
@@ -54,6 +55,8 @@ class ExtractedClassBuilder {
private JavaCodeStyleManager myJavaCodeStyleManager;
private Set<PsiField> myFieldsNeedingSetters;
private Set<PsiField> myFieldsNeedingGetter;
private List<PsiField> enumConstantFields;
private PsiType myEnumParameterType;
public void setClassName(String className) {
this.className = className;
@@ -105,10 +108,8 @@ class ExtractedClassBuilder {
if (packageName.length() > 0) out.append("package " + packageName + ';');
out.append("public ");
if (hasAbstractMethod()) {
out.append("abstract ");
}
out.append("class ");
fields.removeAll(enumConstantFields);
out.append(hasEnumConstants() ? "enum " : "class ");
out.append(className);
if (!typeParams.isEmpty()) {
out.append('<');
@@ -152,7 +153,13 @@ class ExtractedClassBuilder {
out.append(' ' + backPointerName + ";");
}
outputFieldsAndInitializers(out);
if (needConstructor() || requiresBackPointer) {
if (hasEnumConstants()) {
final String fieldName = getValueFieldName();
out.append("\n").append("private ").append(myEnumParameterType.getCanonicalText()).append(" ").append(fieldName).append(";\n");
out.append("public ").append(myEnumParameterType.getCanonicalText()).append(" ")
.append(getterName()).append("(){\nreturn ").append(fieldName).append(";\n}\n");
}
if (hasEnumConstants() || needConstructor() || requiresBackPointer) {
outputConstructor(out);
}
outputMethods(out);
@@ -161,13 +168,17 @@ class ExtractedClassBuilder {
return out.toString();
}
private boolean hasAbstractMethod() {
for (PsiMethod method : methods) {
if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
return true;
}
}
return false;
private String getterName() {//todo unique getterName: see also com.intellij.refactoring.extractclass.usageInfo.ReplaceStaticVariableAccess
return PropertyUtil.suggestGetterName("value", myEnumParameterType);
}
private boolean hasEnumConstants() {
return !enumConstantFields.isEmpty();
}
private String getValueFieldName() {
final String myValue = myJavaCodeStyleManager.variableNameToPropertyName("value", VariableKind.FIELD);
return myJavaCodeStyleManager.suggestUniqueVariableName(myValue, enumConstantFields.get(0), true);
}
private void calculateBackpointerName() {
@@ -221,7 +232,7 @@ class ExtractedClassBuilder {
private void outputMethods(StringBuffer out) {
for (PsiMethod method : methods) {
outputMutatedMethod(out, method);
method.accept(new Mutator(out));
}
}
@@ -231,16 +242,6 @@ class ExtractedClassBuilder {
}
}
private void outputMutatedInitializer(StringBuffer out, PsiClassInitializer initializer) {
final PsiElementVisitor visitor = new Mutator(out);
initializer.accept(visitor);
}
private void outputMutatedMethod(StringBuffer out, PsiMethod method) {
final PsiElementVisitor visitor = new Mutator(out);
method.accept(visitor);
}
private void outputMutatedInnerClass(StringBuffer out, PsiClass innerClass, boolean makePublic) {
if (makePublic) {
try {
@@ -250,12 +251,26 @@ class ExtractedClassBuilder {
LOGGER.error(e);
}
}
final PsiElementVisitor visitor = new Mutator(out);
innerClass.accept(visitor);
innerClass.accept(new Mutator(out));
}
private void outputFieldsAndInitializers(StringBuffer out) {
private void outputFieldsAndInitializers(final StringBuffer out) {
if (hasEnumConstants()) {
out.append(StringUtil.join(enumConstantFields, new Function<PsiField, String>() {
public String fun(PsiField field) {
final StringBuffer fieldStr = new StringBuffer(field.getName().toUpperCase() + "(");
final PsiExpression initializer = field.getInitializer();
if (initializer != null) {
initializer.accept(new Mutator(fieldStr));
}
fieldStr.append(")");
return fieldStr.toString();
}
}, ", "));
out.append(";");
}
final List<PsiClassInitializer> remainingInitializers = new ArrayList<PsiClassInitializer>(initializers);
for (final PsiField field : fields) {
final Iterator<PsiClassInitializer> initializersIterator = remainingInitializers.iterator();
@@ -263,12 +278,12 @@ class ExtractedClassBuilder {
while (initializersIterator.hasNext()) {
final PsiClassInitializer initializer = initializersIterator.next();
if (initializer.getTextRange().getStartOffset() < fieldOffset) {
outputMutatedInitializer(out, initializer);
initializer.accept(new Mutator(out));
initializersIterator.remove();
}
}
outputField(field, out);
field.accept(new Mutator(out));
if (myFieldsNeedingGetter != null && myFieldsNeedingGetter.contains(field)) {
out.append(PropertyUtil.generateGetterPrototype(field).getText());
@@ -281,27 +296,13 @@ class ExtractedClassBuilder {
}
}
for (PsiClassInitializer initializer : remainingInitializers) {
outputMutatedInitializer(out, initializer);
initializer.accept(new Mutator(out));
}
}
private String calculateStrippedName(PsiVariable variable) {
String name = variable.getName();
if (name == null) {
return null;
}
if (variable instanceof PsiField) {
name = myJavaCodeStyleManager.variableNameToPropertyName(name, variable.hasModifierProperty(PsiModifier.STATIC)
? VariableKind.STATIC_FIELD
: VariableKind.FIELD);
}
return name;
}
private void outputConstructor(@NonNls StringBuffer out) {
out.append("\tpublic " + className + '(');
out.append("\t").append(hasEnumConstants() ? "" : "public ").append(className).append('(');
if (requiresBackPointer) {
final String parameterName = myJavaCodeStyleManager.propertyNameToVariableName(backPointerName, VariableKind.PARAMETER);
out.append(originalClassName);
@@ -318,6 +319,8 @@ class ExtractedClassBuilder {
out.append('>');
}
out.append(' ' + parameterName);
} else if (hasEnumConstants()) {
out.append(myEnumParameterType.getCanonicalText()).append(" ").append("value");
}
out.append(")");
@@ -331,14 +334,13 @@ class ExtractedClassBuilder {
out.append("\t\t" + backPointerName + " = " + parameterName + ";");
}
} else if (hasEnumConstants()) {
final String fieldName = getValueFieldName();
out.append(fieldName.equals("value") ? "this." : "").append(fieldName).append(" = value;");
}
out.append("\t}");
}
private void outputField(PsiField field, @NonNls StringBuffer out) {
field.accept(new Mutator(out));
}
public void setRequiresBackPointer(boolean requiresBackPointer) {
this.requiresBackPointer = requiresBackPointer;
}
@@ -358,15 +360,21 @@ class ExtractedClassBuilder {
}
private boolean fieldIsExtracted(PsiField field) {
for (PsiField psiField : fields) {
if (psiField.equals(field)) {
return true;
}
}
final ArrayList<PsiField> extractedFields = new ArrayList<PsiField>(fields);
extractedFields.addAll(enumConstantFields);
if (extractedFields.contains(field)) return true;
final PsiClass containingClass = field.getContainingClass();
return innerClasses.contains(containingClass);
}
public void setExtractAsEnum(List<PsiField> extractAsEnum) {
this.enumConstantFields = extractAsEnum;
if (hasEnumConstants()) {
myEnumParameterType = enumConstantFields.get(0).getType();
}
}
private class Mutator extends JavaElementVisitor {
@NonNls
private final StringBuffer out;
@@ -402,11 +410,14 @@ class ExtractedClassBuilder {
if (fieldIsExtracted(field)) {
final String name = field.getName();
if (qualifier != null && name.equals(expression.getReferenceName())) {
out.append("this.");
if (enumConstantFields.contains(field)) {
out.append(name.toUpperCase()).append(".").append(getterName()).append("()");
} else {
if (qualifier != null && name.equals(expression.getReferenceName())) {
out.append("this.");
}
out.append(name);
}
out.append(name);
}
else {
if (field.hasModifierProperty(PsiModifier.STATIC)) {
@@ -16,6 +16,7 @@
package com.intellij.refactoring.extractclass.usageInfo;
import com.intellij.psi.PsiReferenceExpression;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.refactoring.psi.MutationUtils;
import com.intellij.refactoring.util.FixableUsageInfo;
import com.intellij.util.IncorrectOperationException;
@@ -23,14 +24,17 @@ import com.intellij.util.IncorrectOperationException;
public class ReplaceStaticVariableAccess extends FixableUsageInfo {
private final PsiReferenceExpression expression;
private final String delegateClass;
private final boolean myEnumConstant;
public ReplaceStaticVariableAccess(PsiReferenceExpression expression, String delegateClass) {
public ReplaceStaticVariableAccess(PsiReferenceExpression expression, String delegateClass, boolean enumConstant) {
super(expression);
this.expression = expression;
this.delegateClass = delegateClass;
}
myEnumConstant = enumConstant;
}
public void fixUsage() throws IncorrectOperationException {
MutationUtils.replaceExpression(delegateClass + '.' + expression.getReferenceName(), expression);
MutationUtils.replaceExpression(delegateClass + '.' + expression.getReferenceName() + (myEnumConstant ? "." + PropertyUtil.suggestGetterName("value", expression.getType())+
"()" : ""), expression);
}
}
@@ -164,7 +164,8 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
PsiElement anchor = getNormalizedAnchor(anchorElement);
boolean tempDeleteSelf = false;
final Boolean outOfCodeBlockExtraction = selectedExpr.getUserData(ElementToWorkOn.OUT_OF_CODE_BLOCK);
boolean tempDeleteSelf = outOfCodeBlockExtraction != null;
if (element.getParent() instanceof PsiExpressionStatement && anchor.equals(anchorElement)) {
PsiStatement statement = (PsiStatement)element.getParent();
if (statement.getParent() instanceof PsiCodeBlock) {
@@ -252,7 +253,16 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
if (expr.getParent() instanceof PsiParenthesizedExpression) {
expr = (PsiExpression)expr.getParent();
}
if (deleteSelf) {
if (outOfCodeBlockExtraction != null) {
final int endOffset = selectedExpr.getUserData(ElementToWorkOn.TEXT_RANGE).getEndOffset();
PsiElement endElement = element.getContainingFile().findElementAt(endOffset);
while (true) {
final PsiElement parent = endElement.getParent();
if (parent instanceof PsiClass) break;
endElement = parent;
}
element.getParent().deleteChildRange(element, PsiTreeUtil.skipSiblingsBackward(endElement, PsiWhiteSpace.class));
} else if (deleteSelf) {
element.getParent().delete();
}
@@ -643,7 +653,7 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
public Settings(String fieldName, boolean replaceAll,
boolean declareStatic, boolean declareFinal,
InitializationPlace initializerPlace, @Modifier String visibility, PsiLocalVariable localVariableToRemove, PsiType forcedType,
InitializationPlace initializerPlace, String visibility, PsiLocalVariable localVariableToRemove, PsiType forcedType,
boolean deleteLocalVariable,
PsiClass targetClass,
final boolean annotateAsNonNls,
@@ -43,6 +43,7 @@ public class ElementToWorkOn {
public static final Key<String> PREFIX = Key.create("prefix");
public static final Key<String> SUFFIX = Key.create("suffix");
public static final Key<RangeMarker> TEXT_RANGE = Key.create("range");
public static final Key<Boolean> OUT_OF_CODE_BLOCK= Key.create("out_of_code_block");
private ElementToWorkOn(PsiLocalVariable localVariable, PsiExpression expr) {
myLocalVariable = localVariable;
@@ -37,6 +37,7 @@ import com.intellij.refactoring.util.occurences.ExpressionOccurenceManager;
import com.intellij.refactoring.util.occurences.OccurenceManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
public class IntroduceConstantHandler extends BaseExpressionToFieldHandler {
@@ -199,8 +199,10 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
if (elementAtEnd == null) return null;
PsiExpression tempExpr;
final PsiElement elementAt = PsiTreeUtil.findCommonParent(elementAtStart, elementAtEnd);
if (PsiTreeUtil.getParentOfType(elementAt, PsiExpression.class, false) == null) return null;
PsiElement elementAt = PsiTreeUtil.findCommonParent(elementAtStart, elementAtEnd);
if (PsiTreeUtil.getParentOfType(elementAt, PsiExpression.class, false) == null) {
elementAt = null;
}
final PsiLiteralExpression literalExpression = PsiTreeUtil.getParentOfType(elementAt, PsiLiteralExpression.class);
final PsiLiteralExpression startLiteralExpression = PsiTreeUtil.getParentOfType(elementAtStart, PsiLiteralExpression.class);
@@ -286,7 +288,19 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
FileDocumentManager.getInstance().getDocument(file.getVirtualFile()).createRangeMarker(startOffset, endOffset);
tempExpr.putUserData(ElementToWorkOn.TEXT_RANGE, rangeMarker);
tempExpr.putUserData(ElementToWorkOn.PARENT, parent);
if (parent != null) {
tempExpr.putUserData(ElementToWorkOn.PARENT, parent);
}
else {
PsiErrorElement errorElement = PsiTreeUtil.getNextSiblingOfType(elementAtStart, PsiErrorElement.class);
if (errorElement == null) {
errorElement = PsiTreeUtil.getParentOfType(elementAtStart, PsiErrorElement.class);
}
if (errorElement == null) return null;
if (!(errorElement.getParent() instanceof PsiClass)) return null;
tempExpr.putUserData(ElementToWorkOn.PARENT, errorElement);
tempExpr.putUserData(ElementToWorkOn.OUT_OF_CODE_BLOCK, Boolean.TRUE);
}
final String fakeInitializer = "intellijidearulezzz";
final int[] refIdx = new int[1];
@@ -567,18 +581,21 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
final String prefix,
final String suffix,
final PsiElement parent, final RangeMarker rangeMarker, int[] refIdx) {
final String allText = parent.getContainingFile().getText();
final TextRange parentRange = parent.getTextRange();
String text = refText;
if (parent != null) {
final String allText = parent.getContainingFile().getText();
final TextRange parentRange = parent.getTextRange();
String beg = allText.substring(parentRange.getStartOffset(), rangeMarker.getStartOffset());
if (StringUtil.stripQuotesAroundValue(beg).trim().length() == 0 && prefix == null) beg = "";
String beg = allText.substring(parentRange.getStartOffset(), rangeMarker.getStartOffset());
if (StringUtil.stripQuotesAroundValue(beg).trim().length() == 0 && prefix == null) beg = "";
String end = allText.substring(rangeMarker.getEndOffset(), parentRange.getEndOffset());
if (StringUtil.stripQuotesAroundValue(end).trim().length() == 0 && suffix == null) end = "";
String end = allText.substring(rangeMarker.getEndOffset(), parentRange.getEndOffset());
if (StringUtil.stripQuotesAroundValue(end).trim().length() == 0 && suffix == null) end = "";
final String start = beg + (prefix != null ? prefix : "");
refIdx[0] = start.length();
final String text = start + refText + (suffix != null ? suffix : "") + end;
final String start = beg + (prefix != null ? prefix : "");
refIdx[0] = start.length();
text = start + refText + (suffix != null ? suffix : "") + end;
}
return JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText(text, parent);
}
@@ -30,6 +30,7 @@ import com.intellij.codeInsight.PsiEquivalenceUtil;
import com.intellij.codeInsight.intention.AddAnnotationFix;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
@@ -60,6 +61,7 @@ import java.util.*;
public class PullUpHelper extends BaseRefactoringProcessor{
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.memberPullUp.PullUpHelper");
private static final Key<Boolean> PRESERVE_QUALIFIER = Key.<Boolean>create("PRESERVE_QUALIFIER");
private final PsiClass mySourceClass;
private final PsiClass myTargetSuperClass;
private final boolean myIsTargetInterface;
@@ -234,6 +236,20 @@ public class PullUpHelper extends BaseRefactoringProcessor{
ChangeContextUtil.decodeContextInfo(myTargetSuperClass, null, null);
for (final PsiMember movedMember : myMembersAfterMove) {
movedMember.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitReferenceExpression(PsiReferenceExpression expression) {
final PsiExpression qualifierExpression = expression.getQualifierExpression();
if (qualifierExpression != null) {
final Boolean preserveQualifier = qualifierExpression.getCopyableUserData(PRESERVE_QUALIFIER);
if (preserveQualifier != null && !preserveQualifier) {
qualifierExpression.delete();
return;
}
}
super.visitReferenceExpression(expression);
}
});
final JavaRefactoringListenerManager listenerManager = JavaRefactoringListenerManager.getInstance(movedMember.getProject());
((JavaRefactoringListenerManagerImpl)listenerManager).fireMemberMoved(mySourceClass, movedMember);
}
@@ -632,7 +648,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{
}
private void fixReferencesToStatic(PsiElement classMember, Set<PsiMember> movedMembers) throws IncorrectOperationException {
StaticReferencesCollector collector = new StaticReferencesCollector(movedMembers);
final StaticReferencesCollector collector = new StaticReferencesCollector(movedMembers);
classMember.accept(collector);
ArrayList<PsiJavaCodeReferenceElement> refs = collector.getReferences();
ArrayList<PsiElement> members = collector.getReferees();
@@ -649,18 +665,19 @@ public class PullUpHelper extends BaseRefactoringProcessor{
(PsiReferenceExpression) factory.createExpressionFromText
("a." + ((PsiNamedElement) namedElement).getName(),
null);
final PsiExpression qualifierExpression = newRef.getQualifierExpression();
PsiExpression qualifierExpression = newRef.getQualifierExpression();
assert qualifierExpression != null;
qualifierExpression.replace(factory.createReferenceExpression(aClass));
qualifierExpression = (PsiExpression)qualifierExpression.replace(factory.createReferenceExpression(aClass));
qualifierExpression.putCopyableUserData(PRESERVE_QUALIFIER, ref.isQualified());
ref.replace(newRef);
}
}
}
private class StaticReferencesCollector extends ClassMemberReferencesVisitor {
ArrayList<PsiJavaCodeReferenceElement> myReferences;
ArrayList<PsiElement> myReferees;
ArrayList<PsiClass> myRefereeClasses;
private ArrayList<PsiJavaCodeReferenceElement> myReferences;
private ArrayList<PsiElement> myReferees;
private ArrayList<PsiClass> myRefereeClasses;
private final Set<PsiMember> myMovedMembers;
private StaticReferencesCollector(Set<PsiMember> movedMembers) {
@@ -684,7 +701,6 @@ public class PullUpHelper extends BaseRefactoringProcessor{
}
protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) {
if (classMember instanceof PsiClass) return;
if (classMember.hasModifierProperty(PsiModifier.STATIC)) {
if (!myMovedMembers.contains(classMember) &&
RefactoringHierarchyUtil.isMemberBetween(myTargetSuperClass, mySourceClass, classMember)) {
@@ -692,7 +708,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{
myReferees.add(classMember);
myRefereeClasses.add(classMember.getContainingClass());
}
else if ((myMovedMembers.contains(classMember) || myMembersAfterMove.contains(classMember)) && classMemberReference.isQualified()) {
else if (myMovedMembers.contains(classMember) || myMembersAfterMove.contains(classMember)) {
myReferences.add(classMemberReference);
myReferees.add(classMember);
myRefereeClasses.add(myTargetSuperClass);
@@ -18,7 +18,7 @@ package com.intellij.refactoring.openapi.impl;
import com.intellij.refactoring.JavaRefactoringActionHandlerFactory;
import com.intellij.refactoring.RefactoringActionHandler;
import com.intellij.refactoring.anonymousToInner.AnonymousToInnerHandler;
import com.intellij.refactoring.changeSignature.ChangeSignatureHandler;
import com.intellij.refactoring.changeSignature.JavaChangeSignatureHandler;
import com.intellij.refactoring.convertToInstanceMethod.ConvertToInstanceMethodHandler;
import com.intellij.refactoring.encapsulateFields.EncapsulateFieldsHandler;
import com.intellij.refactoring.extractInterface.ExtractInterfaceHandler;
@@ -86,7 +86,7 @@ public class JavaRefactoringActionHandlerFactoryImpl extends JavaRefactoringActi
}
public RefactoringActionHandler createChangeSignatureHandler() {
return new ChangeSignatureHandler();
return new JavaChangeSignatureHandler();
}
public RefactoringActionHandler createExtractSuperclassHandler() {
@@ -146,6 +146,12 @@ public class RenameJavaClassProcessor extends RenamePsiElementProcessor {
PsiClass parent = (PsiClass)aClass.getParent();
Collection<PsiClass> inheritors = ClassInheritorsSearch.search(parent, parent.getUseScope(), true).findAll();
for (PsiClass inheritor : inheritors) {
if (newName.equals(inheritor.getName())) {
final ClassCollisionsDetector classCollisionsDetector = new ClassCollisionsDetector(aClass);
for (PsiReference reference : ReferencesSearch.search(inheritor, new LocalSearchScope(inheritor))) {
classCollisionsDetector.addClassCollisions(reference.getElement(), newName, result);
}
}
PsiClass[] inners = inheritor.getInnerClasses();
for (PsiClass inner : inners) {
if (newName.equals(inner.getName())) {
@@ -90,7 +90,7 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto
final PsiElement element = reference.getElement();
final PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class);
if (newExpression != null && !PsiTreeUtil.isAncestor(builderClass, element, false)) {
usages.add(new ReplaceConstructorWithSettersChainInfo(newExpression, myClassName, myParametersMap));
usages.add(new ReplaceConstructorWithSettersChainInfo(newExpression, StringUtil.getQualifiedName(myPackageName, myClassName), myParametersMap));
}
}
}
@@ -73,7 +73,7 @@ public class ReplaceConstructorWithSettersChainInfo extends FixableUsageInfo {
"new " + myBuilderClass + "()." + buf.toString() + "create" + StringUtil.capitalize(constructor.getName()) + "()",
null);
expr.replace(settersChain);
styleManager.shortenClassReferences(expr.replace(settersChain));
}
}
}
@@ -44,13 +44,17 @@ public class MemberSelectionPanel extends JPanel {
setBorder(border);
setLayout(new BorderLayout());
myTable = new MemberSelectionTable(memberInfo, abstractColumnHeader);
myTable = createMemberSelectionTable(memberInfo, abstractColumnHeader);
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable);
add(scrollPane, BorderLayout.CENTER);
}
protected MemberSelectionTable createMemberSelectionTable(List<MemberInfo> memberInfo, String abstractColumnHeader) {
return new MemberSelectionTable(memberInfo, abstractColumnHeader);
}
public MemberSelectionTable getTable() {
return myTable;
}
@@ -33,6 +33,7 @@ import com.intellij.refactoring.util.classMembers.MemberInfo;
import com.intellij.ui.RowIcon;
import com.intellij.util.IconUtil;
import com.intellij.util.VisibilityIcons;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
@@ -47,6 +48,7 @@ public class MemberSelectionTable extends AbstractMemberSelectionTable<PsiMember
super(memberInfos, memberInfoModel, abstractColumnHeader);
}
@Nullable
@Override
protected Object getAbstractColumnValue(MemberInfo memberInfo) {
if (!(memberInfo.getMember() instanceof PsiMethod)) return null;
@@ -24,6 +24,7 @@ import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.RedundantCastUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
@@ -54,7 +55,8 @@ public class InlineUtil {
ChangeContextUtil.encodeContextInfo(initializer, false);
PsiExpression expr = (PsiExpression)ref.replace(initializer);
PsiType exprType = expr.getType();
if (exprType != null && !varType.equals(exprType)) {
if (exprType != null && (!varType.equals(exprType) && varType instanceof PsiPrimitiveType
|| !TypeConversionUtil.isAssignable(varType, exprType))) {
boolean matchedTypes = false;
//try explicit type arguments
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
@@ -307,6 +307,7 @@ public class RefactoringUtil {
public static PsiElement getParentExpressionAnchorElement(PsiElement place) {
PsiElement parent = place.getUserData(ElementToWorkOn.PARENT);
if (place.getUserData(ElementToWorkOn.OUT_OF_CODE_BLOCK) != null) return parent;
if (parent == null) parent = place;
while (true) {
if (isExpressionAnchorElement(parent)) return parent;
@@ -413,20 +414,28 @@ public class RefactoringUtil {
}
public static PsiThisExpression createThisExpression(PsiManager manager, PsiClass qualifierClass) throws IncorrectOperationException {
PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
if (qualifierClass != null) {
PsiThisExpression qualifiedThis = (PsiThisExpression)factory.createExpressionFromText("q.this", null);
qualifiedThis = (PsiThisExpression)CodeStyleManager.getInstance(manager.getProject()).reformat(qualifiedThis);
PsiJavaCodeReferenceElement thisQualifier = qualifiedThis.getQualifier();
LOG.assertTrue(thisQualifier != null);
thisQualifier.bindToElement(qualifierClass);
return qualifiedThis;
}
else {
return (PsiThisExpression)factory.createExpressionFromText("this", null);
}
return RefactoringUtil.<PsiThisExpression>createQualifiedExpression(manager, qualifierClass, "this");
}
public static PsiSuperExpression createSuperExpression(PsiManager manager, PsiClass qualifierClass) throws IncorrectOperationException {
return RefactoringUtil.<PsiSuperExpression>createQualifiedExpression(manager, qualifierClass, "super");
}
private static <T extends PsiQualifiedExpression> T createQualifiedExpression(PsiManager manager, PsiClass qualifierClass, String qName) throws IncorrectOperationException {
PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
if (qualifierClass != null) {
T qualifiedThis = (T)factory.createExpressionFromText("q." + qName, null);
qualifiedThis = (T)CodeStyleManager.getInstance(manager.getProject()).reformat(qualifiedThis);
PsiJavaCodeReferenceElement thisQualifier = qualifiedThis.getQualifier();
LOG.assertTrue(thisQualifier != null);
thisQualifier.bindToElement(qualifierClass);
return qualifiedThis;
}
else {
return (T)factory.createExpressionFromText(qName, null);
}
}
/**
* removes a reference to the specified class from the reference list given
*
@@ -537,6 +546,7 @@ public class RefactoringUtil {
public static PsiElement getAnchorElementForMultipleExpressions(PsiExpression[] occurrences, PsiElement scope) {
PsiElement anchor = null;
for (PsiExpression occurrence : occurrences) {
// if (!occurrence.isPhysical()) continue;
if (scope != null && !PsiTreeUtil.isAncestor(scope, occurrence, false)) {
continue;
}
@@ -384,6 +384,12 @@ public class DuplicatesFinder {
final PsiExpression candidateQualifier = candidateRefExpr.getQualifierExpression();
if (patternQualifier == null) {
PsiClass contextClass = PsiTreeUtil.getParentOfType(pattern, PsiClass.class);
if (candidateQualifier instanceof PsiReferenceExpression) {
final PsiElement resolved = ((PsiReferenceExpression)candidateQualifier).resolve();
if (resolved instanceof PsiClass && contextClass != null && contextClass.isInheritor((PsiClass)resolved, true)) {
return true;
}
}
return contextClass != null && match.registerInstanceExpression(candidateQualifier, contextClass);
} else {
if (candidateQualifier == null) {
@@ -411,6 +417,14 @@ public class DuplicatesFinder {
contextClass = thisCandidate;
}
return contextClass != null && match.putParameter(parameter, RefactoringUtil.createThisExpression(patternQualifier.getManager(), contextClass));
} else if (patternQualifier instanceof PsiReferenceExpression) {
final PsiElement resolved = ((PsiReferenceExpression)patternQualifier).resolve();
if (resolved instanceof PsiClass) {
final PsiClass classContext = PsiTreeUtil.getParentOfType(candidate, PsiClass.class);
if (classContext != null && classContext.isInheritor((PsiClass)resolved, true)) {
return true;
}
}
}
return false;
@@ -441,6 +455,13 @@ public class DuplicatesFinder {
final PsiElement candidateContextClass = candidateQualifier == null ? PsiTreeUtil.getParentOfType(candidate, PsiClass.class) : candidateQualifier.resolve();
return contextClass == candidateContextClass;
}
} else if (pattern instanceof PsiSuperExpression) {
final PsiJavaCodeReferenceElement qualifier = ((PsiSuperExpression)pattern).getQualifier();
final PsiElement contextClass = qualifier == null ? PsiTreeUtil.getParentOfType(pattern, PsiClass.class) : qualifier.resolve();
if (candidate instanceof PsiSuperExpression) {
final PsiJavaCodeReferenceElement candidateQualifier = ((PsiSuperExpression)candidate).getQualifier();
return contextClass == (candidateQualifier != null ? candidateQualifier.resolve() : PsiTreeUtil.getParentOfType(candidate, PsiClass.class));
}
}
PsiElement[] children1 = getFilteredChildren(pattern);
@@ -48,8 +48,8 @@ import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.extractMethod.InputVariables;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.util.VisibilityUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -257,7 +257,12 @@ public class MethodDuplicatesHandler implements RefactoringActionHandler {
} else if (needStaticQualifier || myMethod.hasModifierProperty(PsiModifier.STATIC)) {
qualifierExpression.replace(factory.createReferenceExpression(containingClass));
} else {
qualifierExpression.replace(RefactoringUtil.createThisExpression(containingClass.getManager(), containingClass));
final PsiClass psiClass = PsiTreeUtil.getParentOfType(match.getMatchStart(), PsiClass.class);
if (psiClass != null && psiClass.isInheritor(containingClass, true)) {
qualifierExpression.replace(RefactoringUtil.createSuperExpression(containingClass.getManager(), psiClass));
} else {
qualifierExpression.replace(RefactoringUtil.createThisExpression(containingClass.getManager(), containingClass));
}
}
}
VisibilityUtil.escalateVisibility(myMethod, match.getMatchStart());
@@ -0,0 +1,19 @@
public class Foo {
public Foo() {
Runnable r = new Runnable() {
public void run() {
Goo<String> g = new Goo<String>() {
@Override
void foo() {
<selection>//To change body of implemented methods use File | Settings | File Templates.</selection>
}
};
}
};
}
}
abstract class Goo<T> {
abstract void foo();
}
@@ -0,0 +1,14 @@
public class Foo {
public Foo() {
Runnable r = new Runnable() {
public void run() {
Goo<String> g = new G<caret>
}
};
}
}
abstract class Goo<T> {
abstract void foo();
}
@@ -1,4 +1,6 @@
import java.io.*;
import java.io.EOFException;
import java.io.IOException;
import java.io.InterruptedIOException;
public interface Idea4780 {
/**
@@ -1,4 +1,4 @@
import java.util.*;
import java.util.Map;
class Test {
Map someMap;
@@ -1,9 +1,10 @@
package br.com.vivo.torpedeiro.pull.impl;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import br.com.vivo.torpedeiro.pull.MensagemPull;
import br.com.vivo.torpedeiro.pull.PullDAO;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
/**
* Implementa? padr?de {@link PullDAO} que realiza todas as opera?s utilizando SQL atrav?de um {@link
@@ -1,10 +1,10 @@
package br.com.vivo.torpedeiro.pull.impl;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import br.com.vivo.torpedeiro.pull.MensagemPull;
import br.com.vivo.torpedeiro.pull.PullDAO;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
/**
* Implementa? padr?de {@link PullDAO} que realiza todas as opera?s utilizando SQL atrav?de um {@link
@@ -0,0 +1,14 @@
class List<T> {}
class Base<T> {
void fo<caret>o(String s, List<T>... l) {}
}
class Inheritor extends Base<Integer> {
void foo(String s, List<Integer>... l) {}
{
new Inheritor().foo("a", new List<Integer>());
}
}
@@ -0,0 +1,14 @@
class List<T> {}
class Base<T> {
void foo(List<T>[] l, String s) {}
}
class Inheritor extends Base<Integer> {
void foo(List<Integer>[] l, String s) {}
{
new Inheritor().foo(new List[]{new List<Integer>()}, "a");
}
}
@@ -1,4 +1,3 @@
import java.util.*;
class A1<T> {
A1(){}
@@ -0,0 +1,12 @@
public enum EEnum {
FOO("foo"), BAR(FOO.getValue());
private String value;
public String getValue() {
return value;
}
EEnum(String value) {
this.value = value;
}
}
@@ -0,0 +1,2 @@
class Test {
}
@@ -0,0 +1,4 @@
class Test {
public static final String FOO = "foo";
public static final String BAR = FOO;
}
@@ -0,0 +1,4 @@
class Test {
public static final String FOO = "foo";
public static final String BAR = FOO;
}
@@ -0,0 +1,4 @@
class Test {
public static final String FOO = "foo";
public static final String BAR = FOO;
}
@@ -0,0 +1,12 @@
public enum EEnum {
FOO("foo");
private String value;
public String getValue() {
return value;
}
EEnum(String value) {
this.value = value;
}
}
@@ -0,0 +1,2 @@
class Test {
}
@@ -0,0 +1,3 @@
class Test {
public static final String FOO = "foo";
}
@@ -0,0 +1,16 @@
public enum EEnum {
FOO("foo");
private String value;
public String getValue() {
return value;
}
EEnum(String value) {
this.value = value;
}
void foo() {
System.out.println(FOO.getValue());
}
}
@@ -0,0 +1,6 @@
class Test {
public static final String FOO = "foo";
void foo() {
System.out.println(FOO);
}
}
@@ -0,0 +1,12 @@
public enum EEnum {
FOO("foo");
private String value;
public String getValue() {
return value;
}
EEnum(String value) {
this.value = value;
}
}
@@ -0,0 +1,5 @@
class Test {
void foo() {
System.out.println(EEnum.FOO.getValue());
}
}
@@ -0,0 +1,6 @@
class Test {
public static final String FOO = "foo";
void foo() {
System.out.println(FOO);
}
}
@@ -0,0 +1,13 @@
public enum EEnum {
FOO("foo");
public int value = 0;
private String value1;
public String getValue() {
return value1;
}
EEnum(String value) {
value1 = value;
}
}
@@ -0,0 +1,2 @@
class Test {
}

Some files were not shown because too many files have changed in this diff Show More