From e60f40535f220310444a50c8d8b12f1656c94a40 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 16 Jan 2013 15:28:06 +0100 Subject: [PATCH 01/13] explicitly adding project sdk to the candidate sdk list when launching external build process; more robust launching error processing --- .../src/com/intellij/compiler/impl/CompileDriver.java | 5 ++--- .../src/com/intellij/compiler/server/BuildManager.java | 10 ++++++++-- .../src/org/jetbrains/jps/api/CmdlineProtoUtil.java | 10 ++++++++-- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 568bb42b28a0..346641f66bb2 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -521,11 +521,10 @@ public class CompileDriver { @Override public void handleFailure(UUID sessionId, CmdlineRemoteProto.Message.Failure failure) { - compileContext.addMessage(CompilerMessageCategory.ERROR, failure.getDescription(), null, -1, -1); - final String trace = failure.getStacktrace(); + compileContext.addMessage(CompilerMessageCategory.ERROR, failure.hasDescription()? failure.getDescription() : "", null, -1, -1); + final String trace = failure.hasStacktrace()? failure.getStacktrace() : null; if (trace != null) { LOG.info(trace); - System.out.println(trace); } compileContext.putUserData(COMPILE_SERVER_BUILD_STATUS, ExitStatus.ERRORS); } diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index c33b1de3f854..5cc6610b558f 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -554,7 +554,7 @@ public class BuildManager implements ApplicationComponent{ projectTaskQueue.submit(new Runnable() { @Override public void run() { - ExecutionException execFailure = null; + Throwable execFailure = null; try { if (project.isDisposed()) { return; @@ -595,7 +595,7 @@ public class BuildManager implements ApplicationComponent{ handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure("Disconnected from build process", null)); } } - catch (ExecutionException e) { + catch (Throwable e) { execFailure = e; } finally { @@ -690,12 +690,18 @@ public class BuildManager implements ApplicationComponent{ int sdkMinorVersion = 0; final Set candidates = new HashSet(); + final Sdk defaultSdk = ProjectRootManager.getInstance(project).getProjectSdk(); + if (defaultSdk != null && defaultSdk.getSdkType() instanceof JavaSdk) { + candidates.add(defaultSdk); + } + for (Module module : ModuleManager.getInstance(project).getModules()) { final Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); if (sdk != null && sdk.getSdkType() instanceof JavaSdk) { candidates.add(sdk); } } + // now select the latest version from the sdks that are used in the project, but not older than the internal sdk version for (Sdk candidate : candidates) { final String vs = candidate.getVersionString(); diff --git a/jps/jps-builders/src/org/jetbrains/jps/api/CmdlineProtoUtil.java b/jps/jps-builders/src/org/jetbrains/jps/api/CmdlineProtoUtil.java index bc71808cf346..46397f75509b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/api/CmdlineProtoUtil.java +++ b/jps/jps-builders/src/org/jetbrains/jps/api/CmdlineProtoUtil.java @@ -127,7 +127,9 @@ public class CmdlineProtoUtil { public static CmdlineRemoteProto.Message.Failure createFailure(String description, @Nullable Throwable cause) { final CmdlineRemoteProto.Message.Failure.Builder builder = CmdlineRemoteProto.Message.Failure.newBuilder(); - builder.setDescription(description); + if (description != null) { + builder.setDescription(description); + } if (cause != null) { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final PrintStream stream = new PrintStream(baos); @@ -137,7 +139,11 @@ public class CmdlineProtoUtil { finally { stream.close(); } - builder.setStacktrace(new String(baos.toByteArray())); + final String stacktrace = new String(baos.toByteArray()); + builder.setStacktrace(stacktrace); + if (description == null) { + builder.setDescription(stacktrace); + } } return builder.build(); } From e16b526924a8b352d37b8f66b6d64e810c89c367 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 16 Jan 2013 15:29:04 +0100 Subject: [PATCH 02/13] explicitly adding project sdk to the candidate sdk list when launching external build process; more robust launching error processing --- .../com/intellij/compiler/server/AutoMakeMessageHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java index 05bfe722e3ba..2bb40e93ccda 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java @@ -110,7 +110,7 @@ class AutoMakeMessageHandler extends DefaultMessageHandler { @Override public void handleFailure(UUID sessionId, CmdlineRemoteProto.Message.Failure failure) { - final String msg = "Auto make failure: " + failure.getDescription(); + final String msg = "Auto make failure: " + (failure.hasDescription()? failure.getDescription() : ""); CompilerManager.NOTIFICATION_GROUP.createNotification(msg, MessageType.INFO); ProblemsView.SERVICE.getInstance(myProject).addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.ERROR, msg), sessionId); } From 196ccea2eff99fc3f23acbc3a846bfec7076d4ea Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 16 Jan 2013 15:30:46 +0100 Subject: [PATCH 03/13] explicitly adding project sdk to the candidate sdk list when launching external build process; more robust launching error processing --- .../intellij/compiler/server/AutoMakeMessageHandler.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java index 2bb40e93ccda..bc50140789d1 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java @@ -110,7 +110,11 @@ class AutoMakeMessageHandler extends DefaultMessageHandler { @Override public void handleFailure(UUID sessionId, CmdlineRemoteProto.Message.Failure failure) { - final String msg = "Auto make failure: " + (failure.hasDescription()? failure.getDescription() : ""); + String descr = failure.hasDescription() ? failure.getDescription() : null; + if (descr == null) { + descr = failure.hasStacktrace()? failure.getStacktrace() : ""; + } + final String msg = "Auto make failure: " + descr; CompilerManager.NOTIFICATION_GROUP.createNotification(msg, MessageType.INFO); ProblemsView.SERVICE.getInstance(myProject).addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.ERROR, msg), sessionId); } From 92592d68f49b74ab551c74242951ec92860f4a52 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 16 Jan 2013 15:45:05 +0100 Subject: [PATCH 04/13] fix compilation --- .../generate/tostring/GenerateToStringActionHandlerImpl.java | 2 ++ .../generate/tostring/inspection/GenerateToStringQuickFix.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java index 0f7541163689..c4a1922742f3 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java @@ -40,6 +40,8 @@ import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.generate.tostring.config.Config; +import org.jetbrains.generate.tostring.psi.PsiAdapter; +import org.jetbrains.generate.tostring.psi.PsiAdapterFactory; import org.jetbrains.generate.tostring.template.TemplateResource; import org.jetbrains.generate.tostring.template.TemplatesManager; import org.jetbrains.generate.tostring.view.TemplatesPanel; diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/GenerateToStringQuickFix.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/GenerateToStringQuickFix.java index b711808e06cf..c1b23d027e10 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/GenerateToStringQuickFix.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/GenerateToStringQuickFix.java @@ -38,7 +38,7 @@ public class GenerateToStringQuickFix extends AbstractGenerateToStringQuickFix { // execute the action GenerateToStringActionHandler handler = new GenerateToStringActionHandlerImpl(); - handler.executeActionQickFix(project, clazz); + handler.executeActionQuickFix(project, clazz); } } From 4cbc38008adb428a85ff10e8ec127c35ec85c705 Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 16 Jan 2013 14:08:52 +0100 Subject: [PATCH 05/13] lambda: incompatible lambda parameters type check fixed according to wildcards (IDEA-99073) --- .../daemon/impl/analysis/HighlightVisitorImpl.java | 3 ++- .../lambda/params/FormalParamsWithWildcards.java | 9 +++++++++ .../daemonCodeAnalyzer/lambda/params/Raw.java | 4 ++-- .../codeInsight/daemon/lambda/LambdaParamsTest.java | 4 ++++ 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParamsWithWildcards.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 58218357921f..fdf7506d9e39 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -269,7 +269,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); for (int i = 0; i < lambdaParameters.length; i++) { PsiParameter lambdaParameter = lambdaParameters[i]; - if (!TypeConversionUtil.isAssignable(LambdaUtil.getSubstitutor(interfaceMethod, resolveResult).substitute(parameters[i].getType()), lambdaParameter.getType())) { + if (!TypeConversionUtil.isAssignable(lambdaParameter.getType(), + GenericsUtil.eliminateWildcards(LambdaUtil.getSubstitutor(interfaceMethod, resolveResult).substitute(parameters[i].getType())))) { myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, lambdaParameter, incompatibleTypesMessage)); break; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParamsWithWildcards.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParamsWithWildcards.java new file mode 100644 index 000000000000..0bbcdd54dd92 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParamsWithWildcards.java @@ -0,0 +1,9 @@ +class Test { + public interface I { + public V put(K k); + } + + { + final I i = (Number n) -> n.toString(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/Raw.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/Raw.java index e99747fa6169..eeaa80410bb6 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/Raw.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/Raw.java @@ -1,7 +1,7 @@ class Test { { - Comparable c = (String o)->{ + Comparable c = (String o)->{ return 0; - }; + }; } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java index ec1c083f372a..f93f7ac9025c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java @@ -41,6 +41,10 @@ public class LambdaParamsTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testFormalParamsWithWildcards() throws Exception { + doTest(); + } + private void doTest() throws Exception { doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false); } From e097ce592a49bcbb2807a958bf297751a65e31f2 Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 16 Jan 2013 15:38:27 +0100 Subject: [PATCH 06/13] move initializer to setup: disable if acceptable framework contains corrupted template (IDEA-98880) --- .../BaseMoveInitializerToMethodAction.java | 1 + .../testIntegration/JavaTestFramework.java | 5 ++-- .../MoveInitializerToSetUpMethodAction.java | 29 ++++++++++++++++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseMoveInitializerToMethodAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseMoveInitializerToMethodAction.java index 0f9081ceb6cb..549a47fb208d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseMoveInitializerToMethodAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseMoveInitializerToMethodAction.java @@ -79,6 +79,7 @@ public abstract class BaseMoveInitializerToMethodAction extends PsiElementBaseIn final Collection methodsToAddInitialization = getOrCreateMethods(project, editor, element.getContainingFile(), aClass); + if (methodsToAddInitialization.isEmpty()) return; final List assignments = addFieldAssignments(field, methodsToAddInitialization); field.getInitializer().delete(); diff --git a/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java b/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java index 67636d5ce4ac..9e389dda012e 100644 --- a/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java +++ b/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java @@ -108,8 +108,9 @@ public abstract class JavaTestFramework implements TestFramework { return null; } - protected PsiMethod createSetUpPatternMethod(JVMElementFactory factory) { + public PsiMethod createSetUpPatternMethod(JVMElementFactory factory) { final FileTemplate template = FileTemplateManager.getInstance().getCodeTemplate(getSetUpMethodFileTemplateDescriptor().getFileName()); - return factory.createMethodFromText(StringUtil.replace(template.getText(), "${BODY}\n", ""), null); + final String templateText = StringUtil.replace(StringUtil.replace(template.getText(), "${BODY}\n", ""), "${NAME}", "setUp"); + return factory.createMethodFromText(templateText, null); } } diff --git a/java/java-impl/src/com/intellij/testIntegration/intention/MoveInitializerToSetUpMethodAction.java b/java/java-impl/src/com/intellij/testIntegration/intention/MoveInitializerToSetUpMethodAction.java index 7d8f852942a8..fdaa574c2871 100644 --- a/java/java-impl/src/com/intellij/testIntegration/intention/MoveInitializerToSetUpMethodAction.java +++ b/java/java-impl/src/com/intellij/testIntegration/intention/MoveInitializerToSetUpMethodAction.java @@ -18,9 +18,14 @@ package com.intellij.testIntegration.intention; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.TestFrameworks; import com.intellij.codeInsight.intention.impl.BaseMoveInitializerToMethodAction; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.testIntegration.JavaTestFramework; +import com.intellij.testIntegration.TestFramework; import com.intellij.testIntegration.TestIntegrationUtils; import org.jetbrains.annotations.NotNull; @@ -32,6 +37,8 @@ import java.util.Collections; * @author cdr */ public class MoveInitializerToSetUpMethodAction extends BaseMoveInitializerToMethodAction { + private static final Logger LOG = Logger.getInstance("#" + MoveInitializerToSetUpMethodAction.class.getName()); + @Override @NotNull public String getFamilyName() { @@ -46,7 +53,27 @@ public class MoveInitializerToSetUpMethodAction extends BaseMoveInitializerToMet @Override public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { - return super.isAvailable(project, editor, element) && TestIntegrationUtils.isTest(element); + final boolean isAvailable = super.isAvailable(project, editor, element) && TestIntegrationUtils.isTest(element); + if (isAvailable) { + final PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class); + LOG.assertTrue(field != null); + final PsiClass aClass = field.getContainingClass(); + LOG.assertTrue(aClass != null); + final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); + for (TestFramework framework : Extensions.getExtensions(TestFramework.EXTENSION_NAME)) { + if (framework instanceof JavaTestFramework && framework.isTestClass(aClass)) { + try { + ((JavaTestFramework)framework).createSetUpPatternMethod(elementFactory); + return true; + } + catch (Exception e) { + return false; + } + } + } + return true; + } + return false; } @NotNull From d6ef6309104c9e6e3486bd293bda2efaacdd7d69 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Wed, 16 Jan 2013 19:12:00 +0400 Subject: [PATCH 07/13] IDEA-98523 No warning for duplicate dependencies with different versions --- .../MavenDuplicateDependenciesInspection.java | 15 ++-- .../MavenDuplicatedInspectionTest.groovy | 76 ++++++++++++++++++- 2 files changed, 83 insertions(+), 8 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicateDependenciesInspection.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicateDependenciesInspection.java index a8980f56e4a0..ef79271a312d 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicateDependenciesInspection.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/inspections/MavenDuplicateDependenciesInspection.java @@ -17,9 +17,9 @@ package org.jetbrains.idea.maven.dom.inspections; import com.intellij.codeHighlighting.HighlightDisplayLevel; import com.intellij.lang.annotation.HighlightSeverity; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.util.Processor; import com.intellij.util.containers.hash.HashSet; @@ -65,8 +65,14 @@ public class MavenDuplicateDependenciesInspection extends BasicDomElementsInspec for (MavenDomDependency d : dependencies) { if (d == dependency) continue; - if (d.getParent() == dependency.getParent() || scope(d).equals(scope(dependency))) { - duplicatedDependencies.add(d); + if (d.getParent() == dependency.getParent()) { + duplicatedDependencies.add(d); // Dependencies in same file must be unique by groupId:artifactId:type:classifier + } + else { + if (scope(d).equals(scope(dependency)) + && Comparing.equal(d.getVersion().getStringValue(), dependency.getVersion().getStringValue())) { + duplicatedDependencies.add(d); // Dependencies in same file must be unique by groupId:artifactId:VERSION:type:classifier:SCOPE + } } } @@ -176,11 +182,10 @@ public class MavenDuplicateDependenciesInspection extends BasicDomElementsInspec if (StringUtil.isEmptyOrSpaces(groupId) || StringUtil.isEmptyOrSpaces(artifactId)) return null; - String version = coordinates.getVersion().getStringValue(); String type = coordinates.getType().getStringValue(); String classifier = coordinates.getClassifier().getStringValue(); - return groupId + ":" + artifactId + ":" + version + ":" + type + ":" + classifier; + return groupId + ":" + artifactId + ":" + type + ":" + classifier; } @NotNull diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedInspectionTest.groovy b/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedInspectionTest.groovy index e2519e42d16e..9bee055ff90b 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedInspectionTest.groovy +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/inspections/MavenDuplicatedInspectionTest.groovy @@ -23,7 +23,7 @@ import org.jetbrains.idea.maven.dom.inspections.MavenDuplicateDependenciesInspec */ class MavenDuplicatedInspectionTest extends MavenDomTestCase { - public void testDuplicatedInOneFile() { + public void testDuplicatedInSameFile() { myFixture.enableInspections(MavenDuplicateDependenciesInspection) createProjectPom(""" @@ -49,7 +49,32 @@ class MavenDuplicatedInspectionTest extends MavenDomTestCase { checkHighlighting() } - public void testDuplicatedInParent1() { + public void testDuplicatedInSameFileDifferentVersion() { + myFixture.enableInspections(MavenDuplicateDependenciesInspection) + + createProjectPom(""" + mavenParent + childA + 1.0 + + + <dependency> + junit + junit + 3.8.2 + + <dependency> + junit + junit + 3.8.1 + + +""") + + checkHighlighting() + } + + public void testDuplicatedInParentDifferentScope() { myFixture.enableInspections(MavenDuplicateDependenciesInspection) createModulePom("child", """ @@ -98,7 +123,7 @@ class MavenDuplicatedInspectionTest extends MavenDomTestCase { checkHighlighting(myProjectPom, true, false, true) } - public void testDuplicatedInParent2() { + public void testDuplicatedInParentSameScope() { myFixture.enableInspections(MavenDuplicateDependenciesInspection) createModulePom("child", """ @@ -146,4 +171,49 @@ class MavenDuplicatedInspectionTest extends MavenDomTestCase { checkHighlighting(myProjectPom, true, false, true) } + public void testDuplicatedInParentDifferentVersion() { + myFixture.enableInspections(MavenDuplicateDependenciesInspection) + + createModulePom("child", """ + mavenParent + child + 1.0 + + + mavenParent + parent + 1.0 + + + + + junit + junit + 3.8.1 + + +""") + + importProject(""" + mavenParent + parent + 1.0 + pom + + + child + + + + + junit + junit + 3.8.2 + + +""") + + checkHighlighting(myProjectPom, true, false, true) + } + } From 1c25958c2d79807485d81e6adb71fe9e8d228a3a Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Jan 2013 14:57:51 +0100 Subject: [PATCH 08/13] live templates shall not prevent completion by enter with a preview --- .../completion/JavaAutoPopupTest.groovy | 50 ++++--------------- .../completion/CompletionLookupArranger.java | 10 +++- 2 files changed, 19 insertions(+), 41 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy index 904e83c41fe9..4f25bb4743f0 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -60,14 +60,14 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { } """) type('i') - assertContains("if", "iterable", "int") + assertContains("iterable", "if", "int") type('t') assertContains "iterable" assertEquals 'iterable', lookup.currentItem.lookupString type('er') - assertContains("iter", "iterable") + assertContains "iterable", "iter" assertEquals 'iterable', lookup.currentItem.lookupString assert lookup.focused @@ -76,7 +76,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { } def assertContains(String... items) { - assert myFixture.lookupElementStrings.containsAll(items as List) + myFixture.assertPreferredCompletionItems(0, items) } public void testRecalculateItemsOnBackspace() { @@ -89,7 +89,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { } """) type "r" - assertContains "iter", "iterable" + assertContains "iterable", "iter" type '\b' assertContains "iterable" @@ -104,7 +104,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { assertContains "iterable" type "r" - assertContains "iter", "iterable" + assertContains "iterable", "iter" } public void testExplicitSelectionShouldSurvive() { @@ -124,8 +124,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { assertEquals 'iterable2', lookup.currentItem.lookupString type "r" - assertContains "iter", "iterable", 'iterable2' - assertEquals 'iterable2', lookup.currentItem.lookupString + myFixture.assertPreferredCompletionItems 2, "iterable", "iter", 'iterable2' } @@ -146,8 +145,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { assertEquals 'iterable2', lookup.currentItem.lookupString type "r" - assertContains "iter", "iterable", 'iterable2' - assertEquals 'iterable2', lookup.currentItem.lookupString + myFixture.assertPreferredCompletionItems 2, "iterable", "iter", 'iterable2' } @@ -554,7 +552,7 @@ public interface Test { """) type('i') def offset = myFixture.editor.caretModel.offset - assertContains "if", "iterable", "int" + assertContains "iterable", "if", "int" edt { myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT) } assert myFixture.editor.caretModel.offset == offset + 1 @@ -569,7 +567,7 @@ public interface Test { joinAutopopup() joinCompletion() assert !lookup.calculating - assertContains "if", "iterable", "int" + assertContains "iterable", "if", "int" assertEquals 'iterable', lookup.currentItem.lookupString edt { myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT) } @@ -656,26 +654,6 @@ public interface Test { } } - public void testTemplateSelectionByComma() { - myFixture.configureByText("a.java", """ -class Foo { - int itea = 2; - int itera = 2; - - { - it - } -} -""") - type 'e' - assertContains "itea", "itera" - type 'r' - assertContains "iter", "itera" - type ',' - assert !lookup - assert myFixture.editor.document.text.contains('itera,') - } - public void testTemplateSelectionBySpace() { myFixture.configureByText("a.java", """ class Foo { @@ -959,7 +937,7 @@ class Foo { } type('_') - assertContains 'x__foo', 'x__goo' + myFixture.assertPreferredCompletionItems 1, 'x__foo', 'x__goo' edt { assert goo == TargetElementUtil.instance.findTargetElement(myFixture.editor, TargetElementUtil.LOOKUP_ITEM_ACCEPTED) myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP) @@ -1076,14 +1054,6 @@ public class UTest { return editor } - public void _testCharSelectionUndo() { - myFixture.configureByText "a.java", "class Foo {{ }}" - def editor = openEditorForUndo(); - type('ArrStoExce.') - edt { UndoManager.getInstance(project).undo(editor) } - assert myFixture.editor.document.text.contains('ArrStoExce.') - } - public void testAutopopupTypingUndo() { myFixture.configureByText "a.java", "class Foo {{ }}" def editor = openEditorForUndo(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java index d93c17c9418d..9a5bad57d526 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java @@ -230,7 +230,15 @@ public class CompletionLookupArranger extends LookupArranger { ensureItemAdded(items, model, byRelevance, relevantSelection); ensureEverythingVisibleAdded(lookup, model, byRelevance); - return new ArrayList(model); + ArrayList result = new ArrayList(model); + if (result.size() > 1) { + LookupElement first = result.get(0); + if (isLiveTemplate(first) && isPrefixItem(lookup, first, true)) { + ContainerUtil.swapElements(result, 0, 1); + } + } + + return result; } private static void ensureEverythingVisibleAdded(LookupImpl lookup, final LinkedHashSet model, Iterator byRelevance) { From b565ef6fa921bf5a35cac60adf410686528c3ea9 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Jan 2013 15:16:36 +0100 Subject: [PATCH 09/13] IDEA-99162 Switch between alphabetical and relevance completion sorting using a popup menu --- .../codeInsight/lookup/impl/LookupImpl.java | 49 ++++++++++++++----- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 5d0df23ca057..b578aa396cc6 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -17,19 +17,22 @@ package com.intellij.codeInsight.lookup.impl; import com.intellij.codeInsight.CodeInsightBundle; -import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.completion.CodeCompletionFeatures; +import com.intellij.codeInsight.completion.CompletionLookupArranger; +import com.intellij.codeInsight.completion.PrefixMatcher; +import com.intellij.codeInsight.completion.ShowHideIntentionIconLookupAction; import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; import com.intellij.codeInsight.hint.HintManager; import com.intellij.codeInsight.hint.HintManagerImpl; import com.intellij.codeInsight.lookup.*; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.icons.AllIcons; +import com.intellij.ide.DataManager; import com.intellij.ide.IdeEventQueue; import com.intellij.ide.ui.UISettings; import com.intellij.lang.LangBundle; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; @@ -63,6 +66,7 @@ import com.intellij.ui.popup.AbstractPopup; import com.intellij.util.Alarm; import com.intellij.util.CollectConsumer; import com.intellij.util.ObjectUtils; +import com.intellij.util.PlatformIcons; import com.intellij.util.containers.ConcurrentHashMap; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.AbstractLayoutManager; @@ -216,15 +220,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable mySortingLabel.setBorder(new LineBorder(Color.LIGHT_GRAY)); mySortingLabel.setOpaque(true); - new ClickListener() { - @Override - public boolean onClick(MouseEvent e, int clickCount) { - FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_CHANGE_SORTING); - UISettings.getInstance().SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY = !UISettings.getInstance().SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY; - updateSorting(); - return true; - } - }.installOn(mySortingLabel); + new ChangeLookupSorting().installOn(mySortingLabel); updateSorting(); myModalityState = ModalityState.stateForComponent(getComponent()); } @@ -254,7 +250,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable }); } - private void updateSorting() { + void updateSorting() { final boolean lexi = UISettings.getInstance().SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY; mySortingLabel.setIcon(lexi ? AllIcons.Ide.LookupAlphanumeric : AllIcons.Ide.LookupRelevance); mySortingLabel.setToolTipText(lexi ? "Click to sort variants by relevance" : "Click to sort variants alphabetically"); @@ -1488,4 +1484,31 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable void setPreview(CompletionPreview preview) { myPreview = preview; } + + private class ChangeLookupSorting extends ClickListener { + + @Override + public boolean onClick(MouseEvent e, int clickCount) { + DataContext context = DataManager.getInstance().getDataContext(mySortingLabel); + DefaultActionGroup group = new DefaultActionGroup(); + group.add(createSortingAction(true)); + group.add(createSortingAction(false)); + JBPopupFactory.getInstance().createActionGroupPopup("Change sorting", group, context, JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false).showInBestPositionFor( + context); + return true; + } + + private AnAction createSortingAction(boolean checked) { + boolean currentSetting = UISettings.getInstance().SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY; + final boolean newSetting = checked ? currentSetting : !currentSetting; + return new AnAction(newSetting ? "Sort lexicographically" : "Sort by relevance", null, checked ? PlatformIcons.CHECK_ICON : null) { + @Override + public void actionPerformed(AnActionEvent e) { + FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_CHANGE_SORTING); + UISettings.getInstance().SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY = newSetting; + updateSorting(); + } + }; + } + } } From b799bfb238acb261e0f2075d23601b9b0c252c8e Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Jan 2013 15:59:52 +0100 Subject: [PATCH 10/13] simplify lookup element choosing --- .../lookup/impl/actions/ChooseItemAction.java | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemAction.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemAction.java index d5521424b27e..c6221d298051 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemAction.java @@ -28,11 +28,7 @@ import com.intellij.codeInsight.template.impl.TemplateImpl; import com.intellij.codeInsight.template.impl.TemplateSettings; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.command.UndoConfirmationPolicy; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.actionSystem.DocCommandGroupId; import com.intellij.openapi.editor.actionSystem.EditorAction; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.util.TextRange; @@ -54,11 +50,6 @@ public abstract class ChooseItemAction extends EditorAction { this.finishingChar = finishingChar; } - @Override - public boolean executeInCommand(Editor editor, DataContext dataContext) { - return false; - } - @Override public void execute(@NotNull final Editor editor, final DataContext dataContext) { final LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(editor); @@ -77,18 +68,8 @@ public abstract class ChooseItemAction extends EditorAction { } else if (finishingChar == '.') { FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_FINISH_BY_CONTROL_DOT); } - - lookup.uninstallPreview(); - Runnable command = new Runnable() { - @Override - public void run() { - lookup.finishLookup(finishingChar); - } - }; - Document doc = editor.getDocument(); - DocCommandGroupId group = DocCommandGroupId.noneGroupId(doc); - CommandProcessor.getInstance().executeCommand(editor.getProject(), command, "Completion", group, UndoConfirmationPolicy.DEFAULT, doc); + lookup.finishLookup(finishingChar); } From 41539924b3c89369d86e5b57467cae7e4e449cbb Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Jan 2013 16:00:02 +0100 Subject: [PATCH 11/13] IDEA-99104 Add introduce variable action as possibility to finish completion action --- .../actions/BaseRefactoringAction.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/actions/BaseRefactoringAction.java b/platform/lang-impl/src/com/intellij/refactoring/actions/BaseRefactoringAction.java index c7a80c8cf0d2..da105cd31dc2 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/actions/BaseRefactoringAction.java +++ b/platform/lang-impl/src/com/intellij/refactoring/actions/BaseRefactoringAction.java @@ -17,10 +17,18 @@ package com.intellij.refactoring.actions; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.codeInsight.lookup.Lookup; +import com.intellij.codeInsight.lookup.LookupEx; +import com.intellij.codeInsight.lookup.LookupManager; +import com.intellij.codeInsight.lookup.impl.LookupImpl; import com.intellij.ide.IdeEventQueue; import com.intellij.lang.Language; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.command.UndoConfirmationPolicy; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.DocCommandGroupId; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; @@ -87,7 +95,22 @@ public abstract class BaseRefactoringAction extends AnAction { InplaceRefactoring.unableToStartWarning(project, editor); return; } - + + final LookupEx lookup = LookupManager.getActiveLookup(editor); + if (lookup instanceof LookupImpl) { + Runnable command = new Runnable() { + @Override + public void run() { + ((LookupImpl)lookup).finishLookup(Lookup.NORMAL_SELECT_CHAR); + } + }; + assert editor != null; + Document doc = editor.getDocument(); + DocCommandGroupId group = DocCommandGroupId.noneGroupId(doc); + CommandProcessor.getInstance().executeCommand(editor.getProject(), command, "Completion", group, UndoConfirmationPolicy.DEFAULT, doc); + } + + IdeEventQueue.getInstance().setEventCount(eventCount); if (editor != null) { final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); From 1f6878e3ebbba00c7f214cdfaed388dee88f68b4 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 16 Jan 2013 16:34:25 +0100 Subject: [PATCH 12/13] Better generate toString dialog title and friendlier error message when chosen template is invalid --- .../GenerateToStringActionHandlerImpl.java | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java index c4a1922742f3..a955b7d83dc0 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java @@ -98,9 +98,8 @@ public class GenerateToStringActionHandlerImpl extends EditorWriteActionHandler final MemberChooserBuilder builder = new MemberChooserBuilder(project); final MemberChooserHeaderPanel header = new MemberChooserHeaderPanel(clazz); builder.setHeaderPanel(header); - boolean isJdk15Enabled = PsiUtil.isLanguageLevel5OrHigher(clazz); - builder.overrideAnnotationVisible(isJdk15Enabled); - builder.setTitle(calcCurrentTitle()); + builder.overrideAnnotationVisible(PsiUtil.isLanguageLevel5OrHigher(clazz)); + builder.setTitle("Generate toString()"); logger.debug("Displaying member chooser dialog"); SwingUtilities.invokeLater(new Runnable() { @@ -122,7 +121,7 @@ public class GenerateToStringActionHandlerImpl extends EditorWriteActionHandler GenerateToStringWorker.executeGenerateActionLater(clazz, editor, selectedMembers, template, dialog.isInsertOverrideAnnotation()); } else { - Messages.showWarningDialog("The template chosen is invalid.", "Broken Template"); + HintManager.getInstance().showErrorHint(editor, "toString() template '" + template.getFileName() + "' is invalid"); } } } @@ -131,20 +130,7 @@ public class GenerateToStringActionHandlerImpl extends EditorWriteActionHandler logger.debug("+++ doExecuteAction - END +++"); } - private static String calcCurrentTitle() { - final TemplateResource template = TemplatesManager.getInstance().getDefaultTemplate(); - - if (template.isValidTemplate()) { - return "Generate " + template.getTargetMethodName(); - } - else { - return "Generate"; - } - } - public static void updateDialog(PsiClass clazz, MemberChooser dialog) { - dialog.setTitle(calcCurrentTitle()); - final PsiElementClassMember[] members = buildMembersToShow(clazz); dialog.resetElements(members); dialog.selectElements(members); @@ -158,7 +144,6 @@ public class GenerateToStringActionHandlerImpl extends EditorWriteActionHandler PsiField[] filteredFields = GenerateToStringUtils.filterAvailableFields(project, psi, clazz, config.getFilterPattern()); if (logger.isDebugEnabled()) logger.debug("Number of fields after filtering: " + filteredFields.length); - if (logger.isDebugEnabled()) logger.debug("Number of fields after filtering: " + filteredFields.length); PsiMethod[] filteredMethods = new PsiMethod[0]; if (config.enableMethods) { // filter methods as it is enabled from config From d274b1aee0a28525058fef8dfc1c6ec5861ec968 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 16 Jan 2013 16:52:13 +0100 Subject: [PATCH 13/13] Make PsiAdapter a utility class and related cleanup --- .../GenerateToStringActionHandlerImpl.java | 15 +- .../tostring/GenerateToStringUtils.java | 52 ++-- .../tostring/GenerateToStringWorker.java | 93 +++---- .../InsertAfterEqualsHashCodeStrategy.java | 22 +- .../tostring/config/InsertLastStrategy.java | 13 +- .../tostring/element/ClassElement.java | 10 +- .../tostring/element/ElementFactory.java | 84 +++--- .../tostring/element/ElementUtils.java | 37 +-- .../AbstractGenerateToStringQuickFix.java | 10 +- .../ClassHasNoToStringMethodInspection.java | 16 +- .../FieldNotUsedInToStringInspection.java | 11 +- .../generate/tostring/psi/PsiAdapter.java | 248 +++++++----------- .../tostring/psi/PsiAdapterFactory.java | 43 --- 13 files changed, 225 insertions(+), 429 deletions(-) delete mode 100644 plugins/generate-tostring/src/org/jetbrains/generate/tostring/psi/PsiAdapterFactory.java diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java index a955b7d83dc0..1fc2b7c4940b 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringActionHandlerImpl.java @@ -32,7 +32,6 @@ import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.options.TabbedConfigurable; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Disposer; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; @@ -40,8 +39,6 @@ import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.generate.tostring.config.Config; -import org.jetbrains.generate.tostring.psi.PsiAdapter; -import org.jetbrains.generate.tostring.psi.PsiAdapterFactory; import org.jetbrains.generate.tostring.template.TemplateResource; import org.jetbrains.generate.tostring.template.TemplatesManager; import org.jetbrains.generate.tostring.view.TemplatesPanel; @@ -137,18 +134,16 @@ public class GenerateToStringActionHandlerImpl extends EditorWriteActionHandler } private static PsiElementClassMember[] buildMembersToShow(PsiClass clazz) { - Project project = clazz.getProject(); - - PsiAdapter psi = PsiAdapterFactory.getPsiAdapter(); Config config = GenerateToStringContext.getConfig(); - - PsiField[] filteredFields = GenerateToStringUtils.filterAvailableFields(project, psi, clazz, config.getFilterPattern()); + PsiField[] filteredFields = GenerateToStringUtils.filterAvailableFields(clazz, config.getFilterPattern()); if (logger.isDebugEnabled()) logger.debug("Number of fields after filtering: " + filteredFields.length); - PsiMethod[] filteredMethods = new PsiMethod[0]; + PsiMethod[] filteredMethods; if (config.enableMethods) { // filter methods as it is enabled from config - filteredMethods = GenerateToStringUtils.filterAvailableMethods(psi, clazz, config.getFilterPattern()); + filteredMethods = GenerateToStringUtils.filterAvailableMethods(clazz, config.getFilterPattern()); if (logger.isDebugEnabled()) logger.debug("Number of methods after filtering: " + filteredMethods.length); + } else { + filteredMethods = PsiMethod.EMPTY_ARRAY; } return GenerateToStringUtils.combineToClassMemberList(filteredFields, filteredMethods); diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringUtils.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringUtils.java index c74798537cb2..c35426335ad7 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringUtils.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 the original author or authors. + * Copyright 2001-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.psi.*; +import org.jetbrains.annotations.NotNull; import org.jetbrains.generate.tostring.config.FilterPattern; import org.jetbrains.generate.tostring.element.ElementFactory; import org.jetbrains.generate.tostring.element.FieldElement; @@ -48,23 +49,22 @@ public class GenerateToStringUtils { /** * Filters the list of fields from the class with the given parameters from the {@link org.jetbrains.generate.tostring.config.Config config} settings. * - * @param project Project - * @param psi PSI adapter * @param clazz the class to filter it's fields * @param pattern the filter pattern to filter out unwanted fields - * @return fields avaiable for this action after the filter process. + * @return fields available for this action after the filter process. */ - public static PsiField[] filterAvailableFields(Project project, PsiAdapter psi, PsiClass clazz, FilterPattern pattern) { + @NotNull + public static PsiField[] filterAvailableFields(PsiClass clazz, FilterPattern pattern) { if (log.isDebugEnabled()) log.debug("Filtering fields using the pattern: " + pattern); List availableFields = new ArrayList(); // performs til filtering process - PsiField[] fields = clazz.getFields(); + PsiField[] fields = clazz.getFields(); for (PsiField field : fields) { - FieldElement fe = ElementFactory.newFieldElement(project, field, psi); + FieldElement fe = ElementFactory.newFieldElement(field); if (log.isDebugEnabled()) log.debug("Field being filtered: " + fe); - // if the field matches the pattern then it shouldn't be in the list of avaialble fields + // if the field matches the pattern then it shouldn't be in the list of available fields if (!fe.applyFilter(pattern)) { availableFields.add(field); } @@ -81,51 +81,53 @@ public class GenerateToStringUtils { *
  • public, non static, non abstract *
      * - * @param psi PSI adapter + * * @param clazz the class to filter it's fields * @param pattern the filter pattern to filter out unwanted fields - * @return methods avaiable for this action after the filter process. + * @return methods available for this action after the filter process. */ - public static PsiMethod[] filterAvailableMethods(PsiAdapter psi, PsiClass clazz, FilterPattern pattern) { + @NotNull + public static PsiMethod[] filterAvailableMethods(PsiClass clazz, @NotNull FilterPattern pattern) { if (log.isDebugEnabled()) log.debug("Filtering methods using the pattern: " + pattern); List availableMethods = new ArrayList(); - PsiElementFactory elementFactory = JavaPsiFacade.getInstance(clazz.getProject()).getElementFactory(); - PsiMethod[] methods = clazz.getMethods(); + PsiMethod[] methods = clazz.getMethods(); for (PsiMethod method : methods) { - MethodElement me = ElementFactory.newMethodElement(method, elementFactory, psi); - if (log.isDebugEnabled()) log.debug("Method being filtered: " + me); - // the method should be a getter - if (!me.isGetter()) { + if (!PsiAdapter.isGetterMethod(method)) { continue; } // must not return void - if (me.isReturnTypeVoid()) { + final PsiType returnType = method.getReturnType(); + if (returnType == null || PsiType.VOID.equals(returnType)) { continue; } // method should be public, non static, non abstract - if (!me.isModifierPublic() || me.isModifierStatic() || me.isModifierAbstract()) { + if (!method.hasModifierProperty(PsiModifier.PUBLIC) || method.hasModifierProperty(PsiModifier.STATIC) || + method.hasModifierProperty(PsiModifier.ABSTRACT)) { continue; } // method should not be a getter for an existing field - if (clazz.findFieldByName(me.getFieldName(), false) != null) { + String fieldName = PsiAdapter.getGetterFieldName(method); + if (clazz.findFieldByName(fieldName, false) != null) { continue; } // must not be named toString or getClass - if ("toString".equals(me.getMethodName()) || "getClass".equals(me.getMethodName())) { + final String methodName = method.getName(); + if ("toString".equals(methodName) || "getClass".equals(methodName)) { continue; } - // if the method matches the pattern then it shouldn't be in the list of avaialble methods + // if the method matches the pattern then it shouldn't be in the list of available methods + MethodElement me = ElementFactory.newMethodElement(method); if (!me.applyFilter(pattern)) { if (log.isDebugEnabled()) - log.debug("Adding the method " + method.getName() + " as there is not a field for this getter"); + log.debug("Adding the method " + methodName + " as there is not a field for this getter"); availableMethods.add(method); } } @@ -133,7 +135,7 @@ public class GenerateToStringUtils { return availableMethods.toArray(new PsiMethod[availableMethods.size()]); } - /** + /** * Handles any exception during the executing on this plugin. * * @param project PSI project @@ -144,7 +146,7 @@ public class GenerateToStringUtils { log.info(e); if (e instanceof GenerateCodeException) { - // code generation error - display velocity errror in error dialog so user can identify problem quicker + // code generation error - display velocity error in error dialog so user can identify problem quicker Messages.showMessageDialog(project, "Velocity error generating code - see IDEA log for more details (stacktrace should be in idea.log):\n" + e.getMessage(), "Warning", Messages.getWarningIcon()); } else if (e instanceof PluginException) { // plugin related error - could be recoverable. diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringWorker.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringWorker.java index d2dd14f394ef..1b711621a3c2 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringWorker.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringWorker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ */ package org.jetbrains.generate.tostring; -import com.intellij.codeInsight.intention.AddAnnotationFix; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -29,17 +28,16 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.util.IncorrectOperationException; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.generate.tostring.config.*; import org.jetbrains.generate.tostring.element.*; import org.jetbrains.generate.tostring.exception.GenerateCodeException; import org.jetbrains.generate.tostring.psi.PsiAdapter; -import org.jetbrains.generate.tostring.psi.PsiAdapterFactory; import org.jetbrains.generate.tostring.template.TemplateResource; import org.jetbrains.generate.tostring.velocity.VelocityFactory; import org.jetbrains.generate.tostring.view.MethodExistsDialog; @@ -50,13 +48,10 @@ import java.util.*; public class GenerateToStringWorker { private static final Logger logger = Logger.getInstance("#org.jetbrains.generate.tostring.GenerateToStringWorker"); - private final PsiElementFactory elementFactory; private final JVMElementFactory topLevelFactory; private final CodeStyleManager codeStyleManager; private final Editor editor; - private final PsiFile containingFile; private final PsiClass clazz; - private final PsiAdapter psi; private final Config config; private final Project project; private final boolean hasOverrideAnnotation; @@ -64,12 +59,9 @@ public class GenerateToStringWorker { public GenerateToStringWorker(PsiClass clazz, Editor editor, boolean insertAtOverride) { this.clazz = clazz; this.project = clazz.getProject(); - this.psi = PsiAdapterFactory.getPsiAdapter(); this.editor = editor; - this.elementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); this.topLevelFactory = JVMElementFactories.getFactory(clazz.getLanguage(), project); this.codeStyleManager = CodeStyleManager.getInstance(project); - this.containingFile = clazz.getContainingFile(); this.config = GenerateToStringContext.getConfig(); this.hasOverrideAnnotation = insertAtOverride; } @@ -109,7 +101,7 @@ public class GenerateToStringWorker { } /** - * This method get's the choice if there is an existing toString method. + * This method gets the choice if there is an existing toString method. *
      1) If there is a settings to always override use this. *
      2) Prompt a dialog and let the user decide. * @@ -119,7 +111,7 @@ public class GenerateToStringWorker { private ConflictResolutionPolicy exitsMethodDialog(TemplateResource template) { final DuplicatonPolicy dupPolicy = config.getReplaceDialogInitialOption(); if (dupPolicy == DuplicatonPolicy.ASK) { - PsiMethod existingMethod = psi.findMethodByName(clazz, template.getTargetMethodName()); + PsiMethod existingMethod = PsiAdapter.findMethodByName(clazz, template.getTargetMethodName()); if (existingMethod != null) { return MethodExistsDialog.showDialog(template.getTargetMethodName()); } @@ -139,7 +131,7 @@ public class GenerateToStringWorker { * @param template the template to use */ private void beforeCreateToStringMethod(Map params, TemplateResource template) { - PsiMethod existingMethod = psi.findMethodByName(clazz, template.getTargetMethodName()); // find the existing method + PsiMethod existingMethod = PsiAdapter.findMethodByName(clazz, template.getTargetMethodName()); // find the existing method if (existingMethod != null && existingMethod.getDocComment() != null) { PsiDocComment doc = existingMethod.getDocComment(); if (doc != null) { @@ -172,7 +164,7 @@ public class GenerateToStringWorker { body = StringUtil.convertLineSeparators(body); // create psi newMethod named toString() - PsiMethod newMethod = topLevelFactory.createMethodFromText(template.getMethodSignature() + " { " + body + " }", null); + PsiMethod newMethod = topLevelFactory.createMethodFromText(template.getMethodSignature() + " { " + body + " }", clazz); codeStyleManager.reformat(newMethod); // insertNewMethod conflict resolution policy (add/replace, duplicate, cancel) @@ -183,17 +175,7 @@ public class GenerateToStringWorker { } if (hasOverrideAnnotation) { - annotate(toStringMethod, "java.lang.Override"); - } - - // add annotations - if (template.hasAnnotations()) { - String[] annotations = template.getAnnotations(); - // must reverse loop to add annotations in the same order as in the template (when inserting it would insert in top) - for (int i = annotations.length - 1; i > -1; i--) { - String text = annotations[i]; - psi.addAnnotationToMethod(topLevelFactory, toStringMethod, text); - } + toStringMethod.getModifierList().addAnnotation("java.lang.Override"); } // applyJavaDoc conflict resolution policy (add or keep existing) @@ -204,20 +186,16 @@ public class GenerateToStringWorker { newJavaDoc = velocityGenerateCode(selectedMembers, params, newJavaDoc); if (logger.isDebugEnabled()) logger.debug("JavaDoc body generated from Velocity:\n" + newJavaDoc); - applyJavaDoc(toStringMethod, elementFactory, codeStyleManager, existingJavaDoc, newJavaDoc); + applyJavaDoc(toStringMethod, existingJavaDoc, newJavaDoc); } // return the created method return toStringMethod; } - private void applyJavaDoc(PsiMethod newMethod, - PsiElementFactory elementFactory, - CodeStyleManager codeStyleManager, - String existingJavaDoc, - String newJavaDoc) throws IncorrectOperationException { + private static void applyJavaDoc(PsiMethod newMethod, String existingJavaDoc, String newJavaDoc) { String text = newJavaDoc != null ? newJavaDoc : existingJavaDoc; // prefer to use new javadoc - psi.addOrReplaceJavadoc(elementFactory, codeStyleManager, newMethod, text, true); + PsiAdapter.addOrReplaceJavadoc(newMethod, text, true); } @@ -229,24 +207,23 @@ public class GenerateToStringWorker { * @param template the template to use * @throws IncorrectOperationException is thrown by IDEA */ - private void afterCreateToStringMethod(PsiMethod method, Map params, TemplateResource template) - throws IncorrectOperationException { - + private void afterCreateToStringMethod(PsiMethod method, Map params, TemplateResource template) { + PsiFile containingFile = clazz.getContainingFile(); if (containingFile instanceof PsiJavaFile) { final PsiJavaFile javaFile = (PsiJavaFile)containingFile; // if the code uses Arrays, then make sure java.util.Arrays is imported. String javaCode = method.getText(); if (javaCode.indexOf("Arrays.") > 0 && - !(psi.hasImportStatement(javaFile, "java.util.*") || psi.hasImportStatement(javaFile, "java.util.Arrays"))) { + !(PsiAdapter.hasImportStatement(javaFile, "java.util.*") || PsiAdapter.hasImportStatement(javaFile, "java.util.Arrays"))) { // java.util.Arrays must be imported as java.util.* since the addImportStatement method doens't support onDemand-import statement yet. - psi.addImportStatement(javaFile, "java.util.*", elementFactory); + PsiAdapter.addImportStatement(javaFile, "java.util.*"); } // if the code uses Reflection (Field[]), then make sure java.lang.reflect.Field is imported. if (javaCode.indexOf("Field[]") > 0 && - !(psi.hasImportStatement(javaFile, "java.lang.reflect.*") || psi.hasImportStatement(javaFile, "java.lang.reflect.Field"))) { + !(PsiAdapter.hasImportStatement(javaFile, "java.lang.reflect.*") || PsiAdapter.hasImportStatement(javaFile, "java.lang.reflect.Field"))) { // java.lang.reflect.Field must be imported as java.lang.reflect.* since the addImportStatement method doens't support onDemand-import statement yet. - psi.addImportStatement(javaFile, "java.lang.reflect.*", elementFactory); + PsiAdapter.addImportStatement(javaFile, "java.lang.reflect.*"); } // any additional packages to import from the params @@ -260,7 +237,7 @@ public class GenerateToStringWorker { // jump to method if (config.isJumpToMethod() && editor != null) { - PsiMethod newMethod = psi.findMethodByName(clazz, template.getTargetMethodName()); + PsiMethod newMethod = PsiAdapter.findMethodByName(clazz, template.getTargetMethodName()); if (newMethod != null) { int offset = newMethod.getTextOffset(); if (offset > 2) { @@ -279,12 +256,12 @@ public class GenerateToStringWorker { * @param packageNames names of packages (must end with .* and be seperated by ; or ,) * @throws IncorrectOperationException error adding imported package */ - private void autoImportPackages(PsiJavaFile psiJavaFile, String packageNames) throws IncorrectOperationException { + private static void autoImportPackages(PsiJavaFile psiJavaFile, String packageNames) throws IncorrectOperationException { StringTokenizer tok = new StringTokenizer(packageNames, ","); while (tok.hasMoreTokens()) { String packageName = tok.nextToken().trim(); // trim in case of space if (logger.isDebugEnabled()) logger.debug("Auto importing package: " + packageName); - psi.addImportStatement(psiJavaFile, packageName, elementFactory); + PsiAdapter.addImportStatement(psiJavaFile, packageName); } } @@ -295,7 +272,7 @@ public class GenerateToStringWorker { * * @param selectedMembers the selected members as both {@link com.intellij.psi.PsiField} and {@link com.intellij.psi.PsiMethod}. * @param params additional parameters stored with key/value in the map. - * @param templateMacro the veloicty macro template + * @param templateMacro the velocity macro template * @return code (usually javacode). Returns null if templateMacro is null. * @throws GenerateCodeException is thrown when there is an error generating the javacode. */ @@ -311,15 +288,15 @@ public class GenerateToStringWorker { // field information logger.debug("Velocity Context - adding fields"); - vc.put("fields", ElementUtils.getOnlyAsFieldElements(project, psi, selectedMembers)); + vc.put("fields", ElementUtils.getOnlyAsFieldElements(selectedMembers)); // method information logger.debug("Velocity Context - adding methods"); - vc.put("methods", ElementUtils.getOnlyAsMethodElements(elementFactory, psi, selectedMembers)); + vc.put("methods", ElementUtils.getOnlyAsMethodElements(selectedMembers)); // element information (both fields and methods) logger.debug("Velocity Context - adding members (fields and methods)"); - List elements = ElementUtils.getOnlyAsFieldAndMethodElements(project, elementFactory, psi, selectedMembers); + List elements = ElementUtils.getOnlyAsFieldAndMethodElements(selectedMembers); // sort elements if enabled and not using chooser dialog if (config.getSortElements() != 0) { Collections.sort(elements, new ElementComparator(config.getSortElements())); @@ -327,11 +304,11 @@ public class GenerateToStringWorker { vc.put("members", elements); // class information - ClassElement ce = ElementFactory.newClassElement(project, clazz, psi); + ClassElement ce = ElementFactory.newClassElement(clazz); vc.put("class", ce); if (logger.isDebugEnabled()) logger.debug("Velocity Context - adding class: " + ce); - // information to keep as it is to avoid breaking compability with prior releases + // information to keep as it is to avoid breaking compatibility with prior releases vc.put("classname", config.isUseFullyQualifiedName() ? ce.getQualifiedName() : ce.getName()); vc.put("FQClassname", ce.getQualifiedName()); @@ -348,9 +325,9 @@ public class GenerateToStringWorker { params.put("autoImportPackages", (String)vc.get("autoImportPackages")); } - // add java.io.Serializable if choosen in [settings] and does not already implements it + // add java.io.Serializable if chosen in [settings] and does not already implements it if (config.isAddImplementSerializable() && !ce.isImplements("java.io.Serializable")) { - psi.addImplements(project, clazz, "java.io.Serializable"); + PsiAdapter.addImplements(clazz, "java.io.Serializable"); } } @@ -365,13 +342,13 @@ public class GenerateToStringWorker { * Generates the toString() code for the specified class and selected * fields, doing the work through a WriteAction ran by a CommandProcessor. * - * @param selectedMemebers list of members selected + * @param selectedMembers list of members selected * @param template the choosen template to use * @param insertAtOverride */ public static void executeGenerateActionLater(final PsiClass clazz, final Editor editor, - final Collection selectedMemebers, + final Collection selectedMembers, final TemplateResource template, final boolean insertAtOverride) { Runnable writeCommand = new Runnable() { @@ -379,7 +356,7 @@ public class GenerateToStringWorker { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { try { - new GenerateToStringWorker(clazz, editor, insertAtOverride).execute(selectedMemebers, template); + new GenerateToStringWorker(clazz, editor, insertAtOverride).execute(selectedMembers, template); } catch (Exception e) { GenerateToStringUtils.handleException(clazz.getProject(), e); @@ -389,14 +366,6 @@ public class GenerateToStringWorker { } }; - PsiAdapterFactory.getPsiAdapter().executeCommand(clazz.getProject(), writeCommand); - } - - private static void annotate(@NotNull PsiMethod result, String fqn) throws IncorrectOperationException { - Project project = result.getProject(); - AddAnnotationFix fix = new AddAnnotationFix(fqn, result); - if (fix.isAvailable(project, null, result.getContainingFile())) { - fix.invoke(project, null, result.getContainingFile()); - } + PsiAdapter.executeCommand(clazz.getProject(), writeCommand); } } diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/config/InsertAfterEqualsHashCodeStrategy.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/config/InsertAfterEqualsHashCodeStrategy.java index c5841b41934a..9fa4c073ff5b 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/config/InsertAfterEqualsHashCodeStrategy.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/config/InsertAfterEqualsHashCodeStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 the original author or authors. + * Copyright 2001-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,8 @@ import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; import com.intellij.util.IncorrectOperationException; -import org.jetbrains.generate.tostring.psi.PsiAdapter; -import org.jetbrains.generate.tostring.psi.PsiAdapterFactory; import org.jetbrains.annotations.NotNull; +import org.jetbrains.generate.tostring.psi.PsiAdapter; /** * Inserts the method after the hashCode/equals methods in the javafile. @@ -29,26 +28,18 @@ import org.jetbrains.annotations.NotNull; public class InsertAfterEqualsHashCodeStrategy implements InsertNewMethodStrategy { private static final InsertAfterEqualsHashCodeStrategy instance = new InsertAfterEqualsHashCodeStrategy(); - private static PsiAdapter psi; - private InsertAfterEqualsHashCodeStrategy() { - } + private InsertAfterEqualsHashCodeStrategy() {} public static InsertAfterEqualsHashCodeStrategy getInstance() { return instance; } public PsiMethod insertNewMethod(PsiClass clazz, @NotNull PsiMethod newMethod, Editor editor) throws IncorrectOperationException { - // lazy initialize otherwise IDEA throws error: Component requests are not allowed before they are created - if (psi == null) { - psi = PsiAdapterFactory.getPsiAdapter(); - } + PsiMethod methodHashCode = PsiAdapter.findHashCodeMethod(clazz); + PsiMethod methodEquals = PsiAdapter.findEqualsMethod(clazz); - // if main method exists and is the last then add toString just before main method - PsiMethod methodHashCode = psi.findHashCodeMethod(clazz); - PsiMethod methodEquals = psi.findEqualsMethod(clazz); - - // if both methos exist determine the last method in the javafile + // if both methods exist determine the last method in the javafile PsiMethod method; if (methodEquals != null && methodHashCode != null) { if (methodEquals.getTextOffset() > methodHashCode.getTextOffset()) { @@ -74,5 +65,4 @@ public class InsertAfterEqualsHashCodeStrategy implements InsertNewMethodStrateg public String toString() { return "After equals/hashCode"; } - } diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/config/InsertLastStrategy.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/config/InsertLastStrategy.java index cc6b969b914c..b6b9fff04364 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/config/InsertLastStrategy.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/config/InsertLastStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 the original author or authors. + * Copyright 2001-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,9 +20,8 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.util.IncorrectOperationException; -import org.jetbrains.generate.tostring.psi.PsiAdapter; -import org.jetbrains.generate.tostring.psi.PsiAdapterFactory; import org.jetbrains.annotations.NotNull; +import org.jetbrains.generate.tostring.psi.PsiAdapter; /** * Inserts the method last in the javafile. @@ -31,18 +30,16 @@ public class InsertLastStrategy implements InsertNewMethodStrategy { private static final InsertLastStrategy instance = new InsertLastStrategy(); - private InsertLastStrategy() { - } + private InsertLastStrategy() {} public static InsertLastStrategy getInstance() { return instance; } - public PsiMethod insertNewMethod(PsiClass clazz, @NotNull PsiMethod newMethod, Editor editor) throws IncorrectOperationException { - PsiAdapter psi = PsiAdapterFactory.getPsiAdapter(); + public PsiMethod insertNewMethod(PsiClass clazz, @NotNull PsiMethod newMethod, Editor editor) { // if main method exists and is the last then add toString just before main method - PsiMethod mainMethod = psi.findPublicStaticVoidMainMethod(clazz); + PsiMethod mainMethod = PsiAdapter.findPublicStaticVoidMainMethod(clazz); if (mainMethod != null) { // add before main method if it is the last method PsiMethod[] methods = clazz.getMethods(); diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ClassElement.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ClassElement.java index 3432b6c81e6b..395e5e03e811 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ClassElement.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ClassElement.java @@ -30,7 +30,6 @@ public class ClassElement implements Serializable { private String name; private String qualifiedName; - private boolean hasSuper; private String superName; private String superQualifiedName; private String[] implementNames; @@ -123,12 +122,8 @@ public class ClassElement implements Serializable { this.qualifiedName = FQClassname; } - public boolean isHasSuper() { - return hasSuper; - } - - public void setHasSuper(boolean hasSuper) { - this.hasSuper = hasSuper; + public boolean hasSuper() { + return this.superName != null; } public boolean isDeprecated() { @@ -167,7 +162,6 @@ public class ClassElement implements Serializable { return "ClassElement{" + "name='" + name + "'" + ", qualifiedName='" + qualifiedName + "'" + - ", hasSuper=" + hasSuper + ", superName='" + superName + "'" + ", superQualifiedName='" + superQualifiedName + "'" + ", implementNames=" + (implementNames == null ? null : Arrays.asList(implementNames)) + diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ElementFactory.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ElementFactory.java index d5ca95abf134..21bb6f423d17 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ElementFactory.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ElementFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 the original author or authors. + * Copyright 2001-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.jetbrains.generate.tostring.element; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; import com.intellij.psi.*; import org.jetbrains.generate.tostring.psi.PsiAdapter; @@ -33,12 +32,10 @@ public class ElementFactory { /** * Creates a new {@link ClassElement} object. * - * @param project the IDEA project. * @param clazz class information. - * @param psi the psi adapter * @return a new {@link ClassElement} object. */ - public static ClassElement newClassElement(Project project, PsiClass clazz, PsiAdapter psi) { + public static ClassElement newClassElement(PsiClass clazz) { ClassElement ce = new ClassElement(); // name @@ -46,12 +43,11 @@ public class ElementFactory { ce.setQualifiedName(clazz.getQualifiedName()); // super - ce.setHasSuper(psi.hasSuperClass(project, clazz)); - PsiClass superClass = psi.getSuperClass(project, clazz); - ce.setSuperName(superClass == null ? null : superClass.getName()); + PsiClass superClass = clazz.getSuperClass(); + ce.setSuperName((superClass == null) ? null : superClass.getName()); // interfaces - ce.setImplementNames(psi.getImplementsClassnames(clazz)); + ce.setImplementNames(PsiAdapter.getImplementsClassnames(clazz)); // other ce.setEnum(clazz.isEnum()); @@ -65,28 +61,24 @@ public class ElementFactory { /** * Create a new {@link FieldElement} object. * - * @param project the IDEA project. * @param field the {@link com.intellij.psi.PsiField} to get the information from. - * @param psi the psi adapter * @return a new {@link FieldElement} object. */ - public static FieldElement newFieldElement(Project project, PsiField field, PsiAdapter psi) { - PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); - + public static FieldElement newFieldElement(PsiField field) { FieldElement fe = new FieldElement(); - PsiType type = field.getType(); - fe.setName(field.getName()); - if (psi.isConstantField(field)) fe.setConstant(true); - if (psi.isEnumField(field)) fe.setEnum(true); + if (PsiAdapter.isConstantField(field)) fe.setConstant(true); + if (PsiAdapter.isEnumField(field)) fe.setEnum(true); PsiModifierList modifiers = field.getModifierList(); if (modifiers != null) { if (modifiers.hasModifierProperty(PsiModifier.TRANSIENT)) fe.setModifierTransient(true); if (modifiers.hasModifierProperty(PsiModifier.VOLATILE)) fe.setModifierVolatile(true); } - setElementInfo(fe, factory, type, modifiers, psi); + PsiElementFactory factory = JavaPsiFacade.getInstance(field.getProject()).getElementFactory(); + PsiType type = field.getType(); + setElementInfo(fe, factory, type, modifiers); return fe; } @@ -95,12 +87,10 @@ public class ElementFactory { * Creates a new {@link MethodElement} object. * * @param method the PSI method object. - * @param factory the PsiAdapterFactory. - * @param psi the psi adapter * @return a new {@link MethodElement} object. * @since 2.15 */ - public static MethodElement newMethodElement(PsiMethod method, PsiElementFactory factory, PsiAdapter psi) { + public static MethodElement newMethodElement(PsiMethod method) { MethodElement me = new MethodElement(); PsiType type = method.getReturnType(); PsiModifierList modifiers = method.getModifierList(); @@ -111,21 +101,21 @@ public class ElementFactory { log.warn("This method does not have a valid return type: " + method.getName() + ", returnType=" + type); return me; } - - setElementInfo(me, factory, type, modifiers, psi); + PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); + setElementInfo(me, factory, type, modifiers); // names - String fieldName = psi.getGetterFieldName(factory, method); + String fieldName = PsiAdapter.getGetterFieldName(method); me.setName(fieldName == null ? method.getName() : fieldName); me.setFieldName(fieldName); me.setMethodName(method.getName()); // getter - me.setGetter(psi.isGetterMethod(factory, method)); + me.setGetter(PsiAdapter.isGetterMethod(method)); // misc me.setDeprecated(method.isDeprecated()); - me.setReturnTypeVoid(psi.isTypeOfVoid(method.getReturnType())); + me.setReturnTypeVoid(PsiAdapter.isTypeOfVoid(method.getReturnType())); // modifiers if (modifiers.hasModifierProperty(PsiModifier.ABSTRACT)) me.setModifierAbstract(true); @@ -138,48 +128,46 @@ public class ElementFactory { * Sets the basic element information from the given type. * * @param element the element to set information from the type - * @param factory the PsiAdapterFactory. + * @param factory * @param type the type - * @param psi the psi adapter. * @param modifiers modifier list * @since 2.15 */ private static void setElementInfo(AbstractElement element, PsiElementFactory factory, PsiType type, - PsiModifierList modifiers, - PsiAdapter psi) { + PsiModifierList modifiers) { // type names - element.setTypeName(psi.getTypeClassName(type)); - element.setTypeQualifiedName(psi.getTypeQualifiedClassName(type)); + element.setTypeName(PsiAdapter.getTypeClassName(type)); + element.setTypeQualifiedName(PsiAdapter.getTypeQualifiedClassName(type)); // arrays, collections and maps types - if (psi.isObjectArrayType(type)) { + if (PsiAdapter.isObjectArrayType(type)) { element.setObjectArray(true); element.setArray(true); // additional specify if the element is a string array - if (psi.isStringArrayType(type)) element.setStringArray(true); + if (PsiAdapter.isStringArrayType(type)) element.setStringArray(true); } - else if (psi.isPrimitiveArrayType(type)) { + else if (PsiAdapter.isPrimitiveArrayType(type)) { element.setPrimitiveArray(true); element.setArray(true); } - if (psi.isCollectionType(factory, type)) element.setCollection(true); - if (psi.isListType(factory, type)) element.setList(true); - if (psi.isSetType(factory, type)) element.setSet(true); - if (psi.isMapType(factory, type)) element.setMap(true); + if (PsiAdapter.isCollectionType(factory, type)) element.setCollection(true); + if (PsiAdapter.isListType(factory, type)) element.setList(true); + if (PsiAdapter.isSetType(factory, type)) element.setSet(true); + if (PsiAdapter.isMapType(factory, type)) element.setMap(true); // other types - if (psi.isPrimitiveType(type)) element.setPrimitive(true); - if (psi.isObjectType(factory, type)) element.setObject(true); - if (psi.isStringType(factory, type)) element.setString(true); - if (psi.isNumericType(factory, type)) element.setNumeric(true); - if (psi.isDateType(factory, type)) element.setDate(true); - if (psi.isCalendarType(factory, type)) element.setCalendar(true); - if (psi.isBooleanType(factory, type)) element.setBoolean(true); + if (PsiAdapter.isPrimitiveType(type)) element.setPrimitive(true); + if (PsiAdapter.isObjectType(factory, type)) element.setObject(true); + if (PsiAdapter.isStringType(factory, type)) element.setString(true); + if (PsiAdapter.isNumericType(factory, type)) element.setNumeric(true); + if (PsiAdapter.isDateType(factory, type)) element.setDate(true); + if (PsiAdapter.isCalendarType(factory, type)) element.setCalendar(true); + if (PsiAdapter.isBooleanType(factory, type)) element.setBoolean(true); // modifiers if (modifiers != null) { @@ -196,7 +184,5 @@ public class ElementFactory { } else if (modifiers.hasModifierProperty(PsiModifier.PRIVATE)) element.setModifierPrivate(true); } - } - } diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ElementUtils.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ElementUtils.java index a6939103001b..3c2ddae6e73c 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ElementUtils.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/element/ElementUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 the original author or authors. + * Copyright 2001-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,9 @@ */ package org.jetbrains.generate.tostring.element; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiElementFactory; import com.intellij.psi.PsiField; import com.intellij.psi.PsiMember; import com.intellij.psi.PsiMethod; -import org.jetbrains.generate.tostring.psi.PsiAdapter; import java.util.ArrayList; import java.util.Collection; @@ -31,24 +28,21 @@ import java.util.List; */ public class ElementUtils { - private ElementUtils() { - } + private ElementUtils() {} /** - * Get's the list of members to be put in the VelocityContext. + * Gets the list of members to be put in the VelocityContext. * - * @param project Project - * @param psi PSI adapter * @param members a list of {@link com.intellij.psi.PsiMember} objects. * @return a filtered list of only the fields as {@link FieldElement} objects. */ - public static List getOnlyAsFieldElements(Project project, PsiAdapter psi, Collection members) { + public static List getOnlyAsFieldElements(Collection members) { List fieldElementList = new ArrayList(); for (PsiMember member : members) { if (member instanceof PsiField) { PsiField field = (PsiField) member; - FieldElement fe = ElementFactory.newFieldElement(project, field, psi); + FieldElement fe = ElementFactory.newFieldElement(field); fieldElementList.add(fe); } } @@ -57,20 +51,18 @@ public class ElementUtils { } /** - * Get's the list of members to be put in the VelocityContext. + * Gets the list of members to be put in the VelocityContext. * - * @param psi PSI adapter - * @param elementFactory Element Factory * @param members a list of {@link com.intellij.psi.PsiMember} objects. * @return a filtered list of only the methods as a {@link MethodElement} objects. */ - public static List getOnlyAsMethodElements(PsiElementFactory elementFactory, PsiAdapter psi, Collection members) { + public static List getOnlyAsMethodElements(Collection members) { List methodElementList = new ArrayList(); for (PsiMember member : members) { if (member instanceof PsiMethod) { PsiMethod method = (PsiMethod) member; - MethodElement me = ElementFactory.newMethodElement(method, elementFactory, psi); + MethodElement me = ElementFactory.newMethodElement(method); methodElementList.add(me); } } @@ -79,30 +71,25 @@ public class ElementUtils { } /** - * Get's the list of members to be put in the VelocityContext. + * Gets the list of members to be put in the VelocityContext. * - * @param project Project - * @param elementFactory Element Factory - * @param psi PSI adapter * @param members a list of {@link com.intellij.psi.PsiMember} objects. * @return a filtered list of only the methods as a {@link FieldElement} or {@link MethodElement} objects. */ - public static List getOnlyAsFieldAndMethodElements(Project project, PsiElementFactory elementFactory, PsiAdapter psi, Collection members) { + public static List getOnlyAsFieldAndMethodElements(Collection members) { List elementList = new ArrayList(); for (PsiMember member : members) { if (member instanceof PsiField) { PsiField field = (PsiField) member; - FieldElement fe = ElementFactory.newFieldElement(project, field, psi); + FieldElement fe = ElementFactory.newFieldElement(field); elementList.add(fe); } else if (member instanceof PsiMethod) { PsiMethod method = (PsiMethod) member; - MethodElement me = ElementFactory.newMethodElement(method, elementFactory, psi); + MethodElement me = ElementFactory.newMethodElement(method); elementList.add(me); } } - return elementList; } - } diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/AbstractGenerateToStringQuickFix.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/AbstractGenerateToStringQuickFix.java index c0cba4040c9e..06c7e210cf58 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/AbstractGenerateToStringQuickFix.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/AbstractGenerateToStringQuickFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 the original author or authors. + * Copyright 2001-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,6 @@ package org.jetbrains.generate.tostring.inspection; import com.intellij.codeInspection.LocalQuickFix; -import org.jetbrains.generate.tostring.psi.PsiAdapter; -import org.jetbrains.generate.tostring.psi.PsiAdapterFactory; import org.jetbrains.annotations.NotNull; /** @@ -25,12 +23,6 @@ import org.jetbrains.annotations.NotNull; */ public abstract class AbstractGenerateToStringQuickFix implements LocalQuickFix { - protected PsiAdapter psi; - - public AbstractGenerateToStringQuickFix() { - psi = PsiAdapterFactory.getPsiAdapter(); - } - @NotNull public String getName() { return "Generate toString()"; diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/ClassHasNoToStringMethodInspection.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/ClassHasNoToStringMethodInspection.java index 3c9b9edfa4eb..aa97f31a60c3 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/ClassHasNoToStringMethodInspection.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/ClassHasNoToStringMethodInspection.java @@ -25,8 +25,6 @@ import com.intellij.util.ui.CheckBox; import org.jetbrains.annotations.NotNull; import org.jetbrains.generate.tostring.GenerateToStringContext; import org.jetbrains.generate.tostring.GenerateToStringUtils; -import org.jetbrains.generate.tostring.psi.PsiAdapter; -import org.jetbrains.generate.tostring.psi.PsiAdapterFactory; import org.jetbrains.generate.tostring.util.StringUtil; import javax.swing.*; @@ -83,8 +81,6 @@ public class ClassHasNoToStringMethodInspection extends AbstractToStringInspecti if (nameIdentifier == null || clazz.getName() == null) return; - PsiAdapter psi = PsiAdapterFactory.getPsiAdapter(); - // must not be an exception if (excludeException && InheritanceUtil.isInheritor(clazz, CommonClassNames.JAVA_LANG_THROWABLE)) { log.debug("This class is an exception"); @@ -130,19 +126,17 @@ public class ClassHasNoToStringMethodInspection extends AbstractToStringInspecti } // get list of fields and getter methods supposed to be dumped in the toString method - Project project = clazz.getProject(); - fields = GenerateToStringUtils.filterAvailableFields(project, psi, clazz, GenerateToStringContext.getConfig().getFilterPattern()); + fields = GenerateToStringUtils.filterAvailableFields(clazz, GenerateToStringContext.getConfig().getFilterPattern()); PsiMethod[] methods = null; if (GenerateToStringContext.getConfig().isEnableMethods()) { // okay 'getters in code generation' is enabled so check - methods = GenerateToStringUtils.filterAvailableMethods(psi, clazz, GenerateToStringContext.getConfig().getFilterPattern()); + methods = GenerateToStringUtils.filterAvailableMethods(clazz, GenerateToStringContext.getConfig().getFilterPattern()); } // there should be any fields - if (fields == null && methods == null) - return; - else if (Math.max( fields == null ? 0 : fields.length, methods == null ? 0 : methods.length) == 0) - return; + if (Math.max(fields.length, methods == null ? 0 : methods.length) == 0) { + return; + } // okay some fields/getter methods are supposed to dumped, does a toString method exist final PsiMethod[] toStringMethods = clazz.findMethodsByName("toString", false); diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/FieldNotUsedInToStringInspection.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/FieldNotUsedInToStringInspection.java index 34829ad795a6..18798fd68e32 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/FieldNotUsedInToStringInspection.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/FieldNotUsedInToStringInspection.java @@ -24,7 +24,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.generate.tostring.GenerateToStringContext; import org.jetbrains.generate.tostring.GenerateToStringUtils; import org.jetbrains.generate.tostring.psi.PsiAdapter; -import org.jetbrains.generate.tostring.psi.PsiAdapterFactory; /** * Intention to check if the current class toString() method is out of @@ -80,7 +79,6 @@ public class FieldNotUsedInToStringInspection extends AbstractToStringInspection } // must have fields - PsiAdapter psi = PsiAdapterFactory.getPsiAdapter(); PsiField[] fields = clazz.getFields(); if (fields.length == 0) { log.debug("Class does not have any fields"); @@ -88,7 +86,7 @@ public class FieldNotUsedInToStringInspection extends AbstractToStringInspection } // a toString method must exist - PsiMethod toStringMethod = psi.findMethodByName(clazz, "toString"); + PsiMethod toStringMethod = PsiAdapter.findMethodByName(clazz, "toString"); if (toStringMethod == null) { log.debug("No toString() method"); return; @@ -113,7 +111,7 @@ public class FieldNotUsedInToStringInspection extends AbstractToStringInspection // get list of fields supposed to be dumped in the toString method Project project = clazz.getProject(); - fields = GenerateToStringUtils.filterAvailableFields(project, psi, clazz, GenerateToStringContext.getConfig().getFilterPattern()); + fields = GenerateToStringUtils.filterAvailableFields(clazz, GenerateToStringContext.getConfig().getFilterPattern()); if (fields.length == 0) { log.debug("No fields to be dumped as all fields was excluded (exclude field by XXX from Settings)"); return; @@ -159,8 +157,7 @@ public class FieldNotUsedInToStringInspection extends AbstractToStringInspection } // a toString method must exist - PsiAdapter psi = PsiAdapterFactory.getPsiAdapter(); - PsiMethod toStringMethod = psi.findMethodByName(clazz, "toString"); + PsiMethod toStringMethod = PsiAdapter.findMethodByName(clazz, "toString"); if (toStringMethod == null) { log.debug("No toString() method"); return; @@ -188,7 +185,7 @@ public class FieldNotUsedInToStringInspection extends AbstractToStringInspection } // get list of methods supposed to be dumped in the toString method - methods = GenerateToStringUtils.filterAvailableMethods(psi, clazz, GenerateToStringContext.getConfig().getFilterPattern()); + methods = GenerateToStringUtils.filterAvailableMethods(clazz, GenerateToStringContext.getConfig().getFilterPattern()); if (methods.length == 0) { log.debug("No getter methods to be dumped as all methods was excluded or a field existed for the getter method (exclude method by XXX from Settings)"); return; diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/psi/PsiAdapter.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/psi/PsiAdapter.java index d262cb5960cc..556c31ec9300 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/psi/PsiAdapter.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/psi/PsiAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 the original author or authors. + * Copyright 2001-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,22 +34,18 @@ import org.jetbrains.generate.tostring.util.StringUtil; */ public class PsiAdapter { - /** - * Constructor - use {@link PsiAdapterFactory}. - */ - protected PsiAdapter() { - } + private PsiAdapter() {} - /** + /** * Returns true if a field is constant. *

      - * This is identifed as the name of the field is only in uppercase and it has + * This is identified as the name of the field is only in uppercase and it has * a static modifier. * * @param field field to check if it's a constant * @return true if constant. */ - public boolean isConstantField(PsiField field) { + public static boolean isConstantField(PsiField field) { PsiModifierList list = field.getModifierList(); if (list == null) { return false; @@ -65,7 +61,7 @@ public class PsiAdapter { } /** - * Find's an existing method with the given name. + * Finds an existing method with the given name. * If there isn't a method with the name, null is returned. * * @param clazz the class @@ -73,25 +69,26 @@ public class PsiAdapter { * @return the found method, null if none exist */ @Nullable - public PsiMethod findMethodByName(PsiClass clazz, String name) { + public static PsiMethod findMethodByName(PsiClass clazz, String name) { PsiMethod[] methods = clazz.getMethods(); - // use reverse to find from botton as the duplicate conflict resolution policy requires this + // use reverse to find from bottom as the duplicate conflict resolution policy requires this for (int i = methods.length - 1; i >= 0; i--) { PsiMethod method = methods[i]; - if (name.equals(method.getName())) + if (name.equals(method.getName())) { return method; + } } return null; } /** - * Returns true if the given field a primtive array type (e.g., int[], long[], float[]). + * Returns true if the given field a primitive array type (e.g., int[], long[], float[]). * * @param type type. - * @return true if field is a primitve array type. + * @return true if field is a primitive array type. */ - public boolean isPrimitiveArrayType(PsiType type) { + public static boolean isPrimitiveArrayType(PsiType type) { return type instanceof PsiArrayType && isPrimitiveType(((PsiArrayType) type).getComponentType()); } @@ -101,7 +98,7 @@ public class PsiAdapter { * @param type type. * @return true if it's an Object array type. */ - public boolean isObjectArrayType(PsiType type) { + public static boolean isObjectArrayType(PsiType type) { return type instanceof PsiArrayType && !isPrimitiveType(((PsiArrayType) type).getComponentType()); } @@ -111,7 +108,7 @@ public class PsiAdapter { * @param type type. * @return true if it's a String array type. */ - public boolean isStringArrayType(PsiType type) { + public static boolean isStringArrayType(PsiType type) { if (isPrimitiveType(type)) return false; @@ -125,7 +122,7 @@ public class PsiAdapter { * @param type type. * @return true if it's a Collection type. */ - public boolean isCollectionType(PsiElementFactory factory, PsiType type) { + public static boolean isCollectionType(PsiElementFactory factory, PsiType type) { return isTypeOf(factory, type, "java.util.Collection"); } @@ -136,7 +133,7 @@ public class PsiAdapter { * @param type type. * @return true if it's a Map type. */ - public boolean isMapType(PsiElementFactory factory, PsiType type) { + public static boolean isMapType(PsiElementFactory factory, PsiType type) { return isTypeOf(factory, type, CommonClassNames.JAVA_UTIL_MAP); } @@ -147,7 +144,7 @@ public class PsiAdapter { * @param type type. * @return true if it's a Map type. */ - public boolean isSetType(PsiElementFactory factory, PsiType type) { + public static boolean isSetType(PsiElementFactory factory, PsiType type) { return isTypeOf(factory, type, CommonClassNames.JAVA_UTIL_SET); } @@ -158,7 +155,7 @@ public class PsiAdapter { * @param type type. * @return true if it's a Map type. */ - public boolean isListType(PsiElementFactory factory, PsiType type) { + public static boolean isListType(PsiElementFactory factory, PsiType type) { return isTypeOf(factory, type, CommonClassNames.JAVA_UTIL_LIST); } @@ -169,7 +166,7 @@ public class PsiAdapter { * @param type type. * @return true if it's a String type. */ - public boolean isStringType(PsiElementFactory factory, PsiType type) { + public static boolean isStringType(PsiElementFactory factory, PsiType type) { return isTypeOf(factory, type, "java.lang.String"); } @@ -180,7 +177,7 @@ public class PsiAdapter { * @param type type. * @return true if it's an Object type. */ - public boolean isObjectType(PsiElementFactory factory, PsiType type) { + public static boolean isObjectType(PsiElementFactory factory, PsiType type) { return isTypeOf(factory, type, CommonClassNames.JAVA_LANG_OBJECT); } @@ -191,7 +188,7 @@ public class PsiAdapter { * @param type type. * @return true if it's a Date type. */ - public boolean isDateType(PsiElementFactory factory, PsiType type) { + public static boolean isDateType(PsiElementFactory factory, PsiType type) { return isTypeOf(factory, type, "java.util.Date"); } @@ -202,7 +199,7 @@ public class PsiAdapter { * @param type type. * @return true if it's a Calendar type. */ - public boolean isCalendarType(PsiElementFactory factory, PsiType type) { + public static boolean isCalendarType(PsiElementFactory factory, PsiType type) { return isTypeOf(factory, type, "java.util.Calendar"); } @@ -213,7 +210,7 @@ public class PsiAdapter { * @param type type. * @return true if it's a Boolean or boolean type. */ - public boolean isBooleanType(PsiElementFactory factory, PsiType type) { + public static boolean isBooleanType(PsiElementFactory factory, PsiType type) { if (isPrimitiveType(type)) { // test for simple type of boolean String s = type.getCanonicalText(); @@ -231,7 +228,7 @@ public class PsiAdapter { * @param type type. * @return true if it's a numeric type. */ - public boolean isNumericType(PsiElementFactory factory, PsiType type) { + public static boolean isNumericType(PsiElementFactory factory, PsiType type) { if (isPrimitiveType(type)) { // test for simple type of numeric String s = type.getCanonicalText(); @@ -242,36 +239,37 @@ public class PsiAdapter { } } - /** + /** * Does the javafile have the import statement? * * @param javaFile javafile. * @param importStatement import statement to test existing for. * @return true if the javafile has the import statement. */ - public boolean hasImportStatement(PsiJavaFile javaFile, String importStatement) { + public static boolean hasImportStatement(PsiJavaFile javaFile, String importStatement) { PsiImportList importList = javaFile.getImportList(); if (importList == null) { return false; } if (importStatement.endsWith(".*")) { - return (importList.findOnDemandImportStatement(fixImportStatement(importStatement)) != null); + return importList.findOnDemandImportStatement(fixImportStatement(importStatement)) != null; } else { - return (importList.findSingleClassImportStatement(importStatement) != null); + return importList.findSingleClassImportStatement(importStatement) != null; } } /** - * Add's an importstatement to the javafile and optimizes the imports afterwards. + * Adds an import statement to the javafile and optimizes the imports afterwards. + * * * @param javaFile javafile. - * @param importStatementOnDemand name of importstatement, must be with a wildcard (etc. java.util.*). - * @param factory PSI element factory. + * @param importStatementOnDemand name of import statement, must be with a wildcard (etc. java.util.*). * @throws com.intellij.util.IncorrectOperationException - * is thrown if there is an error creating the importstatement. + * is thrown if there is an error creating the import statement. */ - public void addImportStatement(PsiJavaFile javaFile, String importStatementOnDemand, PsiElementFactory factory) throws IncorrectOperationException { + public static void addImportStatement(PsiJavaFile javaFile, String importStatementOnDemand) { + PsiElementFactory factory = JavaPsiFacade.getInstance(javaFile.getProject()).getElementFactory(); PsiImportStatement is = factory.createImportStatementOnDemand(fixImportStatement(importStatementOnDemand)); // add the import to the file, and optimize the imports @@ -293,7 +291,7 @@ public class PsiAdapter { * @param importStatementOnDemand import statement * @return import statement only with packagename */ - private String fixImportStatement(String importStatementOnDemand) { + private static String fixImportStatement(String importStatementOnDemand) { if (importStatementOnDemand.endsWith(".*")) { return importStatementOnDemand.substring(0, importStatementOnDemand.length() - 2); } else { @@ -311,33 +309,14 @@ public class PsiAdapter { } /** - * Does this class have a super class? - *

      - * If the class just extends java.lang.Object then false is returned. - * Extending java.lang.Object is not concidered the class to have a super class. - * - * @param project the IDEA project - * @param clazz the class to test - * @return true if this class extends another class. - */ - public boolean hasSuperClass(Project project, PsiClass clazz) { - PsiClass superClass = getSuperClass(project, clazz); - if (superClass == null) { - return false; - } - - return (!"Object".equals(superClass.getName())); - } - - /** - * Get's the fields fully qualified classname (etc java.lang.String, java.util.ArrayList) + * Gets the fields fully qualified classname (etc java.lang.String, java.util.ArrayList) * * @param type the type. * @return the fully qualified classname, null if the field is a primitive. * @see #getTypeClassName(com.intellij.psi.PsiType) for the non qualified version. */ @Nullable - public String getTypeQualifiedClassName(PsiType type) { + public static String getTypeQualifiedClassName(PsiType type) { if (isPrimitiveType(type)) { return null; } @@ -352,14 +331,14 @@ public class PsiAdapter { } /** - * Get's the fields classname (etc. String, ArrayList) + * Gets the fields classname (etc. String, ArrayList) * * @param type the type. * @return the classname, null if the field is a primitive. * @see #getTypeQualifiedClassName(com.intellij.psi.PsiType) for the qualified version. */ @Nullable - public String getTypeClassName(PsiType type) { + public static String getTypeClassName(PsiType type) { String name = getTypeQualifiedClassName(type); // return null if it was a primitive type @@ -371,14 +350,14 @@ public class PsiAdapter { return name.substring(i + 1, name.length()); } - /** + /** * Finds the public static void main(String[] args) method. * * @param clazz the class. * @return the method if it exists, null if not. */ @Nullable - public PsiMethod findPublicStaticVoidMainMethod(PsiClass clazz) { + public static PsiMethod findPublicStaticVoidMainMethod(PsiClass clazz) { PsiMethod[] methods = clazz.findMethodsByName("main", false); // is it public static void main(String[] args) @@ -395,7 +374,7 @@ public class PsiAdapter { // must have void as return type PsiType returnType = method.getReturnType(); - if (returnType == null || returnType.equalsToText("void")) { + if (!PsiType.VOID.equals(returnType)) { continue; } @@ -421,8 +400,6 @@ public class PsiAdapter { /** * Add or replaces the javadoc comment to the given method. * - * @param factory element factory. - * @param codeStyleManager CodeStyleManager. * @param method the method the javadoc should be added/set to. * @param javadoc the javadoc comment. * @param replace true if any existing javadoc should be replaced. false will not replace any existing javadoc and thus leave the javadoc untouched. @@ -430,7 +407,9 @@ public class PsiAdapter { * @throws IncorrectOperationException is thrown if error adding/replacing the javadoc comment. */ @Nullable - public PsiComment addOrReplaceJavadoc(PsiElementFactory factory, CodeStyleManager codeStyleManager, PsiMethod method, String javadoc, boolean replace) throws IncorrectOperationException { + public static PsiComment addOrReplaceJavadoc(PsiMethod method, String javadoc, boolean replace) { + final Project project = method.getProject(); + PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); PsiComment comment = factory.createCommentFromText(javadoc, null); // does a method already exists? @@ -439,6 +418,7 @@ public class PsiAdapter { if (replace) { // javadoc already exists, so replace doc.replace(comment); + final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); codeStyleManager.reformat(method); // to reformat javadoc return comment; } else { @@ -448,6 +428,7 @@ public class PsiAdapter { } else { // add new javadoc method.addBefore(comment, method.getFirstChild()); + final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); codeStyleManager.reformat(method); // to reformat javadoc return comment; } @@ -459,8 +440,8 @@ public class PsiAdapter { * @param type the type. * @return true if a void type, false if not. */ - public boolean isTypeOfVoid(PsiType type) { - return (type != null && type.equalsToText("void")); + public static boolean isTypeOfVoid(PsiType type) { + return type != null && type.equalsToText("void"); } /** @@ -469,27 +450,30 @@ public class PsiAdapter { * The name of the method must start with get or is. * And if the method is a isXXX then the method must return a java.lang.Boolean or boolean. * - * @param factory element factory. + * * @param method the method * @return true if a getter method, false if not. */ - public boolean isGetterMethod(PsiElementFactory factory, PsiMethod method) { + public static boolean isGetterMethod(PsiMethod method) { // must not be a void method if (isTypeOfVoid(method.getReturnType())) { return false; } - + final PsiParameterList parameterList = method.getParameterList(); + if (parameterList.getParametersCount() != 0) { + return false; + } if (method.getName().matches("^(is|has)\\p{Upper}.*")) { - return isBooleanType(factory, method.getReturnType()); + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(method.getProject()); + return isBooleanType(factory, method.getReturnType()); } else if (method.getName().matches("^(get)\\p{Upper}.*")) { return true; } - return false; } /** - * Get's the field name of the getter method. + * Gets the field name of the getter method. *

      * The method must be a getter method for a field. * Returns null if this method is not a getter. @@ -499,28 +483,27 @@ public class PsiAdapter { *

      * Example: methodName=getName will return fieldname=name * - * @param factory element factory. + * * @param method the method * @return the fieldname if this is a getter method. - * @see #isGetterMethod(com.intellij.psi.PsiElementFactory,com.intellij.psi.PsiMethod) for the getter check + * @see #isGetterMethod(com.intellij.psi.PsiMethod) for the getter check */ @Nullable - public String getGetterFieldName(PsiElementFactory factory, PsiMethod method) { + public static String getGetterFieldName(PsiMethod method) { // must be a getter - if (!isGetterMethod(factory, method)) { + if (!isGetterMethod(method)) { return null; } - return PropertyUtil.getPropertyNameByGetter(method); } - /** + /** * Returns true if the field is enum (JDK1.5). * * @param field field to check if it's a enum * @return true if enum. */ - public boolean isEnumField(PsiField field) { + public static boolean isEnumField(PsiField field) { PsiType type = field.getType(); // must not be an primitive type @@ -541,7 +524,7 @@ public class PsiAdapter { } return clazz.isEnum(); - } + } /** * Is the class an exception - extends Throwable (will check super). @@ -553,14 +536,14 @@ public class PsiAdapter { return InheritanceUtil.isInheritor(clazz, CommonClassNames.JAVA_LANG_THROWABLE); } - /** + /** * Finds the public boolean equals(Object o) method. * * @param clazz the class. * @return the method if it exists, null if not. */ @Nullable - public PsiMethod findEqualsMethod(PsiClass clazz) { + public static PsiMethod findEqualsMethod(PsiClass clazz) { PsiMethod[] methods = clazz.findMethodsByName("equals", false); // is it public boolean equals(Object o) @@ -571,13 +554,13 @@ public class PsiAdapter { } // must not be static - if (method.hasModifierProperty(PsiModifier.STATIC)) { - continue; - } + if (method.hasModifierProperty(PsiModifier.STATIC)) { + continue; + } // must have boolean as return type PsiType returnType = method.getReturnType(); - if (returnType == null || !returnType.equalsToText("boolean")) { + if (!PsiType.BOOLEAN.equals(returnType)) { continue; } @@ -607,7 +590,7 @@ public class PsiAdapter { * @return the method if it exists, null if not. */ @Nullable - public PsiMethod findHashCodeMethod(PsiClass clazz) { + public static PsiMethod findHashCodeMethod(PsiClass clazz) { PsiMethod[] methods = clazz.findMethodsByName("hashCode", false); // is it public int hashCode() @@ -618,19 +601,19 @@ public class PsiAdapter { } // must not be static - if (method.hasModifierProperty(PsiModifier.STATIC)) { - continue; - } + if (method.hasModifierProperty(PsiModifier.STATIC)) { + continue; + } // must have int as return type PsiType returnType = method.getReturnType(); - if (returnType == null || !returnType.equalsToText("int")) { + if (!PsiType.INT.equals(returnType)) { continue; } // must not have a parameter - PsiParameter[] parameters = method.getParameterList().getParameters(); - if (parameters.length != 0) { + PsiParameterList parameters = method.getParameterList(); + if (parameters.getParametersCount() != 0) { continue; } @@ -642,39 +625,15 @@ public class PsiAdapter { return null; } - /** - * Adds/replaces the given annotation text to the method. - * - * @param factory element factory. - * @param method the method the javadoc should be added/set to. - * @param annotation the annotation as text. - * @return the added annotation object - * @throws IncorrectOperationException is thrown if error adding/replacing the javadoc comment. - */ - public PsiAnnotation addAnnotationToMethod(JVMElementFactory factory, PsiMethod method, String annotation) throws IncorrectOperationException { - PsiAnnotation ann = method.getModifierList().findAnnotation(annotation); - if (ann == null) { - // add new annotation - ann = factory.createAnnotationFromText(annotation, method.getModifierList()); - PsiModifierList modifierList = method.getModifierList(); - modifierList.addBefore(ann, modifierList.getFirstChild()); - } else { - PsiModifierList modifierList = method.getModifierList(); - modifierList.replace(ann); // already exist so replace - } - - return ann; - } - /** * Check if the given type against a FQ classname (assignable). * * @param factory IDEA factory * @param type the type * @param typeFQClassName the FQ classname to test against. - * @return true if the given type is assigneable of FQ classname. + * @return true if the given type is assignable of FQ classname. */ - protected boolean isTypeOf(PsiElementFactory factory, PsiType type, String typeFQClassName) { + protected static boolean isTypeOf(PsiElementFactory factory, PsiType type, String typeFQClassName) { // fix for IDEA where fields can have 'void' type and generate NPE. if (isTypeOfVoid(type)) { return false; @@ -693,35 +652,12 @@ public class PsiAdapter { } /** - * Get's the superclass. - * - * @param project IDEA project - * @param clazz the class - * @return the super, null if not found. - */ - @Nullable - public PsiClass getSuperClass(Project project, PsiClass clazz) { - PsiReferenceList list = clazz.getExtendsList(); - - // check if no superclass at all - if (list == null || list.getReferencedTypes().length != 1) { - return null; - } - - // have superclass get it [0] is the index of the superclass (a class can not extend more than one class) - GlobalSearchScope scope = list.getReferencedTypes()[0].getResolveScope(); - String classname = list.getReferencedTypes()[0].getCanonicalText(); - - return JavaPsiFacade.getInstance(project).findClass(classname, scope); - } - - /** - * Get's the names the given class implements (not FQ names). + * Gets the names the given class implements (not FQ names). * * @param clazz the class * @return the names. */ - public String[] getImplementsClassnames(PsiClass clazz) { + public static String[] getImplementsClassnames(PsiClass clazz) { PsiClass[] interfaces = clazz.getInterfaces(); if (interfaces == null || interfaces.length == 0) { @@ -743,30 +679,30 @@ public class PsiAdapter { * @param type the type. * @return true if primitive, false if not. */ - public boolean isPrimitiveType(PsiType type) { + public static boolean isPrimitiveType(PsiType type) { return type instanceof PsiPrimitiveType; } /** - * Executes the given runable in IDEA command. + * Executes the given runnable in IDEA command. * * @param project IDEA project - * @param runable the runable task to exexute. + * @param runnable the runnable task to execute. */ - public void executeCommand(Project project, Runnable runable) { - CommandProcessor.getInstance().executeCommand(project, runable, "GenerateToString", null); + public static void executeCommand(Project project, Runnable runnable) { + CommandProcessor.getInstance().executeCommand(project, runnable, "GenerateToString", null); } /** - * Add's the interface name to the class implementation list. + * Adds the interface name to the class implementation list. * - * @param project IDEA project * @param clazz the class * @param interfaceName the interface name the class should implement * @throws IncorrectOperationException is thrown by IDEA. */ - public void addImplements(Project project, PsiClass clazz, String interfaceName) throws IncorrectOperationException { - JavaPsiFacade facade = JavaPsiFacade.getInstance(project); + public static void addImplements(PsiClass clazz, String interfaceName) { + final Project project = clazz.getProject(); + JavaPsiFacade facade = JavaPsiFacade.getInstance(project); // get the interface class PsiClass interfaceClass = facade.findClass(interfaceName, GlobalSearchScope.allScope(project)); diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/psi/PsiAdapterFactory.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/psi/PsiAdapterFactory.java deleted file mode 100644 index 3e797fa5bb44..000000000000 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/psi/PsiAdapterFactory.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2001-2007 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.generate.tostring.psi; - -/** - * Factory to get a PsiAdapter class compatible with the correct version of IDEA. - * - * @see PsiAdapter - */ -public class PsiAdapterFactory { - - private static PsiAdapter instance; // singleton instance - - private PsiAdapterFactory() { - } - - /** - * Gets the PsiAdapter - * - * @return the PsiAdapter used for the current version of IDEA. - */ - public static PsiAdapter getPsiAdapter() { - if (instance == null) { - instance = new PsiAdapter(); - } - - return instance; - } - -}