From 0346db21102bcbafe5d3778fe39ae3237139b5a9 Mon Sep 17 00:00:00 2001 From: UNV Date: Fri, 11 Apr 2025 08:47:41 +0300 Subject: [PATCH 1/2] Reformatting of configuration producers. --- ...tractApplicationConfigurationProducer.java | 140 +++---- .../ApplicationConfigurationProducer.java | 6 +- .../JarApplicationConfigurationProducer.java | 56 +-- .../TestDiscoveryConfigurationProducer.java | 286 +++++++------- .../AbstractInClassConfigurationProducer.java | 255 ++++++------ .../impl/JavaPsiImplementationHelperImpl.java | 370 +++++++++--------- .../typeMigration/TypeMigrationRules.java | 211 +++++----- .../rules/DisjunctionTypeConversionRule.java | 98 +++-- .../rules/RootTypeConversionRule.java | 327 +++++++++------- .../rules/TypeConversionRule.java | 41 +- 10 files changed, 906 insertions(+), 884 deletions(-) diff --git a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/application/AbstractApplicationConfigurationProducer.java b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/application/AbstractApplicationConfigurationProducer.java index 263d7d561..8e22b4630 100644 --- a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/application/AbstractApplicationConfigurationProducer.java +++ b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/application/AbstractApplicationConfigurationProducer.java @@ -33,84 +33,86 @@ import jakarta.annotation.Nullable; public abstract class AbstractApplicationConfigurationProducer extends JavaRunConfigurationProducerBase { - public AbstractApplicationConfigurationProducer(final ApplicationConfigurationType configurationType) { - super(configurationType); - } - - @Override - protected boolean setupConfigurationFromContext(T configuration, ConfigurationContext context, Ref sourceElement) { - final Location contextLocation = context.getLocation(); - if (contextLocation == null) { - return false; - } - final Location location = JavaExecutionUtil.stepIntoSingleClass(contextLocation); - if (location == null) { - return false; - } - final PsiElement element = location.getPsiElement(); - if (!element.isPhysical()) { - return false; + public AbstractApplicationConfigurationProducer(final ApplicationConfigurationType configurationType) { + super(configurationType); } - PsiElement currentElement = element; - PsiMethod method; - while ((method = findMain(currentElement)) != null) { - final PsiClass aClass = method.getContainingClass(); - if (ConfigurationUtil.MAIN_CLASS.test(aClass)) { - sourceElement.set(method); + + @Override + protected boolean setupConfigurationFromContext(T configuration, ConfigurationContext context, Ref sourceElement) { + final Location contextLocation = context.getLocation(); + if (contextLocation == null) { + return false; + } + final Location location = JavaExecutionUtil.stepIntoSingleClass(contextLocation); + if (location == null) { + return false; + } + final PsiElement element = location.getPsiElement(); + if (!element.isPhysical()) { + return false; + } + PsiElement currentElement = element; + PsiMethod method; + while ((method = findMain(currentElement)) != null) { + final PsiClass aClass = method.getContainingClass(); + if (ConfigurationUtil.MAIN_CLASS.test(aClass)) { + sourceElement.set(method); + setupConfiguration(configuration, aClass, context); + return true; + } + currentElement = method.getParent(); + } + final PsiClass aClass = ApplicationConfigurationType.getMainClass(element); + if (aClass == null) { + return false; + } + sourceElement.set(aClass); setupConfiguration(configuration, aClass, context); return true; - } - currentElement = method.getParent(); - } - final PsiClass aClass = ApplicationConfigurationType.getMainClass(element); - if (aClass == null) { - return false; } - sourceElement.set(aClass); - setupConfiguration(configuration, aClass, context); - return true; - } - private void setupConfiguration(T configuration, final PsiClass aClass, final ConfigurationContext context) { - configuration.MAIN_CLASS_NAME = JavaExecutionUtil.getRuntimeQualifiedName(aClass); - configuration.setGeneratedName(); - setupConfigurationModule(context, configuration); - } + private void setupConfiguration(T configuration, final PsiClass aClass, final ConfigurationContext context) { + configuration.MAIN_CLASS_NAME = JavaExecutionUtil.getRuntimeQualifiedName(aClass); + configuration.setGeneratedName(); + setupConfigurationModule(context, configuration); + } - @Nullable - private static PsiMethod findMain(PsiElement element) { - PsiMethod method; - while ((method = PsiTreeUtil.getParentOfType(element, PsiMethod.class)) != null) { - if (PsiMethodUtil.isMainMethod(method)) { - return method; - } else { - element = method.getParent(); - } + @Nullable + private static PsiMethod findMain(PsiElement element) { + PsiMethod method; + while ((method = PsiTreeUtil.getParentOfType(element, PsiMethod.class)) != null) { + if (PsiMethodUtil.isMainMethod(method)) { + return method; + } + else { + element = method.getParent(); + } + } + return null; } - return null; - } - @Override - public boolean isConfigurationFromContext(T appConfiguration, ConfigurationContext context) { - final PsiElement location = context.getPsiLocation(); - final PsiClass aClass = ApplicationConfigurationType.getMainClass(location); - if (aClass != null && Comparing.equal(JavaExecutionUtil.getRuntimeQualifiedName(aClass), appConfiguration.MAIN_CLASS_NAME)) { - final PsiMethod method = PsiTreeUtil.getParentOfType(location, PsiMethod.class, false); - if (method != null && TestFrameworks.getInstance().isTestMethod(method)) { - return false; - } + @Override + public boolean isConfigurationFromContext(T appConfiguration, ConfigurationContext context) { + final PsiElement location = context.getPsiLocation(); + final PsiClass aClass = ApplicationConfigurationType.getMainClass(location); + if (aClass != null && Comparing.equal(JavaExecutionUtil.getRuntimeQualifiedName(aClass), appConfiguration.MAIN_CLASS_NAME)) { + final PsiMethod method = PsiTreeUtil.getParentOfType(location, PsiMethod.class, false); + if (method != null && TestFrameworks.getInstance().isTestMethod(method)) { + return false; + } - final Module configurationModule = appConfiguration.getConfigurationModule().getModule(); - if (Comparing.equal(context.getModule(), configurationModule)) { - return true; - } + final Module configurationModule = appConfiguration.getConfigurationModule().getModule(); + if (Comparing.equal(context.getModule(), configurationModule)) { + return true; + } - ApplicationConfiguration template = (ApplicationConfiguration) context.getRunManager().getConfigurationTemplate(getConfigurationFactory()).getConfiguration(); - final Module predefinedModule = template.getConfigurationModule().getModule(); - if (Comparing.equal(predefinedModule, configurationModule)) { - return true; - } + ApplicationConfiguration template = + (ApplicationConfiguration)context.getRunManager().getConfigurationTemplate(getConfigurationFactory()).getConfiguration(); + final Module predefinedModule = template.getConfigurationModule().getModule(); + if (Comparing.equal(predefinedModule, configurationModule)) { + return true; + } + } + return false; } - return false; - } } diff --git a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/application/ApplicationConfigurationProducer.java b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/application/ApplicationConfigurationProducer.java index fc3d9d7a0..7e327cd8d 100644 --- a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/application/ApplicationConfigurationProducer.java +++ b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/application/ApplicationConfigurationProducer.java @@ -19,7 +19,7 @@ @ExtensionImpl public class ApplicationConfigurationProducer extends AbstractApplicationConfigurationProducer { - public ApplicationConfigurationProducer() { - super(ApplicationConfigurationType.getInstance()); - } + public ApplicationConfigurationProducer() { + super(ApplicationConfigurationType.getInstance()); + } } diff --git a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/jar/JarApplicationConfigurationProducer.java b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/jar/JarApplicationConfigurationProducer.java index f807d5223..9f07acc21 100644 --- a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/jar/JarApplicationConfigurationProducer.java +++ b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/jar/JarApplicationConfigurationProducer.java @@ -31,35 +31,39 @@ */ @ExtensionImpl public class JarApplicationConfigurationProducer extends RunConfigurationProducer { - public JarApplicationConfigurationProducer() { - super(JarApplicationConfigurationType.getInstance()); - } - - @Override - protected boolean setupConfigurationFromContext(JarApplicationConfiguration configuration, ConfigurationContext context, Ref sourceElement) { - VirtualFile file = getJarFileFromContext(context); - if (file != null) { - configuration.setName(file.getName()); - configuration.setJarPath(file.getPath()); - return true; + public JarApplicationConfigurationProducer() { + super(JarApplicationConfigurationType.getInstance()); } - return false; - } - @Nullable - private static VirtualFile getJarFileFromContext(ConfigurationContext context) { - Location location = context.getLocation(); - if (location == null) { - return null; + @Override + protected boolean setupConfigurationFromContext( + JarApplicationConfiguration configuration, + ConfigurationContext context, + Ref sourceElement + ) { + VirtualFile file = getJarFileFromContext(context); + if (file != null) { + configuration.setName(file.getName()); + configuration.setJarPath(file.getPath()); + return true; + } + return false; } - VirtualFile file = location.getVirtualFile(); - return file != null && FileUtil.extensionEquals(file.getName(), "jar") ? file : null; - } + @Nullable + private static VirtualFile getJarFileFromContext(ConfigurationContext context) { + Location location = context.getLocation(); + if (location == null) { + return null; + } + + VirtualFile file = location.getVirtualFile(); + return file != null && FileUtil.extensionEquals(file.getName(), "jar") ? file : null; + } - @Override - public boolean isConfigurationFromContext(JarApplicationConfiguration configuration, ConfigurationContext context) { - VirtualFile file = getJarFileFromContext(context); - return file != null && FileUtil.pathsEqual(file.getPath(), configuration.getJarPath()); - } + @Override + public boolean isConfigurationFromContext(JarApplicationConfiguration configuration, ConfigurationContext context) { + VirtualFile file = getJarFileFromContext(context); + return file != null && FileUtil.pathsEqual(file.getPath(), configuration.getJarPath()); + } } diff --git a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testDiscovery/TestDiscoveryConfigurationProducer.java b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testDiscovery/TestDiscoveryConfigurationProducer.java index 085825d15..54f28d77b 100644 --- a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testDiscovery/TestDiscoveryConfigurationProducer.java +++ b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testDiscovery/TestDiscoveryConfigurationProducer.java @@ -48,156 +48,138 @@ import java.util.HashSet; -public abstract class TestDiscoveryConfigurationProducer extends JavaRunConfigurationProducerBase -{ - protected TestDiscoveryConfigurationProducer(ConfigurationType type) - { - super(type); - } - - - protected abstract void setPosition(JavaTestConfigurationBase configuration, PsiLocation position); - - protected abstract Pair getPosition(JavaTestConfigurationBase configuration); - - @Override - protected boolean setupConfigurationFromContext(final JavaTestConfigurationBase configuration, ConfigurationContext configurationContext, Ref ref) - { - if(!TestDiscoveryExtension.TESTDISCOVERY_ENABLED) - { - return false; - } - final Location contextLocation = configurationContext.getLocation(); - assert contextLocation != null; - final Location location = JavaExecutionUtil.stepIntoSingleClass(contextLocation); - if(location == null) - { - return false; - } - final PsiMethod sourceMethod = getSourceMethod(location); - final Pair position = getPosition(sourceMethod); - if(sourceMethod != null && position != null) - { - try - { - final Project project = configuration.getProject(); - final TestDiscoveryIndex testDiscoveryIndex = TestDiscoveryIndex.getInstance(project); - final Collection testsByMethodName = testDiscoveryIndex.getTestsByMethodName(position.first, position.second); - if(testsByMethodName == null || ContainerUtil.filter(testsByMethodName, s -> s.startsWith(configuration.getFrameworkPrefix())).isEmpty()) - { - return false; - } - setPosition(configuration, new PsiLocation<>(sourceMethod)); - configuration.setName("Tests for " + StringUtil.getShortName(position.first) + "." + position.second); - - final RunnerAndConfigurationSettings template = configurationContext.getRunManager().getConfigurationTemplate(getConfigurationFactory()); - final Module predefinedModule = ((ModuleBasedConfiguration) template.getConfiguration()).getConfigurationModule().getModule(); - if(predefinedModule != null) - { - configuration.setModule(predefinedModule); - } - - //potentially this set won't be big, it reflects modules from where user starts his tests - final Collection modules = testDiscoveryIndex.getTestModulesByMethodName(position.first, position.second, configuration.getFrameworkPrefix()); - if(modules.isEmpty()) - { - return true; - } - - final List survivedModules = new ArrayList<>(); - final ModuleManager moduleManager = ModuleManager.getInstance(project); - for(String moduleName : modules) - { - final Module moduleByName = moduleManager.findModuleByName(moduleName); - if(moduleByName != null) - { - survivedModules.add(moduleByName); - } - } - if(survivedModules.isEmpty()) - { - return true; - } - - final Set allModules = new HashSet<>(Arrays.asList(moduleManager.getModules())); - survivedModules.forEach(module -> - { - final List dependentModules = ModuleUtilCore.getAllDependentModules(module); - dependentModules.add(module); - allModules.retainAll(dependentModules); - }); - if(!allModules.isEmpty()) - { - Module aModule = allModules.iterator().next(); - for(Module module : survivedModules) - { - if(allModules.contains(module)) - { - aModule = module; - } - } - configuration.setModule(aModule); - } - - return true; - } - catch(IOException e) - { - return false; - } - } - return false; - } - - @Override - protected Module findModule(JavaTestConfigurationBase configuration, Module contextModule) - { - return null; - } - - private static PsiMethod getSourceMethod(Location location) - { - final PsiElement psiElement = location.getPsiElement(); - final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(psiElement, PsiMethod.class); - if(psiMethod != null) - { - final PsiClass containingClass = psiMethod.getContainingClass(); - if(containingClass != null) - { - final TestFramework testFramework = TestFrameworks.detectFramework(containingClass); - if(testFramework != null) - { - return null; - } - return psiMethod; - } - } - return null; - } - - private static Pair getPosition(PsiMethod method) - { - if(method == null) - { - return null; - } - final PsiClass containingClass = method.getContainingClass(); - if(containingClass == null) - { - return null; - } - final String qualifiedName = containingClass.getQualifiedName(); - if(qualifiedName != null) - { - return Pair.create(qualifiedName, method.getName()); - } - return null; - } - - @Override - public boolean isConfigurationFromContext(JavaTestConfigurationBase configuration, ConfigurationContext configurationContext) - { - final Pair position = getPosition(getSourceMethod(configurationContext.getLocation())); - return position != null && position.equals(getPosition(configuration)); - } +public abstract class TestDiscoveryConfigurationProducer extends JavaRunConfigurationProducerBase { + protected TestDiscoveryConfigurationProducer(ConfigurationType type) { + super(type); + } + + protected abstract void setPosition(JavaTestConfigurationBase configuration, PsiLocation position); + + protected abstract Pair getPosition(JavaTestConfigurationBase configuration); + + @Override + protected boolean setupConfigurationFromContext( + final JavaTestConfigurationBase configuration, + ConfigurationContext configurationContext, + Ref ref + ) { + if (!TestDiscoveryExtension.TESTDISCOVERY_ENABLED) { + return false; + } + final Location contextLocation = configurationContext.getLocation(); + assert contextLocation != null; + final Location location = JavaExecutionUtil.stepIntoSingleClass(contextLocation); + if (location == null) { + return false; + } + final PsiMethod sourceMethod = getSourceMethod(location); + final Pair position = getPosition(sourceMethod); + if (sourceMethod != null && position != null) { + try { + final Project project = configuration.getProject(); + final TestDiscoveryIndex testDiscoveryIndex = TestDiscoveryIndex.getInstance(project); + final Collection testsByMethodName = testDiscoveryIndex.getTestsByMethodName(position.first, position.second); + if (testsByMethodName == null || ContainerUtil.filter( + testsByMethodName, + s -> s.startsWith(configuration.getFrameworkPrefix()) + ).isEmpty()) { + return false; + } + setPosition(configuration, new PsiLocation<>(sourceMethod)); + configuration.setName("Tests for " + StringUtil.getShortName(position.first) + "." + position.second); + + final RunnerAndConfigurationSettings template = + configurationContext.getRunManager().getConfigurationTemplate(getConfigurationFactory()); + final Module predefinedModule = + ((ModuleBasedConfiguration)template.getConfiguration()).getConfigurationModule().getModule(); + if (predefinedModule != null) { + configuration.setModule(predefinedModule); + } + + //potentially this set won't be big, it reflects modules from where user starts his tests + final Collection modules = + testDiscoveryIndex.getTestModulesByMethodName(position.first, position.second, configuration.getFrameworkPrefix()); + if (modules.isEmpty()) { + return true; + } + + final List survivedModules = new ArrayList<>(); + final ModuleManager moduleManager = ModuleManager.getInstance(project); + for (String moduleName : modules) { + final Module moduleByName = moduleManager.findModuleByName(moduleName); + if (moduleByName != null) { + survivedModules.add(moduleByName); + } + } + if (survivedModules.isEmpty()) { + return true; + } + + final Set allModules = new HashSet<>(Arrays.asList(moduleManager.getModules())); + survivedModules.forEach(module -> + { + final List dependentModules = ModuleUtilCore.getAllDependentModules(module); + dependentModules.add(module); + allModules.retainAll(dependentModules); + }); + if (!allModules.isEmpty()) { + Module aModule = allModules.iterator().next(); + for (Module module : survivedModules) { + if (allModules.contains(module)) { + aModule = module; + } + } + configuration.setModule(aModule); + } + + return true; + } + catch (IOException e) { + return false; + } + } + return false; + } + + @Override + protected Module findModule(JavaTestConfigurationBase configuration, Module contextModule) { + return null; + } + + private static PsiMethod getSourceMethod(Location location) { + final PsiElement psiElement = location.getPsiElement(); + final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(psiElement, PsiMethod.class); + if (psiMethod != null) { + final PsiClass containingClass = psiMethod.getContainingClass(); + if (containingClass != null) { + final TestFramework testFramework = TestFrameworks.detectFramework(containingClass); + if (testFramework != null) { + return null; + } + return psiMethod; + } + } + return null; + } + + private static Pair getPosition(PsiMethod method) { + if (method == null) { + return null; + } + final PsiClass containingClass = method.getContainingClass(); + if (containingClass == null) { + return null; + } + final String qualifiedName = containingClass.getQualifiedName(); + if (qualifiedName != null) { + return Pair.create(qualifiedName, method.getName()); + } + return null; + } + + @Override + public boolean isConfigurationFromContext(JavaTestConfigurationBase configuration, ConfigurationContext configurationContext) { + final Pair position = getPosition(getSourceMethod(configurationContext.getLocation())); + return position != null && position.equals(getPosition(configuration)); + } } diff --git a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testframework/AbstractInClassConfigurationProducer.java b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testframework/AbstractInClassConfigurationProducer.java index b26f342fb..f760428f4 100644 --- a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testframework/AbstractInClassConfigurationProducer.java +++ b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testframework/AbstractInClassConfigurationProducer.java @@ -40,135 +40,128 @@ import consulo.language.psi.util.PsiTreeUtil; import jakarta.annotation.Nonnull; -public abstract class AbstractInClassConfigurationProducer extends AbstractJavaTestConfigurationProducer -{ - private static final Logger LOG = Logger.getInstance(AbstractInClassConfigurationProducer.class); - - protected AbstractInClassConfigurationProducer(ConfigurationType configurationType) - { - super(configurationType); - } - - @Override - public void onFirstRun(@Nonnull final ConfigurationFromContext configuration, @Nonnull final ConfigurationContext fromContext, @Nonnull Runnable performRunnable) - { - final PsiElement psiElement = configuration.getSourceElement(); - if(psiElement instanceof PsiMethod || psiElement instanceof PsiClass) - { - - final PsiMethod psiMethod; - final PsiClass containingClass; - - if(psiElement instanceof PsiMethod) - { - psiMethod = (PsiMethod) psiElement; - containingClass = psiMethod.getContainingClass(); - } - else - { - psiMethod = null; - containingClass = (PsiClass) psiElement; - } - - final InheritorChooser inheritorChooser = new InheritorChooser() - { - @Override - protected void runForClasses(List classes, PsiMethod method, ConfigurationContext context, Runnable performRunnable) - { - ((T) configuration.getConfiguration()).bePatternConfiguration(classes, method); - super.runForClasses(classes, method, context, performRunnable); - } - - @Override - protected void runForClass(PsiClass aClass, PsiMethod psiMethod, ConfigurationContext context, Runnable performRunnable) - { - if(psiElement instanceof PsiMethod) - { - final Project project = psiMethod.getProject(); - final MethodLocation methodLocation = new MethodLocation(project, psiMethod, PsiLocation.fromPsiElement(aClass)); - ((T) configuration.getConfiguration()).beMethodConfiguration(methodLocation); - } - else - { - ((T) configuration.getConfiguration()).beClassConfiguration(aClass); - } - super.runForClass(aClass, psiMethod, context, performRunnable); - } - }; - if(inheritorChooser.runMethodInAbstractClass(fromContext, performRunnable, psiMethod, containingClass, aClass -> aClass.hasModifierProperty(PsiModifier.ABSTRACT) && isTestClass(aClass))) - { - return; - } - } - super.onFirstRun(configuration, fromContext, performRunnable); - } - - @Override - protected boolean setupConfigurationFromContext(T configuration, ConfigurationContext context, Ref sourceElement) - { - if(isMultipleElementsSelected(context)) - { - return false; - } - - final Location contextLocation = context.getLocation(); - setupConfigurationParamName(configuration, contextLocation); - - PsiClass psiClass = null; - PsiElement element = context.getPsiLocation(); - while(element != null) - { - if(element instanceof PsiClass && isTestClass((PsiClass) element)) - { - psiClass = (PsiClass) element; - break; - } - else if(element instanceof PsiMember) - { - psiClass = contextLocation instanceof MethodLocation ? ((MethodLocation) contextLocation).getContainingClass() : contextLocation instanceof PsiMemberParameterizedLocation ? ( - (PsiMemberParameterizedLocation) contextLocation).getContainingClass() : ((PsiMember) element).getContainingClass(); - if(isTestClass(psiClass)) - { - break; - } - } - else if(element instanceof PsiClassOwner) - { - final PsiClass[] classes = ((PsiClassOwner) element).getClasses(); - if(classes.length == 1) - { - psiClass = classes[0]; - break; - } - } - element = element.getParent(); - } - if(!isTestClass(psiClass)) - { - return false; - } - - PsiElement psiElement = psiClass; - RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(context); - setupConfigurationModule(context, configuration); - final Module originalModule = configuration.getConfigurationModule().getModule(); - configuration.beClassConfiguration(psiClass); - - PsiMethod method = PsiTreeUtil.getParentOfType(context.getPsiLocation(), PsiMethod.class, false); - while(method != null) - { - if(isTestMethod(false, method)) - { - configuration.beMethodConfiguration(MethodLocation.elementInClass(method, psiClass)); - psiElement = method; - } - method = PsiTreeUtil.getParentOfType(method, PsiMethod.class); - } - - configuration.restoreOriginalModule(originalModule); - LOG.assertTrue(configuration.getConfigurationModule().getModule() != null); - settings.setName(configuration.getName()); - sourceElement.set(psiElement); - return true; - } +public abstract class AbstractInClassConfigurationProducer extends AbstractJavaTestConfigurationProducer { + private static final Logger LOG = Logger.getInstance(AbstractInClassConfigurationProducer.class); + + protected AbstractInClassConfigurationProducer(ConfigurationType configurationType) { + super(configurationType); + } + + @Override + public void onFirstRun( + @Nonnull final ConfigurationFromContext configuration, + @Nonnull final ConfigurationContext fromContext, + @Nonnull Runnable performRunnable + ) { + final PsiElement psiElement = configuration.getSourceElement(); + if (psiElement instanceof PsiMethod || psiElement instanceof PsiClass) { + + final PsiMethod psiMethod; + final PsiClass containingClass; + + if (psiElement instanceof PsiMethod) { + psiMethod = (PsiMethod)psiElement; + containingClass = psiMethod.getContainingClass(); + } + else { + psiMethod = null; + containingClass = (PsiClass)psiElement; + } + + final InheritorChooser inheritorChooser = new InheritorChooser() { + @Override + protected void runForClasses( + List classes, + PsiMethod method, + ConfigurationContext context, + Runnable performRunnable + ) { + ((T)configuration.getConfiguration()).bePatternConfiguration(classes, method); + super.runForClasses(classes, method, context, performRunnable); + } + + @Override + protected void runForClass(PsiClass aClass, PsiMethod psiMethod, ConfigurationContext context, Runnable performRunnable) { + if (psiElement instanceof PsiMethod) { + final Project project = psiMethod.getProject(); + final MethodLocation methodLocation = new MethodLocation(project, psiMethod, PsiLocation.fromPsiElement(aClass)); + ((T)configuration.getConfiguration()).beMethodConfiguration(methodLocation); + } + else { + ((T)configuration.getConfiguration()).beClassConfiguration(aClass); + } + super.runForClass(aClass, psiMethod, context, performRunnable); + } + }; + if (inheritorChooser.runMethodInAbstractClass( + fromContext, + performRunnable, + psiMethod, + containingClass, + aClass -> aClass.hasModifierProperty(PsiModifier.ABSTRACT) && isTestClass(aClass) + )) { + return; + } + } + super.onFirstRun(configuration, fromContext, performRunnable); + } + + @Override + protected boolean setupConfigurationFromContext(T configuration, ConfigurationContext context, Ref sourceElement) { + if (isMultipleElementsSelected(context)) { + return false; + } + + final Location contextLocation = context.getLocation(); + setupConfigurationParamName(configuration, contextLocation); + + PsiClass psiClass = null; + PsiElement element = context.getPsiLocation(); + while (element != null) { + if (element instanceof PsiClass && isTestClass((PsiClass)element)) { + psiClass = (PsiClass)element; + break; + } + else if (element instanceof PsiMember) { + psiClass = + contextLocation instanceof MethodLocation ? ((MethodLocation)contextLocation).getContainingClass() : contextLocation instanceof PsiMemberParameterizedLocation ? ( + (PsiMemberParameterizedLocation)contextLocation).getContainingClass() : ((PsiMember)element).getContainingClass(); + if (isTestClass(psiClass)) { + break; + } + } + else if (element instanceof PsiClassOwner) { + final PsiClass[] classes = ((PsiClassOwner)element).getClasses(); + if (classes.length == 1) { + psiClass = classes[0]; + break; + } + } + element = element.getParent(); + } + if (!isTestClass(psiClass)) { + return false; + } + + PsiElement psiElement = psiClass; + RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(context); + setupConfigurationModule(context, configuration); + final Module originalModule = configuration.getConfigurationModule().getModule(); + configuration.beClassConfiguration(psiClass); + + PsiMethod method = PsiTreeUtil.getParentOfType(context.getPsiLocation(), PsiMethod.class, false); + while (method != null) { + if (isTestMethod(false, method)) { + configuration.beMethodConfiguration(MethodLocation.elementInClass(method, psiClass)); + psiElement = method; + } + method = PsiTreeUtil.getParentOfType(method, PsiMethod.class); + } + + configuration.restoreOriginalModule(originalModule); + LOG.assertTrue(configuration.getConfigurationModule().getModule() != null); + settings.setName(configuration.getName()); + sourceElement.set(psiElement); + return true; + } } \ No newline at end of file diff --git a/plugin/src/main/java/com/intellij/java/impl/psi/impl/JavaPsiImplementationHelperImpl.java b/plugin/src/main/java/com/intellij/java/impl/psi/impl/JavaPsiImplementationHelperImpl.java index 62eb1e955..0a8a42e4a 100644 --- a/plugin/src/main/java/com/intellij/java/impl/psi/impl/JavaPsiImplementationHelperImpl.java +++ b/plugin/src/main/java/com/intellij/java/impl/psi/impl/JavaPsiImplementationHelperImpl.java @@ -69,224 +69,224 @@ @Singleton @ServiceImpl public class JavaPsiImplementationHelperImpl extends JavaPsiImplementationHelper { - private static final Logger LOG = Logger.getInstance(JavaPsiImplementationHelperImpl.class); + private static final Logger LOG = Logger.getInstance(JavaPsiImplementationHelperImpl.class); - private final Project myProject; - private final MemberOrderService myMemberOrderService; + private final Project myProject; + private final MemberOrderService myMemberOrderService; - @Inject - public JavaPsiImplementationHelperImpl(Project project, MemberOrderService memberOrderService) { - myProject = project; - myMemberOrderService = memberOrderService; - } - - @Override - public PsiClass getOriginalClass(PsiClass psiClass) { - PsiCompiledElement cls = psiClass.getUserData(ClsElementImpl.COMPILED_ELEMENT); - if (cls != null && cls.isValid()) { - return (PsiClass)cls; + @Inject + public JavaPsiImplementationHelperImpl(Project project, MemberOrderService memberOrderService) { + myProject = project; + myMemberOrderService = memberOrderService; } - if (DumbService.isDumb(myProject)) { - return psiClass; - } + @Override + public PsiClass getOriginalClass(PsiClass psiClass) { + PsiCompiledElement cls = psiClass.getUserData(ClsElementImpl.COMPILED_ELEMENT); + if (cls != null && cls.isValid()) { + return (PsiClass)cls; + } - VirtualFile vFile = psiClass.getContainingFile().getVirtualFile(); - final ProjectFileIndex idx = ProjectRootManager.getInstance(myProject).getFileIndex(); - if (vFile == null || !idx.isInLibrarySource(vFile)) { - return psiClass; - } + if (DumbService.isDumb(myProject)) { + return psiClass; + } - String fqn = psiClass.getQualifiedName(); - if (fqn == null) { - return psiClass; - } + VirtualFile vFile = psiClass.getContainingFile().getVirtualFile(); + final ProjectFileIndex idx = ProjectRootManager.getInstance(myProject).getFileIndex(); + if (vFile == null || !idx.isInLibrarySource(vFile)) { + return psiClass; + } - final Set orderEntries = Set.copyOf(idx.getOrderEntriesForFile(vFile)); - GlobalSearchScope librariesScope = LibraryScopeCache.getInstance(myProject).getLibrariesOnlyScope(); - for (PsiClass original : JavaPsiFacade.getInstance(myProject).findClasses(fqn, librariesScope)) { - PsiFile psiFile = original.getContainingFile(); - if (psiFile != null) { - VirtualFile candidateFile = psiFile.getVirtualFile(); - if (candidateFile != null) { - // order for file and vFile has non empty intersection. - List entries = idx.getOrderEntriesForFile(candidateFile); - //noinspection ForLoopReplaceableByForEach - for (int i = 0; i < entries.size(); i++) { - if (orderEntries.contains(entries.get(i))) { - return original; - } - } + String fqn = psiClass.getQualifiedName(); + if (fqn == null) { + return psiClass; } - } - } - return psiClass; - } + final Set orderEntries = Set.copyOf(idx.getOrderEntriesForFile(vFile)); + GlobalSearchScope librariesScope = LibraryScopeCache.getInstance(myProject).getLibrariesOnlyScope(); + for (PsiClass original : JavaPsiFacade.getInstance(myProject).findClasses(fqn, librariesScope)) { + PsiFile psiFile = original.getContainingFile(); + if (psiFile != null) { + VirtualFile candidateFile = psiFile.getVirtualFile(); + if (candidateFile != null) { + // order for file and vFile has non empty intersection. + List entries = idx.getOrderEntriesForFile(candidateFile); + //noinspection ForLoopReplaceableByForEach + for (int i = 0; i < entries.size(); i++) { + if (orderEntries.contains(entries.get(i))) { + return original; + } + } + } + } + } - @Override - public PsiElement getClsFileNavigationElement(PsiJavaFile clsFile) { - PsiClass[] classes = clsFile.getClasses(); - if (classes.length == 0) { - return clsFile; + return psiClass; } - String sourceFileName = ((ClsClassImpl)classes[0]).getSourceFileName(); - String packageName = clsFile.getPackageName(); - String relativePath = packageName.isEmpty() ? sourceFileName : packageName.replace('.', '/') + '/' + sourceFileName; + @Override + public PsiElement getClsFileNavigationElement(PsiJavaFile clsFile) { + PsiClass[] classes = clsFile.getClasses(); + if (classes.length == 0) { + return clsFile; + } - ProjectFileIndex index = ProjectFileIndex.getInstance(clsFile.getProject()); - for (OrderEntry orderEntry : index.getOrderEntriesForFile(clsFile.getContainingFile().getVirtualFile())) { - if (!(orderEntry instanceof OrderEntryWithTracking)) { - continue; - } - for (VirtualFile root : orderEntry.getFiles(SourcesOrderRootType.getInstance())) { - VirtualFile source = root.findFileByRelativePath(relativePath); - if (source != null && source.isValid()) { - PsiFile psiSource = clsFile.getManager().findFile(source); - if (psiSource instanceof PsiClassOwner) { - return psiSource; - } + String sourceFileName = ((ClsClassImpl)classes[0]).getSourceFileName(); + String packageName = clsFile.getPackageName(); + String relativePath = packageName.isEmpty() ? sourceFileName : packageName.replace('.', '/') + '/' + sourceFileName; + + ProjectFileIndex index = ProjectFileIndex.getInstance(clsFile.getProject()); + for (OrderEntry orderEntry : index.getOrderEntriesForFile(clsFile.getContainingFile().getVirtualFile())) { + if (!(orderEntry instanceof OrderEntryWithTracking)) { + continue; + } + for (VirtualFile root : orderEntry.getFiles(SourcesOrderRootType.getInstance())) { + VirtualFile source = root.findFileByRelativePath(relativePath); + if (source != null && source.isValid()) { + PsiFile psiSource = clsFile.getManager().findFile(source); + if (psiSource instanceof PsiClassOwner) { + return psiSource; + } + } + } } - } - } - return clsFile; - } + return clsFile; + } - @Nullable - @Override - public LanguageLevel getClassesLanguageLevel(VirtualFile virtualFile) { - final ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex(); - final VirtualFile sourceRoot = index.getSourceRootForFile(virtualFile); - final VirtualFile folder = virtualFile.getParent(); - if (sourceRoot != null && folder != null) { - String relativePath = VirtualFileUtil.getRelativePath(folder, sourceRoot, '/'); - if (relativePath == null) { - throw new AssertionError("Null relative path: folder=" + folder + "; root=" + sourceRoot); - } - List orderEntries = index.getOrderEntriesForFile(virtualFile); - if (orderEntries.isEmpty()) { - LOG.error("Inconsistent: " + DirectoryIndex.getInstance(myProject).getInfoForFile(folder).toString()); - } - final VirtualFile[] files = orderEntries.get(0).getFiles(BinariesOrderRootType.getInstance()); - for (VirtualFile rootFile : files) { - final VirtualFile classFile = rootFile.findFileByRelativePath(relativePath); - if (classFile != null) { - final PsiJavaFile javaFile = getPsiFileInRoot(classFile); - if (javaFile != null) { - return javaFile.getLanguageLevel(); - } + @Nullable + @Override + public LanguageLevel getClassesLanguageLevel(VirtualFile virtualFile) { + final ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex(); + final VirtualFile sourceRoot = index.getSourceRootForFile(virtualFile); + final VirtualFile folder = virtualFile.getParent(); + if (sourceRoot != null && folder != null) { + String relativePath = VirtualFileUtil.getRelativePath(folder, sourceRoot, '/'); + if (relativePath == null) { + throw new AssertionError("Null relative path: folder=" + folder + "; root=" + sourceRoot); + } + List orderEntries = index.getOrderEntriesForFile(virtualFile); + if (orderEntries.isEmpty()) { + LOG.error("Inconsistent: " + DirectoryIndex.getInstance(myProject).getInfoForFile(folder).toString()); + } + final VirtualFile[] files = orderEntries.get(0).getFiles(BinariesOrderRootType.getInstance()); + for (VirtualFile rootFile : files) { + final VirtualFile classFile = rootFile.findFileByRelativePath(relativePath); + if (classFile != null) { + final PsiJavaFile javaFile = getPsiFileInRoot(classFile); + if (javaFile != null) { + return javaFile.getLanguageLevel(); + } + } + } + final Module moduleForFile = ModuleUtilCore.findModuleForFile(virtualFile, myProject); + if (moduleForFile == null) { + return null; + } + final JavaModuleExtension extension = ModuleUtilCore.getExtension(moduleForFile, JavaModuleExtension.class); + return extension == null ? null : extension.getLanguageLevel(); } - } - final Module moduleForFile = ModuleUtilCore.findModuleForFile(virtualFile, myProject); - if (moduleForFile == null) { return null; - } - final JavaModuleExtension extension = ModuleUtilCore.getExtension(moduleForFile, JavaModuleExtension.class); - return extension == null ? null : extension.getLanguageLevel(); } - return null; - } - @Nullable - private PsiJavaFile getPsiFileInRoot(final VirtualFile dirFile) { - final VirtualFile[] children = dirFile.getChildren(); - for (VirtualFile child : children) { - if (JavaClassFileType.INSTANCE.equals(child.getFileType())) { - final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(child); - if (psiFile instanceof PsiJavaFile) { - return (PsiJavaFile)psiFile; + @Nullable + private PsiJavaFile getPsiFileInRoot(final VirtualFile dirFile) { + final VirtualFile[] children = dirFile.getChildren(); + for (VirtualFile child : children) { + if (JavaClassFileType.INSTANCE.equals(child.getFileType())) { + final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(child); + if (psiFile instanceof PsiJavaFile) { + return (PsiJavaFile)psiFile; + } + } } - } + return null; } - return null; - } - @Override - public ASTNode getDefaultImportAnchor(PsiImportList list, PsiImportStatementBase statement) { - CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(list.getProject()); - ImportHelper importHelper = new ImportHelper(settings); - return importHelper.getDefaultAnchor(list, statement); - } - - @Nullable - @Override - @RequiredReadAction - public PsiElement getDefaultMemberAnchor(@Nonnull PsiClass aClass, @Nonnull PsiMember member) { - CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(aClass.getProject()); - PsiElement anchor = myMemberOrderService.getAnchor(member, settings.getCommonSettings(JavaLanguage.INSTANCE), aClass); - - PsiElement newAnchor = skipWhitespaces(aClass, anchor); - if (newAnchor != null) { - return newAnchor; + @Override + public ASTNode getDefaultImportAnchor(PsiImportList list, PsiImportStatementBase statement) { + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(list.getProject()); + ImportHelper importHelper = new ImportHelper(settings); + return importHelper.getDefaultAnchor(list, statement); } - if (anchor != null && anchor != aClass) { - anchor = anchor.getNextSibling(); - while (anchor instanceof PsiJavaToken && (anchor.getText().equals(",") || anchor.getText().equals(";"))) { - final boolean afterComma = anchor.getText().equals(","); - anchor = anchor.getNextSibling(); - if (afterComma) { - newAnchor = skipWhitespaces(aClass, anchor); - if (newAnchor != null) { + @Nullable + @Override + @RequiredReadAction + public PsiElement getDefaultMemberAnchor(@Nonnull PsiClass aClass, @Nonnull PsiMember member) { + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(aClass.getProject()); + PsiElement anchor = myMemberOrderService.getAnchor(member, settings.getCommonSettings(JavaLanguage.INSTANCE), aClass); + + PsiElement newAnchor = skipWhitespaces(aClass, anchor); + if (newAnchor != null) { return newAnchor; - } } - } - if (anchor != null) { - return anchor; - } - } - // The main idea is to avoid to anchor to 'white space' element because that causes reformatting algorithm - // to perform incorrectly. The algorithm is encapsulated at the PostprocessReformattingAspect.doPostponedFormattingInner(). - final PsiElement lBrace = aClass.getLBrace(); - if (lBrace != null) { - PsiElement result = lBrace.getNextSibling(); - while (result instanceof PsiWhiteSpace) { - result = result.getNextSibling(); - } - return result; - } + if (anchor != null && anchor != aClass) { + anchor = anchor.getNextSibling(); + while (anchor instanceof PsiJavaToken && (anchor.getText().equals(",") || anchor.getText().equals(";"))) { + final boolean afterComma = anchor.getText().equals(","); + anchor = anchor.getNextSibling(); + if (afterComma) { + newAnchor = skipWhitespaces(aClass, anchor); + if (newAnchor != null) { + return newAnchor; + } + } + } + if (anchor != null) { + return anchor; + } + } - return aClass.getRBrace(); - } + // The main idea is to avoid to anchor to 'white space' element because that causes reformatting algorithm + // to perform incorrectly. The algorithm is encapsulated at the PostprocessReformattingAspect.doPostponedFormattingInner(). + final PsiElement lBrace = aClass.getLBrace(); + if (lBrace != null) { + PsiElement result = lBrace.getNextSibling(); + while (result instanceof PsiWhiteSpace) { + result = result.getNextSibling(); + } + return result; + } - private static PsiElement skipWhitespaces(PsiClass aClass, PsiElement anchor) { - if (anchor != null && PsiTreeUtil.skipSiblingsForward(anchor, PsiWhiteSpace.class) == aClass.getRBrace()) { - // Given member should be inserted as the last child. - return aClass.getRBrace(); + return aClass.getRBrace(); } - return null; - } - - @Override - public void setupCatchBlock(String exceptionName, PsiElement context, PsiCatchSection catchSection) { - final FileTemplate catchBodyTemplate = - FileTemplateManager.getInstance(catchSection.getProject()).getCodeTemplate(JavaTemplateUtil.TEMPLATE_CATCH_BODY); - LOG.assertTrue(catchBodyTemplate != null); - final Properties props = new Properties(); - props.setProperty(FileTemplate.ATTRIBUTE_EXCEPTION, exceptionName); - if (context != null && context.isPhysical()) { - final PsiDirectory directory = context.getContainingFile().getContainingDirectory(); - if (directory != null) { - JavaTemplateUtil.setPackageNameAttribute(props, directory); - } + private static PsiElement skipWhitespaces(PsiClass aClass, PsiElement anchor) { + if (anchor != null && PsiTreeUtil.skipSiblingsForward(anchor, PsiWhiteSpace.class) == aClass.getRBrace()) { + // Given member should be inserted as the last child. + return aClass.getRBrace(); + } + return null; } - final PsiCodeBlock codeBlockFromText; - try { - codeBlockFromText = - PsiElementFactory.getInstance(myProject).createCodeBlockFromText("{\n" + catchBodyTemplate.getText(props) + "\n}", null); - } - catch (ProcessCanceledException ce) { - throw ce; - } - catch (Throwable e) { - throw new IncorrectOperationException("Incorrect file template", e); + @Override + public void setupCatchBlock(String exceptionName, PsiElement context, PsiCatchSection catchSection) { + final FileTemplate catchBodyTemplate = + FileTemplateManager.getInstance(catchSection.getProject()).getCodeTemplate(JavaTemplateUtil.TEMPLATE_CATCH_BODY); + LOG.assertTrue(catchBodyTemplate != null); + + final Properties props = new Properties(); + props.setProperty(FileTemplate.ATTRIBUTE_EXCEPTION, exceptionName); + if (context != null && context.isPhysical()) { + final PsiDirectory directory = context.getContainingFile().getContainingDirectory(); + if (directory != null) { + JavaTemplateUtil.setPackageNameAttribute(props, directory); + } + } + + final PsiCodeBlock codeBlockFromText; + try { + codeBlockFromText = + PsiElementFactory.getInstance(myProject).createCodeBlockFromText("{\n" + catchBodyTemplate.getText(props) + "\n}", null); + } + catch (ProcessCanceledException ce) { + throw ce; + } + catch (Throwable e) { + throw new IncorrectOperationException("Incorrect file template", e); + } + catchSection.getCatchBlock().replace(codeBlockFromText); } - catchSection.getCatchBlock().replace(codeBlockFromText); - } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationRules.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationRules.java index 51f06c6b9..5c422af96 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationRules.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationRules.java @@ -31,112 +31,107 @@ /** * @author db */ -public class TypeMigrationRules -{ - private final List myConversionRules; - private final Map myConversionCustomSettings = new HashMap<>(); - private final Project myProject; - private SearchScope mySearchScope; - - public TypeMigrationRules(@Nonnull Project project) - { - myProject = project; - TypeConversionRule[] extensions = TypeConversionRule.EP_NAME.getExtensions(); - myConversionRules = new ArrayList<>(extensions.length + 2); - myConversionRules.add(new RootTypeConversionRule()); - myConversionRules.add(new DisjunctionTypeConversionRule()); - ContainerUtil.addAll(myConversionRules, extensions); - addConversionRuleSettings(new MigrateGetterNameSetting()); - } - - public void addConversionDescriptor(TypeConversionRule rule) - { - myConversionRules.add(rule); - } - - public void addConversionRuleSettings(Object settings) - { - myConversionCustomSettings.put(settings.getClass(), settings); - } - - public T getConversionSettings(Class aClass) - { - return (T) myConversionCustomSettings.get(aClass); - } - - @NonNls - @Nullable - public TypeConversionDescriptorBase findConversion(final PsiType from, - final PsiType to, - final PsiMember member, - final PsiExpression context, - final boolean isCovariantPosition, - final TypeMigrationLabeler labeler) - { - final TypeConversionDescriptorBase conversion = findConversion(from, to, member, context, labeler); - if(conversion != null) - { - return conversion; - } - - if(isCovariantPosition) - { - if(to instanceof PsiEllipsisType) - { - if(TypeConversionUtil.isAssignable(((PsiEllipsisType) to).getComponentType(), from)) - { - return new TypeConversionDescriptorBase(); - } - } - if(TypeConversionUtil.isAssignable(to, from)) - { - return new TypeConversionDescriptorBase(); - } - } - - return !isCovariantPosition && TypeConversionUtil.isAssignable(from, to) ? new TypeConversionDescriptorBase() : null; - } - - @Nullable - public TypeConversionDescriptorBase findConversion(final PsiType from, final PsiType to, final PsiMember member, final PsiExpression context, final TypeMigrationLabeler labeler) - { - for(TypeConversionRule descriptor : myConversionRules) - { - final TypeConversionDescriptorBase conversion = descriptor.findConversion(from, to, member, context, labeler); - if(conversion != null) - { - return conversion; - } - } - return null; - } - - public boolean shouldConvertNull(final PsiType from, final PsiType to, PsiExpression context) - { - return myConversionRules.stream().anyMatch(rule -> rule.shouldConvertNullInitializer(from, to, context)); - } - - public void setBoundScope(@Nonnull SearchScope searchScope) - { - mySearchScope = searchScope.intersectWith(GlobalSearchScope.notScope(LibraryScopeCache.getInstance(myProject).getLibrariesOnlyScope())); - } - - public SearchScope getSearchScope() - { - return mySearchScope; - } - - @Nullable - public Pair bindTypeParameters(final PsiType from, final PsiType to, final PsiMethod method, final PsiExpression context, final TypeMigrationLabeler labeler) - { - for(TypeConversionRule conversionRule : myConversionRules) - { - final Pair typePair = conversionRule.bindTypeParameters(from, to, method, context, labeler); - if(typePair != null) - { - return typePair; - } - } - return null; - } +public class TypeMigrationRules { + private final List myConversionRules; + private final Map myConversionCustomSettings = new HashMap<>(); + private final Project myProject; + private SearchScope mySearchScope; + + public TypeMigrationRules(@Nonnull Project project) { + myProject = project; + TypeConversionRule[] extensions = TypeConversionRule.EP_NAME.getExtensions(); + myConversionRules = new ArrayList<>(extensions.length + 2); + myConversionRules.add(new RootTypeConversionRule()); + myConversionRules.add(new DisjunctionTypeConversionRule()); + ContainerUtil.addAll(myConversionRules, extensions); + addConversionRuleSettings(new MigrateGetterNameSetting()); + } + + public void addConversionDescriptor(TypeConversionRule rule) { + myConversionRules.add(rule); + } + + public void addConversionRuleSettings(Object settings) { + myConversionCustomSettings.put(settings.getClass(), settings); + } + + public T getConversionSettings(Class aClass) { + return (T)myConversionCustomSettings.get(aClass); + } + + @NonNls + @Nullable + public TypeConversionDescriptorBase findConversion( + final PsiType from, + final PsiType to, + final PsiMember member, + final PsiExpression context, + final boolean isCovariantPosition, + final TypeMigrationLabeler labeler + ) { + final TypeConversionDescriptorBase conversion = findConversion(from, to, member, context, labeler); + if (conversion != null) { + return conversion; + } + + if (isCovariantPosition) { + if (to instanceof PsiEllipsisType) { + if (TypeConversionUtil.isAssignable(((PsiEllipsisType)to).getComponentType(), from)) { + return new TypeConversionDescriptorBase(); + } + } + if (TypeConversionUtil.isAssignable(to, from)) { + return new TypeConversionDescriptorBase(); + } + } + + return !isCovariantPosition && TypeConversionUtil.isAssignable(from, to) ? new TypeConversionDescriptorBase() : null; + } + + @Nullable + public TypeConversionDescriptorBase findConversion( + final PsiType from, + final PsiType to, + final PsiMember member, + final PsiExpression context, + final TypeMigrationLabeler labeler + ) { + for (TypeConversionRule descriptor : myConversionRules) { + final TypeConversionDescriptorBase conversion = descriptor.findConversion(from, to, member, context, labeler); + if (conversion != null) { + return conversion; + } + } + return null; + } + + public boolean shouldConvertNull(final PsiType from, final PsiType to, PsiExpression context) { + return myConversionRules.stream().anyMatch(rule -> rule.shouldConvertNullInitializer(from, to, context)); + } + + public void setBoundScope(@Nonnull SearchScope searchScope) { + mySearchScope = + searchScope.intersectWith(GlobalSearchScope.notScope(LibraryScopeCache.getInstance(myProject).getLibrariesOnlyScope())); + } + + public SearchScope getSearchScope() { + return mySearchScope; + } + + @Nullable + public Pair bindTypeParameters( + final PsiType from, + final PsiType to, + final PsiMethod method, + final PsiExpression context, + final TypeMigrationLabeler labeler + ) { + for (TypeConversionRule conversionRule : myConversionRules) { + final Pair typePair = conversionRule.bindTypeParameters(from, to, method, context, labeler); + if (typePair != null) { + return typePair; + } + } + return null; + } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/DisjunctionTypeConversionRule.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/DisjunctionTypeConversionRule.java index 254dd8498..3911b6566 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/DisjunctionTypeConversionRule.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/DisjunctionTypeConversionRule.java @@ -23,59 +23,51 @@ import com.intellij.java.impl.refactoring.typeMigration.TypeConversionDescriptorBase; import com.intellij.java.impl.refactoring.typeMigration.TypeMigrationLabeler; -public class DisjunctionTypeConversionRule extends TypeConversionRule -{ - @Override - public TypeConversionDescriptorBase findConversion(final PsiType from, final PsiType to, final PsiMember member, final PsiExpression context, final TypeMigrationLabeler labeler) - { - if(from instanceof PsiDisjunctionType) - { - final PsiType lub = ((PsiDisjunctionType) from).getLeastUpperBound(); - if(lub instanceof PsiIntersectionType) - { - for(PsiType type : ((PsiIntersectionType) lub).getConjuncts()) - { - final TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(type, to, member, context, labeler); - if(conversion != null) - { - return conversion; - } - } - } - else - { - final TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(lub, to, member, context, labeler); - if(conversion != null) - { - return conversion; - } - } - } +public class DisjunctionTypeConversionRule extends TypeConversionRule { + @Override + public TypeConversionDescriptorBase findConversion( + final PsiType from, + final PsiType to, + final PsiMember member, + final PsiExpression context, + final TypeMigrationLabeler labeler + ) { + if (from instanceof PsiDisjunctionType) { + final PsiType lub = ((PsiDisjunctionType)from).getLeastUpperBound(); + if (lub instanceof PsiIntersectionType) { + for (PsiType type : ((PsiIntersectionType)lub).getConjuncts()) { + final TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(type, to, member, context, labeler); + if (conversion != null) { + return conversion; + } + } + } + else { + final TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(lub, to, member, context, labeler); + if (conversion != null) { + return conversion; + } + } + } - if(to instanceof PsiDisjunctionType) - { - final PsiType lub = ((PsiDisjunctionType) to).getLeastUpperBound(); - if(lub instanceof PsiIntersectionType) - { - for(PsiType type : ((PsiIntersectionType) lub).getConjuncts()) - { - final TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(from, type, member, context, labeler); - if(conversion != null) - { - return conversion; - } - } - } - else - { - final TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(from, lub, member, context, labeler); - if(conversion != null) - { - return conversion; - } - } - } + if (to instanceof PsiDisjunctionType) { + final PsiType lub = ((PsiDisjunctionType)to).getLeastUpperBound(); + if (lub instanceof PsiIntersectionType) { + for (PsiType type : ((PsiIntersectionType)lub).getConjuncts()) { + final TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(from, type, member, context, labeler); + if (conversion != null) { + return conversion; + } + } + } + else { + final TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(from, lub, member, context, labeler); + if (conversion != null) { + return conversion; + } + } + } - return null; - } + return null; + } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/RootTypeConversionRule.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/RootTypeConversionRule.java index 7cb068e17..8d976bd43 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/RootTypeConversionRule.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/RootTypeConversionRule.java @@ -28,166 +28,217 @@ import consulo.util.lang.Comparing; import jakarta.annotation.Nonnull; + import java.util.Arrays; /** * @author anna */ public class RootTypeConversionRule extends TypeConversionRule { - public TypeConversionDescriptorBase findConversion(final PsiType from, final PsiType to, final PsiMember member, final PsiExpression context, final TypeMigrationLabeler labeler) { - if (member != null && to instanceof PsiClassType && from instanceof PsiClassType) { - final PsiClass targetClass = ((PsiClassType) to).resolve(); - if (targetClass != null && member.isPhysical()) { - if (member instanceof PsiMethod) { - PsiMethod method = (PsiMethod) member; - PsiMethod replacer = targetClass.findMethodBySignature(method, true); - if (replacer == null) { - for (PsiMethod superMethod : method.findDeepestSuperMethods()) { - replacer = targetClass.findMethodBySignature(superMethod, true); - if (replacer != null) { - method = superMethod; - break; - } - } - } - if (replacer != null) { - final boolean isStaticMethodConversion = replacer.hasModifierProperty(PsiModifier.STATIC); - boolean isValid = isStaticMethodConversion ? TypeConversionUtil.areTypesConvertible(method.getReturnType(), from) && TypeConversionUtil.areTypesConvertible(replacer - .getReturnType(), to) : TypeConversionUtil.areTypesConvertible(method.getReturnType(), replacer.getReturnType()); - if (isValid) { - final PsiElement parent = context.getParent(); - if (context instanceof PsiMethodReferenceExpression) { - final PsiType functionalInterfaceType = ((PsiMethodReferenceExpression) context).getFunctionalInterfaceType(); - if (Comparing.equal(functionalInterfaceType, to) && method.isEquivalentTo(LambdaUtil.getFunctionalInterfaceMethod(from))) { - return new TypeConversionDescriptorBase() { - @Override - public PsiExpression replace(PsiExpression expression, @Nonnull TypeEvaluator evaluator) throws IncorrectOperationException { - final PsiMethodReferenceExpression methodReferenceExpression = (PsiMethodReferenceExpression) expression; - final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression(); - if (qualifierExpression != null) { - return (PsiExpression) expression.replace(qualifierExpression); - } else { - return expression; - } + public TypeConversionDescriptorBase findConversion( + final PsiType from, + final PsiType to, + final PsiMember member, + final PsiExpression context, + final TypeMigrationLabeler labeler + ) { + if (member != null && to instanceof PsiClassType && from instanceof PsiClassType) { + final PsiClass targetClass = ((PsiClassType)to).resolve(); + if (targetClass != null && member.isPhysical()) { + if (member instanceof PsiMethod) { + PsiMethod method = (PsiMethod)member; + PsiMethod replacer = targetClass.findMethodBySignature(method, true); + if (replacer == null) { + for (PsiMethod superMethod : method.findDeepestSuperMethods()) { + replacer = targetClass.findMethodBySignature(superMethod, true); + if (replacer != null) { + method = superMethod; + break; + } + } } - }; - } - } - if (context instanceof PsiReferenceExpression && parent instanceof PsiMethodCallExpression) { - final JavaResolveResult resolveResult = ((PsiReferenceExpression) context).advancedResolve(false); - final PsiSubstitutor aSubst; - final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression) parent).getMethodExpression(); - final PsiExpression qualifier = methodExpression.getQualifierExpression(); - final PsiClass substitutionClass = method.getContainingClass(); - if (qualifier != null) { - final PsiType evaluatedQualifierType = labeler.getTypeEvaluator().evaluateType(qualifier); - if (evaluatedQualifierType instanceof PsiClassType) { - aSubst = ((PsiClassType) evaluatedQualifierType).resolveGenerics().getSubstitutor(); - } else { - aSubst = PsiSubstitutor.EMPTY; - } - } else { - aSubst = TypeConversionUtil.getClassSubstitutor(member.getContainingClass(), substitutionClass, PsiSubstitutor.EMPTY); - } + if (replacer != null) { + final boolean isStaticMethodConversion = replacer.hasModifierProperty(PsiModifier.STATIC); + boolean isValid = isStaticMethodConversion + ? TypeConversionUtil.areTypesConvertible(method.getReturnType(), from) + && TypeConversionUtil.areTypesConvertible(replacer.getReturnType(), to) + : TypeConversionUtil.areTypesConvertible(method.getReturnType(), replacer.getReturnType()); + if (isValid) { + final PsiElement parent = context.getParent(); + if (context instanceof PsiMethodReferenceExpression) { + final PsiType functionalInterfaceType = + ((PsiMethodReferenceExpression)context).getFunctionalInterfaceType(); + if (Comparing.equal(functionalInterfaceType, to) + && method.isEquivalentTo(LambdaUtil.getFunctionalInterfaceMethod(from))) { + return new TypeConversionDescriptorBase() { + @Override + public PsiExpression replace( + PsiExpression expression, + @Nonnull TypeEvaluator evaluator + ) throws IncorrectOperationException { + final PsiMethodReferenceExpression methodReferenceExpression = + (PsiMethodReferenceExpression)expression; + final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression(); + if (qualifierExpression != null) { + return (PsiExpression)expression.replace(qualifierExpression); + } + else { + return expression; + } + } + }; + } + } + if (context instanceof PsiReferenceExpression && parent instanceof PsiMethodCallExpression) { + final JavaResolveResult resolveResult = ((PsiReferenceExpression)context).advancedResolve(false); + final PsiSubstitutor aSubst; + final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)parent).getMethodExpression(); + final PsiExpression qualifier = methodExpression.getQualifierExpression(); + final PsiClass substitutionClass = method.getContainingClass(); + if (qualifier != null) { + final PsiType evaluatedQualifierType = labeler.getTypeEvaluator().evaluateType(qualifier); + if (evaluatedQualifierType instanceof PsiClassType) { + aSubst = ((PsiClassType)evaluatedQualifierType).resolveGenerics().getSubstitutor(); + } + else { + aSubst = PsiSubstitutor.EMPTY; + } + } + else { + aSubst = TypeConversionUtil.getClassSubstitutor( + member.getContainingClass(), + substitutionClass, + PsiSubstitutor.EMPTY + ); + } - final PsiParameter[] originalParams = ((PsiMethod) member).getParameterList().getParameters(); - final PsiParameter[] migrationParams = replacer.getParameterList().getParameters(); - final PsiExpression[] actualParams = ((PsiMethodCallExpression) parent).getArgumentList().getExpressions(); + final PsiParameter[] originalParams = ((PsiMethod)member).getParameterList().getParameters(); + final PsiParameter[] migrationParams = replacer.getParameterList().getParameters(); + final PsiExpression[] actualParams = ((PsiMethodCallExpression)parent).getArgumentList().getExpressions(); - assert originalParams.length == migrationParams.length; - final PsiSubstitutor methodTypeParamsSubstitutor = labeler.getTypeEvaluator().createMethodSubstitution(originalParams, actualParams, method, context, aSubst != null ? - aSubst : PsiSubstitutor.EMPTY, true); - for (int i = 0; i < originalParams.length; i++) { - final PsiType originalType = resolveResult.getSubstitutor().substitute(originalParams[i].getType()); + assert originalParams.length == migrationParams.length; + final PsiSubstitutor methodTypeParamsSubstitutor = labeler.getTypeEvaluator().createMethodSubstitution( + originalParams, + actualParams, + method, + context, + aSubst != null ? aSubst : PsiSubstitutor.EMPTY, + true + ); + for (int i = 0; i < originalParams.length; i++) { + final PsiType originalType = resolveResult.getSubstitutor().substitute(originalParams[i].getType()); - PsiType type = migrationParams[i].getType(); - if (InheritanceUtil.isInheritorOrSelf(targetClass, substitutionClass, true)) { - final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getClassSubstitutor(substitutionClass, targetClass, PsiSubstitutor.EMPTY); - assert (superClassSubstitutor != null); - type = superClassSubstitutor.substitute(type); - } + PsiType type = migrationParams[i].getType(); + if (InheritanceUtil.isInheritorOrSelf(targetClass, substitutionClass, true)) { + final PsiSubstitutor superClassSubstitutor = + TypeConversionUtil.getClassSubstitutor(substitutionClass, targetClass, PsiSubstitutor.EMPTY); + assert (superClassSubstitutor != null); + type = superClassSubstitutor.substitute(type); + } - final PsiType migrationType = methodTypeParamsSubstitutor.substitute(type); - if (!originalType.equals(migrationType) && !areParametersAssignable(migrationType, i, actualParams)) { - if (migrationType instanceof PsiEllipsisType && actualParams.length != migrationParams.length) { - return null; + final PsiType migrationType = methodTypeParamsSubstitutor.substitute(type); + if (!originalType.equals(migrationType) && !areParametersAssignable(migrationType, i, actualParams)) { + if (migrationType instanceof PsiEllipsisType && actualParams.length != migrationParams.length) { + return null; + } + labeler.migrateExpressionType(actualParams[i], migrationType, context, false, true); + } + } + } + return isStaticMethodConversion ? new MyStaticMethodConversionDescriptor(targetClass) : new TypeConversionDescriptorBase(); + } + } + } + else if (member instanceof PsiField) { + final PsiClass fieldContainingClass = member.getContainingClass(); + if (InheritanceUtil.isInheritorOrSelf(targetClass, fieldContainingClass, true)) { + return new TypeConversionDescriptorBase(); } - labeler.migrateExpressionType(actualParams[i], migrationType, context, false, true); - } } - } - return isStaticMethodConversion ? new MyStaticMethodConversionDescriptor(targetClass) : new TypeConversionDescriptorBase(); } - } - } else if (member instanceof PsiField) { - final PsiClass fieldContainingClass = member.getContainingClass(); - if (InheritanceUtil.isInheritorOrSelf(targetClass, fieldContainingClass, true)) { - return new TypeConversionDescriptorBase(); - } } - } + return null; } - return null; - } - private static boolean areParametersAssignable(PsiType migrationType, int paramId, PsiExpression[] actualParams) { - if (migrationType instanceof PsiEllipsisType) { - if (actualParams.length == paramId) { - // no arguments for ellipsis - return true; - } else if (actualParams.length == paramId + 1) { - // only one argument for ellipsis - return TypeConversionUtil.areTypesAssignmentCompatible(migrationType, actualParams[paramId]) || TypeConversionUtil.areTypesAssignmentCompatible(((PsiEllipsisType) migrationType) - .getComponentType(), actualParams[paramId]); - } else if (actualParams.length > paramId + 1) { - // few arguments - PsiType componentType = ((PsiEllipsisType) migrationType).getComponentType(); - for (int i = paramId; i < actualParams.length; i++) { - if (!TypeConversionUtil.areTypesAssignmentCompatible(componentType, actualParams[i])) { - return false; - } + private static boolean areParametersAssignable(PsiType migrationType, int paramId, PsiExpression[] actualParams) { + if (migrationType instanceof PsiEllipsisType) { + if (actualParams.length == paramId) { + // no arguments for ellipsis + return true; + } + else if (actualParams.length == paramId + 1) { + // only one argument for ellipsis + return TypeConversionUtil.areTypesAssignmentCompatible(migrationType, actualParams[paramId]) + || TypeConversionUtil.areTypesAssignmentCompatible( + ((PsiEllipsisType)migrationType).getComponentType(), + actualParams[paramId] + ); + } + else if (actualParams.length > paramId + 1) { + // few arguments + PsiType componentType = ((PsiEllipsisType)migrationType).getComponentType(); + for (int i = paramId; i < actualParams.length; i++) { + if (!TypeConversionUtil.areTypesAssignmentCompatible(componentType, actualParams[i])) { + return false; + } + } + return true; + } + throw new AssertionError( + " migrationType: " + migrationType + + ", paramId: " + paramId + + ", actualParameters: " + Arrays.toString(actualParams) + ); + } + else { + if (paramId >= actualParams.length) { + return true; + } + return TypeConversionUtil.areTypesAssignmentCompatible(migrationType, actualParams[paramId]); } - return true; - } - throw new AssertionError(" migrationType: " + migrationType + ", paramId: " + paramId + ", actualParameters: " + Arrays.toString(actualParams)); - } else { - if (paramId >= actualParams.length) { - return true; - } - return TypeConversionUtil.areTypesAssignmentCompatible(migrationType, actualParams[paramId]); } - } - private static class MyStaticMethodConversionDescriptor extends TypeConversionDescriptorBase { - private final - @Nonnull - String myTargetClassQName; + private static class MyStaticMethodConversionDescriptor extends TypeConversionDescriptorBase { + private final + @Nonnull + String myTargetClassQName; - private MyStaticMethodConversionDescriptor(PsiClass replacer) { - myTargetClassQName = replacer.getQualifiedName(); - } + private MyStaticMethodConversionDescriptor(PsiClass replacer) { + myTargetClassQName = replacer.getQualifiedName(); + } - @Override - public PsiExpression replace(PsiExpression expression, @Nonnull TypeEvaluator evaluator) throws IncorrectOperationException { - final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) expression; - final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression(); - final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(expression.getProject()); - final PsiMethodCallExpression newMethodCall; - if (qualifierExpression != null) { - JavaCodeStyleManager.getInstance(expression.getProject()).shortenClassReferences(qualifierExpression.replace(elementFactory.createExpressionFromText(myTargetClassQName, expression))); - newMethodCall = methodCallExpression; - } else { - newMethodCall = (PsiMethodCallExpression) expression.replace(elementFactory.createExpressionFromText(myTargetClassQName + "." + expression.getText(), expression)); - } - if (UnnecessarilyQualifiedStaticUsageInspection.isUnnecessarilyQualifiedAccess(newMethodCall.getMethodExpression(), false, false, false)) { - newMethodCall.getMethodExpression().getQualifierExpression().delete(); - } - return newMethodCall; - } + @Override + public PsiExpression replace(PsiExpression expression, @Nonnull TypeEvaluator evaluator) throws IncorrectOperationException { + final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression; + final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression(); + final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(expression.getProject()); + final PsiMethodCallExpression newMethodCall; + if (qualifierExpression != null) { + JavaCodeStyleManager.getInstance(expression.getProject()).shortenClassReferences( + qualifierExpression.replace(elementFactory.createExpressionFromText(myTargetClassQName, expression)) + ); + newMethodCall = methodCallExpression; + } + else { + newMethodCall = (PsiMethodCallExpression)expression.replace(elementFactory.createExpressionFromText( + myTargetClassQName + "." + expression.getText(), + expression + )); + } + if (UnnecessarilyQualifiedStaticUsageInspection.isUnnecessarilyQualifiedAccess( + newMethodCall.getMethodExpression(), + false, + false, + false + )) { + newMethodCall.getMethodExpression().getQualifierExpression().delete(); + } + return newMethodCall; + } - @Override - public String toString() { - return "Static method qualifier conversion -> " + myTargetClassQName; + @Override + public String toString() { + return "Static method qualifier conversion -> " + myTargetClassQName; + } } - } } \ No newline at end of file diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/TypeConversionRule.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/TypeConversionRule.java index 6da2c26c5..6616f3272 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/TypeConversionRule.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/TypeConversionRule.java @@ -32,26 +32,29 @@ */ @ExtensionAPI(ComponentScope.APPLICATION) public abstract class TypeConversionRule { - public static final ExtensionPointName EP_NAME = ExtensionPointName.create(TypeConversionRule.class); + public static final ExtensionPointName EP_NAME = ExtensionPointName.create(TypeConversionRule.class); - @Nullable - public abstract TypeConversionDescriptorBase findConversion(final PsiType from, - final PsiType to, - final PsiMember member, - final PsiExpression context, - final TypeMigrationLabeler labeler); + @Nullable + public abstract TypeConversionDescriptorBase findConversion( + final PsiType from, + final PsiType to, + final PsiMember member, + final PsiExpression context, + final TypeMigrationLabeler labeler + ); + @Nullable + public Pair bindTypeParameters( + PsiType from, + PsiType to, + final PsiMethod method, + final PsiExpression context, + final TypeMigrationLabeler labeler + ) { + return null; + } - @Nullable - public Pair bindTypeParameters(PsiType from, - PsiType to, - final PsiMethod method, - final PsiExpression context, - final TypeMigrationLabeler labeler) { - return null; - } - - public boolean shouldConvertNullInitializer(PsiType from, PsiType to, PsiExpression context) { - return false; - } + public boolean shouldConvertNullInitializer(PsiType from, PsiType to, PsiExpression context) { + return false; + } } \ No newline at end of file From da2df5bd69c4d743a0419c2b004759920816685b Mon Sep 17 00:00:00 2001 From: UNV Date: Fri, 11 Apr 2025 10:23:32 +0300 Subject: [PATCH 2/2] Refactoring of configuration producers. --- ...tractApplicationConfigurationProducer.java | 33 +++-- .../JarApplicationConfigurationProducer.java | 5 +- .../TestDiscoveryConfigurationProducer.java | 95 ++++++------- .../AbstractInClassConfigurationProducer.java | 83 ++++++----- .../impl/JavaPsiImplementationHelperImpl.java | 54 +++---- .../extractclass/EnumTypeConversionRule.java | 16 +-- .../typeMigration/TypeMigrationRules.java | 81 +++++------ .../rules/DisjunctionTypeConversionRule.java | 34 ++--- .../rules/RootTypeConversionRule.java | 132 +++++++++--------- .../rules/TypeConversionRule.java | 20 +-- 10 files changed, 276 insertions(+), 277 deletions(-) diff --git a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/application/AbstractApplicationConfigurationProducer.java b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/application/AbstractApplicationConfigurationProducer.java index 8e22b4630..b4449a8b9 100644 --- a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/application/AbstractApplicationConfigurationProducer.java +++ b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/application/AbstractApplicationConfigurationProducer.java @@ -28,33 +28,36 @@ import consulo.language.psi.util.PsiTreeUtil; import consulo.module.Module; import consulo.util.lang.Comparing; -import consulo.util.lang.ref.Ref; - +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nullable; public abstract class AbstractApplicationConfigurationProducer extends JavaRunConfigurationProducerBase { - public AbstractApplicationConfigurationProducer(final ApplicationConfigurationType configurationType) { + public AbstractApplicationConfigurationProducer(ApplicationConfigurationType configurationType) { super(configurationType); } @Override - protected boolean setupConfigurationFromContext(T configuration, ConfigurationContext context, Ref sourceElement) { - final Location contextLocation = context.getLocation(); + protected boolean setupConfigurationFromContext( + T configuration, + ConfigurationContext context, + SimpleReference sourceElement + ) { + Location contextLocation = context.getLocation(); if (contextLocation == null) { return false; } - final Location location = JavaExecutionUtil.stepIntoSingleClass(contextLocation); + Location location = JavaExecutionUtil.stepIntoSingleClass(contextLocation); if (location == null) { return false; } - final PsiElement element = location.getPsiElement(); + PsiElement element = location.getPsiElement(); if (!element.isPhysical()) { return false; } PsiElement currentElement = element; PsiMethod method; while ((method = findMain(currentElement)) != null) { - final PsiClass aClass = method.getContainingClass(); + PsiClass aClass = method.getContainingClass(); if (ConfigurationUtil.MAIN_CLASS.test(aClass)) { sourceElement.set(method); setupConfiguration(configuration, aClass, context); @@ -62,7 +65,7 @@ protected boolean setupConfigurationFromContext(T configuration, ConfigurationCo } currentElement = method.getParent(); } - final PsiClass aClass = ApplicationConfigurationType.getMainClass(element); + PsiClass aClass = ApplicationConfigurationType.getMainClass(element); if (aClass == null) { return false; } @@ -71,7 +74,7 @@ protected boolean setupConfigurationFromContext(T configuration, ConfigurationCo return true; } - private void setupConfiguration(T configuration, final PsiClass aClass, final ConfigurationContext context) { + private void setupConfiguration(T configuration, PsiClass aClass, ConfigurationContext context) { configuration.MAIN_CLASS_NAME = JavaExecutionUtil.getRuntimeQualifiedName(aClass); configuration.setGeneratedName(); setupConfigurationModule(context, configuration); @@ -93,22 +96,22 @@ private static PsiMethod findMain(PsiElement element) { @Override public boolean isConfigurationFromContext(T appConfiguration, ConfigurationContext context) { - final PsiElement location = context.getPsiLocation(); - final PsiClass aClass = ApplicationConfigurationType.getMainClass(location); + PsiElement location = context.getPsiLocation(); + PsiClass aClass = ApplicationConfigurationType.getMainClass(location); if (aClass != null && Comparing.equal(JavaExecutionUtil.getRuntimeQualifiedName(aClass), appConfiguration.MAIN_CLASS_NAME)) { - final PsiMethod method = PsiTreeUtil.getParentOfType(location, PsiMethod.class, false); + PsiMethod method = PsiTreeUtil.getParentOfType(location, PsiMethod.class, false); if (method != null && TestFrameworks.getInstance().isTestMethod(method)) { return false; } - final Module configurationModule = appConfiguration.getConfigurationModule().getModule(); + Module configurationModule = appConfiguration.getConfigurationModule().getModule(); if (Comparing.equal(context.getModule(), configurationModule)) { return true; } ApplicationConfiguration template = (ApplicationConfiguration)context.getRunManager().getConfigurationTemplate(getConfigurationFactory()).getConfiguration(); - final Module predefinedModule = template.getConfigurationModule().getModule(); + Module predefinedModule = template.getConfigurationModule().getModule(); if (Comparing.equal(predefinedModule, configurationModule)) { return true; } diff --git a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/jar/JarApplicationConfigurationProducer.java b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/jar/JarApplicationConfigurationProducer.java index 9f07acc21..1f395810e 100644 --- a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/jar/JarApplicationConfigurationProducer.java +++ b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/jar/JarApplicationConfigurationProducer.java @@ -21,9 +21,8 @@ import consulo.execution.action.RunConfigurationProducer; import consulo.language.psi.PsiElement; import consulo.util.io.FileUtil; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import consulo.virtualFileSystem.VirtualFile; - import jakarta.annotation.Nullable; /** @@ -39,7 +38,7 @@ public JarApplicationConfigurationProducer() { protected boolean setupConfigurationFromContext( JarApplicationConfiguration configuration, ConfigurationContext context, - Ref sourceElement + SimpleReference sourceElement ) { VirtualFile file = getJarFileFromContext(context); if (file != null) { diff --git a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testDiscovery/TestDiscoveryConfigurationProducer.java b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testDiscovery/TestDiscoveryConfigurationProducer.java index 54f28d77b..4a1e42a0b 100644 --- a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testDiscovery/TestDiscoveryConfigurationProducer.java +++ b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testDiscovery/TestDiscoveryConfigurationProducer.java @@ -15,38 +15,33 @@ */ package com.intellij.java.execution.impl.testDiscovery; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Set; - -import com.intellij.java.language.codeInsight.TestFrameworks; import com.intellij.java.execution.JavaExecutionUtil; import com.intellij.java.execution.impl.JavaTestConfigurationBase; -import consulo.execution.action.Location; -import consulo.execution.action.PsiLocation; +import com.intellij.java.execution.impl.junit.JavaRunConfigurationProducerBase; +import com.intellij.java.language.codeInsight.TestFrameworks; +import com.intellij.java.language.psi.PsiClass; +import com.intellij.java.language.psi.PsiMethod; +import com.intellij.java.language.testIntegration.TestFramework; +import consulo.annotation.access.RequiredReadAction; import consulo.execution.RunnerAndConfigurationSettings; import consulo.execution.action.ConfigurationContext; +import consulo.execution.action.Location; +import consulo.execution.action.PsiLocation; import consulo.execution.configuration.ConfigurationType; import consulo.execution.configuration.ModuleBasedConfiguration; -import com.intellij.java.execution.impl.junit.JavaRunConfigurationProducerBase; +import consulo.language.psi.PsiElement; +import consulo.language.psi.util.PsiTreeUtil; +import consulo.language.util.ModuleUtilCore; import consulo.module.Module; import consulo.module.ModuleManager; -import consulo.language.util.ModuleUtilCore; import consulo.project.Project; -import consulo.util.lang.Pair; -import consulo.util.lang.ref.Ref; -import consulo.util.lang.StringUtil; -import com.intellij.java.language.psi.PsiClass; -import consulo.language.psi.PsiElement; -import com.intellij.java.language.psi.PsiMethod; -import consulo.language.psi.util.PsiTreeUtil; -import com.intellij.java.language.testIntegration.TestFramework; import consulo.util.collection.ContainerUtil; +import consulo.util.lang.Couple; +import consulo.util.lang.StringUtil; +import consulo.util.lang.ref.SimpleReference; -import java.util.HashSet; +import java.io.IOException; +import java.util.*; public abstract class TestDiscoveryConfigurationProducer extends JavaRunConfigurationProducerBase { protected TestDiscoveryConfigurationProducer(ConfigurationType type) { @@ -55,30 +50,31 @@ protected TestDiscoveryConfigurationProducer(ConfigurationType type) { protected abstract void setPosition(JavaTestConfigurationBase configuration, PsiLocation position); - protected abstract Pair getPosition(JavaTestConfigurationBase configuration); + protected abstract Couple getPosition(JavaTestConfigurationBase configuration); @Override + @RequiredReadAction protected boolean setupConfigurationFromContext( - final JavaTestConfigurationBase configuration, + JavaTestConfigurationBase configuration, ConfigurationContext configurationContext, - Ref ref + SimpleReference ref ) { if (!TestDiscoveryExtension.TESTDISCOVERY_ENABLED) { return false; } - final Location contextLocation = configurationContext.getLocation(); + Location contextLocation = configurationContext.getLocation(); assert contextLocation != null; - final Location location = JavaExecutionUtil.stepIntoSingleClass(contextLocation); + Location location = JavaExecutionUtil.stepIntoSingleClass(contextLocation); if (location == null) { return false; } - final PsiMethod sourceMethod = getSourceMethod(location); - final Pair position = getPosition(sourceMethod); + PsiMethod sourceMethod = getSourceMethod(location); + Couple position = getPosition(sourceMethod); if (sourceMethod != null && position != null) { try { - final Project project = configuration.getProject(); - final TestDiscoveryIndex testDiscoveryIndex = TestDiscoveryIndex.getInstance(project); - final Collection testsByMethodName = testDiscoveryIndex.getTestsByMethodName(position.first, position.second); + Project project = configuration.getProject(); + TestDiscoveryIndex testDiscoveryIndex = TestDiscoveryIndex.getInstance(project); + Collection testsByMethodName = testDiscoveryIndex.getTestsByMethodName(position.first, position.second); if (testsByMethodName == null || ContainerUtil.filter( testsByMethodName, s -> s.startsWith(configuration.getFrameworkPrefix()) @@ -88,25 +84,25 @@ protected boolean setupConfigurationFromContext( setPosition(configuration, new PsiLocation<>(sourceMethod)); configuration.setName("Tests for " + StringUtil.getShortName(position.first) + "." + position.second); - final RunnerAndConfigurationSettings template = + RunnerAndConfigurationSettings template = configurationContext.getRunManager().getConfigurationTemplate(getConfigurationFactory()); - final Module predefinedModule = + Module predefinedModule = ((ModuleBasedConfiguration)template.getConfiguration()).getConfigurationModule().getModule(); if (predefinedModule != null) { configuration.setModule(predefinedModule); } //potentially this set won't be big, it reflects modules from where user starts his tests - final Collection modules = + Collection modules = testDiscoveryIndex.getTestModulesByMethodName(position.first, position.second, configuration.getFrameworkPrefix()); if (modules.isEmpty()) { return true; } - final List survivedModules = new ArrayList<>(); - final ModuleManager moduleManager = ModuleManager.getInstance(project); + List survivedModules = new ArrayList<>(); + ModuleManager moduleManager = ModuleManager.getInstance(project); for (String moduleName : modules) { - final Module moduleByName = moduleManager.findModuleByName(moduleName); + Module moduleByName = moduleManager.findModuleByName(moduleName); if (moduleByName != null) { survivedModules.add(moduleByName); } @@ -115,10 +111,9 @@ protected boolean setupConfigurationFromContext( return true; } - final Set allModules = new HashSet<>(Arrays.asList(moduleManager.getModules())); - survivedModules.forEach(module -> - { - final List dependentModules = ModuleUtilCore.getAllDependentModules(module); + Set allModules = new HashSet<>(Arrays.asList(moduleManager.getModules())); + survivedModules.forEach(module -> { + List dependentModules = ModuleUtilCore.getAllDependentModules(module); dependentModules.add(module); allModules.retainAll(dependentModules); }); @@ -147,12 +142,12 @@ protected Module findModule(JavaTestConfigurationBase configuration, Module cont } private static PsiMethod getSourceMethod(Location location) { - final PsiElement psiElement = location.getPsiElement(); - final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(psiElement, PsiMethod.class); + PsiElement psiElement = location.getPsiElement(); + PsiMethod psiMethod = PsiTreeUtil.getParentOfType(psiElement, PsiMethod.class); if (psiMethod != null) { - final PsiClass containingClass = psiMethod.getContainingClass(); + PsiClass containingClass = psiMethod.getContainingClass(); if (containingClass != null) { - final TestFramework testFramework = TestFrameworks.detectFramework(containingClass); + TestFramework testFramework = TestFrameworks.detectFramework(containingClass); if (testFramework != null) { return null; } @@ -162,24 +157,24 @@ private static PsiMethod getSourceMethod(Location location) { return null; } - private static Pair getPosition(PsiMethod method) { + private static Couple getPosition(PsiMethod method) { if (method == null) { return null; } - final PsiClass containingClass = method.getContainingClass(); + PsiClass containingClass = method.getContainingClass(); if (containingClass == null) { return null; } - final String qualifiedName = containingClass.getQualifiedName(); + String qualifiedName = containingClass.getQualifiedName(); if (qualifiedName != null) { - return Pair.create(qualifiedName, method.getName()); + return Couple.of(qualifiedName, method.getName()); } return null; } @Override public boolean isConfigurationFromContext(JavaTestConfigurationBase configuration, ConfigurationContext configurationContext) { - final Pair position = getPosition(getSourceMethod(configurationContext.getLocation())); + Couple position = getPosition(getSourceMethod(configurationContext.getLocation())); return position != null && position.equals(getPosition(configuration)); } } diff --git a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testframework/AbstractInClassConfigurationProducer.java b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testframework/AbstractInClassConfigurationProducer.java index f760428f4..497d8c45b 100644 --- a/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testframework/AbstractInClassConfigurationProducer.java +++ b/java-execution-impl/src/main/java/com/intellij/java/execution/impl/testframework/AbstractInClassConfigurationProducer.java @@ -16,30 +16,32 @@ package com.intellij.java.execution.impl.testframework; -import java.util.List; - import com.intellij.java.execution.impl.JavaTestConfigurationBase; -import consulo.execution.RunnerAndConfigurationSettings; -import consulo.execution.action.*; -import consulo.execution.action.ConfigurationFromContext; -import consulo.execution.configuration.ConfigurationType; import com.intellij.java.execution.impl.junit.InheritorChooser; import com.intellij.java.execution.impl.junit2.PsiMemberParameterizedLocation; import com.intellij.java.execution.impl.junit2.info.MethodLocation; -import consulo.execution.action.PsiLocation; -import consulo.logging.Logger; -import consulo.module.Module; -import consulo.project.Project; -import consulo.util.lang.ref.Ref; import com.intellij.java.language.psi.PsiClass; import com.intellij.java.language.psi.PsiClassOwner; -import consulo.language.psi.PsiElement; import com.intellij.java.language.psi.PsiMember; import com.intellij.java.language.psi.PsiMethod; -import com.intellij.java.language.psi.PsiModifier; +import consulo.annotation.access.RequiredReadAction; +import consulo.execution.RunnerAndConfigurationSettings; +import consulo.execution.action.ConfigurationContext; +import consulo.execution.action.ConfigurationFromContext; +import consulo.execution.action.Location; +import consulo.execution.action.PsiLocation; +import consulo.execution.configuration.ConfigurationType; +import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; +import consulo.logging.Logger; +import consulo.module.Module; +import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; +import java.util.List; + public abstract class AbstractInClassConfigurationProducer extends AbstractJavaTestConfigurationProducer { private static final Logger LOG = Logger.getInstance(AbstractInClassConfigurationProducer.class); @@ -48,19 +50,19 @@ protected AbstractInClassConfigurationProducer(ConfigurationType configurationTy } @Override + @RequiredUIAccess public void onFirstRun( - @Nonnull final ConfigurationFromContext configuration, - @Nonnull final ConfigurationContext fromContext, + @Nonnull ConfigurationFromContext configuration, + @Nonnull ConfigurationContext fromContext, @Nonnull Runnable performRunnable ) { - final PsiElement psiElement = configuration.getSourceElement(); + PsiElement psiElement = configuration.getSourceElement(); if (psiElement instanceof PsiMethod || psiElement instanceof PsiClass) { + PsiMethod psiMethod; + PsiClass containingClass; - final PsiMethod psiMethod; - final PsiClass containingClass; - - if (psiElement instanceof PsiMethod) { - psiMethod = (PsiMethod)psiElement; + if (psiElement instanceof PsiMethod method) { + psiMethod = method; containingClass = psiMethod.getContainingClass(); } else { @@ -68,8 +70,9 @@ public void onFirstRun( containingClass = (PsiClass)psiElement; } - final InheritorChooser inheritorChooser = new InheritorChooser() { + InheritorChooser inheritorChooser = new InheritorChooser() { @Override + @SuppressWarnings("unchecked") protected void runForClasses( List classes, PsiMethod method, @@ -81,10 +84,11 @@ protected void runForClasses( } @Override + @SuppressWarnings("unchecked") protected void runForClass(PsiClass aClass, PsiMethod psiMethod, ConfigurationContext context, Runnable performRunnable) { if (psiElement instanceof PsiMethod) { - final Project project = psiMethod.getProject(); - final MethodLocation methodLocation = new MethodLocation(project, psiMethod, PsiLocation.fromPsiElement(aClass)); + Project project = psiMethod.getProject(); + MethodLocation methodLocation = new MethodLocation(project, psiMethod, PsiLocation.fromPsiElement(aClass)); ((T)configuration.getConfiguration()).beMethodConfiguration(methodLocation); } else { @@ -98,7 +102,7 @@ protected void runForClass(PsiClass aClass, PsiMethod psiMethod, ConfigurationCo performRunnable, psiMethod, containingClass, - aClass -> aClass.hasModifierProperty(PsiModifier.ABSTRACT) && isTestClass(aClass) + aClass -> aClass.isAbstract() && isTestClass(aClass) )) { return; } @@ -107,31 +111,38 @@ protected void runForClass(PsiClass aClass, PsiMethod psiMethod, ConfigurationCo } @Override - protected boolean setupConfigurationFromContext(T configuration, ConfigurationContext context, Ref sourceElement) { + @RequiredReadAction + protected boolean setupConfigurationFromContext( + T configuration, + ConfigurationContext context, + SimpleReference sourceElement + ) { if (isMultipleElementsSelected(context)) { return false; } - final Location contextLocation = context.getLocation(); + Location contextLocation = context.getLocation(); setupConfigurationParamName(configuration, contextLocation); PsiClass psiClass = null; PsiElement element = context.getPsiLocation(); while (element != null) { - if (element instanceof PsiClass && isTestClass((PsiClass)element)) { - psiClass = (PsiClass)element; + if (element instanceof PsiClass aClass && isTestClass(aClass)) { + psiClass = aClass; break; } - else if (element instanceof PsiMember) { - psiClass = - contextLocation instanceof MethodLocation ? ((MethodLocation)contextLocation).getContainingClass() : contextLocation instanceof PsiMemberParameterizedLocation ? ( - (PsiMemberParameterizedLocation)contextLocation).getContainingClass() : ((PsiMember)element).getContainingClass(); + else if (element instanceof PsiMember member) { + psiClass = contextLocation instanceof MethodLocation methodLocation + ? methodLocation.getContainingClass() + : contextLocation instanceof PsiMemberParameterizedLocation memberParameterizedLocation + ? memberParameterizedLocation.getContainingClass() + : member.getContainingClass(); if (isTestClass(psiClass)) { break; } } - else if (element instanceof PsiClassOwner) { - final PsiClass[] classes = ((PsiClassOwner)element).getClasses(); + else if (element instanceof PsiClassOwner classOwner) { + PsiClass[] classes = classOwner.getClasses(); if (classes.length == 1) { psiClass = classes[0]; break; @@ -146,7 +157,7 @@ else if (element instanceof PsiClassOwner) { PsiElement psiElement = psiClass; RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(context); setupConfigurationModule(context, configuration); - final Module originalModule = configuration.getConfigurationModule().getModule(); + Module originalModule = configuration.getConfigurationModule().getModule(); configuration.beClassConfiguration(psiClass); PsiMethod method = PsiTreeUtil.getParentOfType(context.getPsiLocation(), PsiMethod.class, false); diff --git a/plugin/src/main/java/com/intellij/java/impl/psi/impl/JavaPsiImplementationHelperImpl.java b/plugin/src/main/java/com/intellij/java/impl/psi/impl/JavaPsiImplementationHelperImpl.java index 0a8a42e4a..15c4b6f82 100644 --- a/plugin/src/main/java/com/intellij/java/impl/psi/impl/JavaPsiImplementationHelperImpl.java +++ b/plugin/src/main/java/com/intellij/java/impl/psi/impl/JavaPsiImplementationHelperImpl.java @@ -32,7 +32,6 @@ import consulo.content.base.SourcesOrderRootType; import consulo.fileTemplate.FileTemplate; import consulo.fileTemplate.FileTemplateManager; -import consulo.ide.impl.idea.openapi.roots.impl.LibraryScopeCache; import consulo.java.language.module.extension.JavaModuleExtension; import consulo.language.ast.ASTNode; import consulo.language.codeStyle.CodeStyleSettings; @@ -40,6 +39,7 @@ import consulo.language.codeStyle.arrangement.MemberOrderService; import consulo.language.psi.*; import consulo.language.psi.scope.GlobalSearchScope; +import consulo.language.psi.scope.LibraryScopeCache; import consulo.language.psi.util.PsiTreeUtil; import consulo.language.util.IncorrectOperationException; import consulo.language.util.ModuleUtilCore; @@ -92,7 +92,7 @@ public PsiClass getOriginalClass(PsiClass psiClass) { } VirtualFile vFile = psiClass.getContainingFile().getVirtualFile(); - final ProjectFileIndex idx = ProjectRootManager.getInstance(myProject).getFileIndex(); + ProjectFileIndex idx = ProjectRootManager.getInstance(myProject).getFileIndex(); if (vFile == null || !idx.isInLibrarySource(vFile)) { return psiClass; } @@ -102,7 +102,7 @@ public PsiClass getOriginalClass(PsiClass psiClass) { return psiClass; } - final Set orderEntries = Set.copyOf(idx.getOrderEntriesForFile(vFile)); + Set orderEntries = Set.copyOf(idx.getOrderEntriesForFile(vFile)); GlobalSearchScope librariesScope = LibraryScopeCache.getInstance(myProject).getLibrariesOnlyScope(); for (PsiClass original : JavaPsiFacade.getInstance(myProject).findClasses(fqn, librariesScope)) { PsiFile psiFile = original.getContainingFile(); @@ -125,6 +125,7 @@ public PsiClass getOriginalClass(PsiClass psiClass) { } @Override + @RequiredReadAction public PsiElement getClsFileNavigationElement(PsiJavaFile clsFile) { PsiClass[] classes = clsFile.getClasses(); if (classes.length == 0) { @@ -157,9 +158,9 @@ public PsiElement getClsFileNavigationElement(PsiJavaFile clsFile) { @Nullable @Override public LanguageLevel getClassesLanguageLevel(VirtualFile virtualFile) { - final ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex(); - final VirtualFile sourceRoot = index.getSourceRootForFile(virtualFile); - final VirtualFile folder = virtualFile.getParent(); + ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex(); + VirtualFile sourceRoot = index.getSourceRootForFile(virtualFile); + VirtualFile folder = virtualFile.getParent(); if (sourceRoot != null && folder != null) { String relativePath = VirtualFileUtil.getRelativePath(folder, sourceRoot, '/'); if (relativePath == null) { @@ -169,35 +170,33 @@ public LanguageLevel getClassesLanguageLevel(VirtualFile virtualFile) { if (orderEntries.isEmpty()) { LOG.error("Inconsistent: " + DirectoryIndex.getInstance(myProject).getInfoForFile(folder).toString()); } - final VirtualFile[] files = orderEntries.get(0).getFiles(BinariesOrderRootType.getInstance()); + VirtualFile[] files = orderEntries.get(0).getFiles(BinariesOrderRootType.getInstance()); for (VirtualFile rootFile : files) { - final VirtualFile classFile = rootFile.findFileByRelativePath(relativePath); + VirtualFile classFile = rootFile.findFileByRelativePath(relativePath); if (classFile != null) { - final PsiJavaFile javaFile = getPsiFileInRoot(classFile); + PsiJavaFile javaFile = getPsiFileInRoot(classFile); if (javaFile != null) { return javaFile.getLanguageLevel(); } } } - final Module moduleForFile = ModuleUtilCore.findModuleForFile(virtualFile, myProject); + Module moduleForFile = ModuleUtilCore.findModuleForFile(virtualFile, myProject); if (moduleForFile == null) { return null; } - final JavaModuleExtension extension = ModuleUtilCore.getExtension(moduleForFile, JavaModuleExtension.class); + JavaModuleExtension extension = ModuleUtilCore.getExtension(moduleForFile, JavaModuleExtension.class); return extension == null ? null : extension.getLanguageLevel(); } return null; } @Nullable - private PsiJavaFile getPsiFileInRoot(final VirtualFile dirFile) { - final VirtualFile[] children = dirFile.getChildren(); - for (VirtualFile child : children) { - if (JavaClassFileType.INSTANCE.equals(child.getFileType())) { - final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(child); - if (psiFile instanceof PsiJavaFile) { - return (PsiJavaFile)psiFile; - } + @RequiredReadAction + private PsiJavaFile getPsiFileInRoot(VirtualFile dirFile) { + for (VirtualFile child : dirFile.getChildren()) { + if (JavaClassFileType.INSTANCE.equals(child.getFileType()) + && PsiManager.getInstance(myProject).findFile(child) instanceof PsiJavaFile javaFile) { + return javaFile; } } return null; @@ -225,7 +224,7 @@ public PsiElement getDefaultMemberAnchor(@Nonnull PsiClass aClass, @Nonnull PsiM if (anchor != null && anchor != aClass) { anchor = anchor.getNextSibling(); while (anchor instanceof PsiJavaToken && (anchor.getText().equals(",") || anchor.getText().equals(";"))) { - final boolean afterComma = anchor.getText().equals(","); + boolean afterComma = anchor.getText().equals(","); anchor = anchor.getNextSibling(); if (afterComma) { newAnchor = skipWhitespaces(aClass, anchor); @@ -241,7 +240,7 @@ public PsiElement getDefaultMemberAnchor(@Nonnull PsiClass aClass, @Nonnull PsiM // The main idea is to avoid to anchor to 'white space' element because that causes reformatting algorithm // to perform incorrectly. The algorithm is encapsulated at the PostprocessReformattingAspect.doPostponedFormattingInner(). - final PsiElement lBrace = aClass.getLBrace(); + PsiElement lBrace = aClass.getLBrace(); if (lBrace != null) { PsiElement result = lBrace.getNextSibling(); while (result instanceof PsiWhiteSpace) { @@ -253,6 +252,7 @@ public PsiElement getDefaultMemberAnchor(@Nonnull PsiClass aClass, @Nonnull PsiM return aClass.getRBrace(); } + @RequiredReadAction private static PsiElement skipWhitespaces(PsiClass aClass, PsiElement anchor) { if (anchor != null && PsiTreeUtil.skipSiblingsForward(anchor, PsiWhiteSpace.class) == aClass.getRBrace()) { // Given member should be inserted as the last child. @@ -263,23 +263,23 @@ private static PsiElement skipWhitespaces(PsiClass aClass, PsiElement anchor) { @Override public void setupCatchBlock(String exceptionName, PsiElement context, PsiCatchSection catchSection) { - final FileTemplate catchBodyTemplate = + FileTemplate catchBodyTemplate = FileTemplateManager.getInstance(catchSection.getProject()).getCodeTemplate(JavaTemplateUtil.TEMPLATE_CATCH_BODY); LOG.assertTrue(catchBodyTemplate != null); - final Properties props = new Properties(); + Properties props = new Properties(); props.setProperty(FileTemplate.ATTRIBUTE_EXCEPTION, exceptionName); if (context != null && context.isPhysical()) { - final PsiDirectory directory = context.getContainingFile().getContainingDirectory(); + PsiDirectory directory = context.getContainingFile().getContainingDirectory(); if (directory != null) { JavaTemplateUtil.setPackageNameAttribute(props, directory); } } - final PsiCodeBlock codeBlockFromText; + PsiCodeBlock codeBlockFromText; try { - codeBlockFromText = - PsiElementFactory.getInstance(myProject).createCodeBlockFromText("{\n" + catchBodyTemplate.getText(props) + "\n}", null); + codeBlockFromText = PsiElementFactory.getInstance(myProject) + .createCodeBlockFromText("{\n" + catchBodyTemplate.getText(props) + "\n}", null); } catch (ProcessCanceledException ce) { throw ce; diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/EnumTypeConversionRule.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/EnumTypeConversionRule.java index 65b783242..41f15fc6b 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/EnumTypeConversionRule.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/EnumTypeConversionRule.java @@ -44,26 +44,26 @@ public TypeConversionDescriptorBase findConversion( PsiExpression context, TypeMigrationLabeler labeler ) { - final PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(context, PsiMethodCallExpression.class, false); + PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(context, PsiMethodCallExpression.class, false); if (callExpression != null) { - final PsiMethod resolved = callExpression.resolveMethod(); + PsiMethod resolved = callExpression.resolveMethod(); if (resolved != null) { - final SearchScope searchScope = labeler.getRules().getSearchScope(); + SearchScope searchScope = labeler.getRules().getSearchScope(); if (!PsiSearchScopeUtil.isInScope(searchScope, resolved)) { return null; } } } - final PsiField field = PsiTreeUtil.getParentOfType(context, PsiField.class); + PsiField field = PsiTreeUtil.getParentOfType(context, PsiField.class); if (field != null && !myEnumConstants.contains(field) && field.isStatic() && field.isFinal() && field.hasInitializer()) { return null; } - final PsiClass toClass = PsiUtil.resolveClassInType(to); + PsiClass toClass = PsiUtil.resolveClassInType(to); if (toClass != null && toClass.isEnum()) { - final PsiMethod[] constructors = toClass.getConstructors(); + PsiMethod[] constructors = toClass.getConstructors(); if (constructors.length == 1) { - final PsiMethod constructor = constructors[0]; - final PsiParameter[] parameters = constructor.getParameterList().getParameters(); + PsiMethod constructor = constructors[0]; + PsiParameter[] parameters = constructor.getParameterList().getParameters(); if (parameters.length == 1 && TypeConversionUtil.isAssignable(parameters[0].getType(), from)) { return new TypeConversionDescriptorBase(); } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationRules.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationRules.java index 5c422af96..7b53445b6 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationRules.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationRules.java @@ -3,30 +3,23 @@ // found in the LICENSE file. package com.intellij.java.impl.refactoring.typeMigration; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import jakarta.annotation.Nonnull; -import jakarta.annotation.Nullable; - -import org.jetbrains.annotations.NonNls; -import consulo.project.Project; -import consulo.ide.impl.idea.openapi.roots.impl.LibraryScopeCache; -import consulo.util.lang.Pair; -import com.intellij.java.language.psi.PsiEllipsisType; -import com.intellij.java.language.psi.PsiExpression; -import com.intellij.java.language.psi.PsiMember; -import com.intellij.java.language.psi.PsiMethod; -import com.intellij.java.language.psi.PsiType; -import consulo.language.psi.scope.GlobalSearchScope; -import consulo.content.scope.SearchScope; -import com.intellij.java.language.psi.util.TypeConversionUtil; import com.intellij.java.impl.refactoring.typeMigration.rules.DisjunctionTypeConversionRule; import com.intellij.java.impl.refactoring.typeMigration.rules.RootTypeConversionRule; import com.intellij.java.impl.refactoring.typeMigration.rules.TypeConversionRule; +import com.intellij.java.language.psi.*; +import com.intellij.java.language.psi.util.TypeConversionUtil; +import consulo.content.scope.SearchScope; +import consulo.language.psi.scope.GlobalSearchScope; +import consulo.language.psi.scope.LibraryScopeCache;import consulo.project.Project; import consulo.util.collection.ContainerUtil; +import consulo.util.lang.Couple; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * @author db @@ -55,28 +48,28 @@ public void addConversionRuleSettings(Object settings) { myConversionCustomSettings.put(settings.getClass(), settings); } + @SuppressWarnings("unchecked") public T getConversionSettings(Class aClass) { return (T)myConversionCustomSettings.get(aClass); } - @NonNls @Nullable public TypeConversionDescriptorBase findConversion( - final PsiType from, - final PsiType to, - final PsiMember member, - final PsiExpression context, - final boolean isCovariantPosition, - final TypeMigrationLabeler labeler + PsiType from, + PsiType to, + PsiMember member, + PsiExpression context, + boolean isCovariantPosition, + TypeMigrationLabeler labeler ) { - final TypeConversionDescriptorBase conversion = findConversion(from, to, member, context, labeler); + TypeConversionDescriptorBase conversion = findConversion(from, to, member, context, labeler); if (conversion != null) { return conversion; } if (isCovariantPosition) { - if (to instanceof PsiEllipsisType) { - if (TypeConversionUtil.isAssignable(((PsiEllipsisType)to).getComponentType(), from)) { + if (to instanceof PsiEllipsisType ellipsisType) { + if (TypeConversionUtil.isAssignable(ellipsisType.getComponentType(), from)) { return new TypeConversionDescriptorBase(); } } @@ -90,14 +83,14 @@ public TypeConversionDescriptorBase findConversion( @Nullable public TypeConversionDescriptorBase findConversion( - final PsiType from, - final PsiType to, - final PsiMember member, - final PsiExpression context, - final TypeMigrationLabeler labeler + PsiType from, + PsiType to, + PsiMember member, + PsiExpression context, + TypeMigrationLabeler labeler ) { for (TypeConversionRule descriptor : myConversionRules) { - final TypeConversionDescriptorBase conversion = descriptor.findConversion(from, to, member, context, labeler); + TypeConversionDescriptorBase conversion = descriptor.findConversion(from, to, member, context, labeler); if (conversion != null) { return conversion; } @@ -105,7 +98,7 @@ public TypeConversionDescriptorBase findConversion( return null; } - public boolean shouldConvertNull(final PsiType from, final PsiType to, PsiExpression context) { + public boolean shouldConvertNull(PsiType from, PsiType to, PsiExpression context) { return myConversionRules.stream().anyMatch(rule -> rule.shouldConvertNullInitializer(from, to, context)); } @@ -119,15 +112,15 @@ public SearchScope getSearchScope() { } @Nullable - public Pair bindTypeParameters( - final PsiType from, - final PsiType to, - final PsiMethod method, - final PsiExpression context, - final TypeMigrationLabeler labeler + public Couple bindTypeParameters( + PsiType from, + PsiType to, + PsiMethod method, + PsiExpression context, + TypeMigrationLabeler labeler ) { for (TypeConversionRule conversionRule : myConversionRules) { - final Pair typePair = conversionRule.bindTypeParameters(from, to, method, context, labeler); + Couple typePair = conversionRule.bindTypeParameters(from, to, method, context, labeler); if (typePair != null) { return typePair; } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/DisjunctionTypeConversionRule.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/DisjunctionTypeConversionRule.java index 3911b6566..94cdf5908 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/DisjunctionTypeConversionRule.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/DisjunctionTypeConversionRule.java @@ -26,42 +26,42 @@ public class DisjunctionTypeConversionRule extends TypeConversionRule { @Override public TypeConversionDescriptorBase findConversion( - final PsiType from, - final PsiType to, - final PsiMember member, - final PsiExpression context, - final TypeMigrationLabeler labeler + PsiType from, + PsiType to, + PsiMember member, + PsiExpression context, + TypeMigrationLabeler labeler ) { - if (from instanceof PsiDisjunctionType) { - final PsiType lub = ((PsiDisjunctionType)from).getLeastUpperBound(); - if (lub instanceof PsiIntersectionType) { - for (PsiType type : ((PsiIntersectionType)lub).getConjuncts()) { - final TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(type, to, member, context, labeler); + if (from instanceof PsiDisjunctionType disjunctionType) { + PsiType lub = disjunctionType.getLeastUpperBound(); + if (lub instanceof PsiIntersectionType intersectionType) { + for (PsiType type : intersectionType.getConjuncts()) { + TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(type, to, member, context, labeler); if (conversion != null) { return conversion; } } } else { - final TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(lub, to, member, context, labeler); + TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(lub, to, member, context, labeler); if (conversion != null) { return conversion; } } } - if (to instanceof PsiDisjunctionType) { - final PsiType lub = ((PsiDisjunctionType)to).getLeastUpperBound(); - if (lub instanceof PsiIntersectionType) { - for (PsiType type : ((PsiIntersectionType)lub).getConjuncts()) { - final TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(from, type, member, context, labeler); + if (to instanceof PsiDisjunctionType disjunctionType) { + PsiType lub = disjunctionType.getLeastUpperBound(); + if (lub instanceof PsiIntersectionType intersectionType) { + for (PsiType type : intersectionType.getConjuncts()) { + TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(from, type, member, context, labeler); if (conversion != null) { return conversion; } } } else { - final TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(from, lub, member, context, labeler); + TypeConversionDescriptorBase conversion = labeler.getRules().findConversion(from, lub, member, context, labeler); if (conversion != null) { return conversion; } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/RootTypeConversionRule.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/RootTypeConversionRule.java index 8d976bd43..415aeb9c5 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/RootTypeConversionRule.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/RootTypeConversionRule.java @@ -23,8 +23,10 @@ import com.intellij.java.language.psi.codeStyle.JavaCodeStyleManager; import com.intellij.java.language.psi.util.InheritanceUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; +import consulo.annotation.access.RequiredWriteAction; import consulo.language.psi.PsiElement; import consulo.language.util.IncorrectOperationException; +import consulo.ui.annotation.RequiredUIAccess; import consulo.util.lang.Comparing; import jakarta.annotation.Nonnull; @@ -35,18 +37,19 @@ * @author anna */ public class RootTypeConversionRule extends TypeConversionRule { + @Override + @RequiredUIAccess public TypeConversionDescriptorBase findConversion( - final PsiType from, - final PsiType to, - final PsiMember member, - final PsiExpression context, - final TypeMigrationLabeler labeler + PsiType from, + PsiType to, + PsiMember member, + PsiExpression context, + TypeMigrationLabeler labeler ) { - if (member != null && to instanceof PsiClassType && from instanceof PsiClassType) { - final PsiClass targetClass = ((PsiClassType)to).resolve(); + if (member != null && to instanceof PsiClassType toClassType && from instanceof PsiClassType fromClassType) { + PsiClass targetClass = toClassType.resolve(); if (targetClass != null && member.isPhysical()) { - if (member instanceof PsiMethod) { - PsiMethod method = (PsiMethod)member; + if (member instanceof PsiMethod method) { PsiMethod replacer = targetClass.findMethodBySignature(method, true); if (replacer == null) { for (PsiMethod superMethod : method.findDeepestSuperMethods()) { @@ -58,47 +61,43 @@ public TypeConversionDescriptorBase findConversion( } } if (replacer != null) { - final boolean isStaticMethodConversion = replacer.hasModifierProperty(PsiModifier.STATIC); + boolean isStaticMethodConversion = replacer.isStatic(); boolean isValid = isStaticMethodConversion - ? TypeConversionUtil.areTypesConvertible(method.getReturnType(), from) - && TypeConversionUtil.areTypesConvertible(replacer.getReturnType(), to) + ? TypeConversionUtil.areTypesConvertible(method.getReturnType(), fromClassType) + && TypeConversionUtil.areTypesConvertible(replacer.getReturnType(), toClassType) : TypeConversionUtil.areTypesConvertible(method.getReturnType(), replacer.getReturnType()); if (isValid) { - final PsiElement parent = context.getParent(); - if (context instanceof PsiMethodReferenceExpression) { - final PsiType functionalInterfaceType = - ((PsiMethodReferenceExpression)context).getFunctionalInterfaceType(); - if (Comparing.equal(functionalInterfaceType, to) - && method.isEquivalentTo(LambdaUtil.getFunctionalInterfaceMethod(from))) { - return new TypeConversionDescriptorBase() { - @Override - public PsiExpression replace( - PsiExpression expression, - @Nonnull TypeEvaluator evaluator - ) throws IncorrectOperationException { - final PsiMethodReferenceExpression methodReferenceExpression = - (PsiMethodReferenceExpression)expression; - final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression(); - if (qualifierExpression != null) { - return (PsiExpression)expression.replace(qualifierExpression); - } - else { - return expression; - } + PsiElement parent = context.getParent(); + if (context instanceof PsiMethodReferenceExpression methodRefExpr + && Comparing.equal(methodRefExpr.getFunctionalInterfaceType(), toClassType) + && method.isEquivalentTo(LambdaUtil.getFunctionalInterfaceMethod(fromClassType))) { + return new TypeConversionDescriptorBase() { + @Override + public PsiExpression replace( + PsiExpression expression, + @Nonnull TypeEvaluator evaluator + ) throws IncorrectOperationException { + PsiMethodReferenceExpression methodReferenceExpression = + (PsiMethodReferenceExpression)expression; + PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression(); + if (qualifierExpression != null) { + return (PsiExpression)expression.replace(qualifierExpression); } - }; - } + else { + return expression; + } + } + }; } - if (context instanceof PsiReferenceExpression && parent instanceof PsiMethodCallExpression) { - final JavaResolveResult resolveResult = ((PsiReferenceExpression)context).advancedResolve(false); - final PsiSubstitutor aSubst; - final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)parent).getMethodExpression(); - final PsiExpression qualifier = methodExpression.getQualifierExpression(); - final PsiClass substitutionClass = method.getContainingClass(); + if (context instanceof PsiReferenceExpression refExpr && parent instanceof PsiMethodCallExpression methodCall) { + JavaResolveResult resolveResult = refExpr.advancedResolve(false); + PsiSubstitutor aSubst; + PsiExpression qualifier = methodCall.getMethodExpression().getQualifierExpression(); + PsiClass substitutionClass = method.getContainingClass(); if (qualifier != null) { - final PsiType evaluatedQualifierType = labeler.getTypeEvaluator().evaluateType(qualifier); - if (evaluatedQualifierType instanceof PsiClassType) { - aSubst = ((PsiClassType)evaluatedQualifierType).resolveGenerics().getSubstitutor(); + PsiType evaluatedQualifierType = labeler.getTypeEvaluator().evaluateType(qualifier); + if (evaluatedQualifierType instanceof PsiClassType qualifierClassType) { + aSubst = qualifierClassType.resolveGenerics().getSubstitutor(); } else { aSubst = PsiSubstitutor.EMPTY; @@ -112,12 +111,12 @@ public PsiExpression replace( ); } - final PsiParameter[] originalParams = ((PsiMethod)member).getParameterList().getParameters(); - final PsiParameter[] migrationParams = replacer.getParameterList().getParameters(); - final PsiExpression[] actualParams = ((PsiMethodCallExpression)parent).getArgumentList().getExpressions(); + PsiParameter[] originalParams = ((PsiMethod)member).getParameterList().getParameters(); + PsiParameter[] migrationParams = replacer.getParameterList().getParameters(); + PsiExpression[] actualParams = ((PsiMethodCallExpression)parent).getArgumentList().getExpressions(); assert originalParams.length == migrationParams.length; - final PsiSubstitutor methodTypeParamsSubstitutor = labeler.getTypeEvaluator().createMethodSubstitution( + PsiSubstitutor methodTypeParamsSubstitutor = labeler.getTypeEvaluator().createMethodSubstitution( originalParams, actualParams, method, @@ -126,17 +125,17 @@ public PsiExpression replace( true ); for (int i = 0; i < originalParams.length; i++) { - final PsiType originalType = resolveResult.getSubstitutor().substitute(originalParams[i].getType()); + PsiType originalType = resolveResult.getSubstitutor().substitute(originalParams[i].getType()); PsiType type = migrationParams[i].getType(); if (InheritanceUtil.isInheritorOrSelf(targetClass, substitutionClass, true)) { - final PsiSubstitutor superClassSubstitutor = + PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getClassSubstitutor(substitutionClass, targetClass, PsiSubstitutor.EMPTY); assert (superClassSubstitutor != null); type = superClassSubstitutor.substitute(type); } - final PsiType migrationType = methodTypeParamsSubstitutor.substitute(type); + PsiType migrationType = methodTypeParamsSubstitutor.substitute(type); if (!originalType.equals(migrationType) && !areParametersAssignable(migrationType, i, actualParams)) { if (migrationType instanceof PsiEllipsisType && actualParams.length != migrationParams.length) { return null; @@ -145,12 +144,14 @@ public PsiExpression replace( } } } - return isStaticMethodConversion ? new MyStaticMethodConversionDescriptor(targetClass) : new TypeConversionDescriptorBase(); + return isStaticMethodConversion + ? new MyStaticMethodConversionDescriptor(targetClass) + : new TypeConversionDescriptorBase(); } } } - else if (member instanceof PsiField) { - final PsiClass fieldContainingClass = member.getContainingClass(); + else if (member instanceof PsiField field) { + PsiClass fieldContainingClass = field.getContainingClass(); if (InheritanceUtil.isInheritorOrSelf(targetClass, fieldContainingClass, true)) { return new TypeConversionDescriptorBase(); } @@ -170,9 +171,9 @@ else if (actualParams.length == paramId + 1) { // only one argument for ellipsis return TypeConversionUtil.areTypesAssignmentCompatible(migrationType, actualParams[paramId]) || TypeConversionUtil.areTypesAssignmentCompatible( - ((PsiEllipsisType)migrationType).getComponentType(), - actualParams[paramId] - ); + ((PsiEllipsisType)migrationType).getComponentType(), + actualParams[paramId] + ); } else if (actualParams.length > paramId + 1) { // few arguments @@ -191,28 +192,25 @@ else if (actualParams.length > paramId + 1) { ); } else { - if (paramId >= actualParams.length) { - return true; - } - return TypeConversionUtil.areTypesAssignmentCompatible(migrationType, actualParams[paramId]); + return paramId >= actualParams.length || TypeConversionUtil.areTypesAssignmentCompatible(migrationType, actualParams[paramId]); } } private static class MyStaticMethodConversionDescriptor extends TypeConversionDescriptorBase { - private final @Nonnull - String myTargetClassQName; + private final String myTargetClassQName; private MyStaticMethodConversionDescriptor(PsiClass replacer) { myTargetClassQName = replacer.getQualifiedName(); } @Override + @RequiredWriteAction public PsiExpression replace(PsiExpression expression, @Nonnull TypeEvaluator evaluator) throws IncorrectOperationException { - final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression; - final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression(); - final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(expression.getProject()); - final PsiMethodCallExpression newMethodCall; + PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression; + PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression(); + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(expression.getProject()); + PsiMethodCallExpression newMethodCall; if (qualifierExpression != null) { JavaCodeStyleManager.getInstance(expression.getProject()).shortenClassReferences( qualifierExpression.replace(elementFactory.createExpressionFromText(myTargetClassQName, expression)) diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/TypeConversionRule.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/TypeConversionRule.java index 6616f3272..a00b5ddcd 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/TypeConversionRule.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/rules/TypeConversionRule.java @@ -24,7 +24,7 @@ import consulo.annotation.component.ComponentScope; import consulo.annotation.component.ExtensionAPI; import consulo.component.extension.ExtensionPointName; -import consulo.util.lang.Pair; +import consulo.util.lang.Couple; import jakarta.annotation.Nullable; /** @@ -36,20 +36,20 @@ public abstract class TypeConversionRule { @Nullable public abstract TypeConversionDescriptorBase findConversion( - final PsiType from, - final PsiType to, - final PsiMember member, - final PsiExpression context, - final TypeMigrationLabeler labeler + PsiType from, + PsiType to, + PsiMember member, + PsiExpression context, + TypeMigrationLabeler labeler ); @Nullable - public Pair bindTypeParameters( + public Couple bindTypeParameters( PsiType from, PsiType to, - final PsiMethod method, - final PsiExpression context, - final TypeMigrationLabeler labeler + PsiMethod method, + PsiExpression context, + TypeMigrationLabeler labeler ) { return null; }