From 83aa02a6ed034f348a8caf53a8a12135e3eb4468 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Tue, 1 Feb 2011 11:11:18 +0300 Subject: [PATCH 01/94] IDEA-64810 The "Incorrect type "java.util.List"" Idea exception --- .../plugins/groovy/dsl/toplevel/ClassContextFilter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/ClassContextFilter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/ClassContextFilter.java index 9c67f2d0e1f1..ef09533c3e11 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/ClassContextFilter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/ClassContextFilter.java @@ -66,6 +66,7 @@ public class ClassContextFilter implements ContextFilter { PsiFile place = p.second; //PsiType myType = JavaPsiFacade.getElementFactory(place.getProject()).createTypeFromText(typeText, place); PsiType myType = getCachedType(typeText, place); + if (p.first == PsiType.NULL) return myType == PsiType.NULL; return TypesUtil.isAssignable(myType, p.first, place.getManager(), place.getResolveScope(), false); } }); From 5d66d5ceca7ac879e8dbccdd68c3e1fb13318297 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Tue, 1 Feb 2011 13:17:15 +0300 Subject: [PATCH 02/94] multiple assignment corrected --- .../expressions/GrTupleExpression.java | 3 +++ .../psi/dataFlow/types/TypeDfaInstance.java | 13 ++++--------- .../expressions/GrTupleExpressionImpl.java | 17 ++++++++++++----- .../plugins/groovy/lang/psi/util/PsiUtil.java | 2 +- .../groovy/lang/GroovyHighlightingTest.java | 4 ++++ .../groovy/controlFlow/multipleAssignment.test | 2 +- .../testdata/highlighting/VarNotAssigned.groovy | 9 +++++++++ .../resolve/method/multipleAssignment1/A.groovy | 2 +- .../resolve/method/multipleAssignment2/A.groovy | 2 +- .../resolve/method/multipleAssignment3/A.groovy | 2 +- 10 files changed, 37 insertions(+), 19 deletions(-) create mode 100644 plugins/groovy/testdata/highlighting/VarNotAssigned.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrTupleExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrTupleExpression.java index 522e4602c1a7..e3aa3bf413ad 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrTupleExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrTupleExpression.java @@ -16,8 +16,11 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions; +import com.intellij.psi.PsiElement; + /** * @author ilyas */ public interface GrTupleExpression extends GrExpression { + int indexOf(PsiElement element); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/types/TypeDfaInstance.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/types/TypeDfaInstance.java index d6dc637d833b..c32de5b6689c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/types/TypeDfaInstance.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/types/TypeDfaInstance.java @@ -22,12 +22,8 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrInstanceOfExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.AssertionInstruction; @@ -38,7 +34,6 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; import org.jetbrains.plugins.groovy.lang.psi.impl.TypeInferenceHelper; -import java.util.Arrays; import java.util.Map; /** @@ -89,11 +84,11 @@ public class TypeDfaInstance implements DfaInstance> { return null; } - if (parent instanceof GrListOrMap) { - GrListOrMap list = (GrListOrMap)parent; + if (parent instanceof GrTupleExpression) { + GrTupleExpression list = (GrTupleExpression)parent; if (list.getParent() instanceof GrAssignmentExpression) { // multiple assignment final GrExpression rValue = ((GrAssignmentExpression) list.getParent()).getRValue(); - int idx = Arrays.asList(list.getInitializers()).indexOf(element); + int idx = list.indexOf(element); if (idx >= 0 && rValue != null) { return getMultipleAssignmentTypeComputation(rValue, idx); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrTupleExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrTupleExpressionImpl.java index c969db7e4ba6..a229c81b58da 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrTupleExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrTupleExpressionImpl.java @@ -16,12 +16,13 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrTupleExpression; -import org.jetbrains.annotations.NotNull; -import com.intellij.psi.PsiType; -import com.intellij.psi.JavaPsiFacade; import com.intellij.lang.ASTNode; -import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiType; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrTupleExpression; /** * @author ilyas @@ -40,4 +41,10 @@ public class GrTupleExpressionImpl extends GrExpressionImpl implements GrTupleEx public PsiType getType() { return getTypeByFQName("java.util.List"); } + + @Override + public int indexOf(PsiElement element) { + GrExpression[] children = findChildrenByClass(GrExpression.class); + return ArrayUtil.find(children, element); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java index 02efac8e4b2c..e5a6c555293e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java @@ -115,7 +115,7 @@ public class PsiUtil { public static boolean isLValue(GroovyPsiElement element) { if (element instanceof GrExpression) { PsiElement parent = PsiTreeUtil.skipParentsOfType(element, GrParenthesizedExpression.class); - if (parent instanceof GrListOrMap && !((GrListOrMap)parent).isMap()) { + if (parent instanceof GrTupleExpression) { return isLValue((GroovyPsiElement)parent); } return parent instanceof GrAssignmentExpression && PsiTreeUtil.isAncestor(((GrAssignmentExpression)parent).getLValue(), element, false); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java index 516cf3cf827d..b10c11adfe56 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java @@ -333,4 +333,8 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase { public void testMethodImplementedByDelegate() { doTest(); } + + public void testVarNotAssigned() { + doTest(new UnassignedVariableAccessInspection()); + } } \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/controlFlow/multipleAssignment.test b/plugins/groovy/testdata/groovy/controlFlow/multipleAssignment.test index c5e947920b0d..48182aac4b18 100644 --- a/plugins/groovy/testdata/groovy/controlFlow/multipleAssignment.test +++ b/plugins/groovy/testdata/groovy/controlFlow/multipleAssignment.test @@ -1,6 +1,6 @@ def a def b -[a, b] = [0, 1] +(a, b) = [0, 1] ----- 0(1) element: null 1(2) WRITE a diff --git a/plugins/groovy/testdata/highlighting/VarNotAssigned.groovy b/plugins/groovy/testdata/highlighting/VarNotAssigned.groovy new file mode 100644 index 000000000000..132e40c38d97 --- /dev/null +++ b/plugins/groovy/testdata/highlighting/VarNotAssigned.groovy @@ -0,0 +1,9 @@ +def i=0; +def a, b + +(a, b) = [i++, a] + +println a +println b + + diff --git a/plugins/groovy/testdata/resolve/method/multipleAssignment1/A.groovy b/plugins/groovy/testdata/resolve/method/multipleAssignment1/A.groovy index 49e9b072a10d..62ae48f65bce 100644 --- a/plugins/groovy/testdata/resolve/method/multipleAssignment1/A.groovy +++ b/plugins/groovy/testdata/resolve/method/multipleAssignment1/A.groovy @@ -1,5 +1,5 @@ int a def b, c = 8 -[a, b, c] = [1, 2, ""] +(a, b, c) = [1, 2, ""] c.toLowerCase() \ No newline at end of file diff --git a/plugins/groovy/testdata/resolve/method/multipleAssignment2/A.groovy b/plugins/groovy/testdata/resolve/method/multipleAssignment2/A.groovy index 9ffa61eaeea8..8fd4e7f3e545 100644 --- a/plugins/groovy/testdata/resolve/method/multipleAssignment2/A.groovy +++ b/plugins/groovy/testdata/resolve/method/multipleAssignment2/A.groovy @@ -1,6 +1,6 @@ def a, b, c -[a, b, c] = foo() +(a, b, c) = foo() private List foo() { return [1, 2, ""] diff --git a/plugins/groovy/testdata/resolve/method/multipleAssignment3/A.groovy b/plugins/groovy/testdata/resolve/method/multipleAssignment3/A.groovy index 2ea5a2fed812..9295ff918a7b 100644 --- a/plugins/groovy/testdata/resolve/method/multipleAssignment3/A.groovy +++ b/plugins/groovy/testdata/resolve/method/multipleAssignment3/A.groovy @@ -1,6 +1,6 @@ def a, b, c -[a, b, c] = foo(1) +(a, b, c) = foo(1) private List foo(i) { if (i == 0) From b2fde094ca4384f4b340c5e612a42cf55f710e17 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Wed, 2 Feb 2011 14:56:42 +0300 Subject: [PATCH 03/94] memory leak fixed in IdeTooltipManager --- .../src/com/intellij/ide/IdeTooltipManager.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java index 902711610881..6090897642b6 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java @@ -66,7 +66,6 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener private Runnable myHideRunnable; private JBPopupFactory myPopupFactory; - private JEditorPane myTipLabel; private boolean myShowDelay = true; @@ -176,9 +175,7 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener JLayeredPane layeredPane = IJSwingUtilities.findParentOfType(c, JLayeredPane.class); - myTipLabel = initPane(text, new HintHint(me).setAwtTooltip(true), layeredPane); - - setTipComponent(myTipLabel); + setTipComponent(initPane(text, new HintHint(me).setAwtTooltip(true), layeredPane)); return true; } }.setToCenter(toCenter); From 89945c3c020c07a96dabe549c521f0ff12c22d33 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Wed, 2 Feb 2011 16:54:29 +0300 Subject: [PATCH 04/94] IDEA-60587 add application type to new android component dialog --- .../fileTemplates/j2ee/Application.java.ft | 7 ++++ .../fileTemplates/j2ee/Application.java.html | 5 +++ .../messages/AndroidBundle.properties | 3 +- .../android/AndroidFileTemplateProvider.java | 2 ++ .../actions/NewAndroidComponentAction.java | 7 ++-- .../actions/NewAndroidComponentDialog.java | 36 +++++++++++++++---- .../jetbrains/android/util/AndroidUtils.java | 1 + 7 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 plugins/android/resources/fileTemplates/j2ee/Application.java.ft create mode 100644 plugins/android/resources/fileTemplates/j2ee/Application.java.html diff --git a/plugins/android/resources/fileTemplates/j2ee/Application.java.ft b/plugins/android/resources/fileTemplates/j2ee/Application.java.ft new file mode 100644 index 000000000000..336051a028f2 --- /dev/null +++ b/plugins/android/resources/fileTemplates/j2ee/Application.java.ft @@ -0,0 +1,7 @@ +package ${PACKAGE_NAME}; + +import android.app.Application; + +#parse("File Header.java") +public class ${NAME} extends Application { +} diff --git a/plugins/android/resources/fileTemplates/j2ee/Application.java.html b/plugins/android/resources/fileTemplates/j2ee/Application.java.html new file mode 100644 index 000000000000..09a7bfbff9e3 --- /dev/null +++ b/plugins/android/resources/fileTemplates/j2ee/Application.java.html @@ -0,0 +1,5 @@ + + +

This is a built-in file template used to create custom Application class in Android applications.

+ + \ No newline at end of file diff --git a/plugins/android/resources/messages/AndroidBundle.properties b/plugins/android/resources/messages/AndroidBundle.properties index e98186580071..6a224277a061 100644 --- a/plugins/android/resources/messages/AndroidBundle.properties +++ b/plugins/android/resources/messages/AndroidBundle.properties @@ -231,4 +231,5 @@ android.compilation.error.apt.gen.not.specified=AAPT destination directory not s android.compilation.error.aidl.gen.not.specified=AIDL destination directory not specified for module {0} android.compilation.error.apk.path.not.specified=Final APK path not specified for module {0} android.restart.logcat.action.text=Restart -android.restart.logcat.action.description=Restart logging \ No newline at end of file +android.restart.logcat.action.description=Restart logging +android.new.component.dialog.application.item=Application \ No newline at end of file diff --git a/plugins/android/src/org/jetbrains/android/AndroidFileTemplateProvider.java b/plugins/android/src/org/jetbrains/android/AndroidFileTemplateProvider.java index 660aa42babc8..b35681b54376 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidFileTemplateProvider.java +++ b/plugins/android/src/org/jetbrains/android/AndroidFileTemplateProvider.java @@ -42,6 +42,7 @@ public class AndroidFileTemplateProvider implements FileTemplateGroupDescriptorF @NonNls public static final String RESOURCE_FILE_TEMPLATE = "resourceFile.xml"; @NonNls public static final String LAYOUT_RESOURCE_FILE_TEMPLATE = "layoutResourceFile.xml"; @NonNls public static final String ACTIVITY = "Activity.java"; + @NonNls public static final String APPLICATION = "Application.java"; @NonNls public static final String SERVICE = "Service.java"; @NonNls public static final String BROADCAST_RECEIVER = "Broadcast Receiver.java"; @@ -52,6 +53,7 @@ public class AndroidFileTemplateProvider implements FileTemplateGroupDescriptorF group.addTemplate(new FileTemplateDescriptor(RESOURCE_FILE_TEMPLATE, StdFileTypes.XML.getIcon())); group.addTemplate(new FileTemplateDescriptor(LAYOUT_RESOURCE_FILE_TEMPLATE, StdFileTypes.XML.getIcon())); group.addTemplate(new FileTemplateDescriptor(ACTIVITY, StdFileTypes.JAVA.getIcon())); + group.addTemplate(new FileTemplateDescriptor(APPLICATION, StdFileTypes.JAVA.getIcon())); group.addTemplate(new FileTemplateDescriptor(SERVICE, StdFileTypes.JAVA.getIcon())); group.addTemplate(new FileTemplateDescriptor(BROADCAST_RECEIVER, StdFileTypes.JAVA.getIcon())); group.addTemplate(new FileTemplateDescriptor(REMOTE_INTERFACE_TEMPLATE, AndroidIdlFileType.ourFileType.getIcon())); diff --git a/plugins/android/src/org/jetbrains/android/actions/NewAndroidComponentAction.java b/plugins/android/src/org/jetbrains/android/actions/NewAndroidComponentAction.java index a09b41c039f4..bba3e11c914e 100644 --- a/plugins/android/src/org/jetbrains/android/actions/NewAndroidComponentAction.java +++ b/plugins/android/src/org/jetbrains/android/actions/NewAndroidComponentAction.java @@ -18,7 +18,6 @@ package org.jetbrains.android.actions; import com.intellij.ide.IdeView; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.psi.JavaDirectoryService; import com.intellij.psi.PsiDirectory; @@ -64,12 +63,14 @@ public class NewAndroidComponentAction extends AnAction { return; } - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Module module = LangDataKeys.MODULE.getData(dataContext); + + if (module == null) return; final PsiDirectory dir = view.getOrChooseDirectory(); if (dir == null) return; - NewAndroidComponentDialog dialog = new NewAndroidComponentDialog(project, dir); + NewAndroidComponentDialog dialog = new NewAndroidComponentDialog(module, dir); dialog.show(); if (dialog.getExitCode() != DialogWrapper.OK_EXIT_CODE) { return; diff --git a/plugins/android/src/org/jetbrains/android/actions/NewAndroidComponentDialog.java b/plugins/android/src/org/jetbrains/android/actions/NewAndroidComponentDialog.java index 9e9ff9cf8e7d..aa3cbd09b151 100644 --- a/plugins/android/src/org/jetbrains/android/actions/NewAndroidComponentDialog.java +++ b/plugins/android/src/org/jetbrains/android/actions/NewAndroidComponentDialog.java @@ -18,16 +18,19 @@ package org.jetbrains.android.actions; import com.intellij.CommonBundle; import com.intellij.ide.actions.ElementCreator; import com.intellij.ide.actions.TemplateKindCombo; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Computable; import com.intellij.psi.*; +import com.intellij.psi.search.searches.ClassInheritorsSearch; import com.intellij.util.Icons; import com.intellij.util.IncorrectOperationException; import org.jetbrains.android.AndroidFileTemplateProvider; -import org.jetbrains.android.dom.manifest.*; import org.jetbrains.android.dom.manifest.Action; +import org.jetbrains.android.dom.manifest.*; import org.jetbrains.android.dom.resources.ResourceValue; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.util.AndroidBundle; @@ -55,12 +58,18 @@ public class NewAndroidComponentDialog extends DialogWrapper { private PsiElement[] myCreatedElements; - protected NewAndroidComponentDialog(final Project project, final PsiDirectory directory) { - super(project); + protected NewAndroidComponentDialog(@NotNull final Module module, final PsiDirectory directory) { + super(module.getProject()); myKindLabel.setLabelFor(myKindCombo); myKindCombo.registerUpDownHint(myNameField); myUpDownHint.setIcon(Icons.UP_DOWN_ARROWS); myKindCombo.addItem(AndroidBundle.message("android.new.component.dialog.activity.item"), null, AndroidFileTemplateProvider.ACTIVITY); + + if (!containsCustomApplicationClass(module)) { + myKindCombo.addItem(AndroidBundle.message("android.new.component.dialog.application.item"), null, + AndroidFileTemplateProvider.APPLICATION); + } + myKindCombo.addItem(AndroidBundle.message("android.new.component.dialog.service.item"), null, AndroidFileTemplateProvider.SERVICE); myKindCombo.addItem(AndroidBundle.message("android.new.component.dialog.broadcast.receiver.item"), null, AndroidFileTemplateProvider.BROADCAST_RECEIVER); @@ -68,7 +77,7 @@ public class NewAndroidComponentDialog extends DialogWrapper { AndroidFileTemplateProvider.REMOTE_INTERFACE_TEMPLATE); init(); setTitle(AndroidBundle.message("android.new.component.action.command.name")); - myCreator = new ElementCreator(project, CommonBundle.getErrorTitle()) { + myCreator = new ElementCreator(module.getProject(), CommonBundle.getErrorTitle()) { @Override protected void checkBeforeCreate(String newName) throws IncorrectOperationException { JavaDirectoryService.getInstance().checkCreateClass(directory, newName); @@ -76,7 +85,7 @@ public class NewAndroidComponentDialog extends DialogWrapper { @Override protected PsiElement[] create(String newName) throws Exception { - final PsiElement element = NewAndroidComponentDialog.this.create(newName, directory, project); + final PsiElement element = NewAndroidComponentDialog.this.create(newName, directory, module.getProject()); if (element != null) { return new PsiElement[]{element}; } @@ -93,11 +102,23 @@ public class NewAndroidComponentDialog extends DialogWrapper { public void actionPerformed(ActionEvent e) { String selected = myKindCombo.getSelectedName(); myMarkAsStartupActivityCheckBox.setEnabled(AndroidFileTemplateProvider.ACTIVITY.equals(selected)); - myLabelField.setEnabled(!AndroidFileTemplateProvider.REMOTE_INTERFACE_TEMPLATE.equals(selected)); + myLabelField.setEnabled(!AndroidFileTemplateProvider.REMOTE_INTERFACE_TEMPLATE.equals(selected) && + !AndroidFileTemplateProvider.APPLICATION.equals(selected)); } }); } + private static boolean containsCustomApplicationClass(@NotNull final Module module) { + final JavaPsiFacade facade = JavaPsiFacade.getInstance(module.getProject()); + PsiClass applicationClass = ApplicationManager.getApplication().runReadAction(new Computable() { + @Nullable + public PsiClass compute() { + return facade.findClass(AndroidUtils.APPLICATION_CLASS_NAME, module.getModuleWithDependenciesAndLibrariesScope(false)); + } + }); + return applicationClass != null && ClassInheritorsSearch.search(applicationClass, module.getModuleScope(), true).findFirst() != null; + } + @Nullable private PsiElement create(String newName, PsiDirectory directory, Project project) throws Exception { return doCreate(myKindCombo.getSelectedName(), directory, project, newName, myLabelField.getText(), @@ -175,6 +196,9 @@ public class NewAndroidComponentDialog extends DialogWrapper { receiver.getReceiverClass().setValue(aClass); return receiver; } + else if (AndroidFileTemplateProvider.APPLICATION.equals(templateName)) { + application.getName().setValue(aClass); + } return null; } diff --git a/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java b/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java index 8b4b5aa642ed..324f00486292 100644 --- a/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java +++ b/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java @@ -101,6 +101,7 @@ public class AndroidUtils { public static final String R_JAVA_FILENAME = "R.java"; public static final String ANDROID_PACKAGE = "android"; public static final String VIEW_CLASS_NAME = ANDROID_PACKAGE + ".view.View"; + public static final String APPLICATION_CLASS_NAME = "android.app.Application"; public static final String PREFERENCE_CLASS_NAME = ANDROID_PACKAGE + ".preference.Preference"; public static final String ANIMATION_PACKAGE = "android.view.animation"; public static final String INTERPOLATOR_CLASS_NAME = ANIMATION_PACKAGE + ".Interpolator"; From 09f9fb52f2ebea206413e0f213e51ea455e32697 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Wed, 2 Feb 2011 18:20:31 +0300 Subject: [PATCH 05/94] [10.0.2] IDEA-64933 Drag-and-drop text dont work --- .../openapi/editor/impl/EditorImpl.java | 63 +++++++++++++++++-- .../src/misc/registry.properties | 2 + 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 817d9c403aad..3888e23b5225 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -60,6 +60,7 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Queryable; import com.intellij.openapi.util.*; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; @@ -158,6 +159,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi private boolean isReleased = false; private MouseEvent myMousePressedEvent = null; + private MouseEvent myMouseMovedEvent = null; private int mySavedSelectionStart = -1; private int mySavedSelectionEnd = -1; @@ -226,6 +228,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi private Runnable myGutterSizeUpdater = null; private boolean myGutterNeedsUpdate = false; private Alarm myAppleRepaintAlarm; + + private Alarm myMouseSelectionStateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + private Runnable myMouseSelectionStateResetRunnable; + private boolean myEmbeddedIntoDialogWrapper; private CachedFontContent myLastCache; private boolean mySpacesHaveSameWidth; @@ -610,6 +616,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myPlainFontMetrics = null; myScrollingModel.dispose(); myGutterComponent.dispose(); + myMousePressedEvent = null; + myMouseMovedEvent = null; Disposer.dispose(myCaretModel); clearCaretThread(); @@ -3501,6 +3509,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi selectionModel.setSelection(mySavedSelectionStart, newSelection); getCaretModel().moveToOffset(newSelection); } + cancelAutoResetForMouseSelectionState(); return; } @@ -3511,6 +3520,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi else { selectionModel.setSelection(oldSelectionStart, newCaretOffset); } + cancelAutoResetForMouseSelectionState(); } else { if (caretShift != 0) { @@ -3524,7 +3534,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi else { selectionModel.removeSelection(); } - myMousePressedEvent = null; } } } @@ -4139,10 +4148,38 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } private void setMouseSelectionState(int mouseSelectionState) { + if (getMouseSelectionState() == mouseSelectionState) return; + myMouseSelectionState = mouseSelectionState; myMouseSelectionChangeTimestamp = System.currentTimeMillis(); + + myMouseSelectionStateAlarm.cancelAllRequests(); + if (myMouseSelectionState != MOUSE_SELECTION_STATE_NONE) { + if (myMouseSelectionStateResetRunnable == null) { + myMouseSelectionStateResetRunnable = new Runnable() { + @Override + public void run() { + resetMouseSelectionState(null); + } + }; + } + myMouseSelectionStateAlarm.addRequest(myMouseSelectionStateResetRunnable, Registry.intValue("editor.mouseSelectionStateResetTimeout"), + ModalityState.stateForComponent(myEditorComponent)); + } } + private void resetMouseSelectionState(@Nullable MouseEvent event) { + setMouseSelectionState(MOUSE_SELECTION_STATE_NONE); + + MouseEvent e = event != null ? event : myMouseMovedEvent; + if (e != null) { + validateMousePointer(e); + } + } + + private void cancelAutoResetForMouseSelectionState() { + myMouseSelectionStateAlarm.cancelAllRequests(); + } void replaceInputMethodText(InputMethodEvent e) { getInputMethodRequests(); @@ -4525,7 +4562,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi Math.abs(e.getY() - myMousePressedEvent.getY()) < getLineHeight()) { runMouseClickedCommand(e); } - myMousePressedEvent = null; } public void mouseEntered(MouseEvent e) { @@ -4641,8 +4677,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myInitialMouseEvent = e; - if (myMouseSelectionState != MOUSE_SELECTION_STATE_NONE && System.currentTimeMillis() - myMouseSelectionChangeTimestamp > 1000) { - setMouseSelectionState(MOUSE_SELECTION_STATE_NONE); + if (myMouseSelectionState != MOUSE_SELECTION_STATE_NONE && System.currentTimeMillis() - myMouseSelectionChangeTimestamp > Registry.intValue( + "editor.mouseSelectionStateResetTimeout")) { + resetMouseSelectionState(e); } int x = e.getX(); @@ -4864,7 +4901,23 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } public void mouseMoved(MouseEvent e) { - validateMousePointer(e); + if (getMouseSelectionState() != MOUSE_SELECTION_STATE_NONE) { + if (myMousePressedEvent != null && myMousePressedEvent.getComponent() == e.getComponent()) { + Point lastPoint = myMousePressedEvent.getPoint(); + Point point = e.getPoint(); + int deadZone = Registry.intValue("editor.mouseSelectionStateResetDeadzone"); + if (Math.abs(lastPoint.x - point.x) >= deadZone || Math.abs(lastPoint.y - point.y) >= deadZone) { + resetMouseSelectionState(e); + } + } else { + validateMousePointer(e); + } + } else { + validateMousePointer(e); + } + + myMouseMovedEvent = e; + EditorMouseEvent event = new EditorMouseEvent(EditorImpl.this, e, getMouseEventArea(e)); if (e.getSource() == myGutterComponent) { myGutterComponent.mouseMoved(e); diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 0367c55c0f9a..363e553f9a6c 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -74,6 +74,8 @@ ide.tooltip.initialReshowDelay=300 ide.tooltip.autoDismissDeadZone=300 editor.balloonHints=true +editor.mouseSelectionStateResetTimeout=1000 +editor.mouseSelectionStateResetDeadzone=4 ide.configuration.new.project.structure.errors=false From e21eea82cf007f4d09df72a6133baf6a5afd408a Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 3 Feb 2011 14:28:57 +0100 Subject: [PATCH 06/94] typos --- .../ui/popup/ComponentPopupBuilderImpl.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/popup/ComponentPopupBuilderImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/ComponentPopupBuilderImpl.java index 453ae0c539f6..1bbca67e1ab7 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/ComponentPopupBuilderImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/ComponentPopupBuilderImpl.java @@ -23,9 +23,9 @@ import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; +import com.intellij.ui.InplaceButton; import com.intellij.util.Processor; import com.intellij.util.ui.EmptyIcon; -import com.intellij.ui.InplaceButton; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -44,7 +44,7 @@ public class ComponentPopupBuilderImpl implements ComponentPopupBuilder { private boolean myResizable; private boolean myMovable; private final JComponent myComponent; - private final JComponent myPrefferedFocusedComponent; + private final JComponent myPreferredFocusedComponent; private boolean myRequestFocus; private boolean myForceHeavyweight; private String myDimensionServiceKey = null; @@ -52,7 +52,7 @@ public class ComponentPopupBuilderImpl implements ComponentPopupBuilder { private Project myProject; private boolean myCancelOnClickOutside = true; private final Set myListeners = new LinkedHashSet(); - private boolean myUseDimSevriceForXYLocation; + private boolean myUseDimServiceForXYLocation; private IconButton myCancelButton; private MouseChecker myCancelOnMouseOutCallback; @@ -81,9 +81,9 @@ public class ComponentPopupBuilderImpl implements ComponentPopupBuilder { private boolean myMayBeParent; public ComponentPopupBuilderImpl(final JComponent component, - final JComponent prefferedFocusedComponent) { + final JComponent preferredFocusedComponent) { myComponent = component; - myPrefferedFocusedComponent = prefferedFocusedComponent; + myPreferredFocusedComponent = preferredFocusedComponent; } @NotNull @@ -149,7 +149,7 @@ public class ComponentPopupBuilderImpl implements ComponentPopupBuilder { @NotNull public ComponentPopupBuilder setDimensionServiceKey(final Project project, final String dimensionServiceKey, final boolean useForXYLocation) { myDimensionServiceKey = dimensionServiceKey; - myUseDimSevriceForXYLocation = useForXYLocation; + myUseDimServiceForXYLocation = useForXYLocation; myProject = project; return this; } @@ -203,9 +203,9 @@ public class ComponentPopupBuilderImpl implements ComponentPopupBuilder { @NotNull public JBPopup createPopup() { - final AbstractPopup popup = new AbstractPopup().init(myProject, myComponent, myPrefferedFocusedComponent, myRequestFocus, myFocusable, myForceHeavyweight, + final AbstractPopup popup = new AbstractPopup().init(myProject, myComponent, myPreferredFocusedComponent, myRequestFocus, myFocusable, myForceHeavyweight, myMovable, myDimensionServiceKey, myResizable, myTitle, - myCallback, myCancelOnClickOutside, myListeners, myUseDimSevriceForXYLocation, myCommandButton, + myCallback, myCancelOnClickOutside, myListeners, myUseDimServiceForXYLocation, myCommandButton, myCancelButton, myCancelOnMouseOutCallback, myCancelOnWindow, myTitleIcon, myCancelKeyEnabled, myLocateByContent, myPlacewithinScreen, myMinSize, myAlpha, myMaskProvider, myInStack, myModalContext, myFocusOwners, myAd, From 504f90e475559461f31f4ddf90cc3144fc3e8504 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 3 Feb 2011 16:53:43 +0300 Subject: [PATCH 07/94] check licenses for 3rd party libs --- build/scripts/libLicenses.gant | 139 +++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 build/scripts/libLicenses.gant diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant new file mode 100644 index 000000000000..2502d1b9167a --- /dev/null +++ b/build/scripts/libLicenses.gant @@ -0,0 +1,139 @@ +import org.jetbrains.jps.* + +class LibraryLicense { + String name, libraryName, url, version + String license, licenseUrl +} + +List licensesList = [] +List jetbrainsLibraries = ["tcServiceMessages"] + +binding.setVariable("libraryLicense", {Map args -> + if (args.libraryName == null) { + args.libraryName = args.name; + } + licensesList << new LibraryLicense(args) +}) + +binding.setVariable("jetbrainsLibrary", {String name -> + jetbrainsLibraries << name +}) + +def String getLibraryName(Library lib) { + def name = lib.name + if (name.startsWith("moduleLibrary#")) { + if (lib.classpath.size() != 1) { + project.error("Non-single entry module library $name: $lib.classpath"); + } + String filePath = lib.classpath[0] + return filePath.substring(filePath.lastIndexOf('/')+1) + } + return name +} + +binding.setVariable("checkLibLicenses", { + def libraries = new HashSet() + def lib2Module = new HashMap(); + project.modules.values().each {Module module -> + module.getClasspath(ClasspathKind.PRODUCTION_RUNTIME).each { + if (it instanceof Library) { + lib2Module[it] = module + libraries << it + } + } + } + + def libWithLicenses = licensesList.collect {it.libraryName} as Set + libWithLicenses.addAll(jetbrainsLibraries) + + List withoutLicenses = [] + libraries.each {Library lib -> + def name = getLibraryName(lib) + if (!libWithLicenses.contains(name)) { + withoutLicenses << "$name (used in module ${lib2Module[lib].name})".toString() + } + } + + if (!withoutLicenses.isEmpty()) { + project.warning("Licenses aren't specified for ${withoutLicenses.size()} libraries:") + withoutLicenses.sort(String.CASE_INSENSITIVE_ORDER) + withoutLicenses.each { project.warning(it); } + } +}); + +binding.setVariable("checkLibLicensesAndGenerateTable", {String filePath -> + checkLibLicenses(); + generateLicensesTable(filePath) + notifyArtifactBuilt(filePath) +}) + +binding.setVariable("generateLicensesTable", {String filePath -> + Set modules = project.modules.values().findAll {it["used"] != null} + Set usedLibraries = [] as Set + modules.each { + it.getClasspath(ClasspathKind.PRODUCTION_RUNTIME).each {item -> + if (item instanceof Library) { + usedLibraries << getLibraryName(item) + } + } + } + + def licenses = licensesList.findAll {usedLibraries.contains(it.libraryName) } + List lines = licenses.collect { LibraryLicense lib -> + def name = lib.url != null ? "[$lib.name|$lib.url]" : lib.name + def license = lib.licenseUrl != null ? "[$lib.license|$lib.licenseUrl]" : lib.license + return "|$name| $lib.version|$license|".toString() + } + lines.sort {String.CASE_INSENSITIVE_ORDER} + + FileWriter out = new FileWriter(filePath) + out.println("|| Software || Version || License ||") + lines.each { + out.println(it) + } + out.close() +}) + +libraryLicense(name: "Alloy L&F", libraryName: "alloy.jar", version: "1.4.4", license: "link (company license)", url: "http://www.incors.com/lookandfeel/", licenseUrl: "http://lookandfeel.incors.com/display_licence.php?back=purchase.php&selMenu=Purchase") +libraryLicense(name: "Ant", version: "1.7", license: "Apache 2.0", url: "http://ant.apache.org/", licenseUrl: "http://ant.apache.org/license.html") +libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm", version: "3.3", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html") +libraryLicense(name: "Axis", libraryName: "axis-1.4", version: "1.4", license: "Apache 2.0", url: "http://ws.apache.org/axis/", licenseUrl: "http://svn.jetbrains.org/idea/Trunk/bundled/WebServices/resources/lib/axis-1.4.0/axis.LICENSE") +libraryLicense(name: "CGLib", libraryName: "CGLIB", version: "2.2", license: "Apache", url: "http://cglib.sourceforge.net/", licenseUrl: "http://www.apache.org/foundation/licence-FAQ.html") +libraryLicense(name: "Apache Commons Codec", libraryName: "commons-codec", version: "1.3", license: "Apache 2.0", url: "http://commons.apache.org/codec/", licenseUrl: "http://commons.apache.org/license.html") +libraryLicense(name: "Apache Commons Collections", libraryName: "commons-collections", version: "3.1", license: "Apache 2.0", url: "http://commons.apache.org/collections/", licenseUrl: "http://commons.apache.org/license.html") +libraryLicense(name: "Apache Commons HTTPClient", libraryName: "http-client-3.1", version: "3.1  (with patch by JetBrains)", license: "Apache 2.0", url: "http://hc.apache.org/httpclient-3.x") +libraryLicense(name: "Apache Commons Lang", libraryName: "commons-lang", version: "2.4", license: "Apache 2.0", url: "http://commons.apache.org/lang/", licenseUrl: "http://commons.apache.org/lang/license.html") +libraryLicense(name: "Apache Commons Logging", libraryName: "commons-logging", version: "1.1.1", license: "Apache 2.0", url: "http://commons.apache.org/logging/", licenseUrl: "http://svn.jetbrains.org/idea/Trunk/bundled/WebServices/resources/lib/axis-1.4.0/commons-logging-1.0.4.LICENSE") +libraryLicense(name: "Automaton", libraryName: "automaton.jar", version: "1.11", license: "BSD", url: "http://www.brics.dk/automaton/", licenseUrl: "http://www.opensource.org/licenses/bsd-license.php") +libraryLicense(name: "DTDParser", version: "1.13", license: "LGPL", url: "http://sourceforge.net/projects/dtdparser/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1") +libraryLicense(name: "Ganymed", version: "bundled with SVNKit", license: "BSD", url: "http://www.ganymed.ethz.ch/ssh2/", licenseUrl: "http://www.ganymed.ethz.ch/ssh2/LICENSE.txt") +libraryLicense(name: "Guava", version: "R6", license: "Apache 2.0", url: "http://code.google.com/p/guava-libraries/", licenseUrl: "http://ant.apache.org/license.html") +libraryLicense(name: "Groovy", version: "1.7.3", license: "Apache 2.0", url: "http://groovy.codehaus.org/", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.html") +libraryLicense(name: "JavaCVS", version: "no version number available (with patches by JetBrains)", license: "Sun Public License", url: "http://javacvs.netbeans.org/library/", licenseUrl: "http://www.netbeans.org/about/legal/spl.html") +libraryLicense(name: "Jaxen", version: "", license: "modified Apache", url: "http://www.jaxen.org/", licenseUrl: "http://www.jaxen.org/license.html") +libraryLicense(name: "JavaHelp", version: "2.0_02", license: "included as license/javahelp_license.html in IntelliJ IDEA distribution", url: "http://java.sun.com/products/javahelp/") +libraryLicense(name: "JDOM", version: "1.1 (with patches by JetBrains)", license: "modified Apache", url: "http://www.jdom.org/", licenseUrl: "http://www.jdom.org/docs/faq.html#a0030") +libraryLicense(name: "JGoodies Forms", libraryName: "jgoodies-forms", version: "CVS snapshot as of 5 May 2006", license: "BSD ", url: "http://www.jgoodies.com/freeware/forms/", licenseUrl: "http://www.jgoodies.com/downloads/libraries.html") +libraryLicense(name: "JNA", libraryName: "jna", version: "3.2.4", license: "LGPL 2.1", url: "https://jna.dev.java.net/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1.php") +libraryLicense(name: "JNA", libraryName: "jna.jar", version: "3.2.7", license: "LGPL 2.1", url: "https://jna.dev.java.net/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1.php") +libraryLicense(name: "JUnit", libraryName: "JUnit3", version: "3.8.1", license: "CPL 1.0", url: "http://junit.org/") +libraryLicense(name: "JUnit", libraryName: "JUnit4", version: "4.8", license: "CPL 1.0", url: "http://junit.org/") +libraryLicense(name: "Log4j", libraryName: "Log4J", version: "1.2", license: "Apache 2.0", url: "http://logging.apache.org/log4j/1.2/index.html", licenseUrl: "http://logging.apache.org/license.html") +libraryLicense(name: "Maven", version: "2.2.1", license: "Apache 2.0", url: "http://maven.apache.org/", licenseUrl: "http://maven.apache.org/license.html") +libraryLicense(name: "Microba", libraryName: "microba", version: "0.4.2", license: "BSD", url: "http://microba.sourceforge.net/", licenseUrl: "http://microba.sourceforge.net/license.txt") +libraryLicense(name: "NanoXML", version: "2.2.3", license: "zlib/libpng", url: "http://nanoxml.cyberelf.be/", licenseUrl: "http://devkix.com/nanoxml.php") +libraryLicense(name: "Eclipse JDT Core", libraryName: "Eclipse", version: "3.3", license: "CPL 1.0", url: "http://www.eclipse.org/jdt/core/index.php") +libraryLicense(name: "Jakarta ORO", libraryName: "OroMatcher", version: "2.0.8", license: "Apache", url: "http://jakarta.apache.org/oro/", licenseUrl: "http://svn.apache.org/repos/asf/jakarta/oro/trunk/LICENSE") +libraryLicense(name: "PicoContainer", libraryName: "picocontainer", version: "1.2", license: "BSD", url: "http://www.picocontainer.org/", licenseUrl: "http://docs.codehaus.org/display/PICO/License") +libraryLicense(name: "SVNKit", libraryName: "svnkit.jar", version: "SVN version, 1.1 branch as of 1 Oct 2007", license: "link (commercial license)", url: "http://www.svnkit.com/", licenseUrl: "http://svnkit.com/license.html") +libraryLicense(name: "TestNG", version: "5.7 snapshot", license: "Apache 2.0", url: "http://testng.org/doc/", licenseUrl: "http://code.google.com/p/testng/") +libraryLicense(name: "Trilead SSH", libraryName: "trilead-ssh2-build213.jar", version: "build 213", license: "BSD style (see LICENSE.txt in trilead-ssh-build213.jar)", url: "http://www.trilead.com/SSH_Library/") +libraryLicense(name: "Trove4j", version: "1.1 (with patches by JetBrains)", license: "LGPL", url: "http://trove4j.sourceforge.net/", licenseUrl: "http://trove4j.sourceforge.net/html/license.html") +libraryLicense(name: "Velocity", version: "1.3", license: "Apache", url: "http://velocity.apache.org/", licenseUrl: "http://velocity.apache.org/index.html") +libraryLicense(name: "winp", version: "1.14", license: "MIT", url: "http://winp.dev.java.net/", licenseUrl: "https://winp.dev.java.net/license.html") +libraryLicense(name: "Xerces", version: "2.8.1", license: "Apache 2.0", url: "http://xerces.apache.org/xerces2-j/", licenseUrl: "http://xerces.apache.org/xerces2-j/") +libraryLicense(name: "XML Commons (xml-apis.jar, resolver.jar)", version: "", license: "Apache 2.0, W3C Software License , public domain", url: "http://xml.apache.org/commons/", licenseUrl: "http://xml.apache.org/commons/licenses.html") +libraryLicense(name: "XMLBeans", libraryName: "XmlBeans", version: "2.3.0", license: "Apache 2.0", url: "http://xmlbeans.apache.org/", licenseUrl: "http://svn.jetbrains.org/idea/Trunk/bundled/WebServices/resources/lib/xmlbeans-2.3.0/xmlbeans.LICENSE") +libraryLicense(name: "XML-RPC", libraryName: "XmlRPC", version: "2.0", license: "Apache 2.0", url: "http://ws.apache.org/xmlrpc/xmlrpc2/", licenseUrl: "http://ws.apache.org/xmlrpc/xmlrpc2/license.html") +libraryLicense(name: "XStream", version: "1.2.1", license: "BSD", url: "http://xstream.codehaus.org/", licenseUrl: "http://xstream.codehaus.org/license.html") +libraryLicense(name: "YourKit Java Profiler", libraryName: "yjp-controller-api-redist.jar", version: "7.0.2", license: "link (commercial license)", url: "http://yourkit.com/", licenseUrl: "http://www.yourkit.com/purchase/license.html") From 0a61a805e9e43696175b7b0289820bb6122c3e4c Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 3 Feb 2011 17:02:21 +0300 Subject: [PATCH 08/94] Test fixes - looks like some teamcity agents use non-monospaced font that causes failure of the tests that emulate vertical caret shift and check target column after that --- .../src/com/intellij/openapi/editor/impl/CaretModelImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java index 9d4e8afd9e36..c8a218c3a956 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java @@ -213,7 +213,7 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener, int newLineNumber = visualCaret.line + lineShift; int newColumnNumber = visualCaret.column + columnShift; - if (desiredX >= 0) { + if (desiredX >= 0 && !ApplicationManager.getApplication().isUnitTestMode()) { newColumnNumber = myEditor.xyToVisualPosition(new Point(desiredX, Math.max(0, newLineNumber) * myEditor.getLineHeight())).column; } From 5ff13b444d9c65fc19671e949e7d4cdaf30241fc Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 3 Feb 2011 15:28:28 +0100 Subject: [PATCH 09/94] making variable a stub element type was unnecessary --- .../lang/parser/GroovyElementTypes.java | 30 +------------------ 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java index f520efaac419..3d6b5fae30e2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java @@ -28,7 +28,6 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList; @@ -383,34 +382,7 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy GroovyElementType TUPLE_ERROR = new GroovyElementType("tuple with error"); - GrStubElementType VARIABLE = new GrStubElementType("assigned variable") { - - @Override - public boolean shouldCreateStub(ASTNode node) { - return false; - } - - @Override - public GrVariable createPsi(StubElement stub) { - throw new UnsupportedOperationException("Not implemented"); - } - - @Override - public StubElement createStub(GrVariable psi, StubElement parentStub) { - throw new UnsupportedOperationException("Not implemented"); - } - - @Override - public void serialize(StubElement stub, StubOutputStream dataStream) throws IOException { - throw new UnsupportedOperationException("Not implemented"); - } - - @Override - public StubElement deserialize(StubInputStream dataStream, StubElement parentStub) throws IOException { - throw new UnsupportedOperationException("Not implemented"); - } - }; - + GroovyElementType VARIABLE = new GroovyElementType("assigned variable"); //modifiers GrStubElementType MODIFIERS = new GrModifierListElementType("modifier list"); From 67505a473fe1fce23db394bc106b9a739d855f04 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Thu, 3 Feb 2011 17:52:59 +0300 Subject: [PATCH 10/94] IDEA-64982 large memory usage after closing all projects --- .../ide/actions/ResizeToolWindowAction.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ResizeToolWindowAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ResizeToolWindowAction.java index 6062ff1b4b51..e1af2b50b689 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ResizeToolWindowAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ResizeToolWindowAction.java @@ -21,6 +21,8 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerAdapter; import com.intellij.openapi.ui.ShadowAction; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.*; @@ -39,6 +41,8 @@ public abstract class ResizeToolWindowAction extends AnAction implements DumbAwa private ToolWindow myToolWindow; + private boolean myListenerInstalled; + protected ResizeToolWindowAction() { } @@ -63,6 +67,16 @@ public abstract class ResizeToolWindowAction extends AnAction implements DumbAwa return; } + if (!myListenerInstalled) { + myListenerInstalled = true; + ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerAdapter() { + @Override + public void projectClosed(Project project) { + setDisabled(null); + } + }); + } + Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); if (owner == null || !(SwingUtilities.getWindowAncestor(owner) instanceof IdeFrame)) { setDisabled(e); @@ -99,9 +113,13 @@ public abstract class ResizeToolWindowAction extends AnAction implements DumbAwa } private void setDisabled(AnActionEvent e) { - e.getPresentation().setEnabled(false); + if (e != null) { + e.getPresentation().setEnabled(false); + } + myLastWindow = null; myLastManager = null; + myToolWindow = null; } protected abstract void update(AnActionEvent event, ToolWindow window, ToolWindowManager mgr); From eee9bfc3f255086fdd4bfda17750c13d57fa7059 Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Thu, 3 Feb 2011 17:53:46 +0300 Subject: [PATCH 11/94] IDEA-64783 Can't use private repos in github --- plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java index 030bdb249568..63c775a3c324 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java @@ -171,7 +171,7 @@ public class GithubUtil { } final Element plan = element.getChild("plan"); assert plan != null : "Authentification failed"; - final String privateRepos = plan.getChildText("private_repos"); + final String privateRepos = plan.getChildText("private-repos"); return privateRepos != null && Integer.valueOf(privateRepos) > 0; } catch (Exception e) { From 4196e78c31e33494b2f4dd1269de250eeee51b02 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Thu, 3 Feb 2011 18:06:36 +0300 Subject: [PATCH 12/94] Only parse files in project or under library roots. --- .../intellij/psi/impl/source/text/BlockSupportImpl.java | 2 ++ .../src/com/intellij/testFramework/LightVirtualFile.java | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java index 2395578adf8a..8c49683d476b 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java @@ -168,6 +168,8 @@ public class BlockSupportImpl extends BlockSupport { FileType fileType = viewProvider.getVirtualFile().getFileType(); final LightVirtualFile lightFile = new LightVirtualFile(fileImpl.getName(), fileType, newFileText, viewProvider.getVirtualFile().getCharset(), fileImpl.getModificationStamp()); + lightFile.setOriginalFile(viewProvider.getVirtualFile()); + final FileViewProvider copy = viewProvider.createCopy(lightFile); final PsiFileImpl newFile = (PsiFileImpl)copy.getPsi(fileImpl.getLanguage()); diff --git a/platform/platform-api/src/com/intellij/testFramework/LightVirtualFile.java b/platform/platform-api/src/com/intellij/testFramework/LightVirtualFile.java index 59c97e83ba0e..ce6058e8228b 100644 --- a/platform/platform-api/src/com/intellij/testFramework/LightVirtualFile.java +++ b/platform/platform-api/src/com/intellij/testFramework/LightVirtualFile.java @@ -42,6 +42,7 @@ public class LightVirtualFile extends DeprecatedVirtualFile { private boolean myIsWritable = true; private boolean myValid = true; private Language myLanguage; + private VirtualFile myOriginalFile; public LightVirtualFile() { this(""); @@ -111,6 +112,14 @@ public class LightVirtualFile extends DeprecatedVirtualFile { myContent = content; } + public VirtualFile getOriginalFile() { + return myOriginalFile; + } + + public void setOriginalFile(VirtualFile originalFile) { + myOriginalFile = originalFile; + } + private static class MyVirtualFileSystem extends DeprecatedVirtualFileSystem { @NonNls private static final String PROTOCOL = "mock"; From a034069f0b05505148dabf7d9f716fc68d06c402 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 3 Feb 2011 16:05:20 +0100 Subject: [PATCH 13/94] IDEA-65047 while indexing, do not disable "new" menu on project view --- .../src/com/intellij/ide/actions/WeighingNewActionGroup.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/WeighingNewActionGroup.java b/platform/lang-impl/src/com/intellij/ide/actions/WeighingNewActionGroup.java index b07cf016cb66..37822668bee0 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/WeighingNewActionGroup.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/WeighingNewActionGroup.java @@ -32,6 +32,11 @@ public class WeighingNewActionGroup extends WeighingActionGroup { return myDelegate; } + @Override + public boolean isDumbAware() { + return true; + } + @Override public void update(AnActionEvent e) { super.update(e); From 508368fab03b90a788614d0e27f939be9769da37 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 3 Feb 2011 16:06:45 +0100 Subject: [PATCH 14/94] EA-25447 NPE --- .../codeInsight/template/macro/SuggestIndexNameMacro.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestIndexNameMacro.java b/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestIndexNameMacro.java index 4cdae763a154..0c64857ba37d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestIndexNameMacro.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestIndexNameMacro.java @@ -51,7 +51,7 @@ public class SuggestIndexNameMacro implements Macro{ for(char letter = 'i'; letter <= 'z'; letter++){ for (PsiVariable var : vars) { PsiIdentifier identifier = var.getNameIdentifier(); - if (place.equals(identifier)) continue; + if (identifier == null || place.equals(identifier)) continue; if (var instanceof PsiLocalVariable) { PsiElement parent = var.getParent(); if (parent instanceof PsiDeclarationStatement) { From b3316988e3d73fed5848b5a461e344551f391dba Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 3 Feb 2011 16:27:43 +0100 Subject: [PATCH 15/94] EA-24136 don't show documentation for lookup element when there isn't any --- .../codeInsight/documentation/DocumentationManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java index 7863233390b4..9e2dd837d3d8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java @@ -886,7 +886,7 @@ public class DocumentationManager { void showHint(final JBPopup hint) { final Lookup lookup = LookupManager.getActiveLookup(myEditor); - if (lookup != null) { + if (lookup != null && lookup.getCurrentItem() != null) { lookup.showItemPopup(hint); return; } From b7531d3cfdd6c77cc64c2df6868ea6fa6cb07ad5 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 3 Feb 2011 16:35:10 +0100 Subject: [PATCH 16/94] close choose by name popup by Shift-Enter, allow to check if it was closed this way --- .../intellij/ide/util/gotoByName/ChooseByNameBase.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index 5da50d327f80..1ce37438ccfa 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -127,6 +127,8 @@ public abstract class ChooseByNameBase { protected JBPopup myTextPopup; protected JBPopup myDropdownPopup; + private boolean myClosedByShiftEnter = false; + private static class MatchesComparator implements Comparator { private final String myOriginalPattern; @@ -175,6 +177,10 @@ public abstract class ChooseByNameBase { mySearchInAnyPlace = searchInAnyPlace; } + public boolean isClosedByShiftEnter() { + return myClosedByShiftEnter; + } + /** * Set tool area. The method may be called only before invoke. * @@ -419,6 +425,10 @@ public abstract class ChooseByNameBase { myTextField.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER && (e.getModifiers() & KeyEvent.SHIFT_MASK) != 0) { + myClosedByShiftEnter = true; + close(true); + } if (!myListScrollPane.isVisible()) { return; } From b58fe0f9ff44cc15a6bbaa3e81ed66cbf95adaf4 Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Thu, 3 Feb 2011 18:47:09 +0300 Subject: [PATCH 17/94] More correct escaping when creating new github repos --- .../org/jetbrains/plugins/github/GithubShareAction.java | 9 ++++++++- .../src/org/jetbrains/plugins/github/GithubUtil.java | 3 +-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java index 6cb51c691072..bc27bb0833ba 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java @@ -1,5 +1,9 @@ package org.jetbrains.plugins.github; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationDisplayType; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; @@ -12,6 +16,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.ChangeListManager; @@ -113,7 +118,7 @@ public class GithubShareAction extends DumbAwareAction { try { LOG.info("Creating GitHub repository"); GithubUtil.doREST(settings.getHost(), settings.getLogin(), settings.getPassword(), - "/repos/create?name=" + name + "&description=" + description + "&public=" + (isPrivate ? "0" : "1"), true); + "/repos/create?name=" + name + "&public=" + (isPrivate ? "0" : "1") + "&description=" + JDOMUtil.escapeText(description, true, true), true); LOG.info("Successfully created GitHub repository"); } catch (final Exception e1) { @@ -121,6 +126,8 @@ public class GithubShareAction extends DumbAwareAction { return; } bindToGithub(project, root, gitDetected, settings.getLogin(), name); + Notifications.Bus.notify(new Notification("github", "Success", "Successfully created project ''" + name + "'' on github", + NotificationType.INFORMATION), NotificationDisplayType.BALLOON_ONLY, null); } private void bindToGithub(final Project project, final VirtualFile root, final boolean gitDetected, final String login, final String name) { diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java index 63c775a3c324..9cac56ee2348 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java @@ -6,7 +6,6 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.VcsException; @@ -94,7 +93,7 @@ public class GithubUtil { public static HttpMethod doREST(final String url, final String login, final String password, final String request, final boolean post) throws Exception { final HttpClient client = getHttpClient(login, password); client.getParams().setContentCharset("UTF-8"); - final String uri = JDOMUtil.escapeText("https://" + getHostByUrl(url) + API_URL + request, true, true); + final String uri = "https://" + getHostByUrl(url) + API_URL + request; final HttpMethod method = post ? new PostMethod(uri) : new GetMethod(uri); client.executeMethod(method); return method; From 57ffbf5421f251b137ff18c5be5170391369d9cc Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Thu, 3 Feb 2011 18:57:16 +0300 Subject: [PATCH 18/94] IDEA-65049 correct default paths when module file located not under content root --- .../android/facet/AndroidFacetConfiguration.java | 8 ++++++-- .../jetbrains/android/facet/AndroidFacetEditorTab.java | 4 ++++ .../org/jetbrains/android/maven/AndroidFacetImporter.java | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java index 5c5369ad61a4..25ba1e9fb203 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java @@ -77,15 +77,19 @@ public class AndroidFacetConfiguration implements FacetConfiguration { private AndroidFacet myFacet = null; public void init(@NotNull Module module, @NotNull VirtualFile contentRoot) { + init(module, contentRoot.getPath()); + } + + public void init(@NotNull Module module, @NotNull String baseDirectoryPath) { String moduleDirPath = AndroidRootUtil.getModuleDirPath(module); if (moduleDirPath == null) { return; } - if (moduleDirPath.equals(contentRoot.getPath())) { + if (moduleDirPath.equals(baseDirectoryPath)) { return; } - String s = FileUtil.getRelativePath(moduleDirPath, contentRoot.getPath(), '/'); + String s = FileUtil.getRelativePath(moduleDirPath, baseDirectoryPath, '/'); GEN_FOLDER_RELATIVE_PATH_APT = '/' + s + GEN_FOLDER_RELATIVE_PATH_APT; GEN_FOLDER_RELATIVE_PATH_AIDL = '/' + s + GEN_FOLDER_RELATIVE_PATH_AIDL; diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java index 5afed5173670..99ef1974899a 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java @@ -171,6 +171,10 @@ public class AndroidFacetEditorTab extends FacetEditorTab { public void actionPerformed(ActionEvent e) { AndroidFacetConfiguration configuration = new AndroidFacetConfiguration(); Module module = myContext.getModule(); + VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); + if (contentRoots.length == 1) { + configuration.init(module, contentRoots[0]); + } if (AndroidMavenUtil.isMavenizedModule(module)) { AndroidMavenProvider mavenProvider = AndroidMavenUtil.getMavenProvider(); if (mavenProvider != null) { diff --git a/plugins/android/src/org/jetbrains/android/maven/AndroidFacetImporter.java b/plugins/android/src/org/jetbrains/android/maven/AndroidFacetImporter.java index 8149f074ff51..9e9b93a75adc 100644 --- a/plugins/android/src/org/jetbrains/android/maven/AndroidFacetImporter.java +++ b/plugins/android/src/org/jetbrains/android/maven/AndroidFacetImporter.java @@ -76,6 +76,8 @@ public class AndroidFacetImporter extends FacetImporter Date: Thu, 3 Feb 2011 19:07:30 +0300 Subject: [PATCH 19/94] IDEA-64679 Add github open in browser action to the file tree context menu --- plugins/github/src/META-INF/plugin.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/github/src/META-INF/plugin.xml b/plugins/github/src/META-INF/plugin.xml index 4b2871be9f2b..47d247724ef1 100644 --- a/plugins/github/src/META-INF/plugin.xml +++ b/plugins/github/src/META-INF/plugin.xml @@ -25,6 +25,7 @@ + From 853f00e91c87b761bbea290aefd5fd7141b29562 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 3 Feb 2011 19:17:01 +0300 Subject: [PATCH 20/94] icon -> image --- .../src/com/intellij/util/IconUtil.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/platform/platform-api/src/com/intellij/util/IconUtil.java b/platform/platform-api/src/com/intellij/util/IconUtil.java index 9b4c3a7b13f9..980cf86c3f11 100644 --- a/platform/platform-api/src/com/intellij/util/IconUtil.java +++ b/platform/platform-api/src/com/intellij/util/IconUtil.java @@ -28,9 +28,12 @@ import com.intellij.ui.IconDeferrer; import com.intellij.ui.LayeredIcon; import com.intellij.ui.RowIcon; import com.intellij.util.ui.EmptyIcon; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.*; +import java.awt.image.BufferedImage; public class IconUtil { @@ -178,4 +181,20 @@ public class IconUtil { private static FileIconPatcher[] getPatchers() { return FileIconPatcherHolder.ourPatchers; } + + public static Image toImage(@NotNull Icon icon) { + if (icon instanceof ImageIcon) { + return ((ImageIcon)icon).getImage(); + } + else { + final int w = icon.getIconWidth(); + final int h = icon.getIconHeight(); + final BufferedImage image = GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(w, h, Color.TRANSLUCENT); + final Graphics2D g = image.createGraphics(); + icon.paintIcon(null, g, 0, 0); + g.dispose(); + return image; + } + } } From ac0d984e8d20dd6b365aef3521ad3b2fd7bf2d49 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 3 Feb 2011 19:24:37 +0300 Subject: [PATCH 21/94] rewrote EditorGutterComponent DnD functionality to fix IDEA-36592 Breakpoint drag and drop does not work between two splits (no matter the same or different files) --- .../BreakpointWithHighlighter.java | 17 +- .../editor/markup/GutterDraggableObject.java | 13 +- .../impl/EditorGutterComponentImpl.java | 190 ++++++------------ .../impl/breakpoints/XLineBreakpointImpl.java | 13 +- 4 files changed, 88 insertions(+), 145 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java index 45e9f5bdc89f..a72ed3576209 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java @@ -43,6 +43,7 @@ import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; import com.intellij.psi.jsp.JspFile; import com.intellij.ui.classFilter.ClassFilter; import com.intellij.util.StringBuilderSpinAllocator; @@ -444,8 +445,10 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { return false; } final PsiFile psiFile = position.getFile(); + final PsiFile oldFile = getSourcePosition().getFile(); final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(psiFile); - if (document == null) { + final Document oldDocument = PsiDocumentManager.getInstance(getProject()).getDocument(oldFile); + if (document == null || oldDocument == null) { return false; } final RangeHighlighter newHighlighter = createHighlighter(myProject, document, position.getLine()); @@ -458,13 +461,13 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { reload(); if(!isValid()) { - document.getMarkupModel(myProject).removeHighlighter(myHighlighter); + oldDocument.getMarkupModel(myProject).removeHighlighter(myHighlighter); myHighlighter = oldHighlighter; reload(); return false; } - document.getMarkupModel(myProject).removeHighlighter(oldHighlighter); + oldDocument.getMarkupModel(myProject).removeHighlighter(oldHighlighter); DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager().fireBreakpointChanged(this); updateUI(); @@ -666,11 +669,9 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { public GutterDraggableObject getDraggableObject() { return new GutterDraggableObject() { - public void removeSelf() { - } - - public boolean copy(int line) { - return moveTo(SourcePosition.createFromLine(getSourcePosition().getFile(), line)); + public boolean copy(int line, VirtualFile file) { + final PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(file); + return psiFile == null ? false : moveTo(SourcePosition.createFromLine(psiFile, line)); } public Cursor getCursor(int line) { diff --git a/platform/platform-api/src/com/intellij/openapi/editor/markup/GutterDraggableObject.java b/platform/platform-api/src/com/intellij/openapi/editor/markup/GutterDraggableObject.java index 2a7582caf75a..653a9fcdc736 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/markup/GutterDraggableObject.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/markup/GutterDraggableObject.java @@ -15,6 +15,8 @@ */ package com.intellij.openapi.editor.markup; +import com.intellij.openapi.vfs.VirtualFile; + import java.awt.*; /** @@ -22,21 +24,20 @@ import java.awt.*; * a gutter icon which can be dragged and dropped is the breakpoint icon. * * @author ven + * @author Konstantin Bulenkov * @see GutterIconRenderer#getDraggableObject() */ public interface GutterDraggableObject { - /** - * Called when the drag and drop operation is successfully completed. - */ - void removeSelf(); - /** * Called when the icon is dropped over the specified line. * + * * @param line the line over which the icon has been dropped. + * @param file the DnD target file * @return true if the drag and drop operation has completed successfully, false otherwise. + * @since 10.0.3 */ - boolean copy(int line); + boolean copy(int line, VirtualFile file); /** * Returns the cursor to show when the drag is over the specified line. diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java index 1adc8a45b4d0..1fb75bc9dda8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java @@ -27,6 +27,7 @@ package com.intellij.openapi.editor.impl; import com.intellij.codeInsight.hint.TooltipController; import com.intellij.codeInsight.hint.TooltipGroup; import com.intellij.ide.IdeEventQueue; +import com.intellij.ide.dnd.*; import com.intellij.ide.ui.UISettings; import com.intellij.ide.ui.customization.CustomActionsSchema; import com.intellij.openapi.actionSystem.*; @@ -43,10 +44,12 @@ import com.intellij.openapi.editor.markup.*; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; import com.intellij.ui.HintHint; import com.intellij.ui.awt.RelativePoint; +import com.intellij.util.IconUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.ui.UIUtil; import gnu.trove.TIntArrayList; @@ -59,15 +62,12 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.plaf.ComponentUI; import java.awt.*; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; -import java.awt.dnd.*; import java.awt.event.*; import java.awt.geom.AffineTransform; import java.util.*; import java.util.List; -class EditorGutterComponentImpl extends EditorGutterComponentEx implements MouseListener, MouseMotionListener { +class EditorGutterComponentImpl extends EditorGutterComponentEx implements MouseListener, MouseMotionListener, DnDTarget, DnDSource { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.EditorGutterComponentImpl"); private static final int START_ICON_AREA_WIDTH = 15; private static final int FREE_PAINTERS_AREA_WIDTH = 3; @@ -86,16 +86,14 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse private final Map myProviderToListener = new HashMap(); private static final int GAP_BETWEEN_ANNOTATIONS = 6; private Color myBackgroundColor = null; - private GutterDraggableObject myGutterDraggableObject; private String myLastGutterToolTip = null; private int myLastPreferredHeight = -1; public EditorGutterComponentImpl(EditorImpl editor) { myEditor = editor; if (!ApplicationManager.getApplication().isHeadlessEnvironment()) { - new DropTarget(this, new MyDropTargetListener()); - final DragSource dragSource = DragSource.getDefaultDragSource(); - dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, new MyDragGestureListener()); + DnDManager.getInstance().registerSource(this, this); + DnDManager.getInstance().registerTarget(this, this); } setOpaque(true); } @@ -342,6 +340,57 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse g2.setTransform(old); } + @Override + public boolean update(DnDEvent aEvent) { + aEvent.setDropPossible(true, null); + return false; + } + + @Override + public void drop(DnDEvent aEvent) { + final Object attachedObject = aEvent.getAttachedObject(); + if (attachedObject instanceof GutterIconRenderer) { + final GutterDraggableObject draggableObject = ((GutterIconRenderer)attachedObject).getDraggableObject(); + if (draggableObject != null) { + final int line = convertPointToLineNumber(aEvent.getPoint()); + if (line != -1) { + draggableObject.copy(line, myEditor.getVirtualFile()); + } + } + } + } + + @Override + public void cleanUpOnLeave() { + } + + @Override + public void updateDraggedImage(Image image, Point dropPoint, Point imageOffset) { + } + + @Override + public boolean canStartDragging(DnDAction action, Point dragOrigin) { + return (action == DnDAction.MOVE || action == DnDAction.COPY) && getGutterRenderer(dragOrigin) != null; + } + + @Override + public DnDDragStartBean startDragging(DnDAction action, Point dragOrigin) { + return new DnDDragStartBean(getGutterRenderer(dragOrigin)); + } + + @Override + public Pair createDraggedImage(DnDAction action, Point dragOrigin) { + return new Pair(IconUtil.toImage(getGutterRenderer(dragOrigin).getIcon()), dragOrigin); + } + + @Override + public void dragDropEnd() { + } + + @Override + public void dropActionChanged(int gestureModifiers) { + } + private interface RangeHighlighterProcessor { void process(RangeHighlighter highlighter); } @@ -1264,25 +1313,30 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse TooltipController.getInstance().cancelTooltip(GUTTER_TOOLTIP_GROUP, e, false); } - @Nullable - private GutterIconRenderer getGutterRenderer(final Point p) { - final int ex = convertX((int)p.getX()); + private int convertPointToLineNumber(final Point p) { int line = myEditor.yPositionToLogicalLineNumber((int)p.getY()); - if (line >= myEditor.getDocument().getLineCount()) return null; + if (line >= myEditor.getDocument().getLineCount()) return -1; int startOffset = myEditor.getDocument().getLineStartOffset(line); final FoldRegion region = myEditor.getFoldingModel().getCollapsedRegionAtOffset(startOffset); if (region != null) { line = myEditor.getDocument().getLineNumber(region.getEndOffset()); - if (line >= myEditor.getDocument().getLineCount()) return null; + if (line >= myEditor.getDocument().getLineCount()) return -1; } + return line; + } + @Nullable + private GutterIconRenderer getGutterRenderer(final Point p) { + int line = convertPointToLineNumber(p); + if (line == -1) return null; ArrayList renderers = myLineToGutterRenderers.get(line); if (renderers == null) return null; final GutterIconRenderer[] result = {null}; processIconsRow(line, renderers, new LineGutterIconRendererProcessor() { public void process(int x, int y, GutterIconRenderer renderer) { + final int ex = convertX((int)p.getX()); Icon icon = renderer.getIcon(); if (x <= ex && ex <= x + icon.getIconWidth() && y <= p.getY() && p.getY() <= y + icon.getIconHeight()) { @@ -1310,114 +1364,4 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } myProviderToListener.clear(); } - - private static final DataFlavor[] FLAVORS; - static { - DataFlavor[] flavors; - try { - final Class aClass = EditorGutterComponentImpl.class; - //noinspection HardCodedStringLiteral - flavors = new DataFlavor[]{new DataFlavor( - DataFlavor.javaJVMLocalObjectMimeType + ";class=" + aClass.getName(), "GutterTransferable", aClass.getClassLoader() - )}; - } - catch (ClassNotFoundException e) { - LOG.error(e); // should not happen - flavors = new DataFlavor[0]; - } - FLAVORS = flavors; - } - - private class MyDragGestureListener implements DragGestureListener { - public void dragGestureRecognized(DragGestureEvent dge) { - if ((dge.getDragAction() & DnDConstants.ACTION_MOVE) == 0) return; - final GutterIconRenderer renderer = getGutterRenderer(dge.getDragOrigin()); - if (renderer != null) { - final GutterDraggableObject draggableObject = renderer.getDraggableObject(); - if (draggableObject != null) { - try { - myGutterDraggableObject = draggableObject; - final MyDragSourceListener dragSourceListener = new MyDragSourceListener(); - dge.startDrag(DragSource.DefaultMoveNoDrop, new Transferable () { - public DataFlavor[] getTransferDataFlavors() { - return FLAVORS; - } - - public boolean isDataFlavorSupported(DataFlavor flavor) { - DataFlavor[] flavors = getTransferDataFlavors(); - for (DataFlavor flavor1 : flavors) { - if (flavor.equals(flavor1)) { - return true; - } - } - return false; - } - - public Object getTransferData(DataFlavor flavor) { - return null; - } - }, dragSourceListener); - } - catch (InvalidDnDOperationException e) { - // OK, can't dnd - } - } - - } - } - } - - private class MyDragSourceListener extends DragSourceAdapter { - public void dragEnter(DragSourceDragEvent e) { - updateCursor(e); - } - - public void dragOver(DragSourceDragEvent e) { - updateCursor(e); - } - - public void dropActionChanged(DragSourceDragEvent e) { - e.getDragSourceContext().setCursor(null);//setCursor (e.getDragSourceContext()); - } - - private void updateCursor(final DragSourceDragEvent e) { - final DragSourceContext context = e.getDragSourceContext(); - final Point screenPoint = e.getLocation(); - if (screenPoint != null) { - final Point gutterPoint = new Point(screenPoint); - SwingUtilities.convertPointFromScreen(gutterPoint, EditorGutterComponentImpl.this); - if (contains(gutterPoint)){ - final Point editorPoint = new Point(screenPoint); - SwingUtilities.convertPointFromScreen(editorPoint, myEditor.getContentComponent()); - int line = myEditor.yPositionToLogicalLineNumber((int)editorPoint.getY()); - final Cursor cursor = myGutterDraggableObject.getCursor(line); - context.setCursor(cursor); - return; - } - } - context.setCursor(null); - } - - public void dragDropEnd(DragSourceDropEvent e) { - if (!e.getDropSuccess()) return; - - if (e.getDropAction() == DnDConstants.ACTION_MOVE) { - myGutterDraggableObject.removeSelf(); - } - } - } - - private class MyDropTargetListener extends DropTargetAdapter { - public void drop(DropTargetDropEvent e) { - if (myGutterDraggableObject != null) { - int dropAction = e.getDropAction(); - if ((dropAction & DnDConstants.ACTION_MOVE) != 0) { - int line = myEditor.yPositionToLogicalLineNumber((int)e.getLocation().getY()); - e.dropComplete(myGutterDraggableObject.copy(line)); - return; - } - } - e.rejectDrop(); - } - } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java index b7f931f603d6..7320e895d910 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java @@ -270,8 +270,7 @@ public class XLineBreakpointImpl

extends XBreak } } - private boolean canMoveTo(int line) { - final VirtualFile file = getFile(); + private boolean canMoveTo(int line, VirtualFile file) { return file != null && myType.canPutAt(file, line, getProject()); } @@ -389,11 +388,9 @@ public class XLineBreakpointImpl

extends XBreak @Override public GutterDraggableObject getDraggableObject() { return new GutterDraggableObject() { - public void removeSelf() { - } - - public boolean copy(int line) { - if (canMoveTo(line)) { + public boolean copy(int line, VirtualFile file) { + if (canMoveTo(line, file)) { + setFileUrl(file.getUrl()); setLine(line); return true; } @@ -401,7 +398,7 @@ public class XLineBreakpointImpl

extends XBreak } public Cursor getCursor(int line) { - return canMoveTo(line) ? DragSource.DefaultMoveDrop : DragSource.DefaultMoveNoDrop; + return canMoveTo(line, getFile()) ? DragSource.DefaultMoveDrop : DragSource.DefaultMoveNoDrop; } }; } From 07e41c6a31e7bd50ec9f0574ef92da2e084bf955 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 3 Feb 2011 16:08:55 +0100 Subject: [PATCH 22/94] More validity checks in PSI builder --- .../intellij/lang/impl/PsiBuilderImpl.java | 7 ++ .../intellij/lang/PsiBuilderQuickTest.java | 91 +++++++++++++++++-- 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/lang-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java index bab5d812a610..584caf86eeec 100644 --- a/platform/lang-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java +++ b/platform/lang-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java @@ -988,6 +988,8 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { markTokenTypeChecked(); balanceWhiteSpaces(); + LOG.assertTrue(myProduction.size() > 0, "Parser produced no markers. Text:\n" + myText); + final StartMarker rootMarker = (StartMarker)myProduction.get(0); rootMarker.myParent = rootMarker.myFirstChild = rootMarker.myLastChild = rootMarker.myNext = null; StartMarker curNode = rootMarker; @@ -1027,6 +1029,11 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { LOG.error("Tokens " + missed + " were not inserted into the tree. Text:\n" + myText); } + if (rootMarker.myDoneMarker.myLexemeIndex < myLexemeCount) { + final List missed = CollectionFactory.arrayList(myLexTypes, rootMarker.myDoneMarker.myLexemeIndex, myLexemeCount); + LOG.error("Tokens " + missed + " are outside of root element \"" + rootMarker.myType + "\". Text:\n" + myText); + } + if (myLexStarts.length <= myCurrentLexeme + 1) { resizeLexemes(myCurrentLexeme + 1); } diff --git a/platform/lang-impl/testSrc/com/intellij/lang/PsiBuilderQuickTest.java b/platform/lang-impl/testSrc/com/intellij/lang/PsiBuilderQuickTest.java index c7334ee93512..ab25345b030f 100644 --- a/platform/lang-impl/testSrc/com/intellij/lang/PsiBuilderQuickTest.java +++ b/platform/lang-impl/testSrc/com/intellij/lang/PsiBuilderQuickTest.java @@ -17,6 +17,8 @@ package com.intellij.lang; import com.intellij.lang.impl.PsiBuilderImpl; import com.intellij.lexer.LexerBase; +import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.psi.TokenType; import com.intellij.psi.impl.DebugUtil; import com.intellij.psi.impl.source.tree.ASTStructure; @@ -28,6 +30,8 @@ import com.intellij.util.diff.FlyweightCapableTreeStructure; import com.intellij.util.diff.ShallowNodeComparator; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import java.io.IOException; @@ -35,6 +39,7 @@ import java.io.OutputStream; import java.io.PrintStream; import java.util.List; +import static org.easymock.EasyMock.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -55,6 +60,30 @@ public class PsiBuilderQuickTest { private static final TokenSet WHITESPACE_SET = TokenSet.create(TokenType.WHITE_SPACE); private static final TokenSet COMMENT_SET = TokenSet.create(COMMENT); + private static ApplicationEx myMockApp = null; + + @BeforeClass + public static void setUp() { + if (ApplicationManagerEx.getApplication() == null) { + if (myMockApp == null) { + myMockApp = createMock(ApplicationEx.class); + expect(myMockApp.isInternal()).andReturn(true); + expect(myMockApp.isUnitTestMode()).andReturn(true); + myMockApp.assertReadAccessAllowed(); + expectLastCall().asStub(); + replay(myMockApp); + } + ApplicationManagerEx.setApplication(myMockApp); + } + } + + @AfterClass + public static void tearDown() { + if (myMockApp != null) { + ApplicationManagerEx.setApplication(null); + } + } + @Test public void testPlain() { doTest("a< tokens, boolean atStreamEdge, TokenTextGetter getter) { @@ -403,7 +473,7 @@ public class PsiBuilderQuickTest { } @Test - public void testLightChameleon() throws Exception { + public void testLightChameleon() { final IElementType CHAMELEON_2 = new MyLazyElementType("CHAMELEON_2") { @Override public FlyweightCapableTreeStructure parseContents(LighterLazyParseableNode chameleon) { @@ -578,6 +648,7 @@ public class PsiBuilderQuickTest { final PsiBuilder builder = new PsiBuilderImpl(new MyTestLexer(), TokenSet.EMPTY, TokenSet.EMPTY, text); builder.setDebugMode(true); parser.parse(builder); + builder.getLightTree(); fail("should fail"); } catch (AssertionError e) { From 9c59a9a19f742af876e32efe359c5949a047227d Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 4 Feb 2011 00:40:20 +0300 Subject: [PATCH 23/94] internal action to show inferred psiTypes of groovy expressions --- plugins/groovy/src/META-INF/plugin.xml | 5 +- .../groovy/actions/GrGetPsiTypeAction.java | 119 ++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/actions/GrGetPsiTypeAction.java diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index c776c31f8a79..a62e2b69fa09 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -539,10 +539,13 @@ + + + - + expressions = GrIntroduceHandlerBase.collectExpressions(psiFile, editor, offset); + if (expressions.size() == 1) { + passInner(expressions.get(0)); + } + else { + IntroduceTargetChooser.showChooser(editor, expressions, new Pass() { + @Override + public void pass(GrExpression grExpression) { + passInner(grExpression); + } + }, new Function() { + @Override + public String fun(GrExpression grExpression) { + return grExpression.getText(); + } + }); + } + } + + /** + * Shows an information balloon in a reasonable place at the top right of the window. + * + * @param project our project + * @param message the text, HTML markup allowed + * @param messageType message type, changes the icon and the background. + */ + // TODO: move to a better place + public static void showBalloon(Project project, String message, MessageType messageType) { + // ripped from com.intellij.openapi.vcs.changes.ui.ChangesViewBalloonProblemNotifier + final JFrame frame = WindowManager.getInstance().getFrame(project.isDefault() ? null : project); + if (frame == null) return; + final JComponent component = frame.getRootPane(); + if (component == null) return; + final Rectangle rect = component.getVisibleRect(); + final Point p = new Point(rect.x + rect.width - 10, rect.y + 10); + final RelativePoint point = new RelativePoint(component, p); + + JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(message, messageType.getDefaultIcon(), messageType.getPopupBackground(), null) + .setShowCallout(false).setCloseButtonEnabled(true) + .createBalloon().show(point, Balloon.Position.atLeft); + } + + public static void passInner(GrExpression expression) { + PsiType type = expression.getType(); + String text = type == null ? "type is null" : type.getCanonicalText(); + + showBalloon(expression.getProject(), StringUtil.escapeXml(text), MessageType.INFO); + } + + @Override + public void update(AnActionEvent e) { + Editor editor = PlatformDataKeys.EDITOR.getData(e.getDataContext()); + if (editor != null) { + PsiFile psiFile = HandlerUtils.getPsiFile(editor, e.getDataContext()); + if (psiFile instanceof GroovyFile) { + e.getPresentation().setEnabled(true); + return; + } + } + e.getPresentation().setEnabled(false); + } +} From 5615ea1e98da1416181c11cff4bfb6b5a6b3b039 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 4 Feb 2011 00:49:50 +0300 Subject: [PATCH 24/94] IDEA-64880 collectEntries{} inspection --- .../processors/MethodResolverProcessor.java | 16 +++++++++++++--- .../groovy/lang/resolve/TypeInferenceTest.java | 4 ++++ .../implicitlyReturnedMethodCall/A.groovy | 12 ++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 plugins/groovy/testdata/resolve/inference/implicitlyReturnedMethodCall/A.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java index cde1a139b925..8796d3c740cc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java @@ -26,9 +26,12 @@ import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -60,6 +63,7 @@ public class MethodResolverProcessor extends ResolverProcessor { private final boolean myIsConstructor; private boolean myStopExecuting = false; + private final Set myExitPoints = new HashSet(); public MethodResolverProcessor(String name, GroovyPsiElement place, boolean isConstructor, PsiType thisType, @Nullable PsiType[] argumentTypes, PsiType[] typeArguments) { this(name, place, isConstructor, thisType, argumentTypes, typeArguments, false); @@ -71,6 +75,11 @@ public class MethodResolverProcessor extends ResolverProcessor { myArgumentTypes = argumentTypes; myTypeArguments = typeArguments; myAllVariants = allVariants; + + final GrMethod method = PsiTreeUtil.getParentOfType(myPlace, GrMethod.class, true, GrClosableBlock.class); + if (method != null) { + myExitPoints.addAll(ControlFlowUtils.collectReturns(method.getBlock())); + } } public boolean execute(PsiElement element, ResolveState state) { @@ -216,10 +225,11 @@ public class MethodResolverProcessor extends ResolverProcessor { @Nullable private PsiType getContextType() { - final PsiElement parent = myPlace.getParent().getParent(); + PsiElement call = myPlace.getParent(); + final PsiElement parent = call.getParent(); PsiType rType = null; - if (parent instanceof GrReturnStatement) { - final GrMethod method = PsiTreeUtil.getParentOfType(parent, GrMethod.class); + if (parent instanceof GrReturnStatement || myExitPoints.contains(call)) { + final GrMethod method = PsiTreeUtil.getParentOfType(parent, GrMethod.class, true, GrClosableBlock.class); if (method != null) rType = method.getReturnType(); } else if (parent instanceof GrAssignmentExpression && myPlace.getParent().equals(((GrAssignmentExpression)parent).getRValue())) { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.java index 02fbdad5a539..088c8ce2bda1 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.java @@ -173,4 +173,8 @@ public class TypeInferenceTest extends GroovyResolveTestCase { public void testTupleWithNullInIt() { assertTypeEquals("java.util.List", "A.groovy"); } + + public void testImplicitlyReturnedMethodCall() { + assertTypeEquals("java.util.Map>", "A.groovy"); + } } diff --git a/plugins/groovy/testdata/resolve/inference/implicitlyReturnedMethodCall/A.groovy b/plugins/groovy/testdata/resolve/inference/implicitlyReturnedMethodCall/A.groovy new file mode 100644 index 000000000000..8ae9db76eb9c --- /dev/null +++ b/plugins/groovy/testdata/resolve/inference/implicitlyReturnedMethodCall/A.groovy @@ -0,0 +1,12 @@ +Map> getBasic() { + Map> ranges = new HashMap>() + ranges.keySet().collectEntries { + [it, getBasic(it)] + } +} + +Map getBasic(BasicRange range) {return new HashMap()} + +class BasicRange {} + + From f01e9d2c2e3f21914ad57155d0b3cc2a5a84d331 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 4 Feb 2011 06:46:04 +0100 Subject: [PATCH 25/94] Dependency fixed --- plugins/git4idea/git4idea.iml | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/git4idea/git4idea.iml b/plugins/git4idea/git4idea.iml index 3d79be268cb7..830aa37f58f3 100644 --- a/plugins/git4idea/git4idea.iml +++ b/plugins/git4idea/git4idea.iml @@ -32,6 +32,7 @@ + From 26099475c1953732c042eecc9ac04ddbae972c13 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 4 Feb 2011 09:19:23 +0300 Subject: [PATCH 26/94] added missing library to maven deps --- plugins/maven/facade-impl/maven-facade-impl.iml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/plugins/maven/facade-impl/maven-facade-impl.iml b/plugins/maven/facade-impl/maven-facade-impl.iml index 4a9bdc0ae2ea..d6356b9cf3f3 100644 --- a/plugins/maven/facade-impl/maven-facade-impl.iml +++ b/plugins/maven/facade-impl/maven-facade-impl.iml @@ -119,15 +119,7 @@ - - - - - - - - - + From 8d1cb02778ae0e08f1918d9e21aa87cd7f993cc5 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 4 Feb 2011 10:24:20 +0300 Subject: [PATCH 27/94] fixed memory leaks from snapshot attached to IDEA-65035 --- .../ProjectJdksConfigurable.java | 11 +++- .../ArtifactsStructureConfigurable.java | 10 ++- .../BaseStructureConfigurable.java | 5 ++ .../FacetStructureConfigurable.java | 7 ++- .../GlobalLibrariesConfigurable.java | 7 ++- .../projectRoot/JdkListConfigurable.java | 8 ++- .../ModuleStructureConfigurable.java | 6 +- .../ProjectLibrariesConfigurable.java | 7 ++- .../ScopeChooserConfigurable.java | 12 +++- .../openapi/ui/MasterDetailsComponent.java | 32 +++++++++- .../openapi/ui/MasterDetailsStateService.java | 63 +++++++++---------- .../copyright/ui/CopyrightProfilesPanel.java | 21 +++++-- 12 files changed, 133 insertions(+), 56 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java index 01c93a435756..fa50511d5993 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java @@ -64,10 +64,19 @@ public class ProjectJdksConfigurable extends MasterDetailsComponent { super(); myProject = project; myProjectJdksModel = ProjectStructureConfigurable.getInstance(project).getProjectJdksModel(); - MasterDetailsStateService.getInstance(project).register("ProjectJDKs.UI", this); initTree(); } + @Override + protected String getComponentStateKey() { + return "ProjectJDKs.UI"; + } + + @Override + protected MasterDetailsStateService getStateService() { + return MasterDetailsStateService.getInstance(myProject); + } + protected void initTree() { super.initTree(); new TreeSpeedSearch(myTree, new Convertor() { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java index d82671ef4b17..5e1087318155 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java @@ -34,7 +34,6 @@ import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditorLi import com.intellij.openapi.roots.ui.configuration.projectRoot.*; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement; import com.intellij.openapi.ui.MasterDetailsState; -import com.intellij.openapi.ui.MasterDetailsStateService; import com.intellij.openapi.ui.NamedConfigurable; import com.intellij.packaging.artifacts.*; import com.intellij.packaging.impl.artifacts.ArtifactUtil; @@ -61,7 +60,11 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable { public ArtifactsStructureConfigurable(@NotNull Project project) { super(project, new ArtifactStructureConfigurableState()); - MasterDetailsStateService.getInstance(project).register("ArtifactsStructureConfigurable.UI", this); + } + + @Override + protected String getComponentStateKey() { + return "ArtifactsStructureConfigurable.UI"; } public void init(StructureConfigurableContext context, ModuleStructureConfigurable moduleStructureConfigurable, @@ -160,7 +163,7 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable { } @Override - public MasterDetailsState getState() { + protected MasterDetailsState getState() { ((ArtifactStructureConfigurableState)myState).setDefaultArtifactSettings(myDefaultSettings.getState()); return super.getState(); } @@ -209,6 +212,7 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable { @Override public void reset() { + loadComponentState(); myPackagingEditorContext.resetModifiableModel(); super.reset(); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java index eb3973368615..fb5f2b2aca83 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java @@ -32,6 +32,7 @@ import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.*; import com.intellij.openapi.ui.MasterDetailsComponent; import com.intellij.openapi.ui.MasterDetailsState; +import com.intellij.openapi.ui.MasterDetailsStateService; import com.intellij.openapi.ui.NamedConfigurable; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Condition; @@ -100,6 +101,10 @@ public abstract class BaseStructureConfigurable extends MasterDetailsComponent i }); } + @Override + protected MasterDetailsStateService getStateService() { + return MasterDetailsStateService.getInstance(myProject); + } public ActionCallback navigateTo(@Nullable final Place place, final boolean requestFocus) { if (place == null) return new ActionCallback.Done(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java index e5eb0f045588..b94f19f0b99d 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java @@ -37,7 +37,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.ui.DetailsComponent; -import com.intellij.openapi.ui.MasterDetailsStateService; import com.intellij.openapi.ui.NamedConfigurable; import com.intellij.openapi.util.IconLoader; import org.jetbrains.annotations.NotNull; @@ -59,10 +58,14 @@ public class FacetStructureConfigurable extends BaseStructureConfigurable { public FacetStructureConfigurable(final Project project, ModuleManager moduleManager) { super(project); - MasterDetailsStateService.getInstance(project).register("FacetStructureConfigurable.UI", this); myModuleManager = moduleManager; } + @Override + protected String getComponentStateKey() { + return "FacetStructureConfigurable.UI"; + } + public static FacetStructureConfigurable getInstance(final @NotNull Project project) { return ServiceManager.getService(project, FacetStructureConfigurable.class); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/GlobalLibrariesConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/GlobalLibrariesConfigurable.java index 8ac240060a2a..988bcccf763c 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/GlobalLibrariesConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/GlobalLibrariesConfigurable.java @@ -19,7 +19,6 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; -import com.intellij.openapi.ui.MasterDetailsStateService; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -31,10 +30,14 @@ public class GlobalLibrariesConfigurable extends BaseLibrariesConfigurable { public GlobalLibrariesConfigurable(final Project project) { super(project); - MasterDetailsStateService.getInstance(project).register("GlobalLibrariesConfigurable.UI", this); myLevel = LibraryTablesRegistrar.APPLICATION_LEVEL; } + @Override + protected String getComponentStateKey() { + return "GlobalLibrariesConfigurable.UI"; + } + @Nls public String getDisplayName() { return "Global Libraries"; diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/JdkListConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/JdkListConfigurable.java index 613d0ab370f9..8e8faae3231c 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/JdkListConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/JdkListConfigurable.java @@ -30,7 +30,6 @@ import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.SdkProjectStructureElement; import com.intellij.openapi.ui.MasterDetailsComponent; -import com.intellij.openapi.ui.MasterDetailsStateService; import com.intellij.openapi.ui.NamedConfigurable; import com.intellij.util.Consumer; import org.jetbrains.annotations.Nls; @@ -75,10 +74,15 @@ public class JdkListConfigurable extends BaseStructureConfigurable { public JdkListConfigurable(final Project project, ProjectStructureConfigurable root) { super(project); - MasterDetailsStateService.getInstance(project).register("JdkListConfigurable.UI", this); myJdksTreeModel = root.getProjectJdksModel(); myJdksTreeModel.addListener(myListener); } + + @Override + protected String getComponentStateKey() { + return "JdkListConfigurable.UI"; + } + protected void processRemovedItems() { } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java index 07c7d6a59d2e..efbd4009a52c 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java @@ -50,7 +50,6 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ModuleProj import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureDaemonAnalyzer; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement; import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.MasterDetailsStateService; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.NamedConfigurable; import com.intellij.openapi.util.Comparing; @@ -96,10 +95,13 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple public ModuleStructureConfigurable(Project project, ModuleManager manager) { super(project); - MasterDetailsStateService.getInstance(project).register("ModuleStructureConfigurable.UI", this); myModuleManager = manager; } + @Override + protected String getComponentStateKey() { + return "ModuleStructureConfigurable.UI"; + } protected void initTree() { super.initTree(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ProjectLibrariesConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ProjectLibrariesConfigurable.java index d2cb1f580067..1a9845c9df4f 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ProjectLibrariesConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ProjectLibrariesConfigurable.java @@ -19,7 +19,6 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; -import com.intellij.openapi.ui.MasterDetailsStateService; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -30,10 +29,14 @@ import javax.swing.*; public class ProjectLibrariesConfigurable extends BaseLibrariesConfigurable { public ProjectLibrariesConfigurable(final Project project) { super(project); - MasterDetailsStateService.getInstance(project).register("ProjectLibrariesConfigurable.UI", this); myLevel = LibraryTablesRegistrar.PROJECT_LEVEL; } + @Override + protected String getComponentStateKey() { + return "ProjectLibrariesConfigurable.UI"; + } + @Nls public String getDisplayName() { return "Libraries"; diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserConfigurable.java b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserConfigurable.java index 5c1ea5606de7..1171bdda8b8c 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserConfigurable.java +++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserConfigurable.java @@ -61,6 +61,7 @@ import java.util.*; public class ScopeChooserConfigurable extends MasterDetailsComponent implements NonDefaultProjectConfigurable, SearchableConfigurable { private static final Icon SCOPES = IconLoader.getIcon("/ide/scopeConfigurable.png"); private static final Icon SAVE_ICON = IconLoader.getIcon("/runConfigurations/saveTempConfig.png"); + @NonNls public static final String SCOPE_CHOOSER_CONFIGURABLE_UI_KEY = "ScopeChooserConfigurable.UI"; private final NamedScopesHolder myLocalScopesManager; private final NamedScopesHolder mySharedScopesManager; @@ -81,10 +82,19 @@ public class ScopeChooserConfigurable extends MasterDetailsComponent implements mySharedScopesManager = DependencyValidationManager.getInstance(project); myProject = project; - MasterDetailsStateService.getInstance(project).register("ScopeChooserConfigurable.UI", this); initTree(); } + @Override + protected String getComponentStateKey() { + return SCOPE_CHOOSER_CONFIGURABLE_UI_KEY; + } + + @Override + protected MasterDetailsStateService getStateService() { + return MasterDetailsStateService.getInstance(myProject); + } + protected ArrayList createActions(final boolean fromPopup) { final ArrayList result = new ArrayList(); result.add(new MyAddAction(fromPopup)); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java index f7fea3927e78..c8baff067dbe 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java @@ -323,6 +323,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom protected abstract boolean wasObjectStored(Object editableObject); public void reset() { + loadComponentState(); myHasDeletedItems = false; ((DefaultTreeModel)myTree.getModel()).reload(); //myTree.requestFocus(); @@ -345,6 +346,17 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom updateSelectionFromTree(); } + protected void loadComponentState() { + final String key = getComponentStateKey(); + final MasterDetailsStateService stateService = getStateService(); + if (key != null && stateService != null) { + final MasterDetailsState state = stateService.getComponentState(key, myState.getClass()); + if (state != null) { + loadState(state); + } + } + } + private static String getNodePathString(final MyNode node) { StringBuilder path = new StringBuilder(); MyNode current = node; @@ -365,11 +377,22 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom return path.toString(); } - public MasterDetailsState getState() { + @Nullable + @NonNls + protected String getComponentStateKey() { + return null; + } + + @Nullable + protected MasterDetailsStateService getStateService() { + return null; + } + + protected MasterDetailsState getState() { return myState; } - public void loadState(final MasterDetailsState object) { + protected void loadState(final MasterDetailsState object) { XmlSerializerUtil.copyBean(object, myState); } @@ -391,6 +414,11 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom } }); myRoot.removeAllChildren(); + final String key = getComponentStateKey(); + final MasterDetailsStateService stateService = getStateService(); + if (key != null && stateService != null) { + stateService.setComponentState(key, getState()); + } myCurrentConfigurable = null; } diff --git a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsStateService.java b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsStateService.java index 5b786f55372b..6bd41e819a80 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsStateService.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsStateService.java @@ -33,6 +33,7 @@ import com.intellij.util.xmlb.annotations.Tag; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -46,57 +47,53 @@ import java.util.*; ) public class MasterDetailsStateService implements PersistentStateComponent{ private final SkipDefaultValuesSerializationFilters mySerializationFilter = new SkipDefaultValuesSerializationFilters(); - private final Map myComponents = new HashMap(); - private final States myStates = new States(); + private final Map myStates = new HashMap(); public static MasterDetailsStateService getInstance(@NotNull Project project) { return ServiceManager.getService(project, MasterDetailsStateService.class); } - public void register(@NotNull @NonNls String key, MasterDetailsComponent masterDetailsComponent) { - myComponents.put(key, masterDetailsComponent); - for (ComponentState state : myStates.getStates()) { - if (key.equals(state.myKey)) { - final Element element = state.mySettings; - if (element != null) { - loadComponentState(masterDetailsComponent, element); - } - } - } + /** + * @deprecated override {@link MasterDetailsComponent#getComponentStateKey()} and {@link MasterDetailsComponent#getStateService()} instead + */ + public void register(String key, MasterDetailsComponent component) { } - private static void loadComponentState(MasterDetailsComponent masterDetailsComponent, Element element) { - final MasterDetailsState loadedState = XmlSerializer.deserialize(element, masterDetailsComponent.getState().getClass()); - masterDetailsComponent.loadState(loadedState); + @Nullable + public MasterDetailsState getComponentState(@NotNull @NonNls String key, Class stateClass) { + ComponentState state = myStates.get(key); + return state != null ? XmlSerializer.deserialize(state.mySettings, stateClass) : null; + } + + public void setComponentState(@NotNull @NonNls String key, @NotNull MasterDetailsState state) { + final Element element = XmlSerializer.serialize(state, mySerializationFilter); + if (element == null) { + myStates.remove(key); + } + else { + final ComponentState componentState = new ComponentState(); + componentState.myKey = key; + componentState.mySettings = element; + myStates.put(key, componentState); + } } public States getState() { - myStates.getStates().clear(); - for (Map.Entry entry : myComponents.entrySet()) { - final Element element = XmlSerializer.serialize(entry.getValue().getState(), mySerializationFilter); - if (element != null) { - final ComponentState state = new ComponentState(); - state.myKey = entry.getKey(); - state.mySettings = element; - myStates.getStates().add(state); - } - } - Collections.sort(myStates.getStates(), new Comparator() { + States states = new States(); + states.myStates.addAll(myStates.values()); + Collections.sort(states.getStates(), new Comparator() { @Override public int compare(ComponentState o1, ComponentState o2) { return o1.myKey.compareTo(o2.myKey); } }); - return myStates; + return states; } public void loadState(States states) { - myStates.setStates(states.getStates()); - for (ComponentState state : myStates.getStates()) { - final MasterDetailsComponent component = myComponents.get(state.myKey); - if (component != null) { - loadComponentState(component, state.mySettings); - } + myStates.clear(); + for (ComponentState state : states.getStates()) { + myStates.put(state.myKey, state); } } diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java index 79c6ea143e93..1eebcd37f55a 100644 --- a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java +++ b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java @@ -60,13 +60,22 @@ public class CopyrightProfilesPanel extends MasterDetailsComponent implements Se private final AtomicBoolean myInitialized = new AtomicBoolean(false); public CopyrightProfilesPanel(Project project) { - MasterDetailsStateService.getInstance(project).register("Copyright.UI", this); - myProject = project; - myManager = CopyrightManager.getInstance(project); - initTree(); - } + myProject = project; + myManager = CopyrightManager.getInstance(project); + initTree(); + } - protected void processRemovedItems() { + @Override + protected MasterDetailsStateService getStateService() { + return MasterDetailsStateService.getInstance(myProject); + } + + @Override + protected String getComponentStateKey() { + return "Copyright.UI"; + } + + protected void processRemovedItems() { Map profiles = getAllProfiles(); final List deleted = new ArrayList(); for (CopyrightProfile profile : myManager.getCopyrights()) { From 59761ccc9daa78971c575edd23f8f9d03b333361 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 4 Feb 2011 10:34:29 +0300 Subject: [PATCH 28/94] fixed sorting in licenses table (damn language without type-checking!) --- build/scripts/libLicenses.gant | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant index 2502d1b9167a..0113c6c31625 100644 --- a/build/scripts/libLicenses.gant +++ b/build/scripts/libLicenses.gant @@ -84,7 +84,7 @@ binding.setVariable("generateLicensesTable", {String filePath -> def license = lib.licenseUrl != null ? "[$lib.license|$lib.licenseUrl]" : lib.license return "|$name| $lib.version|$license|".toString() } - lines.sort {String.CASE_INSENSITIVE_ORDER} + lines.sort(String.CASE_INSENSITIVE_ORDER) FileWriter out = new FileWriter(filePath) out.println("|| Software || Version || License ||") From 9ac793caf310dda06937f1c38a56c562dfac1c46 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 09:33:29 +0100 Subject: [PATCH 29/94] remove the old leaky gradle gui which nobody sees anyway --- plugins/groovy/jetgroovy.iml | 9 - plugins/groovy/src/META-INF/plugin.xml | 13 - .../gradle/ui/GradleIdeaSettingsNode.java | 286 ------------- .../groovy/gradle/ui/GradlePanelWrapper.java | 384 ------------------ .../groovy/gradle/ui/GradleSetupPanel.java | 126 ------ .../ui/GradleUIAvailabilityObserver.java | 44 -- .../groovy/gradle/ui/GradleUISettings.java | 125 ------ .../groovy/gradle/ui/ObserverLord.java | 210 ---------- .../groovy/gradle/ui/ShowGradleUIAction.java | 139 ------- 9 files changed, 1336 deletions(-) delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleIdeaSettingsNode.java delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradlePanelWrapper.java delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleSetupPanel.java delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleUIAvailabilityObserver.java delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleUISettings.java delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/ObserverLord.java delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/ShowGradleUIAction.java diff --git a/plugins/groovy/jetgroovy.iml b/plugins/groovy/jetgroovy.iml index bc4aed3e9f68..7950afc27699 100644 --- a/plugins/groovy/jetgroovy.iml +++ b/plugins/groovy/jetgroovy.iml @@ -21,15 +21,6 @@ - - - - - - - - - diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index a62e2b69fa09..e5162b693c5d 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -594,18 +594,5 @@ - - - - - - - - - - - diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleIdeaSettingsNode.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleIdeaSettingsNode.java deleted file mode 100644 index a26a78f80bae..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleIdeaSettingsNode.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright 2009 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.plugins.groovy.gradle.ui; - -import org.gradle.openapi.external.ui.SettingsNodeVersion1; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -/** - This is our Idea-side implementation of a settings node. We'll store them in - a hashmap and then write them out to the Idea project file using its - serialization mechanism. The settings are actually a hiearchy of nodes - similar to xml, but without attributes. - @author mhunsicker -*/ -public class GradleIdeaSettingsNode implements SettingsNodeVersion1 -{ - public List children = new ArrayList(); - public String name; - public String value; - public GradleIdeaSettingsNode parent; - - public GradleIdeaSettingsNode( String name, GradleIdeaSettingsNode parent ) - { - this.name = name; - this.parent = parent; - } - - public void setName( String name ) - { - this.name = name; - } - - public String getName() - { - return name; - } - - public void setValue( String value ) - { - this.value = value; - } - - public String getValue() - { - return value; - } - - public List getChildNodes() - { - return Collections.unmodifiableList( children ); - } - - public List getChildNodes( String name ) - { - List matchingChildren = new ArrayList( ); - - Iterator iterator = children.iterator(); - - while( iterator.hasNext() ) - { - SettingsNodeVersion1 settingsNodeVersion1 = iterator.next(); - if( name.equals( settingsNodeVersion1.getName() ) ) - matchingChildren.add( settingsNodeVersion1 ); - } - - return matchingChildren; - } - - public SettingsNodeVersion1 getChildNode( String name ) - { - Iterator iterator = children.iterator(); - - while( iterator.hasNext() ) - { - SettingsNodeVersion1 settingsNodeVersion1 = iterator.next(); - if( name.equals( settingsNodeVersion1.getName() ) ) - return settingsNodeVersion1; - } - - return null; - } - - public SettingsNodeVersion1 addChild( String name ) - { - GradleIdeaSettingsNode node = new GradleIdeaSettingsNode( name, this ); - children.add( node ); - return node; - } - - public SettingsNodeVersion1 addChildIfNotPresent( String name ) - { - SettingsNodeVersion1 child = getChildNode( name ); - if( child == null ) - child = addChild( name ); - - return child; - } - - - public SettingsNodeVersion1 getNodeAtPath( String ... pathPortions ) - { - if( pathPortions == null || pathPortions.length == 0 ) - return null; - - String firstPathPortion = pathPortions[ 0 ]; - - SettingsNodeVersion1 currentNode = getChildNode( firstPathPortion ); - - int index = 1;//Skip the first one. we've already used that one. - while( index < pathPortions.length && currentNode != null ) - { - String pathPortion = pathPortions[ index ]; - currentNode = currentNode.getChildNode( pathPortion ); - index++; - } - - return currentNode; - } - - private SettingsNodeVersion1 getNodeAtPathCreateIfNotFound( String ... pathPortions ) - { - if( pathPortions == null || pathPortions.length == 0 ) - return null; - - String firstPathPortion = pathPortions[ 0 ]; - - SettingsNodeVersion1 currentNode = getChildNode( firstPathPortion ); - if( currentNode == null ) - currentNode = addChild( firstPathPortion ); - - int index = 1; - while( index < pathPortions.length ) - { - String pathPortion = pathPortions[ index ]; - currentNode = currentNode.getChildNode( pathPortion ); - if( currentNode == null ) - currentNode = addChild( firstPathPortion ); - - index++; - } - - return currentNode; - } - - public void removeAllChildren() - { - children.clear(); - } - - public void removeFromParent() - { - if( parent != null ) - { - if( parent.removeChild( this ) ) - parent = null; - } - } - - private boolean removeChild( GradleIdeaSettingsNode node ) - { - return children.remove( node ); - } - - public void setValueOfChild( String name, String value ) - { - SettingsNodeVersion1 settingsNode = addChildIfNotPresent( name ); - settingsNode.setValue( value ); - } - - public String getValueOfChild( String name, String defaultValue ) - { - SettingsNodeVersion1 settingsNode = getChildNode( name ); - if( settingsNode == null ) - return defaultValue; - - return settingsNode.getValue(); - } - - public int getValueOfChildAsInt( String name, int defaultValue ) - { - SettingsNodeVersion1 settingsNode = getChildNode( name ); - if( settingsNode != null ) - { - String value = settingsNode.getValue(); - - try - { - if( value != null ) - return Integer.parseInt( value ); - } - catch( NumberFormatException e ) - { - //we couldn't parse it. Just return the default. - } - } - return defaultValue; - } - - public void setValueOfChildAsInt( String name, int value ) - { - setValueOfChild( name, Integer.toString( value ) ); - } - - public long getValueOfChildAsLong( String name, long defaultValue ) - { - SettingsNodeVersion1 settingsNode = getChildNode( name ); - if( settingsNode != null ) - { - String value = settingsNode.getValue(); - - try - { - if( value != null ) - return Long.parseLong( value ); - } - catch( NumberFormatException e ) - { - //we couldn't parse it. Just return the default. - } - } - return defaultValue; - } - - public void setValueOfChildAsLong( String name, long value ) - { - setValueOfChild( name, Long.toString( value ) ); - } - - public boolean getValueOfChildAsBoolean( String name, boolean defaultValue ) - { - SettingsNodeVersion1 settingsNode = getChildNode( name ); - if( settingsNode != null ) - { - String value = settingsNode.getValue(); - - //I'm not calling 'Boolean.parseBoolean( value )' because it will return false if the value isn't true/false - //and we want it to return whatever the default is if its not a boolean. This is how the Int and Long functions - //behave. - if( value != null ) - { - if( "true".equalsIgnoreCase( value ) ) - return true; - - if( "false".equalsIgnoreCase( value ) ) - return false; - } - } - - return defaultValue; - } - - public void setValueOfChildAsBoolean( String name, boolean value ) - { - setValueOfChild( name, Boolean.toString( value ) ); - } - - @Override - public String toString() - { - return getName() + "='" + getValue() + "' " + children.size() + " children"; - } - - //this should only be called by the serializer - public void setChildren( List newChildren ) - { - children.clear(); - children.addAll( newChildren ); - } -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradlePanelWrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradlePanelWrapper.java deleted file mode 100644 index c5b154e67518..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradlePanelWrapper.java +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.gradle.ui; - -import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import org.gradle.openapi.external.ui.*; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.gradle.GradleLibraryPresentationProvider; - -import javax.swing.*; -import java.awt.*; -import java.io.File; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - - This shows a self-contained gradle UI inside a panel. It may also show a - gradle setup panel if gradle hasn't been configured or was unable to load. - - The gradle UI is loaded dynamically from an external gradle installation. - There is a gradle open API jar that does the real work (and is part of gradle). - The gradle UI implementation uses versioned interfaces and wrappers to interact - with us. This allows us to be forward and backward compatible with gradle - (although certain major changes will break us). This allows the gradle UI to - change and gain new features that we don't have to know about (new features that - require our interaction obviously won't work, but the wrappers provide an - appropriate default behavior that is defined inside gradle). - - You get the SinglePaneUIVersion1 here as well as add some custom panels to it. - - @author mhunsicker - */ -public class GradlePanelWrapper -{ - private final JPanel mainPanel = new JPanel( new BorderLayout() ); - private Project myProject; - private GradleUISettings settings; - private SinglePaneUIVersion1 singlePaneUIVersion1; - private GradleSetupPanel gradleSetupPanel; - private final List additionalTabs = new ArrayList(); - private final ObserverLord observerLord = new ObserverLord(); - - public void initalize(@Nullable Module module, Project myProject) - { - this.myProject = myProject; - this.settings = GradleUISettings.getInstance(myProject); - - File gradleHomeDirectory = new File( GradleLibraryPresentationProvider.getSdkHome( module, myProject ).getPath() ); - - //this will either load the UI from gradle or display the gradle setup panel. - setupUI( gradleHomeDirectory ); - } - - public Project getProject() { return myProject; } - - private boolean setupUI( final File gradleHomeDirectory ) - { - try - { - if( gradleHomeDirectory == null ) - { - addGradleSetupPanel( "Gradle not configured", (String) null ); - return false; - } - - if( !gradleHomeDirectory.exists() ) - { - addGradleSetupPanel( "Gradle directory does not exist.", gradleHomeDirectory.getAbsolutePath() ); - return false; - } - - //Since this is Swing-related we want to make sure its always executed in the EDT. - //When called by Idea, we're not in the EDT. When called from out setup panel, we - //ARE in the EDT. If this fails, it will add the gradle setup panel. - if( SwingUtilities.isEventDispatchThread() ) - loadUIFromGradle( gradleHomeDirectory ); - else - SwingUtilities.invokeAndWait( new Runnable() - { - public void run() - { - loadUIFromGradle( gradleHomeDirectory ); - } - } ); - - if( singlePaneUIVersion1 != null ) - { - //by default, we'll set it to your project's directory, but this will probably be overridden when its settings are loaded in aboutToShow. - singlePaneUIVersion1.setCurrentDirectory( new File( myProject.getBaseDir().getPath() ) ); - addAdditionalTabs(); - setMainPanelContents( singlePaneUIVersion1.getComponent() ); - singlePaneUIVersion1.aboutToShow(); - return true; - } - } - catch( Exception e ) - { - singlePaneUIVersion1 = null; - notifyGradleUIUnloaded(); - addGradleSetupPanel( "Failed to load the gradle library.", e ); - } - - return false; - } - - /** - This dynamically loads the UI from a gradle installation. We call into - a function inside the gradle open API jar that handles all the reflection - of loading the classes. If this fails, we show the gradle setup panel. - - - @param gradleHomeDirectory where gradle resides - @author mhunsicker - */ - private void loadUIFromGradle( File gradleHomeDirectory ) - { - try - { - singlePaneUIVersion1 = UIFactory.createUI( GradlePanelWrapper.class.getClassLoader(), gradleHomeDirectory, new IdeaUIInteraction(), false ); - final SinglePaneUIVersion1 singlePaneUIVersion1 = getSinglePaneUIVersion1(); - final Project project = getProject(); - - observerLord.notifyObservers( new ObserverLord.ObserverNotification() - { - public void notify( GradleUIAvailabilityObserver observer ) - { - observer.gradleUILoaded( singlePaneUIVersion1, project ); - } - } ); - } - catch( Throwable e ) - { - singlePaneUIVersion1 = null; - notifyGradleUIUnloaded(); - e.printStackTrace(); - addGradleSetupPanel( "Failed to load the gradle library.", e ); - } - } - - /*package*/ void notifyGradleUIUnloaded() - { - observerLord.notifyObservers( new ObserverLord.ObserverNotification() - { - public void notify( GradleUIAvailabilityObserver observer ) - { - observer.gradleUIUnloaded(); - } - } ); - } - - - public JPanel getComponent() - { - return mainPanel; - } - - /** - This sets the main panel to the gradle setup panel. This is used when - we could not load gradle either because of an error or lack of setup. - - - @param message a message of why we're displaying this. - @param messageDetails detailed information about why we're not displaying this. - this will only be visible if the user chooses to show it. - @author mhunsicker - */ - private void addGradleSetupPanel( String message, String messageDetails ) - { - if( gradleSetupPanel == null ) - gradleSetupPanel = new GradleSetupPanel(); - - gradleSetupPanel.setMessage( message, messageDetails ); - setMainPanelContents( gradleSetupPanel.getComponent() ); - } - - private void addGradleSetupPanel( String message, Throwable throwable ) - { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - throwable.printStackTrace(pw); - - addGradleSetupPanel( message, throwable.getMessage() + "\n" + sw.toString() ); - } - - /** - This replaces the main panel's contents with the specified new component. - - @author mhunsicker - */ - private void setMainPanelContents( Component newComponent ) - { - mainPanel.removeAll(); - mainPanel.invalidate(); - mainPanel.add( newComponent, BorderLayout.CENTER ); - mainPanel.validate(); - mainPanel.repaint(); - } - - // - /** - This class is how we interact with Gradle, specifically how to specify - what we use to interact with it. The purpose of SinglePaneUIInteractionVersion1 - is to aid forward/backward compatibility. - @author mhunsicker - */ - private class IdeaUIInteraction implements SinglePaneUIInteractionVersion1 - { - private IdeaUIInteraction() - { - } - - /** - This is only called once and is how we get ahold of the AlternateUIInteraction. - @return an AlternateUIInteraction object. This cannot be null. - @author mhunsicker - */ - public AlternateUIInteractionVersion1 instantiateAlternateUIInteraction() - { - return new IdeaAlternateUIInteraction(); - } - - /** - This is only called once and is how we get ahold of how the owner wants - to store preferences. - @return a settings object. This cannot be null. - @author mhunsicker - */ - public SettingsNodeVersion1 instantiateSettings() - { - return settings.getRootNode(); - } - } - - // - /** - @author mhunsicker - */ - private class IdeaAlternateUIInteraction implements AlternateUIInteractionVersion1 - { - /** - This is called when we should edit the specified files. Open them in the - current IDE or some external editor. - - - @param files the files to open - @author mhunsicker - */ - public void editFiles( List files ) - { - Iterator iterator = files.iterator(); - while( iterator.hasNext() ) - { - File file = iterator.next(); - editFile( file ); - } - } - - /** - Determines if we can call editFiles. This is not a dynamic answer and - should always return either true of false. If you want to change the - answer, return true and then handle the files differently in editFiles. - @return true if support editing files, false otherwise. - @author mhunsicker - */ - public boolean doesSupportEditingFiles() - { - return true; - } - } - - /** - Opens a single file in Idea. - - - @param file the file to open - @author mhunsicker - */ - private void editFile( File file ) - { - if( file != null && file.exists() ) - { - VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile( file ); - if( virtualFile != null ) - FileEditorManager.getInstance( myProject ).openFile( virtualFile, true ); - } - } - - public void close() - { - if( singlePaneUIVersion1 != null ) - { - singlePaneUIVersion1.close(); - - //I'm going to clear this out because I think this is being called multiple times. - setMainPanelContents( new JLabel( "Closing" ) ); - singlePaneUIVersion1 = null; - notifyGradleUIUnloaded(); - } - } - - /** - Call this to determine if we can close. We'll just ask the . - @return . - @author mhunsicker - */ - public boolean canClose() - { - if( singlePaneUIVersion1 != null ) - return singlePaneUIVersion1.canClose( new SinglePaneUIVersion1.CloseInteraction() - { - public boolean promptUserToConfirmClosingWhileBusy() - { - int result = JOptionPane.showConfirmDialog( SwingUtilities.getWindowAncestor( mainPanel ), "Gradle tasks are being currently being executed. Exit anyway?", "Exit While Busy?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE ); - return result == JOptionPane.YES_OPTION; - } - } ); - - return true; - } - - /** - This adds a tab. You'll want to add tabs using this rather than calling - SinglePaneUIVersion1.addTab directly. Why? Because this removes the timing - issues. That is, whether or not we've loaded the gradle UI, you can call - this and we'll show the tabs whenever we do display the UI. - - @param tab the tab to add - @author mhunsicker - */ - public void addTab( GradleTabVersion1 tab ) - { - additionalTabs.add( tab ); - if( singlePaneUIVersion1 != null ) - singlePaneUIVersion1.addTab( singlePaneUIVersion1.getGradleTabCount() + 1, tab ); - } - - public void removeTab( GradleTabVersion1 tab ) - { - additionalTabs.remove( tab ); - if( singlePaneUIVersion1 != null ) - singlePaneUIVersion1.removeTab( tab ); - } - - private void addAdditionalTabs() - { - Iterator iterator = additionalTabs.iterator(); - while( iterator.hasNext() ) - { - GradleTabVersion1 gradleTab = iterator.next(); - singlePaneUIVersion1.addTab( singlePaneUIVersion1.getGradleTabCount() + 1, gradleTab ); - } - } - - /** - @return the single pane UI version1. Note: this is very likely to return - null if this hasn't been setup yet or hasn't loaded yet. - @author mhunsicker - */ - public SinglePaneUIVersion1 getSinglePaneUIVersion1() - { - return singlePaneUIVersion1; - } -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleSetupPanel.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleSetupPanel.java deleted file mode 100644 index afc2c5f3b4d2..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleSetupPanel.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.gradle.ui; - -import com.intellij.ui.ScrollPaneFactory; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; - -/** - - This panel is shown when gradle has not been configured or when an error - occurs trying to locate the gradle installation. It was intended to be a place - where the user could specify a gradle installation. Now, it appears to just - be a placeholder as well as a place to show error message. - - - @author mhunsicker - */ -public class GradleSetupPanel -{ - private JPanel mainPanel; - private JPanel messagePanel; - private JLabel messageLabel; - - private String messageDetails; - private String message; - private JButton detailsButton; - - - public GradleSetupPanel() - { - setupUI(); - } - - public Component getComponent() { return mainPanel; } - - private void setupUI() - { - mainPanel = new JPanel( new BorderLayout() ); - - JPanel innerPanel = new JPanel( ); - innerPanel.setLayout( new BoxLayout( innerPanel, BoxLayout.Y_AXIS ) ); - - innerPanel.add( createMessageComponent() ); - - mainPanel.add( innerPanel, BorderLayout.NORTH ); //this pushes things up. Glue doesn't work in this situation. - - mainPanel.setBorder( BorderFactory.createEmptyBorder( 10, 10, 10, 10 ) ); - } - - private Component createMessageComponent() - { - messagePanel = new JPanel(); - messagePanel.setLayout( new BoxLayout( messagePanel, BoxLayout.X_AXIS ) ); - - messageLabel = new JLabel(); - - detailsButton = new JButton( new AbstractAction( "Details...") - { - public void actionPerformed( ActionEvent e ) - { - showDetails(); - } - }); - - messagePanel.add( messageLabel ); - messagePanel.add( Box.createHorizontalStrut( 10 ) ); - messagePanel.add( detailsButton ); - - messagePanel.setVisible( false ); //hidden by default. - - return messagePanel; - } - - private void showDetails() - { - JTextArea detailsTextArea = new JTextArea( ); - - detailsTextArea.setOpaque( true ); - detailsTextArea.setEditable( false ); - detailsTextArea.setBorder( null ); - - detailsTextArea.setLineWrap( false ); - detailsTextArea.setWrapStyleWord( true ); - - detailsTextArea.setText( message + "\n" + messageDetails ); - detailsTextArea.setCaretPosition( 0 ); //put the caret at the front. - - JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(detailsTextArea); - scrollPane.setPreferredSize( new Dimension( 400, 500 ) ); - - JOptionPane.showMessageDialog( mainPanel, scrollPane ); - } - - public void setMessage( String message, String messageDetails ) - { - this.messageDetails = messageDetails; - this.message = message; - - messageLabel.setText( message ); - - detailsButton.setVisible( messageDetails != null ); //only show the 'details' button if there are details - - messagePanel.setVisible( true ); - } - - public void hideMessage() - { - messagePanel.setVisible( false ); - } -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleUIAvailabilityObserver.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleUIAvailabilityObserver.java deleted file mode 100644 index fa51b39dcd2b..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleUIAvailabilityObserver.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.gradle.ui; - -import com.intellij.openapi.project.Project; -import org.gradle.openapi.external.ui.SinglePaneUIVersion1; - -/** - - This allows you to listen for the gradle UI coming and going. - - @author mhunsicker -*/ -public interface GradleUIAvailabilityObserver -{ - /** - Notification that the gradle UI has been loaded. - - - @param singlePaneUIVersion1 the main gradle UI object. - @param ideaProject - @author mhunsicker - */ - public void gradleUILoaded( SinglePaneUIVersion1 singlePaneUIVersion1, Project ideaProject ); - - /** - Notification that the gradle UI has been unloaded. - @author mhunsicker - */ - public void gradleUIUnloaded(); -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleUISettings.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleUISettings.java deleted file mode 100644 index 686d384edcae..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/GradleUISettings.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.gradle.ui; - -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.openapi.components.StorageScheme; -import com.intellij.openapi.project.Project; -import org.gradle.openapi.external.ui.SettingsNodeVersion1; -import org.jdom.Element; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - This is our Idea-side implementation of settings. We'll store them in - a hashmap and then write them out to the Idea project file using its - serialization mechanism. - - The actual settings are a hiearchy and are stored in instances of - GradleIdeaSettingsNode. This class basically holds onto the root node and - handles the serialization to/from Idea's project files. - - @author mhunsicker -*/ -@State( - name = "GradleUISettings", - storages = { - @Storage(id = "default", file = "$PROJECT_FILE$"), - @Storage(id = "dir", file = "$PROJECT_CONFIG_DIR$/gradle_config.xml", scheme = StorageScheme.DIRECTORY_BASED) - } -) -public class GradleUISettings implements PersistentStateComponent -{ - private GradleIdeaSettingsNode rootNode = new GradleIdeaSettingsNode( "root", null ); - private static final String SETTING = "setting"; - private static final String NAME = "name"; - private static final String VALUE = "value"; - - public GradleIdeaSettingsNode getRootNode() { return rootNode; } - - public Element getState() - { - Element e = new Element( SETTING ); - writeOutSetting(e, rootNode); - return e; - } - - public void loadState(Element element) - { - List settingsNodes = readInSetting( element, null ); - if( !settingsNodes.isEmpty() ) //this should have either 1 or none in it. - rootNode = settingsNodes.get( 0 ); - } - - public static GradleUISettings getInstance(final Project project) - { - return ServiceManager.getService(project, GradleUISettings.class); - } - - private void writeOutSetting( Element parentElement, GradleIdeaSettingsNode node ) - { - Element element = new Element( SETTING ); - parentElement.addContent( element ); - - element.setAttribute( NAME, node.getName() ); - if( node.getValue() != null ) - element.setAttribute( VALUE, node.getValue() ); - - for ( SettingsNodeVersion1 settingsNode : node.getChildNodes()) - writeOutSetting( element, (GradleIdeaSettingsNode)settingsNode ); - } - - /** - This does the real work of reading in settings. This recursively reads - them and because both the parent and children know about each other, we - have to track the children as we read them in. - - @author mhunsicker - */ - private List readInSetting( Element parentElement, GradleIdeaSettingsNode parentNode ) - { - List nodesReadIn = new ArrayList(); - - Iterator iterator = parentElement.getChildren( SETTING ).iterator(); - while( iterator.hasNext() ) - { - Element element = (Element) iterator.next(); - - String name = element.getAttributeValue( NAME ); - - GradleIdeaSettingsNode node = new GradleIdeaSettingsNode( name, parentNode ); - - String value = element.getAttributeValue( VALUE ); - if( value != null ) - node.setValue( value ); - - //read in our children - List myChildren = readInSetting( element, node ); - - //and store them - node.setChildren( myChildren ); - - nodesReadIn.add( node ); - } - - return nodesReadIn; - } -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/ObserverLord.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/ObserverLord.java deleted file mode 100644 index b2b7aae7ecbb..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/ObserverLord.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.gradle.ui; - -import javax.swing.SwingUtilities; -import java.util.List; -import java.util.ArrayList; -import java.util.Iterator; -import java.awt.EventQueue; - -/** - - This is a Swing-friendly observer manager class. Swing-friendly, but can be - used by non-Swing classes. Its meant to abstract the fact that you probably - need to be in the Event Dispatch Thread when receiving notifications inside - Swing-related classes. - - To use this class, add it as a member variable (don't derive from this!) - of a class that you want to be observered. You can have multiple instances - of this if you want to allow for a finer granularity of observing (similar - to components having mouse move listeners and mouse (click) listeners). - Next, create an interface for the observers. Now implement add and remove - observer functions that call the add and remove functions here. Lastly, - implement ObserverNotification and have it call the aforementioned observer - interface appropriately. Note: you should actually implement ObserverNotification - for each "message" you want to send. Example: One that would tell a view - a node was added. One that would tell a view a node was deleted, etc. - While you have multiple notification classes, you only need 1 (or few) - actual observer interfaces, containing all the possible functions called - by all notifications. - @author mhunsicker -*/ - -public class ObserverLord -{ - //////////////////////////////////////////////////////////////////////////// - //////////////////////////// member variables ////////////////////////////// - //////////////////////////////////////////////////////////////////////////// - private final List regularObservers = new ArrayList(); - private final List eventQueueObservers = new ArrayList(); - - - // - /** - Implement this for each call to ObserverLord.notifyObservers. The notify - function usually just has a single call to a function on the observer. - - Example: - - public void notify( MyObserver observer ) - { - observer.myfunction(); - } - - @author mhunsicker - */ - public interface ObserverNotification - { - public void notify( E observer ); - } - - - //////////////////////////////////////////////////////////////////////////// - ///////////////////////////////// methods ////////////////////////////////// - //////////////////////////////////////////////////////////////////////////// - - /** - Adds an observer to our messaging system. - - - @param observer observer to add. - @param inEventQueue true to notify this observer only in the event queue, - false to notify it immediately. - @author mhunsicker - */ - public void addObserver( E observer, boolean inEventQueue ) - { - if( !inEventQueue ) - addIfNew( observer, regularObservers ); - else - addIfNew( observer, eventQueueObservers ); - } - - private void addIfNew( E observer, List destinationList ) - { - if( !destinationList.contains( observer ) ) - destinationList.add( observer ); - } - - /** - Deletes an observer in our messaging system. - - - @param observer in, - - @author mhunsicker - */ - public void removeObserver( E observer ) - { - regularObservers.remove( observer ); - eventQueueObservers.remove( observer ); - } - - - public void removeAllObservers() - { - regularObservers.clear(); - eventQueueObservers.clear(); - } - - /** - Messaging method that handles telling each observer that something - happen to the observable. - - - @param notification in, notification sent to the observer - - @author mhunsicker - */ - public void notifyObservers( ObserverNotification notification ) - { - //notify all the non-event queue observers now. - notifyObserversInternal( regularObservers, notification ); - notifyObserversInEventQueueThread( notification ); - } - - /** - Here is where we notify all the event queue observers. To notify the event - queue observers we have to make sure it occurs in the event queue thread. If - we're not in the event queue, we'll wrap it in an invoke and wait. - - - - @param notification in, notification sent to the observer - - @author mhunsicker - */ - private void notifyObserversInEventQueueThread( final ObserverNotification notification ) - { - if( eventQueueObservers.size() == 0 ) //if we have no event queue observsers, we're done - return; - - if( EventQueue.isDispatchThread() ) - notifyObserversInternal( eventQueueObservers, notification ); - else - { - try - { - SwingUtilities.invokeAndWait( new Runnable() - { - public void run() - { - notifyObserversInternal( eventQueueObservers, notification ); - } - } ); - } - catch( Exception e ) - { - //System.out.println( "notifyObservers exception: " + e.toString() ); - e.printStackTrace(); - } - } - } - - /** - The internal mechanism that actually notifies the observers. We just - iterate though each observer and pass it to the notification mechanism. - - - - @param observers in, objects that changed (observable) - @param notification in, notification sent to the observer - - @author mhunsicker - */ - private void notifyObserversInternal( List observers, ObserverNotification notification ) - { - Iterator iterator = observers.iterator(); - while( iterator.hasNext() ) - { - E observer = iterator.next(); - try - { - notification.notify( observer ); - } - catch( Exception e ) //this is so an error in the notification doesn't stop the entire process. - { - e.printStackTrace(); - } - } - } - - public String toString() - { - return regularObservers.size() + " regular observers, " + eventQueueObservers.size() + " event queue observers"; - } -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/ShowGradleUIAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/ShowGradleUIAction.java deleted file mode 100644 index 10ed49761af1..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/ui/ShowGradleUIAction.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.gradle.ui; - -import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataKeys; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.project.ProjectManagerAdapter; -import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.util.Disposer; -import org.gradle.openapi.external.ui.SettingsNodeVersion1; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.gradle.GradleLibraryPresentationProvider; - -import javax.swing.*; -import java.awt.*; - -//this shows the gradle UI if its not already visible -public class ShowGradleUIAction extends AnAction implements DumbAware { - - public void actionPerformed(AnActionEvent e) { - new GradleUiDialog(e.getData(DataKeys.PROJECT), e.getData(DataKeys.MODULE)).show(); - } - - @Override - public void update(AnActionEvent e) { - boolean enabled = isEnabled(e); - e.getPresentation().setEnabled(enabled); - e.getPresentation().setVisible(enabled); - } - - private static boolean isEnabled(AnActionEvent e) { - if (!"true".equals(System.getProperty("gradle.ui.action"))) { - return false; - } - - Project project = e.getData(DataKeys.PROJECT); - return project != null && GradleLibraryPresentationProvider.getSdkHome(e.getData(DataKeys.MODULE), project) != null; - } - - private static class GradleUiDialog extends DialogWrapper { - private static final String MAIN_COMPONENT_AS_DIALOG = "main-component-as-dialog"; - private static final String LOCATION_Y = "location-y"; - private static final String LOCATION_X = "location-x"; - private static final String HEIGHT = "height"; - private static final String WIDTH = "width"; - - private final GradlePanelWrapper myGradlePanelWrapper; - private Boolean canClose; - private final Project myProject; - - public GradleUiDialog(final Project project, @Nullable final Module module) { - super(project); - myProject = project; - myGradlePanelWrapper = new GradlePanelWrapper(); - myGradlePanelWrapper.initalize(module, project); - Disposer.register(getDisposable(), new Disposable() { - public void dispose() { - saveSettings(project); - myGradlePanelWrapper.close(); - } - }); - setModal(false); - setSize(400, 700); - setTitle("Gradle"); - - ProjectManager.getInstance().addProjectManagerListener(project, new ProjectManagerAdapter() { - public boolean canCloseProject(Project project) { - if (canClose == null) { - canClose = myGradlePanelWrapper.canClose(); - } - return canClose; - } - }); - - init(); - } - - @Override - public void show() { - super.show(); - restoreSettings(myProject); - } - - @Override - protected JComponent createCenterPanel() { - JPanel panel = new JPanel(new BorderLayout()); - panel.add(myGradlePanelWrapper.getComponent()); - panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - return panel; - } - - - //this restores the location and size of the dialog - private void restoreSettings(Project project) { - GradleUISettings gradleUISettings = GradleUISettings.getInstance(project); - SettingsNodeVersion1 settingsNode = gradleUISettings.getRootNode().getChildNode(MAIN_COMPONENT_AS_DIALOG); - if (settingsNode != null) { - int x = settingsNode.getValueOfChildAsInt(LOCATION_X, getLocation().x); - int y = settingsNode.getValueOfChildAsInt(LOCATION_Y, getLocation().y); - int width = settingsNode.getValueOfChildAsInt(WIDTH, getSize().width); - int height = settingsNode.getValueOfChildAsInt(HEIGHT, getSize().height); - - setLocation(x, y); - setSize(width, height); - } - } - - //this restores the location and size of the dialog - private void saveSettings(Project project) { - GradleUISettings gradleUISettings = GradleUISettings.getInstance(project); - SettingsNodeVersion1 settingsNode = gradleUISettings.getRootNode().addChildIfNotPresent(MAIN_COMPONENT_AS_DIALOG); - - settingsNode.setValueOfChildAsInt(LOCATION_X, getLocation().x); - settingsNode.setValueOfChildAsInt(LOCATION_Y, getLocation().y); - settingsNode.setValueOfChildAsInt(WIDTH, getSize().width); - settingsNode.setValueOfChildAsInt(HEIGHT, getSize().height); - } - - } -} From 1cce9d2cba4c755440137bfbf7ad7555ccbbaebc Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 09:34:15 +0100 Subject: [PATCH 30/94] remove gradle-open-api jar as well --- plugins/groovy/lib/gradle-open-api-0.8.jar | Bin 17420 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 plugins/groovy/lib/gradle-open-api-0.8.jar diff --git a/plugins/groovy/lib/gradle-open-api-0.8.jar b/plugins/groovy/lib/gradle-open-api-0.8.jar deleted file mode 100644 index 7d1f06cc6ffd1bb23588985e86d492fedafc3f02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17420 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 From b78dd557e654554e821f4dd2250e3b5b2ce76416 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 4 Feb 2011 12:03:48 +0300 Subject: [PATCH 31/94] GrEnumConstant extends PsiEnumConstant --- .../JavaChangeSignatureUsageProcessor.java | 1 + .../JavaChangeSignatureUsageSearcher.java | 2 +- .../IntroduceConstantDialog.java | 4 +++ ...troduceParameterMethodUsagesProcessor.java | 3 +- .../refactoring/util/RefactoringUtil.java | 6 +++- .../statements/arguments/GrArgumentList.java | 5 ++-- .../typedef/members/GrEnumConstant.java | 17 +++++------ .../arguments/GrArgumentListImpl.java | 14 ++++++++++ .../enumConstant/GrEnumConstantImpl.java | 28 ++++++++++++++++++- .../plugins/groovy/lang/psi/util/PsiUtil.java | 1 + .../groovy/lang/GroovyHighlightingTest.java | 7 ++++- .../highlighting/GroovyEnumInJavaFile.groovy | 3 ++ .../highlighting/GroovyEnumInJavaFile.java | 13 +++++++++ 13 files changed, 89 insertions(+), 15 deletions(-) create mode 100644 plugins/groovy/testdata/highlighting/GroovyEnumInJavaFile.groovy create mode 100644 plugins/groovy/testdata/highlighting/GroovyEnumInJavaFile.java diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java index 794f1eb25189..d96fe3c2a720 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java @@ -227,6 +227,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr final PsiMethod caller = RefactoringUtil.getEnclosingMethod(ref); if (toChangeArguments) { final PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(ref); + LOG.assertTrue(list != null); boolean toInsertDefaultValue = needDefaultValue(changeInfo, caller); if (toInsertDefaultValue && ref instanceof PsiReferenceExpression) { final PsiExpression qualifierExpression = ((PsiReferenceExpression)ref).getQualifierExpression(); diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageSearcher.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageSearcher.java index 9aa7f16d1cfb..bb9ae51d0988 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageSearcher.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageSearcher.java @@ -209,7 +209,7 @@ class JavaChangeSignatureUsageSearcher { if (!isToCatchExceptions) { if (RefactoringUtil.isMethodUsage(element)) { PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(element); - if (!method.isVarArgs() && list.getExpressions().length != parameterCount) continue; + if (list == null || !method.isVarArgs() && list.getExpressions().length != parameterCount) continue; } } if (RefactoringUtil.isMethodUsage(element)) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java index 2155275be5a3..c61a82d31b32 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java @@ -46,6 +46,7 @@ import com.intellij.refactoring.util.RefactoringMessageUtil; import com.intellij.ui.RecentsManager; import com.intellij.ui.ReferenceEditorComboWithBrowseButton; import com.intellij.ui.StateRestoringCheckBox; +import com.intellij.usageView.UsageViewUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.ui.UIUtil; import gnu.trove.THashSet; @@ -396,6 +397,9 @@ class IntroduceConstantDialog extends DialogWrapper { errorString = RefactoringBundle.message("no.field.name.specified"); } else if (!JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(fieldName)) { errorString = RefactoringMessageUtil.getIncorrectIdentifierMessage(fieldName); + } else if (!myParentClass.getLanguage().equals(newClass.getLanguage())) { + errorString = RefactoringBundle.message("move.to.different.language", UsageViewUtil.getType(myParentClass), + myParentClass.getQualifiedName(), newClass.getQualifiedName()); } if (errorString != null) { CommonRefactoringUtil.showErrorMessage( diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java index 29fafed6a148..4d5e856e148a 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java @@ -60,6 +60,7 @@ public class JavaIntroduceParameterMethodUsagesProcessor implements IntroducePar final PsiElement ref = usage.getElement(); PsiCall callExpression = RefactoringUtil.getCallExpressionByMethodReference(ref); PsiExpressionList argList = RefactoringUtil.getArgumentListByMethodReference(ref); + if (argList == null) return true; PsiExpression[] oldArgs = argList.getExpressions(); final PsiExpression anchor; @@ -261,4 +262,4 @@ public class JavaIntroduceParameterMethodUsagesProcessor implements IntroducePar processChangeMethodUsage(data, new ExternalUsageInfo(((PsiMethodCallExpression)superCall.getExpression()).getMethodExpression()), usages); return false; } -} \ No newline at end of file +} diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java index 46f592b0f222..62a71a3d7752 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.ExpectedTypeInfo; import com.intellij.codeInsight.ExpectedTypesProvider; import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil; import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.lang.StdLanguages; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; @@ -618,7 +619,9 @@ public class RefactoringUtil { } public static boolean isMethodUsage(PsiElement element) { - if (element instanceof PsiEnumConstant) return true; + if (element instanceof PsiEnumConstant) { + return StdLanguages.JAVA.equals(element.getLanguage()); + } if (!(element instanceof PsiJavaCodeReferenceElement)) return false; PsiElement parent = element.getParent(); if (parent instanceof PsiCall) { @@ -630,6 +633,7 @@ public class RefactoringUtil { return false; } + @Nullable public static PsiExpressionList getArgumentListByMethodReference(PsiElement ref) { if (ref instanceof PsiEnumConstant) return ((PsiEnumConstant)ref).getArgumentList(); PsiElement parent = ref.getParent(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/arguments/GrArgumentList.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/arguments/GrArgumentList.java index 87fe82c282a7..8c6599a14b05 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/arguments/GrArgumentList.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/arguments/GrArgumentList.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpressionList; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -28,7 +29,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.util.GrNamedArgumentsOwner; * @author ilyas * Plain Argumanet list with parentheses. Cannot contain closure arguments, they are placed outside. */ -public interface GrArgumentList extends GroovyPsiElement, GrNamedArgumentsOwner { +public interface GrArgumentList extends GroovyPsiElement, GrNamedArgumentsOwner, PsiExpressionList { @NotNull GrExpression[] getExpressionArguments(); @NotNull PsiElement[] getAllArguments(); @@ -49,4 +50,4 @@ public interface GrArgumentList extends GroovyPsiElement, GrNamedArgumentsOwner GrExpression removeArgument(int argNumber); GrNamedArgument addNamedArgument(GrNamedArgument namedArgument); -} \ No newline at end of file +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/typedef/members/GrEnumConstant.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/typedef/members/GrEnumConstant.java index c8dc617d7629..9151b4e76d10 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/typedef/members/GrEnumConstant.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/typedef/members/GrEnumConstant.java @@ -16,22 +16,23 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members; -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import com.intellij.psi.PsiEnumConstant; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrConstructorCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; -import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; -import org.jetbrains.annotations.NotNull; -import com.intellij.psi.PsiMethod; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrConstructorCall; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody; /** * @author: Dmitry.Krasilschikov * @date: 06.04.2007 */ -public interface GrEnumConstant extends GrField, GrConstructorCall { +public interface GrEnumConstant extends GrField, GrConstructorCall, PsiEnumConstant { GrEnumConstant[] EMPTY_ARRAY = new GrEnumConstant[0]; + @Nullable GrTypeDefinitionBody getAnonymousBlock(); + + @Override + GrArgumentList getArgumentList(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentListImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentListImpl.java index d3d6d082f15f..6e8711f499fb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentListImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentListImpl.java @@ -18,6 +18,8 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.arguments; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiType; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.impl.source.tree.TreeUtil; import com.intellij.util.ArrayUtil; @@ -222,4 +224,16 @@ public class GrArgumentListImpl extends GroovyPsiElementImpl implements GrArgume } super.deleteChildInternal(child); } + + @NotNull + @Override + public PsiExpression[] getExpressions() { + return PsiExpression.EMPTY_ARRAY; + } + + @NotNull + @Override + public PsiType[] getExpressionTypes() { + return PsiType.EMPTY_ARRAY; + } } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/enumConstant/GrEnumConstantImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/enumConstant/GrEnumConstantImpl.java index 5f34461a15cd..e7b8011160cf 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/enumConstant/GrEnumConstantImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/enumConstant/GrEnumConstantImpl.java @@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; @@ -110,6 +111,7 @@ public class GrEnumConstantImpl extends GrFieldImpl implements GrEnumConstant, P private GroovyResolveResult[] multiResolveConstructorImpl(boolean allVariants) { PsiType[] argTypes = PsiUtil.getArgumentTypes(getFirstChild(), false); PsiClass clazz = getContainingClass(); + assert clazz != null; PsiType thisType = JavaPsiFacade.getInstance(getProject()).getElementFactory().createType(clazz, PsiSubstitutor.EMPTY); MethodResolverProcessor processor = new MethodResolverProcessor(clazz.getName(), this, true, thisType, argTypes, PsiType.EMPTY_ARRAY, allVariants); @@ -128,13 +130,25 @@ public class GrEnumConstantImpl extends GrFieldImpl implements GrEnumConstant, P return findChildByClass(GrArgumentList.class); } + @Override + public PsiEnumConstantInitializer getInitializingClass() { + return null; + } + public GrExpression removeArgument(final int number) { final GrArgumentList list = getArgumentList(); return list != null ? list.removeArgument(number) : null; } public GrNamedArgument addNamedArgument(final GrNamedArgument namedArgument) throws IncorrectOperationException { - return null; + GrArgumentList list = getArgumentList(); + assert list != null; + if (list.getText().trim().length() == 0) { + final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(getProject()); + final GrArgumentList newList = factory.createArgumentList(); + list = (GrArgumentList)list.replace(newList); + } + return list.addNamedArgument(namedArgument); } @Override @@ -167,6 +181,13 @@ public class GrEnumConstantImpl extends GrFieldImpl implements GrEnumConstant, P return PsiImplUtil.extractUniqueElement(multiResolveConstructor()); } + @NotNull + @Override + public JavaResolveResult resolveMethodGenerics() { + return JavaResolveResult.EMPTY; + } + + @Nullable public GrTypeDefinitionBody getAnonymousBlock() { return findChildByClass(GrTypeDefinitionBody.class); } @@ -224,4 +245,9 @@ public class GrEnumConstantImpl extends GrFieldImpl implements GrEnumConstant, P public boolean isSoft() { return false; } + + @Override + public PsiMethod resolveConstructor() { + return resolveMethod(); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java index 4b91a7797960..dd9f84712b30 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java @@ -176,6 +176,7 @@ public class PsiUtil { @Nullable public static GrArgumentList getArgumentsList(PsiElement methodRef) { + if (methodRef instanceof GrEnumConstant) return ((GrEnumConstant)methodRef).getArgumentList(); PsiElement parent = methodRef.getParent(); if (parent instanceof GrCall) { return ((GrCall)parent).getArgumentList(); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java index ced93ecfc6cb..f760de060c87 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java @@ -309,12 +309,17 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase { public void testWrongAnnotation() {doTest();} public void testAmbiguousMethods() { - myFixture.copyFileToProject(getTestName(false)+".java"); + myFixture.copyFileToProject(getTestName(false) + ".java"); doTest(); } public void testMapParamWithNoArgs() {doTest(new GroovyAssignabilityCheckInspection());} + public void testGroovyEnumInJavaFile() { + myFixture.copyFileToProject(getTestName(false)+".groovy"); + myFixture.testHighlighting(true, false, false, getTestName(false) + ".java"); + } + public void testRangeType() { doTest(new GroovyRangeTypeCheckInspection()); } diff --git a/plugins/groovy/testdata/highlighting/GroovyEnumInJavaFile.groovy b/plugins/groovy/testdata/highlighting/GroovyEnumInJavaFile.groovy new file mode 100644 index 000000000000..547a2395f503 --- /dev/null +++ b/plugins/groovy/testdata/highlighting/GroovyEnumInJavaFile.groovy @@ -0,0 +1,3 @@ +enum MyEnum { + E1, E2, E3 +} diff --git a/plugins/groovy/testdata/highlighting/GroovyEnumInJavaFile.java b/plugins/groovy/testdata/highlighting/GroovyEnumInJavaFile.java new file mode 100644 index 000000000000..0f80c596ebc5 --- /dev/null +++ b/plugins/groovy/testdata/highlighting/GroovyEnumInJavaFile.java @@ -0,0 +1,13 @@ +class MyJavaClass { + public static void main(String[] args) { + for (MyEnum e : MyEnum.values()) { + switch (e) { + case E1: + System.out.println("E1"); + break; + case E4: + System.out.println("fail"); + } + } + } +} From b5aa94bed0d2b0e62323f9e9487683897fefa942 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 4 Feb 2011 12:10:40 +0300 Subject: [PATCH 32/94] more licenses for libs added --- build/scripts/libLicenses.gant | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant index 0113c6c31625..2449222cde3a 100644 --- a/build/scripts/libLicenses.gant +++ b/build/scripts/libLicenses.gant @@ -7,11 +7,15 @@ class LibraryLicense { List licensesList = [] List jetbrainsLibraries = ["tcServiceMessages"] +Map predefinedLicenseUrls = ["Apache 2.0": "http://www.apache.org/licenses/LICENSE-2.0"] binding.setVariable("libraryLicense", {Map args -> if (args.libraryName == null) { args.libraryName = args.name; } + if (args.licenseUrl == null) { + args.licenseUrl = predefinedLicenseUrls[args.license] + } licensesList << new LibraryLicense(args) }) @@ -108,7 +112,8 @@ libraryLicense(name: "Automaton", libraryName: "automaton.jar", version: "1.11", libraryLicense(name: "DTDParser", version: "1.13", license: "LGPL", url: "http://sourceforge.net/projects/dtdparser/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1") libraryLicense(name: "Ganymed", version: "bundled with SVNKit", license: "BSD", url: "http://www.ganymed.ethz.ch/ssh2/", licenseUrl: "http://www.ganymed.ethz.ch/ssh2/LICENSE.txt") libraryLicense(name: "Guava", version: "R6", license: "Apache 2.0", url: "http://code.google.com/p/guava-libraries/", licenseUrl: "http://ant.apache.org/license.html") -libraryLicense(name: "Groovy", version: "1.7.3", license: "Apache 2.0", url: "http://groovy.codehaus.org/", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.html") +libraryLicense(name: "Gradle API", libraryName: "gradle-open-api-0.8.jar", version: "0.8", license: "Apache 2.0", url: "http://www.gradle.org/") +libraryLicense(name: "Groovy", version: "1.7.3", license: "Apache 2.0", url: "http://groovy.codehaus.org/") libraryLicense(name: "JavaCVS", version: "no version number available (with patches by JetBrains)", license: "Sun Public License", url: "http://javacvs.netbeans.org/library/", licenseUrl: "http://www.netbeans.org/about/legal/spl.html") libraryLicense(name: "Jaxen", version: "", license: "modified Apache", url: "http://www.jaxen.org/", licenseUrl: "http://www.jaxen.org/license.html") libraryLicense(name: "JavaHelp", version: "2.0_02", license: "included as license/javahelp_license.html in IntelliJ IDEA distribution", url: "http://java.sun.com/products/javahelp/") From d51252bce277a1990151a3e4bdc6073342967b78 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 4 Feb 2011 12:55:17 +0300 Subject: [PATCH 33/94] GrGetPsiTypeAction: don't show anything if there is no expression --- .../org/jetbrains/plugins/groovy/actions/GrGetPsiTypeAction.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/GrGetPsiTypeAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/GrGetPsiTypeAction.java index 3cd8ebb4982c..5d3ea3c43ba8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/GrGetPsiTypeAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/GrGetPsiTypeAction.java @@ -56,6 +56,7 @@ public class GrGetPsiTypeAction extends AnAction implements DumbAware { int offset = editor.getCaretModel().getOffset(); List expressions = GrIntroduceHandlerBase.collectExpressions(psiFile, editor, offset); + if (expressions.size() == 0) return; if (expressions.size() == 1) { passInner(expressions.get(0)); } From 59106cf0682b181ddc91759658016f9da10a0f92 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 4 Feb 2011 13:27:22 +0300 Subject: [PATCH 34/94] fixed groovy layout --- build/scripts/layouts.gant | 1 - 1 file changed, 1 deletion(-) diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index d60883c52939..fc5d672873e1 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -302,7 +302,6 @@ def layoutFull(String home, String targetDirectory) { fileset(dir: "$home/plugins/groovy/resources/conf") - fileset(dir: "${home}/plugins/groovy/lib") } } From a5954a398670bc37a1b25e82f96bcb53f0b84c2b Mon Sep 17 00:00:00 2001 From: Alexey Gopachenko Date: Fri, 4 Feb 2011 00:44:40 +0100 Subject: [PATCH 35/94] Spellchecker add word 'blog' and forms to jetbrains.dic --- .../spellchecker/src/com/intellij/spellchecker/jetbrains.dic | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic index 8cf5d92150de..e1f27db01dae 100644 --- a/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic +++ b/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic @@ -21,6 +21,9 @@ bigfile bigint binlog bool +blog +blogger +blogging btree calc callee From 28c89d2f3129e8dbfc6dc32cf078c07eb2ad72f0 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 4 Feb 2011 13:41:35 +0300 Subject: [PATCH 36/94] GrLightParameter has Groovy language --- .../src/com/intellij/psi/impl/light/LightFieldBuilder.java | 3 ++- .../com/intellij/psi/impl/light/LightMethodBuilder.java | 2 +- .../src/com/intellij/psi/impl/light/LightParameter.java | 5 +++-- .../com/intellij/psi/impl/light/LightVariableBuilder.java | 7 ++++--- .../groovy/lang/psi/impl/synthetic/GrLightParameter.java | 6 ++++-- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/light/LightFieldBuilder.java b/java/java-impl/src/com/intellij/psi/impl/light/LightFieldBuilder.java index 23b717de8240..fb45938f5a31 100644 --- a/java/java-impl/src/com/intellij/psi/impl/light/LightFieldBuilder.java +++ b/java/java-impl/src/com/intellij/psi/impl/light/LightFieldBuilder.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.impl.light; +import com.intellij.lang.StdLanguages; import com.intellij.psi.*; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.util.IncorrectOperationException; @@ -40,7 +41,7 @@ public class LightFieldBuilder extends LightVariableBuilder i } public LightFieldBuilder(PsiManager manager, @NotNull String name, @NotNull PsiType type) { - super(manager, name, type); + super(manager, name, type, StdLanguages.JAVA); } public LightFieldBuilder setContainingClass(PsiClass psiClass) { diff --git a/java/java-impl/src/com/intellij/psi/impl/light/LightMethodBuilder.java b/java/java-impl/src/com/intellij/psi/impl/light/LightMethodBuilder.java index 85b7befa599e..b44a048601d4 100644 --- a/java/java-impl/src/com/intellij/psi/impl/light/LightMethodBuilder.java +++ b/java/java-impl/src/com/intellij/psi/impl/light/LightMethodBuilder.java @@ -180,7 +180,7 @@ public class LightMethodBuilder extends LightElement implements PsiMethod { } public LightMethodBuilder addParameter(@NotNull String name, @NotNull PsiType type) { - return addParameter(new LightParameter(name, type, this)); + return addParameter(new LightParameter(name, type, this, StdLanguages.JAVA)); } @NotNull diff --git a/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java b/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java index 4a71886e16a0..2a8f1ad18082 100644 --- a/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java +++ b/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java @@ -1,5 +1,6 @@ package com.intellij.psi.impl.light; +import com.intellij.lang.Language; import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; @@ -11,8 +12,8 @@ public class LightParameter extends LightVariableBuilder implements PsiParameter private final String myName; private final PsiElement myDeclarationScope; - public LightParameter(@NotNull String name, @NotNull PsiType type, PsiElement declarationScope) { - super(declarationScope.getManager(), name, type); + public LightParameter(@NotNull String name, @NotNull PsiType type, PsiElement declarationScope, Language language) { + super(declarationScope.getManager(), name, type, language); myName = name; myDeclarationScope = declarationScope; } diff --git a/java/java-impl/src/com/intellij/psi/impl/light/LightVariableBuilder.java b/java/java-impl/src/com/intellij/psi/impl/light/LightVariableBuilder.java index aa537cd501b5..8896fde46688 100644 --- a/java/java-impl/src/com/intellij/psi/impl/light/LightVariableBuilder.java +++ b/java/java-impl/src/com/intellij/psi/impl/light/LightVariableBuilder.java @@ -1,5 +1,6 @@ package com.intellij.psi.impl.light; +import com.intellij.lang.Language; import com.intellij.lang.StdLanguages; import com.intellij.psi.*; import com.intellij.psi.impl.ElementPresentationUtil; @@ -25,12 +26,12 @@ public class LightVariableBuilder extends LightE } public LightVariableBuilder(@NotNull String name, @NotNull PsiType type, @NotNull PsiElement navigationElement) { - this(navigationElement.getManager(), name, type); + this(navigationElement.getManager(), name, type, StdLanguages.JAVA); setNavigationElement(navigationElement); } - public LightVariableBuilder(PsiManager manager, @NotNull String name, @NotNull PsiType type) { - super(manager, StdLanguages.JAVA); + public LightVariableBuilder(PsiManager manager, @NotNull String name, @NotNull PsiType type, Language language) { + super(manager, language); myName = name; myType = type; myModifierList = new LightModifierList(manager); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightParameter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightParameter.java index 46a4d1f59e5a..c66b1c4ace11 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightParameter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightParameter.java @@ -21,7 +21,9 @@ import com.intellij.psi.impl.light.LightParameter; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; @@ -34,7 +36,7 @@ public class GrLightParameter extends LightParameter implements GrParameter { private volatile boolean myOptional; public GrLightParameter(@NotNull String name, @NotNull PsiType type, PsiElement scope) { - super(name, type, scope); + super(name, type, scope, GroovyFileType.GROOVY_LANGUAGE); } public GrTypeElement getTypeElementGroovy() { @@ -63,7 +65,7 @@ public class GrLightParameter extends LightParameter implements GrParameter { @NotNull public PsiElement getNameIdentifierGroovy() { - return null; + return GroovyPsiElementFactory.getInstance(getProject()).createReferenceNameFromText(getName()); } public PsiType getTypeGroovy() { From 9687777679998d83f21e04278d6ad8f927e80f65 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 1 Feb 2011 14:53:10 +0300 Subject: [PATCH 37/94] fixed sporadic test failures in light fixtures --- .../fixtures/impl/JavaCodeInsightTestFixtureImpl.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java index 363caf601ddf..c14dff95cc19 100644 --- a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java +++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java @@ -19,6 +19,7 @@ import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.impl.PsiModificationTrackerImpl; import com.intellij.psi.search.ProjectScope; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture; @@ -51,7 +52,7 @@ public class JavaCodeInsightTestFixtureImpl extends CodeInsightTestFixtureImpl i return psiClass; } - private PsiClass addClass(@NonNls final String rootPath, @NotNull @NonNls final String classText) throws IOException { + private PsiClass addClass(@NonNls final String rootPath, @NotNull @NonNls final String classText) { final PsiClass aClass = ((PsiJavaFile)PsiFileFactory.getInstance(getProject()).createFileFromText("a.java", classText)).getClasses()[0]; final String qName = aClass.getQualifiedName(); assert qName != null; @@ -65,6 +66,13 @@ public class JavaCodeInsightTestFixtureImpl extends CodeInsightTestFixtureImpl i return ((PsiJavaFile)psiFile).getClasses()[0]; } + @Override + protected PsiFile addFileToProject(String rootPath, String relativePath, String fileText) { + PsiFile file = super.addFileToProject(rootPath, relativePath, fileText); + ((PsiModificationTrackerImpl)PsiManager.getInstance(getProject()).getModificationTracker()).incCounter(); + return file; + } + @Override @NotNull public PsiClass findClass(@NotNull @NonNls final String name) { From 4020ca6f89f901c10fd89e4d633892c9c201c78c Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 1 Feb 2011 15:38:36 +0300 Subject: [PATCH 38/94] println removed --- .../src/com/intellij/usages/impl/UsageViewManagerImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java index efcfe5b3c918..1b04bb297082 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java @@ -323,8 +323,6 @@ public class UsageViewManagerImpl extends UsageViewManager { if (usageView != null) { usageView.appendUsageLater(usage); } - - if (usageCount % 100 == 0) System.out.println("usageCount = " + usageCount); } return indicator == null || !indicator.isCanceled(); } From 707e4b61774bc6b64cc928573fa16823b66a4311 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 2 Feb 2011 14:58:22 +0300 Subject: [PATCH 39/94] clear cached injected fragments after visiting file during inspection --- .../reference/RefClassImpl.java | 13 +- .../com/intellij/analysis/AnalysisScope.java | 15 ++- .../src/com/intellij/psi/PsiManager.java | 2 +- .../ex/GlobalInspectionContextImpl.java | 5 +- .../reference/RefManagerImpl.java | 1 + .../injected/editor/EditorWindow.java | 6 +- .../src/com/intellij/mock/MockPsiManager.java | 7 +- .../BackwardDependenciesBuilder.java | 1 + .../ForwardDependenciesBuilder.java | 1 + .../psi/impl/AnyPsiChangeListener.java | 21 ++++ .../com/intellij/psi/impl/PsiManagerEx.java | 2 - .../com/intellij/psi/impl/PsiManagerImpl.java | 119 +++++++++--------- .../tree/injected/InjectedLanguageUtil.java | 28 ++++- .../tree/injected/MultiHostRegistrarImpl.java | 2 +- 14 files changed, 146 insertions(+), 77 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/psi/impl/AnyPsiChangeListener.java diff --git a/java/java-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java b/java/java-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java index f795a456d373..bccbd456a2ef 100644 --- a/java/java-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java +++ b/java/java-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java @@ -154,7 +154,7 @@ public class RefClassImpl extends RefJavaElementImpl implements RefClass { } } - if (getConstructors().size() == 0 && !isInterface() && !isAnonymous()) { + if (getConstructors().isEmpty() && !isInterface() && !isAnonymous()) { RefImplicitConstructorImpl refImplicitConstructor = new RefImplicitConstructorImpl(this); setDefaultConstructor(refImplicitConstructor); addConstructor(refImplicitConstructor); @@ -173,7 +173,12 @@ public class RefClassImpl extends RefJavaElementImpl implements RefClass { final PsiClass applet = getRefJavaManager().getApplet(); setApplet(applet != null && psiClass.isInheritor(applet, true)); getRefManager().fireNodeInitialized(this); - getRefManager().getPsiManager().dropResolveCaches(); + PsiManager psiManager = getRefManager().getPsiManager(); + psiManager.dropResolveCaches(); + PsiFile file = psiClass.getContainingFile(); + if (file != null) { + psiManager.dropFileCaches(file); + } } private void initializeSuperReferences(PsiClass psiClass) { @@ -434,7 +439,7 @@ public class RefClassImpl extends RefJavaElementImpl implements RefClass { if (super.isReferenced()) return true; if (isInterface() || isAbstract()) { - if (getSubClasses().size() > 0) return true; + if (!getSubClasses().isEmpty()) return true; } return false; @@ -444,7 +449,7 @@ public class RefClassImpl extends RefJavaElementImpl implements RefClass { if (super.hasSuspiciousCallers()) return true; if (isInterface() || isAbstract()) { - if (getSubClasses().size() > 0) return true; + if (!getSubClasses().isEmpty()) return true; } return false; diff --git a/platform/lang-api/src/com/intellij/analysis/AnalysisScope.java b/platform/lang-api/src/com/intellij/analysis/AnalysisScope.java index c1666f866ab0..9460a5791b6b 100644 --- a/platform/lang-api/src/com/intellij/analysis/AnalysisScope.java +++ b/platform/lang-api/src/com/intellij/analysis/AnalysisScope.java @@ -341,18 +341,23 @@ public class AnalysisScope { if (needReadAction) { PsiDocumentManager.getInstance(psiManager.getProject()).commitAndRunReadAction(new Runnable(){ public void run() { - file.accept(visitor); - psiManager.dropResolveCaches(); + doProcessFile(visitor, psiManager, file); } }); - } else { - file.accept(visitor); - psiManager.dropResolveCaches(); + } + else { + doProcessFile(visitor, psiManager, file); } final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); return indicator == null || !indicator.isCanceled(); } + private static void doProcessFile(PsiElementVisitor visitor, PsiManager psiManager, PsiFile file) { + file.accept(visitor); + psiManager.dropResolveCaches(); + psiManager.dropFileCaches(file); + } + protected void accept(@NotNull final PsiDirectory dir, @NotNull final PsiElementVisitor visitor, final boolean needReadAction) { final Project project = dir.getProject(); final PsiManager psiManager = PsiManager.getInstance(project); diff --git a/platform/lang-api/src/com/intellij/psi/PsiManager.java b/platform/lang-api/src/com/intellij/psi/PsiManager.java index 0d68c4039e4c..2b15ca422656 100644 --- a/platform/lang-api/src/com/intellij/psi/PsiManager.java +++ b/platform/lang-api/src/com/intellij/psi/PsiManager.java @@ -33,7 +33,6 @@ import org.jetbrains.annotations.Nullable; * The main entry point for accessing the PSI services for a project. */ public abstract class PsiManager extends UserDataHolderBase { - /** * Returns the PSI manager instance for the specified project. * @@ -239,4 +238,5 @@ public abstract class PsiManager extends UserDataHolderBase { public abstract void unregisterLanguageInjector(@NotNull LanguageInjector injector); + public abstract void dropFileCaches(@NotNull PsiFile file); } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java index 095d0ab7fae2..731cc9c3faf9 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java @@ -82,7 +82,7 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext { private ProgressIndicator myProgressIndicator; public static final JobDescriptor BUILD_GRAPH = new JobDescriptor(InspectionsBundle.message("inspection.processing.job.descriptor")); - public static final JobDescriptor[] BUILD_GRAPH_ONLY = new JobDescriptor[]{BUILD_GRAPH}; + public static final JobDescriptor[] BUILD_GRAPH_ONLY = {BUILD_GRAPH}; public static final JobDescriptor FIND_EXTERNAL_USAGES = new JobDescriptor(InspectionsBundle.message("inspection.processing.job.descriptor1")); @@ -557,6 +557,9 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext { catch (Exception e) { LOG.error(e); } + finally { + psiManager.dropFileCaches(file); + } } }); } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java index 9ce501903031..2e208934ee8c 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java @@ -373,6 +373,7 @@ public class RefManagerImpl extends RefManager { visitElement(viewProvider.getPsi(language)); } myPsiManager.dropResolveCaches(); + myPsiManager.dropFileCaches(file); } } diff --git a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java index 0f3fc9df5e16..9dc07440394e 100644 --- a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java +++ b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java @@ -109,20 +109,20 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx { if (!editorWindow.isValid()/* || myDocumentWindow.intersects(editorWindow.myDocumentWindow)*/) { editorWindow.dispose(); - InjectedLanguageUtil.clearCaches(editorWindow.getInjectedFile()); + InjectedLanguageUtil.clearCaches(editorWindow.myInjectedFile, editorWindow.getDocument()); iterator.remove(); } } } private boolean isValid() { - return !isDisposed() && myInjectedFile.isValid() && myDocumentWindow.isValid(); + return !isDisposed() && !myInjectedFile.getProject().isDisposed() && myInjectedFile.isValid() && myDocumentWindow.isValid(); } public PsiFile getInjectedFile() { return myInjectedFile; } - public LogicalPosition hostToInjected(LogicalPosition pos) { + public LogicalPosition hostToInjected(@NotNull LogicalPosition pos) { assert isValid(); int offsetInInjected = myDocumentWindow.hostToInjected(myDelegate.logicalPositionToOffset(pos)); return offsetToLogicalPosition(offsetInInjected); diff --git a/platform/lang-impl/src/com/intellij/mock/MockPsiManager.java b/platform/lang-impl/src/com/intellij/mock/MockPsiManager.java index 5e6de80d5fc7..cec66b954e41 100644 --- a/platform/lang-impl/src/com/intellij/mock/MockPsiManager.java +++ b/platform/lang-impl/src/com/intellij/mock/MockPsiManager.java @@ -186,6 +186,10 @@ public class MockPsiManager extends PsiManagerEx { } + @Override + public void dropFileCaches(@NotNull PsiFile file) { + } + public void postponeAutoFormattingInside(Runnable runnable) { PostprocessReformattingAspect.getInstance(getProject()).postponeFormattingInside(runnable); } @@ -222,9 +226,6 @@ public class MockPsiManager extends PsiManagerEx { public void registerRunnableToRunOnChange(@NotNull Runnable runnable) { } - public void registerWeakRunnableToRunOnChange(@NotNull Runnable runnable) { - } - public void registerRunnableToRunOnAnyChange(@NotNull Runnable runnable) { } diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/BackwardDependenciesBuilder.java b/platform/lang-impl/src/com/intellij/packageDependencies/BackwardDependenciesBuilder.java index a5dc7851ff7a..9da752607c63 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/BackwardDependenciesBuilder.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/BackwardDependenciesBuilder.java @@ -113,6 +113,7 @@ public class BackwardDependenciesBuilder extends DependenciesBuilder { } } psiManager.dropResolveCaches(); + psiManager.dropFileCaches(file); } }); } diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ForwardDependenciesBuilder.java b/platform/lang-impl/src/com/intellij/packageDependencies/ForwardDependenciesBuilder.java index 2fae6dbb1455..bddf301256a7 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/ForwardDependenciesBuilder.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/ForwardDependenciesBuilder.java @@ -138,6 +138,7 @@ public class ForwardDependenciesBuilder extends DependenciesBuilder { collectedDeps.addAll(found); psiManager.dropResolveCaches(); + psiManager.dropFileCaches(file); } } collectedDeps.removeAll(processed); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/AnyPsiChangeListener.java b/platform/lang-impl/src/com/intellij/psi/impl/AnyPsiChangeListener.java new file mode 100644 index 000000000000..e47e83aa4168 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/psi/impl/AnyPsiChangeListener.java @@ -0,0 +1,21 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.impl; + +public interface AnyPsiChangeListener { + void beforePsiChanged(boolean isPhysical); + void afterPsiChanged(boolean isPhysical); +} diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiManagerEx.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiManagerEx.java index d4678f1849fa..913dd949d81f 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiManagerEx.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiManagerEx.java @@ -46,8 +46,6 @@ public abstract class PsiManagerEx extends PsiManager { */ public abstract void registerRunnableToRunOnChange(@NotNull Runnable runnable); - public abstract void registerWeakRunnableToRunOnChange(@NotNull Runnable runnable); - /** * @param runnable to be run before physical or non-physical PSI change */ diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiManagerImpl.java index 7d14cde8edea..5d15f66a5f82 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiManagerImpl.java @@ -53,6 +53,7 @@ import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.psi.impl.source.resolve.ResolveCache; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl; +import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.search.PsiSearchHelper; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiModificationTracker; @@ -61,12 +62,13 @@ import com.intellij.testFramework.LightVirtualFile; import com.intellij.util.IncorrectOperationException; import com.intellij.util.ThrowableRunnable; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.messages.MessageBus; +import com.intellij.util.messages.Topic; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import java.io.IOException; -import java.lang.ref.WeakReference; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -76,6 +78,7 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiManagerImpl"); private final Project myProject; + private final MessageBus myMessageBus; private final FileManager myFileManager; private final PsiSearchHelperImpl mySearchHelper; @@ -94,11 +97,6 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { private final List myTreeChangeListeners = ContainerUtil.createEmptyCOWList(); private boolean myTreeChangeEventIsFiring = false; - private final List myRunnablesOnChange = ContainerUtil.createEmptyCOWList(); - private final List> myWeakRunnablesOnChange = ContainerUtil.createEmptyCOWList(); - private final List myRunnablesOnAnyChange = ContainerUtil.createEmptyCOWList(); - private final List myRunnablesAfterAnyChange = ContainerUtil.createEmptyCOWList(); - private boolean myIsDisposed; private VirtualFileFilter myAssertOnFileLoadingFilter = VirtualFileFilter.NONE; @@ -106,6 +104,7 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { private final AtomicInteger myBatchFilesProcessingModeCount = new AtomicInteger(0); private static final Key CACHED_PSI_FILE_COPY_IN_FILECONTENT = Key.create("CACHED_PSI_FILE_COPY_IN_FILECONTENT"); + public static final Topic ANY_PSI_CHANGE_TOPIC = Topic.create("PSI_CHANGE_TOPIC",AnyPsiChangeListener.class, Topic.BroadcastDirection.TO_PARENT); private final List myLanguageInjectors = ContainerUtil.createEmptyCOWList(); @@ -114,8 +113,9 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { StartupManager startupManager, FileTypeManager fileTypeManager, FileDocumentManager fileDocumentManager, - PsiBuilderFactory psiBuilderFactory) { + PsiBuilderFactory psiBuilderFactory, MessageBus messageBus) { myProject = project; + myMessageBus = messageBus; //We need to initialize PsiBuilderFactory service so it won't initialize under PsiLock from ChameleonTransform @SuppressWarnings({"UnusedDeclaration", "UnnecessaryLocalVariable"}) Object used = psiBuilderFactory; @@ -175,6 +175,11 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { nonPhysicalChange(); } + @Override + public void dropFileCaches(@NotNull PsiFile file) { + InjectedLanguageUtil.clearCachedInjectedFragmentsForFile(file); + } + public boolean isInProject(@NotNull PsiElement element) { PsiFile file = element.getContainingFile(); if (file instanceof PsiFileImpl && file.isPhysical() && file.getViewProvider().getVirtualFile() instanceof LightVirtualFile) return true; @@ -368,7 +373,7 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { @TestOnly public void cleanupForNextTest() { - //myFileManager.cleanupForNextTest(); + myFileManager.cleanupForNextTest(); LOG.assertTrue(ApplicationManager.getApplication().isUnitTestMode()); } @@ -495,7 +500,7 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { } public void childAdded(PsiTreeChangeEventImpl event) { - onChange(true); + beforeChange(true); event.setCode(CHILD_ADDED); if (LOG.isDebugEnabled()) { LOG.debug( @@ -504,11 +509,11 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { ); } fireEvent(event); - afterAnyChange(); + afterAnyChange(true); } public void childRemoved(PsiTreeChangeEventImpl event) { - onChange(true); + beforeChange(true); event.setCode(CHILD_REMOVED); if (LOG.isDebugEnabled()) { LOG.debug( @@ -516,11 +521,11 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { ); } fireEvent(event); - afterAnyChange(); + afterAnyChange(true); } public void childReplaced(PsiTreeChangeEventImpl event) { - onChange(true); + beforeChange(true); event.setCode(CHILD_REPLACED); if (LOG.isDebugEnabled()) { LOG.debug( @@ -530,11 +535,11 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { ); } fireEvent(event); - afterAnyChange(); + afterAnyChange(true); } public void childMoved(PsiTreeChangeEventImpl event) { - onChange(true); + beforeChange(true); event.setCode(CHILD_MOVED); if (LOG.isDebugEnabled()) { LOG.debug( @@ -544,11 +549,11 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { ); } fireEvent(event); - afterAnyChange(); + afterAnyChange(true); } public void childrenChanged(PsiTreeChangeEventImpl event) { - onChange(true); + beforeChange(true); event.setCode(CHILDREN_CHANGED); if (LOG.isDebugEnabled()) { LOG.debug( @@ -556,11 +561,11 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { ); } fireEvent(event); - afterAnyChange(); + afterAnyChange(true); } public void propertyChanged(PsiTreeChangeEventImpl event) { - onChange(true); + beforeChange(true); event.setCode(PROPERTY_CHANGED); if (LOG.isDebugEnabled()) { LOG.debug( @@ -571,7 +576,7 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { ); } fireEvent(event); - afterAnyChange(); + afterAnyChange(true); } public void addTreeChangePreprocessor(PsiTreeChangePreprocessor preprocessor) { @@ -658,57 +663,59 @@ public class PsiManagerImpl extends PsiManagerEx implements ProjectComponent { } } - public void registerRunnableToRunOnChange(@NotNull Runnable runnable) { - myRunnablesOnChange.add(runnable); + public void registerRunnableToRunOnChange(@NotNull final Runnable runnable) { + myMessageBus.connect().subscribe(ANY_PSI_CHANGE_TOPIC, new AnyPsiChangeListener() { + @Override + public void beforePsiChanged(boolean isPhysical) { + if (isPhysical) runnable.run(); + } + + @Override + public void afterPsiChanged(boolean isPhysical) { + } + }); } - public void registerWeakRunnableToRunOnChange(@NotNull Runnable runnable) { - myWeakRunnablesOnChange.add(new WeakReference(runnable)); + public void registerRunnableToRunOnAnyChange(@NotNull final Runnable runnable) { // includes non-physical changes + myMessageBus.connect().subscribe(ANY_PSI_CHANGE_TOPIC, new AnyPsiChangeListener() { + @Override + public void beforePsiChanged(boolean isPhysical) { + runnable.run(); + } + + @Override + public void afterPsiChanged(boolean isPhysical) { + } + }); } - public void registerRunnableToRunOnAnyChange(@NotNull Runnable runnable) { // includes non-physical changes - myRunnablesOnAnyChange.add(runnable); - } + public void registerRunnableToRunAfterAnyChange(@NotNull final Runnable runnable) { // includes non-physical changes + myMessageBus.connect().subscribe(ANY_PSI_CHANGE_TOPIC, new AnyPsiChangeListener() { + @Override + public void beforePsiChanged(boolean isPhysical) { + } - public void registerRunnableToRunAfterAnyChange(@NotNull Runnable runnable) { // includes non-physical changes - myRunnablesAfterAnyChange.add(runnable); + @Override + public void afterPsiChanged(boolean isPhysical) { + runnable.run(); + } + }); } public void nonPhysicalChange() { - onChange(false); + beforeChange(false); } public void physicalChange() { - onChange(true); + beforeChange(true); } - private void onChange(boolean isPhysical) { - if (isPhysical) { - runRunnables(myRunnablesOnChange); - - WeakReference[] refs = myWeakRunnablesOnChange.toArray(new WeakReference[myWeakRunnablesOnChange.size()]); - myWeakRunnablesOnChange.clear(); - for (WeakReference ref : refs) { - Runnable runnable = ref != null ? (Runnable)ref.get() : null; - if (runnable != null) { - runnable.run(); - } - } - } - - runRunnables(myRunnablesOnAnyChange); + private void beforeChange(boolean isPhysical) { + myMessageBus.syncPublisher(ANY_PSI_CHANGE_TOPIC).beforePsiChanged(isPhysical); } - private void afterAnyChange() { - runRunnables(myRunnablesAfterAnyChange); - } - - private static void runRunnables(List runnables) { - if (runnables.isEmpty()) return; - //noinspection ForLoopReplaceableByForEach - for (int i = 0; i < runnables.size(); i++) { - runnables.get(i).run(); - } + private void afterAnyChange(boolean isPhysical) { + myMessageBus.syncPublisher(ANY_PSI_CHANGE_TOPIC).afterPsiChanged(isPhysical); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java index b6290097e660..cbb3f482acce 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java @@ -288,12 +288,16 @@ public class InjectedLanguageUtil { private static final Key> INJECTED_REGIONS_KEY = Key.create("INJECTED_REGIONS_KEY"); @NotNull public static List getCachedInjectedDocuments(@NotNull PsiFile hostPsiFile) { + // modification of cachedInjectedDocuments must be under PsiLock only List injected = hostPsiFile.getUserData(INJECTED_DOCS_KEY); if (injected == null) { injected = ((UserDataHolderEx)hostPsiFile).putUserDataIfAbsent(INJECTED_DOCS_KEY, ContainerUtil.createEmptyCOWList()); } return injected; } + public static void clearCachedInjectedFragmentsForFile(@NotNull PsiFile file) { + file.putUserData(INJECTED_DOCS_KEY, null); + } public static void commitAllInjectedDocuments(Document hostDocument, Project project) { List injected = getCachedInjectedRegions(hostDocument); @@ -320,10 +324,32 @@ public class InjectedLanguageUtil { PsiDocumentManagerImpl.checkConsistency(hostPsiFile, hostDocument); } - public static void clearCaches(PsiFile injected) { + public static void clearCaches(@NotNull PsiFile injected, @NotNull DocumentWindowImpl documentWindow) { VirtualFileWindow virtualFile = (VirtualFileWindow)injected.getVirtualFile(); PsiManagerEx psiManagerEx = (PsiManagerEx)injected.getManager(); + if (psiManagerEx.isDisposed()) return; psiManagerEx.getFileManager().setViewProvider((VirtualFile)virtualFile, null); + PsiElement context = injected.getContext(); + PsiFile hostFile; + if (context != null) { + hostFile = context.getContainingFile(); + } + else { + VirtualFile delegate = virtualFile.getDelegate(); + hostFile = delegate.isValid() ? psiManagerEx.findFile(delegate) : null; + } + if (hostFile != null) { + // modification of cachedInjectedDocuments must be under PsiLock + synchronized (PsiLock.LOCK) { + List cachedInjectedDocuments = getCachedInjectedDocuments(hostFile); + for (int i = cachedInjectedDocuments.size() - 1; i >= 0; i--) { + DocumentWindow cachedInjectedDocument = cachedInjectedDocuments.get(i); + if (cachedInjectedDocument == documentWindow) { + cachedInjectedDocuments.remove(i); + } + } + } + } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java index 88494a37acad..1af0f5b82ca5 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java @@ -235,7 +235,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar { PsiFile newFile = registerDocument(documentWindow, psiFile, place, myHostPsiFile, documentManager); boolean mergeHappened = newFile != psiFile; if (mergeHappened) { - InjectedLanguageUtil.clearCaches(psiFile); + InjectedLanguageUtil.clearCaches(psiFile, documentWindow); psiFile = newFile; viewProvider = (InjectedFileViewProvider)psiFile.getViewProvider(); documentWindow = (DocumentWindowImpl)viewProvider.getDocument(); From f7717313bcf472819adb8a8ddc5743e0a88e7bb2 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 2 Feb 2011 17:46:36 +0300 Subject: [PATCH 40/94] cleanup --- .../inferNullity/NullityInferrer.java | 25 +++----------- .../intellij/find/impl/FindInProjectUtil.java | 34 ++++++++----------- .../editor/LazyRangeMarkerFactory.java | 6 ++-- .../usages/impl/rules/ModuleGroupingRule.java | 2 +- 4 files changed, 24 insertions(+), 43 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/inferNullity/NullityInferrer.java b/java/java-impl/src/com/intellij/codeInspection/inferNullity/NullityInferrer.java index 422378077c6d..ce8f7971d4f2 100644 --- a/java/java-impl/src/com/intellij/codeInspection/inferNullity/NullityInferrer.java +++ b/java/java-impl/src/com/intellij/codeInspection/inferNullity/NullityInferrer.java @@ -18,15 +18,8 @@ package com.intellij.codeInspection.inferNullity; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.codeInsight.intention.AddAnnotationFix; -import com.intellij.notification.Notification; -import com.intellij.notification.NotificationDisplayType; -import com.intellij.notification.NotificationType; -import com.intellij.notification.Notifications; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.psi.*; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.OverridingMethodsSearch; @@ -43,16 +36,12 @@ import java.util.Collection; import java.util.HashSet; public class NullityInferrer { - private static final Logger LOG = Logger.getInstance("#" + NullityInferrer.class.getName()); - private static final int MAX_PASSES = 10; private int numAnnotationsAdded = 0; - private final HashSet> myNotNullSet = - new HashSet>(); - private final HashSet> myNullableSet = - new HashSet>(); - private boolean myAnnotateLocalVariables; - private SmartPointerManager myPointerManager; + private final HashSet> myNotNullSet = new HashSet>(); + private final HashSet> myNullableSet = new HashSet>(); + private final boolean myAnnotateLocalVariables; + private final SmartPointerManager myPointerManager; public NullityInferrer(boolean annotateLocalVariables, Project project) { @@ -260,11 +249,7 @@ public class NullityInferrer { @Override public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) { final PsiMethod method = expression.resolveMethod(); - if (method == null) { - neverNull = false; - } else { - neverNull = isNotNull(method); - } + neverNull = method != null && isNotNull(method); } private boolean isNeverNull() { diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java index 8d681e621ba4..9ddc24003f40 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java @@ -269,12 +269,7 @@ public class FindInProjectUtil { String message = ""; if (largeFiles.size() == 1) { final VirtualFile vFile = largeFiles.iterator().next().getVirtualFile(); - message - += "File '" - + getPresentablePath(vFile) - + "' (" - + presentableSize(getFileLength(vFile)) - + ") is "; + message += "File " + presentableFileInfo(vFile) + " is "; } else { message += "Files
"; @@ -282,11 +277,7 @@ public class FindInProjectUtil { int counter = 0; for (PsiFile file : largeFiles) { final VirtualFile vFile = file.getVirtualFile(); - message += - getPresentablePath(vFile) - + " (" - + presentableSize(getFileLength(vFile)) - + ")
"; + message += presentableFileInfo(vFile) + "
"; if (counter++ > 10) break; } @@ -312,6 +303,13 @@ public class FindInProjectUtil { } } + private static String presentableFileInfo(VirtualFile vFile) { + return getPresentablePath(vFile) + + " (" + + presentableSize(getFileLength(vFile)) + + ")"; + } + private static int processUsagesInFile(final PsiFile psiFile, final FindModel findModel, final Processor consumer) { @@ -339,11 +337,11 @@ public class FindInProjectUtil { } private static String getPresentablePath(final VirtualFile virtualFile) { - return ApplicationManager.getApplication().runReadAction(new Computable() { + return "'" + ApplicationManager.getApplication().runReadAction(new Computable() { public String compute() { return virtualFile.getPresentableUrl(); } - }); + }) + "'"; } private static String presentableSize(long bytes) { @@ -434,9 +432,8 @@ public class FindInProjectUtil { final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); final VirtualFileFilter contentFilter = new VirtualFileFilter() { public boolean accept(final VirtualFile file) { - if (file.isDirectory()) return true; - if (fileTypeManager.isFileIgnored(file) || fileTypeManager.getFileTypeByFile(file).isBinary()) return false; - return searchScope.contains(file); + return file.isDirectory() || + !fileTypeManager.isFileIgnored(file) && !fileTypeManager.getFileTypeByFile(file).isBinary() && searchScope.contains(file); } }; for (VirtualFile file : files) { @@ -567,8 +564,7 @@ public class FindInProjectUtil { private static boolean canOptimizeForFastWordSearch(final FindModel findModel) { return !findModel.isRegularExpressions() - && (findModel.getCustomScope() == null || findModel.getCustomScope() instanceof GlobalSearchScope) - ; + && (findModel.getCustomScope() == null || findModel.getCustomScope() instanceof GlobalSearchScope); } private static int addToUsages(@NotNull Document document, @NotNull Processor consumer, @NotNull FindModel findModel, @@ -588,7 +584,7 @@ public class FindInProjectUtil { if (!result.isStringFound()) break; UsageInfo info = new UsageInfo(psiFile, result.getStartOffset(), result.getEndOffset()); - consumer.process(info); + if (!consumer.process(info)) break; count++; final int prevOffset = offset; diff --git a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java index 11968f74288a..ea7beabfed99 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java @@ -35,13 +35,13 @@ import java.util.Iterator; public class LazyRangeMarkerFactory extends AbstractProjectComponent { private final WeakList myMarkers = new WeakList(); - public LazyRangeMarkerFactory(Project project, final FileDocumentManager fdm) { + public LazyRangeMarkerFactory(Project project, final FileDocumentManager fileDocumentManager) { super(project); EditorFactory.getInstance().getEventMulticaster().addDocumentListener(new DocumentAdapter() { public void beforeDocumentChange(DocumentEvent e) { for (Iterator it = myMarkers.iterator(); it.hasNext();) { final LazyMarker marker = it.next(); - final VirtualFile docFile = fdm.getFile(e.getDocument()); + final VirtualFile docFile = fileDocumentManager.getFile(e.getDocument()); if (marker.getFile() == docFile) { marker.ensureDelegate(); it.remove(); @@ -82,7 +82,7 @@ public class LazyRangeMarkerFactory extends AbstractProjectComponent { return marker; } - private static abstract class LazyMarker extends UserDataHolderBase implements RangeMarker{ + private abstract static class LazyMarker extends UserDataHolderBase implements RangeMarker{ private RangeMarker myDelegate = null; private final VirtualFile myFile; protected final int myInitialOffset; diff --git a/platform/usageView/src/com/intellij/usages/impl/rules/ModuleGroupingRule.java b/platform/usageView/src/com/intellij/usages/impl/rules/ModuleGroupingRule.java index 0aec9f5bc2fc..0978ab0e03bb 100644 --- a/platform/usageView/src/com/intellij/usages/impl/rules/ModuleGroupingRule.java +++ b/platform/usageView/src/com/intellij/usages/impl/rules/ModuleGroupingRule.java @@ -57,7 +57,7 @@ public class ModuleGroupingRule implements UsageGroupingRule { private static class LibraryUsageGroup implements UsageGroup { public static final Icon LIBRARY_ICON = IconLoader.getIcon("/nodes/ppLibOpen.png"); - OrderEntry myEntry; + private final OrderEntry myEntry; public void update() { } From 41e7b8d92617f21e5e2176787e43c45abd43b33f Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 2 Feb 2011 18:11:52 +0300 Subject: [PATCH 41/94] test fix --- .../projectView/NavigateFromSourceTest.java | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/projectView/NavigateFromSourceTest.java b/java/java-tests/testSrc/com/intellij/projectView/NavigateFromSourceTest.java index 915b95fe98af..d3597d29cf4b 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/NavigateFromSourceTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/NavigateFromSourceTest.java @@ -37,7 +37,7 @@ import com.intellij.psi.JavaDirectoryService; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiJavaFile; -import com.intellij.testFramework.IdeaTestUtil; +import com.intellij.testFramework.PlatformTestUtil; import javax.swing.*; import java.io.IOException; @@ -56,16 +56,16 @@ public class NavigateFromSourceTest extends BaseProjectViewTestCase { checkNavigateFromSourceBehaviour(psiClass, virtualFile, pane); - IdeaTestUtil.assertTreeEqual(pane.getTree(), "-Project\n" + - " -PsiDirectory: showClassMembers\n" + - " -PsiDirectory: src\n" + - " -PsiDirectory: com\n" + - " -PsiDirectory: package1\n" + - " [Class1]\n" + - " Class2\n" + - getRootFiles() + - " +External Libraries\n" - , true); + PlatformTestUtil.assertTreeEqual(pane.getTree(), "-Project\n" + + " -PsiDirectory: showClassMembers\n" + + " -PsiDirectory: src\n" + + " -PsiDirectory: com\n" + + " -PsiDirectory: package1\n" + + " [Class1]\n" + + " Class2\n" + + getRootFiles() + + " +External Libraries\n" + , true); changeClassTextAndTryToNavigate("class Class11 {}", (PsiJavaFile)containingFile, pane, "-Project\n" + " -PsiDirectory: showClassMembers\n" + @@ -102,19 +102,20 @@ public class NavigateFromSourceTest extends BaseProjectViewTestCase { assertEquals(1, tree.getSelectionCount()); } - private void changeClassTextAndTryToNavigate(final String newClassString, - PsiJavaFile psiFile, - final AbstractProjectViewPSIPane pane, - final String expected) throws IOException, InterruptedException { + private static void changeClassTextAndTryToNavigate(final String newClassString, + PsiJavaFile psiFile, + final AbstractProjectViewPSIPane pane, + final String expected) throws IOException, InterruptedException { PsiClass psiClass = psiFile.getClasses()[0]; final VirtualFile virtualFile = psiClass.getContainingFile().getVirtualFile(); final JTree tree = pane.getTree(); writeToFile(virtualFile, newClassString.getBytes()); - IdeaTestUtil.waitForAlarm(600); + PlatformTestUtil.waitForAlarm(600); + psiClass = psiFile.getClasses()[0]; pane.select(psiClass, virtualFile, true); - IdeaTestUtil.assertTreeEqual(tree, expected, true); + PlatformTestUtil.assertTreeEqual(tree, expected, true); } private static void writeToFile(final VirtualFile virtualFile, final byte[] b) throws IOException { From 585a27da4c408697485c72b4a4d33479398b22e2 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 2 Feb 2011 19:45:46 +0300 Subject: [PATCH 42/94] memleak in progress indicator --- .../intellij/openapi/progress/util/ProgressIndicatorBase.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java index 948c5352a4b5..1e3e682e5154 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java @@ -203,6 +203,7 @@ public class ProgressIndicatorBase extends UserDataHolderBase implements Progres public void processFinish() { if (myOwnerTask != null) { finish(myOwnerTask); + myOwnerTask = null; } } From 4dcebe9883822202479c5271bd55b86475f55b95 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 3 Feb 2011 11:50:24 +0300 Subject: [PATCH 43/94] performance --- .../extensions/impl/ExtensionPointImpl.java | 62 +++++++++---------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionPointImpl.java b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionPointImpl.java index 47f5c9e27cbe..d6eb064ae4bf 100644 --- a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionPointImpl.java +++ b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionPointImpl.java @@ -125,22 +125,21 @@ public class ExtensionPointImpl implements ExtensionPoint { private void internalRegisterExtension(T extension, ExtensionComponentAdapter adapter, int index, boolean runNotifications) { if (myExtensions.contains(extension)) { myLogger.error("Extension was already added: " + extension); + return; } - else { - myExtensions.add(index, extension); - myLoadedAdapters.add(index, adapter); - if (runNotifications) { - if (extension instanceof Extension) { - try { - ((Extension)extension).extensionAdded(this); - } - catch (Throwable e) { - myLogger.error(e); - } + myExtensions.add(index, extension); + myLoadedAdapters.add(index, adapter); + if (runNotifications) { + if (extension instanceof Extension) { + try { + ((Extension)extension).extensionAdded(this); + } + catch (Throwable e) { + myLogger.error(e); } - - notifyListenersOnAdd(extension, adapter.getPluginDescriptor()); } + + notifyListenersOnAdd(extension, adapter.getPluginDescriptor()); } } @@ -163,31 +162,28 @@ public class ExtensionPointImpl implements ExtensionPoint { result = myExtensionsCache; if (result == null) { processAdapters(); - List extensions = new ArrayList(myExtensions); - - List problemExtensions = new ArrayList(); - final Class extensionClass = getExtensionClass(); - for (Iterator iterator = extensions.iterator(); iterator.hasNext();) { - T t = iterator.next(); + //noinspection unchecked + result = myExtensions.toArray((T[])Array.newInstance(extensionClass, myExtensions.size())); + + for (int i = result.length - 1; i >= 0; i--) { + T t = result[i]; + if (i > 0 && result[i] == result[i - 1]) { + LOG.error("Duplicate extension found: " + t + "; " + + " Result: "+ Arrays.asList(result)+";\n" + + " extensions: "+ myExtensions+";\n" + + " getExtensionClass(): "+ extensionClass +";\n" + + " size:"+myExtensions.size()+";"+result.length); + } + if (!extensionClass.isAssignableFrom(t.getClass())) { - problemExtensions.add(t); - iterator.remove(); + LOG.error("Extension '" + t.getClass() + "' must be an instance of '" + extensionClass + "'", + new ExtensionException(t.getClass())); + result = ArrayUtil.remove(result, i); // we assume that usually all extensions are OK } } - for (T problemExtension : problemExtensions) { - LOG.error("Extension '" + problemExtension.getClass() + "' should be instance of '" + extensionClass + "'", new ExtensionException(problemExtension.getClass())); - } - - //noinspection unchecked - myExtensionsCache = result = extensions.toArray((T[])Array.newInstance(extensionClass, extensions.size())); - for (int i = 1; i < result.length; i++) { - assert result[i] != result[i - 1] : "Result: "+ Arrays.asList(result)+";\n" + - " extensions: "+ extensions+";\n" + - " getExtensionClass(): "+ extensionClass +";\n" + - " size:"+extensions.size()+";"+result.length; - } + myExtensionsCache = result; } } } From 489c8b296a58e2ae8b1a16e291b84ebabc5d034e Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 3 Feb 2011 16:17:26 +0300 Subject: [PATCH 44/94] xml tests moved to xml-tests module --- .../com/intellij/util/EnvironmentUtil.java | 8 +++--- .../intellij/util/EnvironmentUtilTest.java | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java diff --git a/platform/util/src/com/intellij/util/EnvironmentUtil.java b/platform/util/src/com/intellij/util/EnvironmentUtil.java index 23a8e8bc7dd9..acbc58b580d4 100644 --- a/platform/util/src/com/intellij/util/EnvironmentUtil.java +++ b/platform/util/src/com/intellij/util/EnvironmentUtil.java @@ -18,7 +18,6 @@ package com.intellij.util; import org.jetbrains.annotations.NonNls; import java.util.Collections; -import java.util.Iterator; import java.util.Map; public class EnvironmentUtil { @@ -27,7 +26,8 @@ public class EnvironmentUtil { private EnvironmentUtil() { } - public static @NonNls Map getEnviromentProperties() { + @NonNls + public static Map getEnviromentProperties() { return ourEnviromentProperties; } @@ -39,8 +39,8 @@ public class EnvironmentUtil { Map enviroment = getEnviromentProperties(); String[] envp = new String[enviroment.size()]; int i = 0; - for (Iterator iterator = enviroment.keySet().iterator(); iterator.hasNext();) { - String name = (String)iterator.next(); + for (Object o : enviroment.keySet()) { + String name = (String)o; String value = (String)enviroment.get(name); envp[i++] = name + "=" + value; } diff --git a/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java b/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java new file mode 100644 index 000000000000..df8ee4893aab --- /dev/null +++ b/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java @@ -0,0 +1,26 @@ +/* + * Created by IntelliJ IDEA. + * User: mike + * Date: Sep 19, 2002 + * Time: 3:27:12 PM + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.util; + +import com.intellij.util.EnvironmentUtil; +import com.intellij.openapi.util.SystemInfo; +import junit.framework.TestCase; + +import java.util.Map; + +public class EnvironmentUtilTest extends TestCase { + public void test1() { + Map enviromentProperties = EnvironmentUtil.getEnviromentProperties(); + assertNotNull(enviromentProperties); + if(SystemInfo.isWindows) + assertNotNull(enviromentProperties.get("Path")); + else + assertNotNull(enviromentProperties.get("PATH")); + } +} From 6e630ff2beeed5865f9e1460d02457654d318c80 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 3 Feb 2011 17:04:26 +0300 Subject: [PATCH 45/94] exception --- .../com/intellij/find/findUsages/FindUsagesManager.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java index 914bc3ee467d..05fece7ba711 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java @@ -362,7 +362,7 @@ public class FindUsagesManager implements JDOMExternalizable { return processor.process(UsageInfoToUsageConverter.convert(descriptor, usageInfo)); } }); - List elements = + final List elements = ApplicationManager.getApplication().runReadAction(new Computable>() { public List compute() { return descriptor.getAllElements(); @@ -381,7 +381,12 @@ public class FindUsagesManager implements JDOMExternalizable { handler.processElementUsages(element, usageInfoProcessor, options); } - PsiManager.getInstance(handler.getProject()).getSearchHelper().processRequests(options.fastTrack, new ReadActionProcessor() { + Project project = ApplicationManager.getApplication().runReadAction(new Computable() { + public Project compute() { + return scopeFile != null ? scopeFile.getProject() : !elements.isEmpty() ? elements.get(0).getProject() : handler.getProject(); + } + }); + PsiManager.getInstance(project).getSearchHelper().processRequests(options.fastTrack, new ReadActionProcessor() { public boolean processInReadAction(final PsiReference ref) { TextRange rangeInElement = ref.getRangeInElement(); return usageInfoProcessor.process(new UsageInfo(ref.getElement(), rangeInElement.getStartOffset(), rangeInElement.getEndOffset(), false)); From 7cda1e3eabae5d28e6a5383a39fc61156f2c6316 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 4 Feb 2011 14:15:33 +0300 Subject: [PATCH 46/94] Closure has GrParameters instead of PsiParameters --- .../psi/api/statements/blocks/GrClosableBlock.java | 3 +-- .../impl/statements/blocks/GrClosableBlockImpl.java | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/blocks/GrClosableBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/blocks/GrClosableBlock.java index d5888ed33aa5..b2e7dc6a1c0c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/blocks/GrClosableBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/blocks/GrClosableBlock.java @@ -17,7 +17,6 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiParameter; import com.intellij.psi.PsiType; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrParametersOwner; @@ -43,7 +42,7 @@ public interface GrClosableBlock extends GrExpression, GrCodeBlock, GrParameters @Nullable PsiType getReturnType(); - PsiParameter[] getAllParameters(); + GrParameter[] getAllParameters(); @Nullable PsiElement getArrow(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java index d4269b22ee4d..130647ec42a7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java @@ -51,7 +51,7 @@ import org.jetbrains.plugins.groovy.refactoring.GroovyNamesUtil; * @author ilyas */ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock { - private volatile PsiParameter mySyntheticItParameter; + private volatile GrParameter mySyntheticItParameter; private GrVariable myOwner; public GrClosableBlockImpl(@NotNull ASTNode node) { @@ -124,9 +124,9 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock return GrParameter.EMPTY_ARRAY; } - public PsiParameter[] getAllParameters() { + public GrParameter[] getAllParameters() { if (hasParametersSection()) return getParameters(); - return new PsiParameter[]{getSyntheticItParameter()}; + return new GrParameter[]{getSyntheticItParameter()}; } @Override @@ -168,9 +168,9 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock mySyntheticItParameter = null; } - public PsiParameter getSyntheticItParameter() { + public GrParameter getSyntheticItParameter() { if (mySyntheticItParameter == null) { - PsiParameter fresh = new ClosureSyntheticParameter(this); + GrParameter fresh = new ClosureSyntheticParameter(this); synchronized (this) { if (mySyntheticItParameter == null) { mySyntheticItParameter = fresh; From 765f7ee7edc830667dedb65181b1ed9aee68d9ae Mon Sep 17 00:00:00 2001 From: "Rustam.Vishnyakov" Date: Fri, 4 Feb 2011 14:51:06 +0300 Subject: [PATCH 47/94] Another fix for JS library scope UI [r=K.Safonov] --- .../ScriptingLibraryMappings.java | 15 +++++---- .../ui/ScriptingContextsConfigurable.java | 32 ++++++++++++++++++- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java index 6b243e37e894..7759cb9fc15f 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java @@ -51,11 +51,15 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings { +public class ScriptingContextsConfigurable extends LanguagePerFileConfigurable + implements LibraryTable.Listener, + Disposable { private final ScriptingLibraryMappings myScriptingLibraryMappings; private final LangScriptingContextConfigurable myParent; @@ -46,6 +52,8 @@ public class ScriptingContextsConfigurable extends LanguagePerFileConfigurable Date: Thu, 3 Feb 2011 21:22:21 +0100 Subject: [PATCH 48/94] Restore file watcher state after failure --- .../openapi/vfs/impl/local/FileWatcher.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java index ecec0eeb9d91..e92eac4c028e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java @@ -93,7 +93,7 @@ public class FileWatcher { myManagingFS = ManagingFS.getInstance(); try { if (!"true".equals(System.getProperty(PROPERTY_WATCHER_DISABLED))) { - startupProcess(); + startupProcess(false); } } catch (IOException ignore) { @@ -236,7 +236,7 @@ public class FileWatcher { } @SuppressWarnings({"IOResourceOpenedButNotSafelyClosed"}) - private void startupProcess() throws IOException { + private void startupProcess(final boolean restart) throws IOException { if (isShuttingDown) return; if (attemptCount++ > MAX_PROCESS_LAUNCH_ATTEMPT_COUNT) { @@ -260,10 +260,22 @@ public class FileWatcher { : PathManager.getBinPath() + File.separatorChar + executableName; if (!new File(pathToExecutable).canExecute()) return; + LOG.info("Starting file watcher: " + pathToExecutable); + notifierProcess = Runtime.getRuntime().exec(new String[]{pathToExecutable}); notifierReader = new BufferedReader(new InputStreamReader(notifierProcess.getInputStream())); notifierWriter = new BufferedWriter(new OutputStreamWriter(notifierProcess.getOutputStream())); + + synchronized (LOCK) { + if (restart && myRecursiveWatchRoots.size() + myFlatWatchRoots.size() > 0) { + final List recursiveWatchRoots = new ArrayList(myRecursiveWatchRoots); + final List flatWatchRoots = new ArrayList(myFlatWatchRoots); + myRecursiveWatchRoots.clear(); + myFlatWatchRoots.clear(); + setWatchRoots(recursiveWatchRoots, flatWatchRoots); + } + } } private void shutdownProcess() { @@ -301,7 +313,7 @@ public class FileWatcher { final String command = readLine(); if (command == null) { // Unexpected process exit, relaunch attempt - startupProcess(); + startupProcess(true); continue; } @@ -352,7 +364,7 @@ public class FileWatcher { final String path = readLine(); if (path == null) { // Unexpected process exit, relaunch attempt - startupProcess(); + startupProcess(true); continue; } From 1cb0160753d00171299c32e996133d074f1aff94 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 4 Feb 2011 16:04:49 +0300 Subject: [PATCH 49/94] correct rename closure parameter --- .../groovy/lang/psi/impl/synthetic/GrLightParameter.java | 3 +-- .../groovy/refactoring/rename/GrLightElementRenamer.java | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightParameter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightParameter.java index c66b1c4ace11..ea8b68dd1ec4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightParameter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightParameter.java @@ -23,7 +23,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; @@ -65,7 +64,7 @@ public class GrLightParameter extends LightParameter implements GrParameter { @NotNull public PsiElement getNameIdentifierGroovy() { - return GroovyPsiElementFactory.getInstance(getProject()).createReferenceNameFromText(getName()); + return null; } public PsiType getTypeGroovy() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/GrLightElementRenamer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/GrLightElementRenamer.java index f8642041bda3..5686bf5aabdd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/GrLightElementRenamer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/GrLightElementRenamer.java @@ -25,6 +25,7 @@ import com.intellij.refactoring.util.CommonRefactoringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; +import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; /** @@ -43,6 +44,7 @@ public class GrLightElementRenamer extends RenamePsiElementProcessor { @Override public boolean canProcessElement(@NotNull PsiElement element) { if (!(element instanceof LightElement)) return false; + if (element instanceof ClosureSyntheticParameter) return false; final Language language = element.getLanguage(); return GroovyFileType.GROOVY_LANGUAGE.equals(language); } From 786760317b826cf83ed6bd692e76598126d546d8 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 14:06:42 +0100 Subject: [PATCH 50/94] EA-24136 don't show documentation for lookup element when there isn't any --- .../com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java index 588624db8824..416ce69bc8a1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java @@ -133,7 +133,7 @@ public class LookupManagerImpl extends LookupManager { final Alarm alarm = new Alarm(); final Runnable request = new Runnable() { public void run() { - if (myActiveLookup == lookup) { + if (myActiveLookup == lookup && lookup.getCurrentItem() != null) { final CompletionProcess completion = CompletionService.getCompletionService().getCurrentCompletion(); if (completion == null || !completion.isAutopopupCompletion()) { DocumentationManager.getInstance(myProject).showJavaDocInfo(editor, psiFile, false); From 86f6b15748f88d432ab92c9f568e9435b523d200 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 4 Feb 2011 16:10:15 +0300 Subject: [PATCH 51/94] don't check methods in closure parameter inference --- .../groovy/lang/psi/ClosureParameterEnhancer.java | 5 ++--- .../groovy/lang/resolve/ResolveMethodTest.groovy | 4 ++++ .../groovy/lang/resolve/TypeInferenceTest.java | 4 ++++ .../resolve/inference/inferWithClosureType/A.groovy | 13 +++++++++++++ .../method/avoidResolveLockInClosure/A.groovy | 10 ++++++++++ 5 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 plugins/groovy/testdata/resolve/inference/inferWithClosureType/A.groovy create mode 100644 plugins/groovy/testdata/resolve/method/avoidResolveLockInClosure/A.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/ClosureParameterEnhancer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/ClosureParameterEnhancer.java index f5d37140bae4..2655e42e61a4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/ClosureParameterEnhancer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/ClosureParameterEnhancer.java @@ -13,7 +13,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.arithmetic.GrRangeExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; import org.jetbrains.plugins.groovy.lang.psi.impl.GrRangeType; import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; @@ -91,8 +90,8 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer { GrExpression expression = ((GrMethodCall)parent).getInvokedExpression(); if (!(expression instanceof GrReferenceExpression)) return null; - final PsiElement resolved = ((GrReferenceExpression)expression).resolve(); - if (!(resolved instanceof GrGdkMethod)) return null; +// final PsiElement resolved = ((GrReferenceExpression)expression).resolve(); +// if (!(resolved instanceof GrGdkMethod)) return null; GrExpression qualifier = ((GrReferenceExpression)expression).getQualifierExpression(); if (qualifier == null) return null; diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy index a4910ad91383..1ba606c731d0 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy @@ -640,4 +640,8 @@ class Zoo { public void testResolveValuesOnEnum() { assertNotNull resolve("A.groovy") } + + public void testAvoidResolveLockInClosure() { + assertNotNull resolve("A.groovy") + } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.java index 088c8ce2bda1..ac8e9b5c568f 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.java @@ -177,4 +177,8 @@ public class TypeInferenceTest extends GroovyResolveTestCase { public void testImplicitlyReturnedMethodCall() { assertTypeEquals("java.util.Map>", "A.groovy"); } + + public void testInferWithClosureType() { + assertTypeEquals("java.util.Date", "A.groovy"); + } } diff --git a/plugins/groovy/testdata/resolve/inference/inferWithClosureType/A.groovy b/plugins/groovy/testdata/resolve/inference/inferWithClosureType/A.groovy new file mode 100644 index 000000000000..6132d62f2687 --- /dev/null +++ b/plugins/groovy/testdata/resolve/inference/inferWithClosureType/A.groovy @@ -0,0 +1,13 @@ +class C { + Date field +} + +enum E { + val({C c -> + def data = c.with { + it.field + } + + print data + }) +} \ No newline at end of file diff --git a/plugins/groovy/testdata/resolve/method/avoidResolveLockInClosure/A.groovy b/plugins/groovy/testdata/resolve/method/avoidResolveLockInClosure/A.groovy new file mode 100644 index 000000000000..6c4045888acb --- /dev/null +++ b/plugins/groovy/testdata/resolve/method/avoidResolveLockInClosure/A.groovy @@ -0,0 +1,10 @@ +class C { + Date field +} + +enum E { + val({C c -> + c.with { + } + }) +} \ No newline at end of file From 8d8ff57115e1ab2fa0cff54b6e25a5f579b4866a Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Fri, 4 Feb 2011 16:14:57 +0300 Subject: [PATCH 52/94] IDEA-37228 Live Template abbreviation is shown cutted if new name is longer then old one --- .../codeInsight/template/impl/TemplateListPanel.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java index 833576847ae6..dd2c4a4c40d4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java @@ -35,6 +35,7 @@ import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.Alarm; import com.intellij.util.ui.ColumnInfo; import com.intellij.util.ui.UIUtil; +import com.intellij.util.ui.tree.TreeUtil; import com.intellij.util.ui.update.UiNotifyConnector; import org.jetbrains.annotations.Nullable; @@ -494,6 +495,17 @@ class TemplateListPanel extends JPanel { myTree.setSelectionInterval(selected, selected); updateTemplateTextArea(); + + List expandedPaths = TreeUtil.collectExpandedPaths(myTree); + TreePath[] selectedPaths = myTree.getSelectionPaths(); + ((DefaultTreeModel)myTree.getModel()).nodeStructureChanged(myTreeRoot); + TreeUtil.restoreExpandedPaths(myTree, expandedPaths); + if (selectedPaths != null) { + myTree.setSelectionPaths(selectedPaths); + } + + myTree.validate(); + myTree.repaint(); } private Map getOptions(final TemplateImpl template) { From 1e8caec1c2953c547d53e7f3637df4ea28c8ac67 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 14:39:48 +0100 Subject: [PATCH 53/94] [alefas] extensible OutOfCodeBlock modification tracking --- .../intellij/psi/impl/JavaPsiFacadeImpl.java | 17 ++++++----- .../source/tree/java/PsiCodeBlockImpl.java | 5 ++++ .../src/com/intellij/psi/PsiCodeBlock.java | 2 +- .../intellij/psi/PsiModifiableCodeBlock.java | 28 +++++++++++++++++++ 4 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 java/openapi/src/com/intellij/psi/PsiModifiableCodeBlock.java diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java b/java/java-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java index b58510caf7c5..e32806c81a66 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java @@ -670,23 +670,22 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable { if (element instanceof PsiFileSystemItem) { return false; } - + if (element == null || element.getParent() == null) return true; - while(true){ - if (element instanceof PsiFile || element instanceof PsiDirectory || element == null){ + PsiElement parent = element; + while (true) { + if (parent instanceof PsiFile || parent instanceof PsiDirectory || parent == null) { return false; } - PsiElement pparent = element.getParent(); - if (element instanceof PsiClass) return false; // anonymous or local class - if (element instanceof PsiCodeBlock){ - if (pparent instanceof PsiMethod || pparent instanceof PsiClassInitializer){ + if (parent instanceof PsiClass) return false; // anonymous or local class + if (parent instanceof PsiModifiableCodeBlock) { + if (!((PsiModifiableCodeBlock)parent).shouldChangeModificationCount(element)) { return true; } } - element = pparent; + parent = parent.getParent(); } } - } } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiCodeBlockImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiCodeBlockImpl.java index 0c04702abc28..c702b47277c2 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiCodeBlockImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiCodeBlockImpl.java @@ -221,4 +221,9 @@ public class PsiCodeBlockImpl extends LazyParseablePsiElement implements PsiCode } return true; } + + public boolean shouldChangeModificationCount(PsiElement place) { + PsiElement pparent = getParent(); + return !(pparent instanceof PsiMethod || pparent instanceof PsiClassInitializer); + } } diff --git a/java/openapi/src/com/intellij/psi/PsiCodeBlock.java b/java/openapi/src/com/intellij/psi/PsiCodeBlock.java index 496a91b05c54..338da097af86 100644 --- a/java/openapi/src/com/intellij/psi/PsiCodeBlock.java +++ b/java/openapi/src/com/intellij/psi/PsiCodeBlock.java @@ -21,7 +21,7 @@ import org.jetbrains.annotations.Nullable; /** * Represents a Java code block, usually surrounded by curly braces. */ -public interface PsiCodeBlock extends PsiElement { +public interface PsiCodeBlock extends PsiElement, PsiModifiableCodeBlock { /** * The empty array of PSI code blocks which can be reused to avoid unnecessary allocations. */ diff --git a/java/openapi/src/com/intellij/psi/PsiModifiableCodeBlock.java b/java/openapi/src/com/intellij/psi/PsiModifiableCodeBlock.java new file mode 100644 index 000000000000..85a9555a401d --- /dev/null +++ b/java/openapi/src/com/intellij/psi/PsiModifiableCodeBlock.java @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi; + +/** + * Represents psi element, which can be modified without caches reset. + * @see com.intellij.psi.util.PsiModificationTracker#getOutOfCodeBlockModificationCount() + */ +public interface PsiModifiableCodeBlock { + /** + * @param place where change was detected + * @return false if specific caches could be saved after the change + */ + boolean shouldChangeModificationCount(PsiElement place); +} From 8fb2e576e3ac21a5ec9f474d4256095ae0a201ed Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 14:50:23 +0100 Subject: [PATCH 54/94] EA-24136 don't show documentation for lookup element when there isn't any --- .../com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java index 588624db8824..416ce69bc8a1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java @@ -133,7 +133,7 @@ public class LookupManagerImpl extends LookupManager { final Alarm alarm = new Alarm(); final Runnable request = new Runnable() { public void run() { - if (myActiveLookup == lookup) { + if (myActiveLookup == lookup && lookup.getCurrentItem() != null) { final CompletionProcess completion = CompletionService.getCompletionService().getCurrentCompletion(); if (completion == null || !completion.isAutopopupCompletion()) { DocumentationManager.getInstance(myProject).showJavaDocInfo(editor, psiFile, false); From d4d47954d4062a9a299d3ff17005702c0b57f458 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 15:41:47 +0100 Subject: [PATCH 55/94] classes are not subject to the 'passing object to itself' sorting heuristic --- .../codeInsight/completion/RecursionWeigher.java | 11 +++-------- .../normalSorting/ClassInCallOfItsMethod.java | 7 +++++++ .../completion/NormalCompletionOrderingTest.java | 10 ++++++++++ .../completion/SmartTypeCompletionOrderingTest.java | 2 +- 4 files changed, 21 insertions(+), 9 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normalSorting/ClassInCallOfItsMethod.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java index 8d481bec614a..4eb4fc592ad4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java @@ -23,7 +23,6 @@ import com.intellij.psi.filters.ElementFilter; import com.intellij.psi.search.searches.DeepestSuperMethodsSearch; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author peter @@ -38,16 +37,12 @@ public class RecursionWeigher extends CompletionWeigher { } public Result weigh(@NotNull final LookupElement element, @NotNull final CompletionLocation location) { - if (location == null) { - return null; - } if (location.getCompletionType() != CompletionType.BASIC && location.getCompletionType() != CompletionType.SMART) return Result.normal; final Object object = element.getObject(); - if (!(object instanceof PsiModifierListOwner) && !(object instanceof PsiExpression)) return Result.normal; + if (!(object instanceof PsiMethod || object instanceof PsiVariable || object instanceof PsiExpression)) return Result.normal; final PsiMethod positionMethod = JavaCompletionUtil.POSITION_METHOD.getValue(location); - if (positionMethod == null) return Result.normal; final PsiElement position = location.getCompletionParameters().getPosition(); final ElementFilter filter = JavaCompletionUtil.recursionFilter(position); @@ -66,7 +61,7 @@ public class RecursionWeigher extends CompletionWeigher { return Result.passingObjectToItself; } - if (expression != null) { + if (expression != null && positionMethod != null) { final ExpectedTypeInfo[] expectedInfos = JavaCompletionUtil.EXPECTED_TYPES.getValue(location); if (expectedInfos != null) { final PsiType itemType = JavaCompletionUtil.getLookupElementType(element); @@ -81,7 +76,7 @@ public class RecursionWeigher extends CompletionWeigher { return Result.normal; } - if (object instanceof PsiMethod) { + if (object instanceof PsiMethod && positionMethod != null) { final PsiMethod method = (PsiMethod)object; if (PsiTreeUtil.isAncestor(reference, position, false) && Comparing.equal(method.getName(), positionMethod.getName()) && diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/ClassInCallOfItsMethod.java b/java/java-tests/testData/codeInsight/completion/normalSorting/ClassInCallOfItsMethod.java new file mode 100644 index 000000000000..c2bc90fdfcb1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/ClassInCallOfItsMethod.java @@ -0,0 +1,7 @@ +import foo.Foo; + +class Bar { + { + Foo.foo(Foox) + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java index 243ec1c0f180..3449fb725e8e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java @@ -160,4 +160,14 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { assertEquals("Foooo.Bar", presentation.getItemText());*/ } + public void testClassInCallOfItsMethod() throws Throwable { + final VirtualFile foo = getSourceRoot().createChildDirectory(this, "foo"); + VfsUtil.saveText(foo.createChildData(this, "Foo.java"), "package foo; public interface Foo {}"); + final VirtualFile bar = getSourceRoot().createChildDirectory(this, "bar"); + VfsUtil.saveText(bar.createChildData(this, "Foo.java"), "package bar; public interface Foo {}"); + + checkPreferredItems(0, "Foo", "Foo"); + assertEquals("foo.Foo", ((JavaPsiClassReferenceElement)getLookup().getCurrentItem()).getQualifiedName()); + } + } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.java index 2443bd43a63c..4f563e00f493 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.java @@ -194,7 +194,7 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase { } public void testFactoryMethodForDefaultType() throws Throwable { - checkPreferredItems(0, "create", "map", "this", "getClass"); + checkPreferredItems(0, "create", "this", "map", "getClass"); } public void testLocalVarsBeforeClassLiterals() throws Throwable { From fb4ff4134bd42e957f237f1ba9369576002ba856 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 15:46:11 +0100 Subject: [PATCH 56/94] diagnostics for EA-25474 --- .../src/com/intellij/psi/impl/search/LowLevelSearchUtil.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java index 1194ef78b5c4..729efea586e3 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java @@ -141,6 +141,10 @@ public class LowLevelSearchUtil { final CharSequence buffer = file.getViewProvider().getContents(); TextRange range = scope.getTextRange(); + if (range == null) { + throw new AssertionError("Element " + scope + " of class " + scope.getClass() + " has null range"); + } + int scopeStart = range.getStartOffset(); int startOffset = scopeStart; int endOffset = range.getEndOffset(); From cd82155f8c16cab4f1a2625a7066f34c9eef8919 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 15:46:11 +0100 Subject: [PATCH 57/94] diagnostics for EA-25474 --- .../src/com/intellij/psi/impl/search/LowLevelSearchUtil.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java index 1194ef78b5c4..729efea586e3 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java @@ -141,6 +141,10 @@ public class LowLevelSearchUtil { final CharSequence buffer = file.getViewProvider().getContents(); TextRange range = scope.getTextRange(); + if (range == null) { + throw new AssertionError("Element " + scope + " of class " + scope.getClass() + " has null range"); + } + int scopeStart = range.getStartOffset(); int startOffset = scopeStart; int endOffset = range.getEndOffset(); From e87ecf68f869e2c478fdd40bca6a03e2c1d150d1 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Fri, 4 Feb 2011 17:59:42 +0300 Subject: [PATCH 58/94] pin active tab fix --- .../src/com/intellij/ide/actions/PinActiveTabAction.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/PinActiveTabAction.java b/platform/platform-impl/src/com/intellij/ide/actions/PinActiveTabAction.java index 8451a1dc23db..6d544958982a 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/PinActiveTabAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/PinActiveTabAction.java @@ -39,11 +39,6 @@ public class PinActiveTabAction extends ToggleAction implements DumbAware { return null; } - // To provide file from editor manager, editor component should be active - if(!ToolWindowManager.getInstance(project).isEditorComponentActive()){ - return null; - } - return PlatformDataKeys.VIRTUAL_FILE.getData(context); } From 33b114fe49a727d03f92b57404c84b3a8b63a498 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 4 Feb 2011 17:43:53 +0300 Subject: [PATCH 59/94] conserve memory --- .../plugins/intelliLang/inject/config/BaseInjection.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/BaseInjection.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/BaseInjection.java index 32b011e790fa..75236bfa391f 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/BaseInjection.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/BaseInjection.java @@ -71,7 +71,7 @@ public class BaseInjection implements Injection, PersistentStateComponent myPlaces = new ArrayList(); + private final ArrayList myPlaces = new ArrayList(); @NotNull public List getInjectionPlaces() { @@ -132,7 +132,7 @@ public class BaseInjection implements Injection, PersistentStateComponent ranges = getMatchingRanges(myCompiledValuePattern.matcher(sb), sb.length()); - return ranges.size() > 0 ? ContainerUtil.map(ranges, new Function() { + return !ranges.isEmpty() ? ContainerUtil.map(ranges, new Function() { public TextRange fun(TextRange s) { return new TextRange(textEscaper.getOffsetInHost(s.getStartOffset(), textRange), textEscaper.getOffsetInHost(s.getEndOffset(), textRange)); } @@ -250,6 +250,7 @@ public class BaseInjection implements Injection, PersistentStateComponent Date: Fri, 4 Feb 2011 17:48:27 +0300 Subject: [PATCH 60/94] cleanup --- .../ex/util/LayeredLexerEditorHighlighter.java | 1 + .../src/com/intellij/util/Alarm.java | 2 +- .../usages/impl/UsageViewTreeModelBuilder.java | 11 ----------- .../usages/impl/UsageNodeTreeBuilderTest.java | 17 +++-------------- 4 files changed, 5 insertions(+), 26 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/ex/util/LayeredLexerEditorHighlighter.java b/platform/lang-impl/src/com/intellij/openapi/editor/ex/util/LayeredLexerEditorHighlighter.java index e74fdb6a038f..6f1918ae803e 100644 --- a/platform/lang-impl/src/com/intellij/openapi/editor/ex/util/LayeredLexerEditorHighlighter.java +++ b/platform/lang-impl/src/com/intellij/openapi/editor/ex/util/LayeredLexerEditorHighlighter.java @@ -357,6 +357,7 @@ public class LayeredLexerEditorHighlighter extends LexerEditorHighlighter { } } + @NotNull private MappedRange insertMapping(int tokenIndex, IElementType outerToken) { CharSequence tokenText = getTokenText(tokenIndex); diff --git a/platform/platform-api/src/com/intellij/util/Alarm.java b/platform/platform-api/src/com/intellij/util/Alarm.java index de2fb35695d3..0c33ef8e85d7 100644 --- a/platform/platform-api/src/com/intellij/util/Alarm.java +++ b/platform/platform-api/src/com/intellij/util/Alarm.java @@ -38,7 +38,7 @@ import java.util.concurrent.TimeUnit; public class Alarm implements Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.util.Alarm"); - private boolean myDisposed; + private volatile boolean myDisposed; private final List myRequests = new ArrayList(); private final List myPendingRequests = new ArrayList(); diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java index bcbb9693d673..8d2da9c0ce91 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java @@ -19,7 +19,6 @@ import com.intellij.usages.UsageTarget; import com.intellij.usages.UsageViewPresentation; import org.jetbrains.annotations.NonNls; -import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; @@ -109,16 +108,6 @@ public class UsageViewTreeModelBuilder extends DefaultTreeModel { super(null, 0, UsageViewTreeModelBuilder.this); } - public void addNode(final DefaultMutableTreeNode node) { - if (!myDetachedMode) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - myTreeModel.insertNodeInto(node, RootGroupNode.this, getNodeInsertionIndex(node)); - } - }); - } - } - @NonNls public String toString() { return "Root "+super.toString(); diff --git a/platform/usageView/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java b/platform/usageView/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java index 37b67c7c8dfe..0d01f31bbcb5 100644 --- a/platform/usageView/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java +++ b/platform/usageView/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java @@ -148,8 +148,7 @@ public class UsageNodeTreeBuilderTest extends TestCase { } public boolean equals(Object o) { - if (!(o instanceof LogUsageGroup)) return false; - return myPower == ((LogUsageGroup)o).myPower; + return o instanceof LogUsageGroup && myPower == ((LogUsageGroup)o).myPower; } public int hashCode() { return myPower; } @@ -240,16 +239,11 @@ public class UsageNodeTreeBuilderTest extends TestCase { @Override public UsageGroup groupUsage(Usage usage) { - MockUsage mockUsage = ((MockUsage)usage); + MockUsage mockUsage = (MockUsage)usage; if (mockUsage.getId() > 1000) return null; - if (mockUsage.getId() % 2 == 0) { - return EVEN; - } - else { - return ODD; - } + return mockUsage.getId() % 2 == 0 ? EVEN : ODD; } } @@ -260,7 +254,6 @@ public class UsageNodeTreeBuilderTest extends TestCase { myId = index; } - public int getId() { return myId; } @@ -316,10 +309,6 @@ public class UsageNodeTreeBuilderTest extends TestCase { return String.valueOf(myId); } - public int compareTo(Usage o) { - return getId() - ((MockUsage)o).getId(); - } - @Override public void navigate(boolean requestFocus) { } From 54c000b5c009688f4ac64874fd964abcd56dae43 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 4 Feb 2011 19:06:49 +0300 Subject: [PATCH 61/94] usage view memory optimization --- .../impl/smartPointers/AnchorElementInfo.java | 88 +---- .../AnchorElementInfoFactory.java | 4 +- .../ImplicitVariableElementInfoFactory.java | 48 ++- .../ImportListElementInfoFactory.java | 32 +- .../usages/impl/rules/ClassGroupingRule.java | 10 +- .../usages/impl/rules/MethodGroupingRule.java | 27 +- .../intellij/psi/IdentitySmartPointer.java | 26 +- .../com/intellij/psi/SmartPointerManager.java | 10 +- .../intellij/psi/SmartPsiElementPointer.java | 6 + .../com/intellij/psi/impl/ElementBase.java | 38 +- .../src/com/intellij/usageView/UsageInfo.java | 73 ++-- .../impl/config/IntentionUsagePanel.java | 26 +- .../ReplaceInProjectManager.java | 63 ++-- .../impl/dataRules/VirtualFileArrayRule.java | 39 +-- .../src/com/intellij/psi/PsiAnchor.java | 61 +++- .../psi/impl/PsiDocumentManagerImpl.java | 83 +++-- .../psi/impl/PsiToDocumentSynchronizer.java | 2 - .../psi/impl/file/impl/FileManagerImpl.java | 6 +- .../impl/smartPointers/FileElementInfo.java | 48 ++- .../impl/smartPointers/HardElementInfo.java | 78 +++++ .../InjectedSelfElementInfo.java | 16 +- .../impl/smartPointers/LazyPointerImpl.java | 86 +++-- .../impl/smartPointers/SelfElementInfo.java | 222 +++++++++--- .../SmartPointerElementInfo.java | 10 + .../SmartPointerElementInfoFactory.java | 3 +- .../impl/smartPointers/SmartPointerEx.java | 7 +- .../SmartPointerManagerImpl.java | 133 ++++--- .../SmartPsiElementPointerImpl.java | 143 ++++---- .../psi/impl/source/tree/ChangeUtil.java | 7 +- .../com/intellij/util/ui/RangeBlinker.java | 10 +- .../impl/FileDocumentManagerImpl.java | 3 +- .../openapi/project/FileContentQueue.java | 2 +- .../testFramework/src/_LastInSuiteTest.java | 4 +- ...akedProjectHunter.java => LeakHunter.java} | 32 +- .../com/intellij/usages/ChunkExtractor.java | 70 ++-- .../com/intellij/usages/UsageDataUtil.java | 73 ++++ .../usages/UsageInfo2UsageAdapter.java | 331 +++++++++--------- .../com/intellij/usages/impl/GroupNode.java | 25 +- .../intellij/usages/impl/UsageViewImpl.java | 126 ++----- .../usages/impl/UsageViewManagerImpl.java | 11 +- platform/usageView/usageView.iml | 1 + .../com/intellij/openapi/util/TextRange.java | 2 +- .../util/containers/TransferToEDTQueue.java | 92 +++++ .../NavigationGutterIconBuilder.java | 38 +- .../util/xml/ElementPresentationManager.java | 4 + 45 files changed, 1347 insertions(+), 872 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/psi/impl/smartPointers/HardElementInfo.java rename platform/testFramework/src/com/intellij/testFramework/{LeakedProjectHunter.java => LeakHunter.java} (87%) create mode 100644 platform/usageView/src/com/intellij/usages/UsageDataUtil.java create mode 100644 platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java index efaf4626a856..19bc73f98c66 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java @@ -15,12 +15,11 @@ */ package com.intellij.psi.impl.smartPointers; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.RangeMarker; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiIdentifier; +import com.intellij.psi.PsiJavaCodeReferenceElement; import com.intellij.psi.xml.XmlToken; import com.intellij.psi.xml.XmlTokenType; import org.jetbrains.annotations.NotNull; @@ -29,72 +28,21 @@ import org.jetbrains.annotations.Nullable; /** * User: cdr */ -class AnchorElementInfo implements SmartPointerElementInfo { - private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.smartPointers.AnchorElementInfo"); - private PsiFile myFile; - private final RangeMarker myMarker; - private int mySyncStartOffset; - private int mySyncEndOffset; - private boolean mySyncMarkerIsValid; - private final Project myProject; - - AnchorElementInfo(@NotNull PsiElement anchor) { - LOG.assertTrue(anchor.isPhysical()); - LOG.assertTrue(anchor.isValid()); - myFile = anchor.getContainingFile(); - myProject = myFile.getProject(); - TextRange range = anchor.getTextRange(); - - final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); - Document document = documentManager.getDocument(myFile); - LOG.assertTrue(!documentManager.isUncommited(document)); - if (myFile.getTextLength() != document.getTextLength()) { - final String docText = document.getText(); - myFile.accept(new PsiRecursiveElementWalkingVisitor() { - @Override - public void visitElement(PsiElement element) { - super.visitElement(element); - TextRange elementRange = element.getTextRange(); - final String rangeText = docText.length() <= elementRange.getEndOffset() ? "(IOOBE: "+docText.length()+" is out of "+elementRange+")" : elementRange.substring(docText); - final String elemText = element.getText(); - if (!rangeText.equals(elemText)) { - throw new AssertionError("PSI text doesn't equal to the document's one: element" + element + "\ndocText=" + rangeText + "\npsiText" + elemText); - } - } - }); - LOG.error("File=" + myFile); - } - myMarker = document.createRangeMarker(range.getStartOffset(), range.getEndOffset(), true); - - mySyncStartOffset = range.getStartOffset(); - mySyncEndOffset = range.getEndOffset(); - mySyncMarkerIsValid = true; - } - - public Document getDocumentToSynchronize() { - return myMarker.getDocument(); - } - - public void documentAndPsiInSync() { - if (!myMarker.isValid()) { - mySyncMarkerIsValid = false; - return; - } - - mySyncStartOffset = myMarker.getStartOffset(); - mySyncEndOffset = myMarker.getEndOffset(); +class AnchorElementInfo extends SelfElementInfo { + AnchorElementInfo(@NotNull PsiElement anchor, PsiFile containingFile) { + super(anchor, containingFile); } @Nullable public PsiElement restoreElement() { if (!mySyncMarkerIsValid) return null; - myFile = SelfElementInfo.restoreFile(myFile, myProject); - if (myFile == null) return null; - PsiElement anchor = myFile.findElementAt(mySyncStartOffset); + PsiFile file = SelfElementInfo.restoreFileFromVirtual(myVirtualFile, myProject); + if (file == null) return null; + PsiElement anchor = file.findElementAt(getSyncStartOffset()); if (anchor == null) return null; TextRange range = anchor.getTextRange(); - if (range.getStartOffset() != mySyncStartOffset || range.getEndOffset() != mySyncEndOffset) return null; + if (range.getStartOffset() != getSyncStartOffset() || range.getEndOffset() != getSyncEndOffset()) return null; if (anchor instanceof PsiIdentifier) { PsiElement parent = anchor.getParent(); @@ -106,20 +54,10 @@ class AnchorElementInfo implements SmartPointerElementInfo { return parent; } - else if (anchor instanceof XmlToken) { + if (anchor instanceof XmlToken) { XmlToken token = (XmlToken)anchor; - return token.getTokenType() == XmlTokenType.XML_NAME ? token.getParent() : null; } - else { - return null; - } - } - - @Override - public void dispose() { - if (myMarker != null) { - myMarker.dispose(); - } + return null; } } diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java index 7c8385fbfe27..c84d8f341b3c 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java @@ -29,7 +29,7 @@ public class AnchorElementInfoFactory implements SmartPointerElementInfoFactory public SmartPointerElementInfo createElementInfo(@NotNull PsiElement element) { PsiElement anchor = getAnchor(element); if (anchor != null) { - return new AnchorElementInfo(anchor); + return new AnchorElementInfo(anchor, element.getContainingFile()); } return null; } @@ -55,7 +55,7 @@ public class AnchorElementInfoFactory implements SmartPointerElementInfoFactory else if (element instanceof XmlTag) { anchor = XmlTagUtil.getStartTagNameElement((XmlTag)element); } - if (anchor != null && !anchor.isPhysical()) return null; + if (anchor != null && (!anchor.isPhysical() || anchor.getTextRange()==null)) return null; return anchor; } diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java index ad95e90b3b6e..403cb17c8e06 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java @@ -15,15 +15,20 @@ */ package com.intellij.psi.impl.smartPointers; -import org.jetbrains.annotations.Nullable; -import com.intellij.psi.PsiElement; -import com.intellij.psi.ImplicitVariable; -import com.intellij.psi.PsiIdentifier; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Segment; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.ImplicitVariable; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiIdentifier; +import com.intellij.psi.util.PsiUtilBase; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class ImplicitVariableElementInfoFactory implements SmartPointerElementInfoFactory { @Nullable - public SmartPointerElementInfo createElementInfo(final PsiElement element) { + public SmartPointerElementInfo createElementInfo(@NotNull final PsiElement element) { if (element instanceof ImplicitVariable) { return new ImplicitVariableInfo((ImplicitVariable) element); } @@ -54,5 +59,38 @@ public class ImplicitVariableElementInfoFactory implements SmartPointerElementIn public void documentAndPsiInSync() { } + + @Override + public void fastenBelt(int offset) { + } + + @Override + public void unfastenBelt(int offset) { + } + + @Override + public int elementHashCode() { + return myVar.hashCode(); + } + + @Override + public boolean pointsToTheSameElementAs(SmartPointerElementInfo other) { + if (other instanceof ImplicitVariableInfo) { + return myVar == ((ImplicitVariableInfo)other).myVar; + } + return Comparing.equal(restoreElement(), other.restoreElement()); + } + + @Override + public VirtualFile getVirtualFile() { + return PsiUtilBase.getVirtualFile(myVar); + } + + @Override + public Segment getSegment() { + PsiIdentifier psiIdentifier = myVar.getNameIdentifier(); + if (psiIdentifier == null || !psiIdentifier.isValid()) return null; + return psiIdentifier.getTextRange(); + } } } diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java index 853a82691117..be18abde62b2 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java @@ -15,42 +15,30 @@ */ package com.intellij.psi.impl.smartPointers; -import org.jetbrains.annotations.Nullable; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiJavaFile; import com.intellij.psi.PsiImportList; -import com.intellij.openapi.editor.Document; +import com.intellij.psi.PsiJavaFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class ImportListElementInfoFactory implements SmartPointerElementInfoFactory { @Nullable - public SmartPointerElementInfo createElementInfo(final PsiElement element) { + public SmartPointerElementInfo createElementInfo(@NotNull final PsiElement element) { if (element instanceof PsiImportList) { return new ImportListInfo((PsiJavaFile)element.getContainingFile()); } return null; } - private static class ImportListInfo implements SmartPointerElementInfo { - private final PsiJavaFile myFile; - - public ImportListInfo(PsiJavaFile file) { - myFile = file; + private static class ImportListInfo extends FileElementInfo { + public ImportListInfo(@NotNull PsiJavaFile file) { + super(file); } public PsiElement restoreElement() { - if (!myFile.isValid()) return null; - return myFile.getImportList(); - } - - @Override - public void dispose() { - } - - public Document getDocumentToSynchronize() { - return null; - } - - public void documentAndPsiInSync() { + PsiElement element = super.restoreElement(); + if (!(element instanceof PsiJavaFile)) return null; + return ((PsiJavaFile)element).getImportList(); } } } diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/ClassGroupingRule.java b/java/java-impl/src/com/intellij/usages/impl/rules/ClassGroupingRule.java index 047ce9493305..9008e87eaafe 100644 --- a/java/java-impl/src/com/intellij/usages/impl/rules/ClassGroupingRule.java +++ b/java/java-impl/src/com/intellij/usages/impl/rules/ClassGroupingRule.java @@ -100,20 +100,16 @@ public class ClassGroupingRule implements UsageGroupingRule { private final SmartPsiElementPointer myClassPointer; private final String myText; private final String myQName; - private Icon myIcon; + private final Icon myIcon; public ClassUsageGroup(PsiClass aClass) { myQName = aClass.getQualifiedName(); myText = createText(aClass); - SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(aClass.getProject()); - myClassPointer = smartPointerManager.createLazyPointer(aClass); - update(); + myClassPointer = SmartPointerManager.getInstance(aClass.getProject()).createSmartPsiElementPointer(aClass); + myIcon = getPsiClass().getIcon(Iconable.ICON_FLAG_VISIBILITY | Iconable.ICON_FLAG_READ_STATUS); } public void update() { - if (isValid()) { - myIcon = getPsiClass().getIcon(Iconable.ICON_FLAG_VISIBILITY | Iconable.ICON_FLAG_READ_STATUS); - } } private static String createText(PsiClass aClass) { diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java index e009b471f795..c36921b48c70 100644 --- a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java +++ b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java @@ -23,6 +23,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Iconable; +import com.intellij.openapi.util.Segment; import com.intellij.openapi.vcs.FileStatus; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; @@ -69,7 +70,7 @@ public class MethodGroupingRule implements UsageGroupingRule { private static class MethodUsageGroup implements UsageGroup, TypeSafeDataProvider { private final SmartPsiElementPointer myMethodPointer; private final String myName; - private Icon myIcon; + private final Icon myIcon; private final Project myProject; public MethodUsageGroup(PsiMethod psiMethod) { @@ -80,15 +81,12 @@ public class MethodGroupingRule implements UsageGroupingRule { PsiFormatUtilBase.SHOW_TYPE ); myProject = psiMethod.getProject(); - myMethodPointer = SmartPointerManager.getInstance(myProject).createLazyPointer(psiMethod); + myMethodPointer = SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(psiMethod); myIcon = getIconImpl(psiMethod); } public void update() { - if (isValid()) { - myIcon = getIconImpl(getMethod()); - } } private static Icon getIconImpl(PsiMethod psiMethod) { @@ -104,10 +102,8 @@ public class MethodGroupingRule implements UsageGroupingRule { return false; } MethodUsageGroup group = (MethodUsageGroup) object; - if (isValid() && group.isValid()) { - return getMethod().getManager().areElementsEquivalent(getMethod(), group.getMethod()); - } - return Comparing.equal(myName, ((MethodUsageGroup)object).myName); + return Comparing.equal(myName, ((MethodUsageGroup)object).myName) + && SmartPointerManager.getInstance(myProject).pointToTheSameElement(myMethodPointer, group.myMethodPointer); } public Icon getIcon(boolean isOpen) { @@ -151,10 +147,15 @@ public class MethodGroupingRule implements UsageGroupingRule { LOG.error("MethodUsageGroup expected but " + usageGroup.getClass() + " found"); } MethodUsageGroup other = (MethodUsageGroup)usageGroup; - PsiMethod myMethod = myMethodPointer.getElement(); - PsiMethod otherMethod = other.myMethodPointer.getElement(); - if (myMethod != null && otherMethod != null && !UsageViewSettings.getInstance().IS_SORT_MEMBERS_ALPHABETICALLY) { - return myMethod.getTextOffset() < otherMethod.getTextOffset() ? -1 : 1; + if (SmartPointerManager.getInstance(myProject).pointToTheSameElement(myMethodPointer, other.myMethodPointer)) { + return 0; + } + if (!UsageViewSettings.getInstance().IS_SORT_MEMBERS_ALPHABETICALLY) { + Segment segment1 = myMethodPointer.getSegment(); + Segment segment2 = other.myMethodPointer.getSegment(); + if (segment1 != null && segment2 != null) { + return segment1.getStartOffset() - segment2.getStartOffset(); + } } return myName.compareTo(other.myName); diff --git a/platform/lang-api/src/com/intellij/psi/IdentitySmartPointer.java b/platform/lang-api/src/com/intellij/psi/IdentitySmartPointer.java index 4f9f45d26faa..03cd2de5a16f 100644 --- a/platform/lang-api/src/com/intellij/psi/IdentitySmartPointer.java +++ b/platform/lang-api/src/com/intellij/psi/IdentitySmartPointer.java @@ -20,14 +20,15 @@ package com.intellij.psi; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Segment; +import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; public class IdentitySmartPointer implements SmartPsiElementPointer { private T myElement; private final PsiFile myFile; - public IdentitySmartPointer(T element, PsiFile file) { + public IdentitySmartPointer(@NotNull T element, @NotNull PsiFile file) { myElement = element; myFile = file; } @@ -41,11 +42,17 @@ public class IdentitySmartPointer implements SmartPsiEleme return myFile.getProject(); } + @Override + public VirtualFile getVirtualFile() { + return myFile.getVirtualFile(); + } + public T getElement() { - if (myElement != null && !myElement.isValid()) { - myElement = null; + T element = myElement; + if (element != null && !element.isValid()) { + element = null; } - return myElement; + return element; } public int hashCode() { @@ -54,10 +61,17 @@ public class IdentitySmartPointer implements SmartPsiEleme } public boolean equals(Object obj) { - return obj instanceof SmartPsiElementPointer && Comparing.equal(getElement(), ((SmartPsiElementPointer)obj).getElement()); + return obj instanceof SmartPsiElementPointer + && SmartPointerManager.getInstance(getProject()).pointToTheSameElement(this, (SmartPsiElementPointer)obj); } public PsiFile getContainingFile() { return myFile; } + + @Override + public Segment getSegment() { + T element = myElement; + return element == null ? null : element.getTextRange(); + } } diff --git a/platform/lang-api/src/com/intellij/psi/SmartPointerManager.java b/platform/lang-api/src/com/intellij/psi/SmartPointerManager.java index 850cf4a1622b..b67cbcb28a4c 100644 --- a/platform/lang-api/src/com/intellij/psi/SmartPointerManager.java +++ b/platform/lang-api/src/com/intellij/psi/SmartPointerManager.java @@ -39,9 +39,17 @@ public abstract class SmartPointerManager { /** * Creates a smart pointer to the specified PSI element which doesn't hold a strong reference to the PSI * element. - * + * @deprecated use {@link #createSmartPsiElementPointer(PsiElement)} instead * @param element the element to create a pointer to. * @return the smart pointer instance. */ @NotNull public abstract SmartPsiElementPointer createLazyPointer(@NotNull E element); + + /** + * @param pointer1 smart pointer to compare + * @param pointer2 smart pointer to compare + * @return true if both pointers point to the same PSI element. + * This method is cheaper than dereferencing both pointers and comparing the result. + */ + public abstract boolean pointToTheSameElement(@NotNull SmartPsiElementPointer pointer1, @NotNull SmartPsiElementPointer pointer2); } diff --git a/platform/lang-api/src/com/intellij/psi/SmartPsiElementPointer.java b/platform/lang-api/src/com/intellij/psi/SmartPsiElementPointer.java index c13bdc0e6ccc..66e847d60439 100644 --- a/platform/lang-api/src/com/intellij/psi/SmartPsiElementPointer.java +++ b/platform/lang-api/src/com/intellij/psi/SmartPsiElementPointer.java @@ -16,6 +16,8 @@ package com.intellij.psi; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Segment; +import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,4 +43,8 @@ public interface SmartPsiElementPointer { @NotNull Project getProject(); + + VirtualFile getVirtualFile(); + + Segment getSegment(); } diff --git a/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java b/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java index 0f12b53223b3..d3676670a0ca 100644 --- a/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java +++ b/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java @@ -23,7 +23,6 @@ import com.intellij.openapi.fileTypes.NativeFileType; import com.intellij.openapi.fileTypes.UnknownFileType; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.IndexNotReadyException; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.Iconable; import com.intellij.openapi.util.UserDataHolderBase; @@ -31,6 +30,8 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.SmartPointerManager; +import com.intellij.psi.SmartPsiElementPointer; import com.intellij.ui.IconDeferrer; import com.intellij.ui.LayeredIcon; import com.intellij.ui.RowIcon; @@ -48,6 +49,14 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.ElementBase"); public static final int FLAGS_LOCKED = 0x800; + private static final NullableFunction ICON_COMPUTE = new NullableFunction() { + public Icon fun(ElementIconRequest request) { + final PsiElement element = request.getElement(); + if (!element.isValid()) return null; + if (element.getProject().isDisposed()) return null; + return computeIconNow(element, request.getFlags()); + } + }; private TIntObjectHashMap myBaseIcon; private static final Icon VISIBILITY_ICON_PLACHOLDER = new EmptyIcon(Icons.PUBLIC_ICON); @@ -88,18 +97,10 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable baseIcon = myBaseIcon.get(flags); } - final Project project = psiElement.getProject(); if (isToDeferIconLoading()) { - return IconDeferrer.getInstance().defer(baseIcon, new ElementIconRequest(psiElement, flags), new NullableFunction() { - public Icon fun(ElementIconRequest request) { - if (project.isDisposed()) return null; - final PsiElement element = request.getElement(); - if (!element.isValid()) return null; - if (element.getProject().isDisposed()) return null; - return computeIconNow(element, request.getFlags()); - } - }); - } else { + return IconDeferrer.getInstance().defer(baseIcon, new ElementIconRequest(psiElement, flags), ICON_COMPUTE); + } + else { if (!psiElement.isValid()) return null; return computeIconNow(psiElement, flags); } @@ -110,12 +111,12 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable } @Nullable - private Icon computeIconNow(PsiElement element, int flags) { + private static Icon computeIconNow(PsiElement element, int flags) { final Icon providersIcon = PsiIconUtil.getProvidersIcon(element, flags); if (providersIcon != null) { return providersIcon instanceof RowIcon ? (RowIcon)providersIcon : createLayeredIcon(providersIcon, flags); } - return getElementIcon(flags); + return ((ElementBase)element).getElementIcon(flags); } protected Icon computeBaseIcon(int flags) { @@ -177,11 +178,16 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable public static class ElementIconRequest extends ComparableObject.Impl { public ElementIconRequest(PsiElement element, int flags) { - super(new Object[] {element, flags}); + super(new Object[] {createPointer(element), flags}); + } + + private static Object createPointer(PsiElement element) { + return SmartPointerManager.getInstance(element.getProject()).createSmartPsiElementPointer(element); } public PsiElement getElement() { - return (PsiElement)getEqualityObjects()[0]; + SmartPsiElementPointer pointer = (SmartPsiElementPointer)getEqualityObjects()[0]; + return pointer.getElement(); } public int getFlags() { diff --git a/platform/lang-api/src/com/intellij/usageView/UsageInfo.java b/platform/lang-api/src/com/intellij/usageView/UsageInfo.java index 2976cfe62ea8..b149bf276776 100644 --- a/platform/lang-api/src/com/intellij/usageView/UsageInfo.java +++ b/platform/lang-api/src/com/intellij/usageView/UsageInfo.java @@ -15,11 +15,12 @@ */ package com.intellij.usageView; +import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Segment; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -29,8 +30,7 @@ import org.jetbrains.annotations.Nullable; public class UsageInfo { public static final UsageInfo[] EMPTY_ARRAY = new UsageInfo[0]; private static final Logger LOG = Logger.getInstance("#com.intellij.usageView.UsageInfo"); - private final SmartPsiElementPointer mySmartPointer; - private final VirtualFile myVirtualFile; + private final SmartPsiElementPointer mySmartPointer; public final int startOffset; // in navigation element public final int endOffset; // in navigation element @@ -38,9 +38,19 @@ public class UsageInfo { public UsageInfo(@NotNull PsiElement element, int startOffset, int endOffset, boolean isNonCodeUsage) { LOG.assertTrue(element.isValid()); - LOG.assertTrue(element == element.getNavigationElement()); - mySmartPointer = SmartPointerManager.getInstance(element.getProject()).createSmartPsiElementPointer(element); - myVirtualFile = element.getContainingFile().getVirtualFile(); + element = element.getNavigationElement(); + SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(element.getProject()); + mySmartPointer = smartPointerManager.createSmartPsiElementPointer(element); + + if (startOffset == -1 && endOffset == -1) { + // calculate natural element range + TextRange range = element.getTextRange(); + if (range == null) { + LOG.error("text range null for " + element + "; " + element.getClass()); + } + startOffset = element.getTextOffset() - range.getStartOffset(); + endOffset = range.getEndOffset() - range.getStartOffset(); + } this.startOffset = startOffset; this.endOffset = endOffset; this.isNonCodeUsage = isNonCodeUsage; @@ -49,22 +59,7 @@ public class UsageInfo { } public UsageInfo(@NotNull PsiElement element, boolean isNonCodeUsage) { - LOG.assertTrue(element.isValid()); - element = element.getNavigationElement(); - - mySmartPointer = SmartPointerManager.getInstance(element.getProject()).createSmartPsiElementPointer(element); - myVirtualFile = element.getContainingFile().getVirtualFile(); - - TextRange range = element.getTextRange(); - if (range == null) { - LOG.error("text range null for " + element+"; "+element.getClass()); - } - startOffset = element.getTextOffset() - range.getStartOffset(); - endOffset = range.getEndOffset() - range.getStartOffset(); - - this.isNonCodeUsage = isNonCodeUsage; - LOG.assertTrue(startOffset >= 0, startOffset); - LOG.assertTrue(endOffset >= startOffset, endOffset-startOffset); + this(element, -1, -1, isNonCodeUsage); } public UsageInfo(@NotNull PsiElement element, int startOffset, int endOffset) { @@ -105,15 +100,25 @@ public class UsageInfo { } public final void navigateTo(boolean requestFocus) { - PsiElement element = getElement(); - if (element == null) return; - VirtualFile file = element.getContainingFile().getVirtualFile(); - TextRange range = element.getTextRange(); - int offset = range.getStartOffset() + startOffset; - Project project = element.getProject(); + int offset = getNavigationOffset(); + VirtualFile file = getVirtualFile(); + Project project = getProject(); FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file, offset), requestFocus); } + public int getNavigationOffset() { + PsiElement element = getElement(); + if (element == null) return -1; + TextRange range = element.getTextRange(); + return range.getStartOffset() + startOffset; + } + public Segment getSegment() { + PsiElement element = getElement(); + if (element == null) return null; + TextRange range = element.getTextRange(); + return new TextRange(range.getStartOffset() + startOffset, Math.min(range.getEndOffset(), range.getStartOffset() + endOffset)); + } + public Project getProject() { return mySmartPointer.getProject(); } @@ -132,9 +137,8 @@ public class UsageInfo { if (endOffset != usageInfo.endOffset) return false; if (isNonCodeUsage != usageInfo.isNonCodeUsage) return false; if (startOffset != usageInfo.startOffset) return false; - PsiElement thisElement = mySmartPointer.getElement(); - PsiElement thatElement = usageInfo.mySmartPointer.getElement(); - return Comparing.equal(thisElement, thatElement); + + return SmartPointerManager.getInstance(getProject()).pointToTheSameElement(mySmartPointer, usageInfo.mySmartPointer); } public int hashCode() { @@ -150,7 +154,12 @@ public class UsageInfo { return mySmartPointer.getContainingFile(); } + @Nullable public VirtualFile getVirtualFile() { - return myVirtualFile; + return mySmartPointer.getVirtualFile(); + } + + public void dispose() { + ((Disposable)mySmartPointer).dispose(); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionUsagePanel.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionUsagePanel.java index 3fb0dbc78880..a3ad3a12743f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionUsagePanel.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionUsagePanel.java @@ -29,6 +29,7 @@ import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.util.Segment; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ui.RangeBlinker; import org.jetbrains.annotations.NonNls; @@ -78,23 +79,28 @@ class IntentionUsagePanel extends JPanel{ } private void setupSpots(Document document) { - List markers = new ArrayList(); + List markers = new ArrayList(); while (true) { String text = document.getText(); - int spotStart = text.indexOf("<" + SPOT_MARKER + ">"); + final int spotStart = text.indexOf("<" + SPOT_MARKER + ">"); if (spotStart < 0) break; - int spotEnd = text.indexOf("", spotStart); + final int spotEnd = text.indexOf("", spotStart); if (spotEnd < 0) break; document.deleteString(spotEnd, spotEnd + SPOT_MARKER.length() + 3); document.deleteString(spotStart, spotStart + SPOT_MARKER.length() + 2); - final RangeMarker spotMarker = document.createRangeMarker(spotStart, spotEnd - SPOT_MARKER.length() - 2); - if (spotMarker == null) { - break; - } - else { - markers.add(spotMarker); - } + Segment spotMarker = new Segment() { + @Override + public int getStartOffset() { + return spotStart; + } + + @Override + public int getEndOffset() { + return spotEnd - SPOT_MARKER.length() - 2; + } + }; + markers.add(spotMarker); } myRangeBlinker.resetMarkers(markers); if (!markers.isEmpty()) { diff --git a/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java b/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java index 08fe256dfad2..c47475e0cc42 100644 --- a/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java +++ b/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java @@ -29,11 +29,11 @@ import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Factory; +import com.intellij.openapi.util.Segment; import com.intellij.openapi.vfs.ReadonlyStatusHandler; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -322,37 +322,40 @@ public class ReplaceInProjectManager { return; } - List markers = ((UsageInfo2UsageAdapter)usage).getRangeMarkers(); - for (RangeMarker marker : markers) { - Document document = marker.getDocument(); - if (!document.isWritable()) return; + final Document document = ((UsageInfo2UsageAdapter)usage).getDocument(); + ((UsageInfo2UsageAdapter)usage).processRangeMarkers(new Processor() { + @Override + public boolean process(Segment segment) { + if (!document.isWritable()) return false; - final int textOffset = marker.getStartOffset(); - if (textOffset < 0 || textOffset >= document.getTextLength()) { - return; + final int textOffset = segment.getStartOffset(); + if (textOffset < 0 || textOffset >= document.getTextLength()) { + return true; + } + final int textEndOffset = segment.getEndOffset(); + if (textEndOffset < 0 || textOffset > document.getTextLength()) { + return true; + } + FindManager findManager = FindManager.getInstance(myProject); + final CharSequence foundString = document.getCharsSequence().subSequence(textOffset, textEndOffset); + FindResult findResult = findManager.findString(document.getCharsSequence(), textOffset, replaceContext.getFindModel()); + if (!findResult.isStringFound()) { + return true; + } + String stringToReplace = null; + try { + stringToReplace = + findManager.getStringToReplace(foundString.toString(), replaceContext.getFindModel(), textOffset, document.getText()); + } + catch (FindManager.MalformedReplacementStringException e) { + Messages.showErrorDialog(myProject, e.getMessage(), FindBundle.message("find.replace.invalid.replacement.string.title")); + } + if (stringToReplace != null) { + document.replaceString(textOffset, textEndOffset, stringToReplace); + } + return true; } - final int textEndOffset = marker.getEndOffset(); - if (textEndOffset < 0 || textOffset > document.getTextLength()) { - return; - } - FindManager findManager = FindManager.getInstance(myProject); - final CharSequence foundString = document.getCharsSequence().subSequence(textOffset, textEndOffset); - FindResult findResult = findManager.findString(document.getCharsSequence(), textOffset, replaceContext.getFindModel()); - if (!findResult.isStringFound()) { - return; - } - String stringToReplace = null; - try { - stringToReplace = - findManager.getStringToReplace(foundString.toString(), replaceContext.getFindModel(), textOffset, document.getText()); - } - catch (FindManager.MalformedReplacementStringException e) { - Messages.showErrorDialog(myProject, e.getMessage(), FindBundle.message("find.replace.invalid.replacement.string.title")); - } - if (stringToReplace != null) { - document.replaceString(textOffset, textEndOffset, stringToReplace); - } - } + }); } }); } diff --git a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/VirtualFileArrayRule.java b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/VirtualFileArrayRule.java index 462c30c6d566..fcd84136349a 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/VirtualFileArrayRule.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/VirtualFileArrayRule.java @@ -30,15 +30,13 @@ import com.intellij.psi.PsiDirectoryContainer; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.usages.Usage; +import com.intellij.usages.UsageDataUtil; import com.intellij.usages.UsageTarget; import com.intellij.usages.UsageView; -import com.intellij.usages.rules.UsageInFile; -import com.intellij.usages.rules.UsageInFiles; import com.intellij.util.containers.ContainerUtil; import java.util.ArrayList; import java.util.HashSet; -import java.util.Set; public class VirtualFileArrayRule implements GetDataRule { public Object getData(final DataProvider dataProvider) { @@ -84,44 +82,13 @@ public class VirtualFileArrayRule implements GetDataRule { Usage[] usages = UsageView.USAGES_KEY.getData(dataProvider); UsageTarget[] usageTargets = UsageView.USAGE_TARGETS_KEY.getData(dataProvider); - if (usages != null || usageTargets != null) { - return getFilesFromUsages(usages, usageTargets); + if (usages != null || usageTargets != null) { + return UsageDataUtil.provideVirtualFileArray(usages, usageTargets); } - return null; } - private static VirtualFile[] getFilesFromUsages(Usage[] usages, UsageTarget[] usageTargets) { - Set result = new HashSet(); - - if (usages != null) { - for (Usage usage : usages) { - if (!usage.isValid()) continue; - if (usage instanceof UsageInFile) { - UsageInFile usageInFile = (UsageInFile)usage; - result.add(usageInFile.getFile()); - } - - if (usage instanceof UsageInFiles) { - UsageInFiles usageInFiles = (UsageInFiles)usage; - ContainerUtil.addAll(result, usageInFiles.getFiles()); - } - } - } - - if (usageTargets != null) { - for (UsageTarget usageTarget : usageTargets) { - if (!usageTarget.isValid()) continue; - VirtualFile[] files = usageTarget.getFiles(); - if (files != null) { - ContainerUtil.addAll(result, files); - } - } - } - - return VfsUtil.toVirtualFileArray(result); - } private static Object getFilesFromPsiElement(PsiElement elem) { if (elem instanceof PsiFile) { diff --git a/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java b/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java index d53354d09306..808dfd9ec6e4 100644 --- a/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java +++ b/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java @@ -21,10 +21,12 @@ import com.intellij.lang.Language; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.NullableComputable; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.impl.light.LightElement; +import com.intellij.psi.impl.smartPointers.SelfElementInfo; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.psi.impl.source.PsiFileWithStubSupport; import com.intellij.psi.stubs.IStubElementType; @@ -61,6 +63,8 @@ public abstract class PsiAnchor { if (file == null) { return new HardReference(element); } + VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile == null) return new HardReference(element); if (element instanceof StubBasedPsiElement && element.isPhysical() && (element instanceof PsiCompiledElement || ((PsiFileImpl)file).getContentElementType() instanceof IStubFileElementType)) { final StubBasedPsiElement elt = (StubBasedPsiElement)element; @@ -88,7 +92,7 @@ public abstract class PsiAnchor { } if (lang == null) lang = element.getLanguage(); - return new TreeRangeReference(file, textRange.getStartOffset(), textRange.getEndOffset(), element.getClass(), lang); + return new TreeRangeReference(file, textRange.getStartOffset(), textRange.getEndOffset(), element.getClass(), lang, virtualFile); } private static int calcStubIndex(StubBasedPsiElement psi) { @@ -112,16 +116,22 @@ public abstract class PsiAnchor { return -1; // it is possible via custom stub builder intentionally not producing stubs for stubbed elements } - private static class TreeRangeReference extends PsiAnchor { - private final PsiFile myFile; + private final VirtualFile myVirtualFile; + private final Project myProject; private final Language myLanguage; private final int myStartOffset; private final int myEndOffset; private final Class myClass; - private TreeRangeReference(final PsiFile file, final int startOffset, final int endOffset, final Class aClass, final Language language) { - myFile = file; + private TreeRangeReference(@NotNull PsiFile file, + int startOffset, + int endOffset, + @NotNull Class aClass, + @NotNull Language language, + @NotNull VirtualFile virtualFile) { + myVirtualFile = virtualFile; + myProject = file.getProject(); myStartOffset = startOffset; myEndOffset = endOffset; myClass = aClass; @@ -130,7 +140,9 @@ public abstract class PsiAnchor { @Nullable public PsiElement retrieve() { - PsiElement element = myFile.getViewProvider().findElementAt(myStartOffset, myLanguage); + PsiFile psiFile = getFile(); + if (psiFile == null || !psiFile.isValid()) return null; + PsiElement element = psiFile.getViewProvider().findElementAt(myStartOffset, myLanguage); if (element == null) return null; while (!element.getClass().equals(myClass) || @@ -144,7 +156,7 @@ public abstract class PsiAnchor { } public PsiFile getFile() { - return myFile; + return SelfElementInfo.restoreFileFromVirtual(myVirtualFile, myProject); } public int getStartOffset() { @@ -161,24 +173,26 @@ public abstract class PsiAnchor { final TreeRangeReference that = (TreeRangeReference)o; - if (myEndOffset != that.myEndOffset) return false; - if (myStartOffset != that.myStartOffset) return false; - if (myClass != null ? !myClass.equals(that.myClass) : that.myClass != null) return false; - if (myFile != null ? !myFile.equals(that.myFile) : that.myFile != null) return false; - - return true; + return myEndOffset == that.myEndOffset && + myStartOffset == that.myStartOffset && + myClass.equals(that.myClass) && + myVirtualFile.equals(that.myVirtualFile); } public int hashCode() { int result = myClass != null ? myClass.getName().hashCode() : 0; result = 31 * result + myStartOffset; //todo result = 31 * result + myEndOffset; - if (myFile != null) { - result = 31 * result + myFile.getName().hashCode(); - } + result = 31 * result + myVirtualFile.getName().hashCode(); return result; } + + @Override + public boolean pointsToTheSameElementAs(PsiAnchor other) { + if (other instanceof TreeRangeReference) return equals(other); + return Comparing.equal(retrieve(), other.retrieve()); + } } private static class HardReference extends PsiAnchor { @@ -217,9 +231,14 @@ public abstract class PsiAnchor { public int hashCode() { return myElement.hashCode(); } + + @Override + public boolean pointsToTheSameElementAs(PsiAnchor other) { + return myElement == other.retrieve(); + } } - public static class StubIndexReference extends PsiAnchor { + private static class StubIndexReference extends PsiAnchor { private final VirtualFile myVirtualFile; private final Project myProject; private final int myIndex; @@ -313,6 +332,14 @@ public abstract class PsiAnchor { if (resolved == null) throw new PsiInvalidElementAccessException(null); return resolved.getTextRange().getEndOffset(); } + + @Override + public boolean pointsToTheSameElementAs(PsiAnchor other) { + if (other instanceof StubIndexReference) return equals(other); + return Comparing.equal(retrieve(), other.retrieve()); + } } + + public abstract boolean pointsToTheSameElementAs(PsiAnchor other); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java index 792c763c64aa..d8aa92c6e0d5 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java @@ -16,6 +16,7 @@ package com.intellij.psi.impl; +import com.intellij.AppTopics; import com.intellij.injected.editor.DocumentWindow; import com.intellij.lang.ASTNode; import com.intellij.openapi.application.Application; @@ -31,6 +32,7 @@ import com.intellij.openapi.editor.event.DocumentListener; import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.editor.impl.DocumentImpl; import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; @@ -48,6 +50,7 @@ import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.text.BlockSupport; import com.intellij.util.SmartList; import com.intellij.util.concurrency.Semaphore; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.messages.MessageBus; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -74,8 +77,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec private volatile boolean myIsCommitInProgress; private final PsiToDocumentSynchronizer mySynchronizer; - private final List myListeners = new ArrayList(); - private Listener[] myCachedListeners = null; //guarded by mylisteners + private final List myListeners = ContainerUtil.createEmptyCOWList(); private final SmartPointerManagerImpl mySmartPointerManager; public PsiDocumentManagerImpl(Project project, @@ -91,6 +93,17 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec mySynchronizer = new PsiToDocumentSynchronizer(this, bus); myPsiManager.addPsiTreeChangeListener(mySynchronizer); editorFactory.getEventMulticaster().addDocumentListener(this, myProject); + bus.connect().subscribe(AppTopics.FILE_DOCUMENT_SYNC, new FileDocumentManagerAdapter() { + @Override + public void fileContentLoaded(final VirtualFile virtualFile, Document document) { + PsiFile psiFile = ApplicationManager.getApplication().runReadAction(new Computable() { + public PsiFile compute() { + return getCachedPsiFile(virtualFile); + } + }); + fireDocumentCreated(document, psiFile); + } + }); } public void projectOpened() { @@ -183,8 +196,6 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec } } - fireDocumentCreated(document, file); - return document; } @@ -366,27 +377,12 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec } } - private Listener[] getCachedListeners() { - synchronized (myListeners) { - if (myCachedListeners == null) { - myCachedListeners = myListeners.toArray(new Listener[myListeners.size()]); - } - return myCachedListeners; - } - } - public void addListener(@NotNull Listener listener) { - synchronized (myListeners) { - myListeners.add(listener); - myCachedListeners = null; - } + myListeners.add(listener); } public void removeListener(@NotNull Listener listener) { - synchronized (myListeners) { - myListeners.remove(listener); - myCachedListeners = null; - } + myListeners.remove(listener); } public boolean isDocumentBlockedByPsi(@NotNull Document doc) { @@ -402,15 +398,13 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec } private void fireDocumentCreated(Document document, PsiFile file) { - Listener[] listeners = getCachedListeners(); - for (Listener listener : listeners) { + for (Listener listener : myListeners) { listener.documentCreated(document, file); } } private void fireFileCreated(Document document, PsiFile file) { - Listener[] listeners = getCachedListeners(); - for (Listener listener : listeners) { + for (Listener listener : myListeners) { listener.fileCreated(file, document); } } @@ -425,11 +419,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec if (textBlock.isEmpty()) return false; ((DocumentImpl)document).normalizeRangeMarkers(); myIsCommitInProgress = true; - try{ - if (mySmartPointerManager != null) { // mock tests - SmartPointerManagerImpl.synchronizePointers(file); - } - + try { myTreeElementBeingReparsedSoItWontBeCollected = ((PsiFileImpl)file).calcTreeElement(); if (textBlock.isEmpty()) return false ; // if tree was just loaded above textBlock will be cleared by contentsLoaded @@ -479,9 +469,6 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec } myBlockSupport.reparseRange(file, startOffset, endOffset, lengthShift, chars); - textBlock.unlock(); - textBlock.clear(); - if (file.getTextLength() != document.getTextLength()) { if (ApplicationManagerEx.getApplicationEx().isInternal()) { boolean x = false; @@ -502,8 +489,15 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec } } finally { + textBlock.unlock(); + textBlock.clear(); + myTreeElementBeingReparsedSoItWontBeCollected = null; myIsCommitInProgress = false; + + if (mySmartPointerManager != null) { // mock tests + SmartPointerManagerImpl.synchronizePointers(file); + } } return true; } @@ -530,12 +524,18 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec final FileViewProvider provider = getCachedViewProvider(document); if (provider == null) return; - if (provider.getVirtualFile().getFileType().isBinary()) return; + VirtualFile virtualFile = provider.getVirtualFile(); + if (virtualFile.getFileType().isBinary()) return; final List files = provider.getAllFiles(); boolean hasLockedBlocks = false; for (PsiFile file : files) { if (file == null) continue; + + if (file.isPhysical() && mySmartPointerManager != null) { // mock tests + SmartPointerManagerImpl.fastenBelts(file, event.getOffset()); + } + final TextBlock textBlock = getTextBlock(document, file); if (textBlock.isLocked()) { hasLockedBlocks = true; @@ -553,12 +553,6 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec myIsCommitInProgress = false; } } - - if (file.isPhysical()) { - if (mySmartPointerManager != null) { // mock tests - SmartPointerManagerImpl.fastenBelts(file); - } - } } if (!hasLockedBlocks) { @@ -570,19 +564,20 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec final Document document = event.getDocument(); final FileViewProvider viewProvider = getCachedViewProvider(document); if (viewProvider == null) return; - if (viewProvider.getVirtualFile().getFileType().isBinary()) return; + VirtualFile virtualFile = viewProvider.getVirtualFile(); + if (virtualFile.getFileType().isBinary()) return; if (viewProvider.getManager() != myPsiManager) return; final List files = viewProvider.getAllFiles(); boolean commitNecessary = false; for (PsiFile file : files) { if (file == null || file instanceof PsiFileImpl && ((PsiFileImpl)file).getTreeElement() == null) continue; + if (mySmartPointerManager != null) { // mock tests + SmartPointerManagerImpl.unfastenBelts(file, event.getOffset()); + } final TextBlock textBlock = getTextBlock(document, file); if (textBlock.isLocked()) continue; - if (mySmartPointerManager != null) { // mock tests - SmartPointerManagerImpl.unfastenBelts(file); - } textBlock.documentChanged(event); assert file instanceof PsiFileImpl || "mock.file".equals(file.getName()) && ApplicationManager.getApplication().isUnitTestMode() : event + "; file="+file+"; allFiles="+files+"; viewProvider="+viewProvider; diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java index 819fb5c75547..0f59c3011580 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java @@ -26,7 +26,6 @@ import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl; import com.intellij.util.messages.MessageBus; import org.jetbrains.annotations.Nullable; @@ -88,7 +87,6 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter { final boolean insideTransaction = myTransactionsMap.containsKey(document); if(!insideTransaction){ document.setModificationStamp(psiFile.getModificationStamp()); - SmartPointerManagerImpl.synchronizePointers(psiFile); if (LOG.isDebugEnabled()) { PsiDocumentManagerImpl.checkConsistency(psiFile, document); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java index bc08a0f12638..855428bd1783 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java @@ -866,7 +866,7 @@ public class FileManagerImpl implements FileManager { } if (oldPsiFile != null && oldPsiFile.isPhysical()) { - SmartPointerManagerImpl.fastenBelts(oldPsiFile); + SmartPointerManagerImpl.fastenBelts(oldPsiFile, 0); } ApplicationManager.getApplication().runWriteAction( new ExternalChangeAction() { @@ -1085,7 +1085,9 @@ public class FileManagerImpl implements FileManager { removeFilesAndDirsRecursively(child); } } - else myVFileToViewProviderMap.remove(vFile); + else { + myVFileToViewProviderMap.remove(vFile); + } } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java index c825b9ec7302..67500e1be06b 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java @@ -15,9 +15,12 @@ */ package com.intellij.psi.impl.smartPointers; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Segment; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; @@ -26,15 +29,12 @@ import org.jetbrains.annotations.NotNull; * User: cdr */ class FileElementInfo implements SmartPointerElementInfo { - private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.smartPointers.FileElementInfo"); - private PsiFile myFile; + private final VirtualFile myVirtualFile; private final Project myProject; public FileElementInfo(@NotNull PsiFile file) { - LOG.assertTrue(file.isPhysical()); - myFile = file; - - myProject = myFile.getProject(); + myVirtualFile = file.getVirtualFile(); + myProject = file.getProject(); } public Document getDocumentToSynchronize() { @@ -44,12 +44,42 @@ class FileElementInfo implements SmartPointerElementInfo { public void documentAndPsiInSync() { } + @Override + public void fastenBelt(int offset) { + } + + @Override + public void unfastenBelt(int offset) { + } + public PsiElement restoreElement() { - myFile = SelfElementInfo.restoreFile(myFile, myProject); - return myFile; + return SelfElementInfo.restoreFileFromVirtual(myVirtualFile, myProject); } @Override public void dispose() { } + + @Override + public int elementHashCode() { + return myVirtualFile.hashCode(); + } + + @Override + public boolean pointsToTheSameElementAs(SmartPointerElementInfo other) { + if (other instanceof FileElementInfo) { + return myVirtualFile == ((FileElementInfo)other).myVirtualFile; + } + return Comparing.equal(restoreElement(), other.restoreElement()); + } + + @Override + public VirtualFile getVirtualFile() { + return myVirtualFile; + } + + @Override + public Segment getSegment() { + return new TextRange(0, (int)myVirtualFile.getLength()); + } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/HardElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/HardElementInfo.java new file mode 100644 index 000000000000..3627aeb1b0e9 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/HardElementInfo.java @@ -0,0 +1,78 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.impl.smartPointers; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Segment; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiUtilBase; +import org.jetbrains.annotations.NotNull; + +/** +* User: cdr +*/ +class HardElementInfo implements SmartPointerElementInfo { + private final PsiElement myElement; + + public HardElementInfo(@NotNull PsiElement element) { + myElement = element; + } + + public Document getDocumentToSynchronize() { + return null; + } + + public void documentAndPsiInSync() { + } + + @Override + public void fastenBelt(int offset) { + } + + @Override + public void unfastenBelt(int offset) { + } + + public PsiElement restoreElement() { + return myElement; + } + + @Override + public void dispose() { + } + + @Override + public int elementHashCode() { + return myElement.hashCode(); + } + + @Override + public boolean pointsToTheSameElementAs(SmartPointerElementInfo other) { + return Comparing.equal(myElement, other.restoreElement()); + } + + @Override + public VirtualFile getVirtualFile() { + return PsiUtilBase.getVirtualFile(myElement); + } + + @Override + public Segment getSegment() { + return myElement.getTextRange(); + } +} diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java index 6d98f3736a25..88143db18c5c 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java @@ -18,7 +18,9 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.injected.editor.DocumentWindow; import com.intellij.openapi.editor.Document; import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; /** @@ -27,14 +29,16 @@ import org.jetbrains.annotations.NotNull; class InjectedSelfElementInfo extends SelfElementInfo { private DocumentWindow myDocument; - InjectedSelfElementInfo(@NotNull PsiElement anchor, @NotNull Document document) { - super(anchor, document); - - assert myFile.getContext() != null; + InjectedSelfElementInfo(@NotNull PsiElement anchor, PsiFile containingFile) { + super(anchor, containingFile); + assert containingFile.getContext() != null; } - protected TextRange getPersistentAnchorRange(final PsiElement anchor, final Document document) { - final TextRange textRange = super.getPersistentAnchorRange(anchor, document); + protected TextRange getPersistentAnchorRange(final PsiElement anchor) { + final TextRange textRange = super.getPersistentAnchorRange(anchor); + Document document = PsiDocumentManager.getInstance(anchor.getProject()).getDocument(anchor.getContainingFile()); + // must be non-text file + if (!(document instanceof DocumentWindow)) return textRange; myDocument = (DocumentWindow)document; return myDocument.injectedToHost(textRange); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/LazyPointerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/LazyPointerImpl.java index b091bc7de1b2..c22b15b37e3f 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/LazyPointerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/LazyPointerImpl.java @@ -16,6 +16,9 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Segment; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.util.ReflectionCache; import org.jetbrains.annotations.NotNull; @@ -27,7 +30,7 @@ public class LazyPointerImpl implements SmartPointerEx private final Class myElementClass; private final Project myProject; - public LazyPointerImpl(E element) { + LazyPointerImpl(@NotNull E element) { myElementClass = element.getClass(); if (element instanceof PsiCompiledElement) { myElement = element; @@ -38,21 +41,35 @@ public class LazyPointerImpl implements SmartPointerEx myProject = element.getProject(); } + public boolean pointsToTheSameElementAs(LazyPointerImpl pointer) { + if (myElementClass != pointer.myElementClass) return false; + if (myElement != null) return pointer.myElement == myElement; + if (myAnchor != null && pointer.myAnchor != null) { + return myAnchor.pointsToTheSameElementAs(pointer.myAnchor); + } + if (myPointer != null && pointer.myPointer != null) { + return SmartPointerManager.getInstance(myProject).pointToTheSameElement(myPointer, pointer.myPointer); + } + return Comparing.equal(getElement(), pointer.getElement()); + } + private static SmartPsiElementPointer setupPointer(PsiElement element) { return SmartPointerManager.getInstance(element.getProject()).createSmartPsiElementPointer(element); } - public void fastenBelt() { + public void fastenBelt(int offset) { if (myAnchor != null) { final PsiElement element = myAnchor.retrieve(); if (element != null) { myPointer = setupPointer(element); - ((SmartPointerEx)myPointer).fastenBelt(); + //((SmartPointerEx)myPointer).fastenBelt(offset); myAnchor = null; } - else myAnchor = null; } } + @Override + public void unfastenBelt(int offset) { + } public void documentAndPsiInSync() { } @@ -60,20 +77,12 @@ public class LazyPointerImpl implements SmartPointerEx public boolean equals(final Object o) { if (this == o) return true; if (!(o instanceof LazyPointerImpl)) return false; - final LazyPointerImpl that = (LazyPointerImpl)o; - - if (myAnchor != null ? !myAnchor.equals(that.myAnchor) : that.myAnchor != null) return false; - if (myElement != null ? !myElement.equals(that.myElement) : that.myElement != null) return false; - if (myElementClass != null ? !myElementClass.equals(that.myElementClass) : that.myElementClass != null) return false; - if (myPointer != null ? !myPointer.equals(that.myPointer) : that.myPointer != null) return false; - - return true; + return pointsToTheSameElementAs(that); } public int hashCode() { - int result; - result = (myElement != null ? myElement.hashCode() : 0); + int result = myElement != null ? myElement.hashCode() : 0; result = 31 * result + (myAnchor != null ? myAnchor.hashCode() : 0); result = 31 * result + (myPointer != null ? myPointer.hashCode() : 0); result = 31 * result + (myElementClass != null ? myElementClass.hashCode() : 0); @@ -85,11 +94,20 @@ public class LazyPointerImpl implements SmartPointerEx return myProject; } + @Override + public VirtualFile getVirtualFile() { + PsiFile psiFile = getContainingFile(); + return psiFile == null ? null : psiFile.getVirtualFile(); + } + public E getElement() { - if (myElement != null) return myElement.isValid() ? myElement : null; - if (myPointer != null) return (E) myPointer.getElement(); - if (myAnchor != null) { - final PsiElement psiElement = myAnchor.retrieve(); + E element = myElement; + if (element != null) return element.isValid() ? element : null; + SmartPsiElementPointer pointer = myPointer; + if (pointer != null) return (E) pointer.getElement(); + PsiAnchor anchor = myAnchor; + if (anchor != null) { + final PsiElement psiElement = anchor.retrieve(); if (psiElement != null) { return ReflectionCache.isAssignable(myElementClass, psiElement.getClass()) ? (E) psiElement : null; } @@ -99,12 +117,19 @@ public class LazyPointerImpl implements SmartPointerEx } public PsiFile getContainingFile() { - if (myElement != null) { - return myElement.getContainingFile(); + E element = myElement; + if (element != null) { + return element.getContainingFile(); } - if (myAnchor != null) { - return myAnchor.getFile(); + PsiAnchor anchor = myAnchor; + if (anchor != null) { + return anchor.getFile(); + } + + SmartPsiElementPointer pointer = myPointer; + if (pointer != null) { + return pointer.getContainingFile(); } return null; @@ -114,4 +139,21 @@ public class LazyPointerImpl implements SmartPointerEx public void dispose() { if (myPointer != null) ((SmartPointerEx)myPointer).dispose(); } + + @Override + public Segment getSegment() { + E element = myElement; + if (element != null && element.isValid()) return element.getTextRange(); + SmartPsiElementPointer pointer = myPointer; + if (pointer != null) return pointer.getSegment(); + PsiAnchor anchor = myAnchor; + if (anchor != null) { + final PsiElement psiElement = anchor.retrieve(); + if (psiElement != null) { + return psiElement.getTextRange(); + } + } + + return null; + } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java index 8f338691024f..2975a3c156c3 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java @@ -18,7 +18,10 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Segment; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; @@ -28,70 +31,144 @@ import com.intellij.psi.PsiManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.ref.Reference; +import java.lang.ref.SoftReference; + /** * User: cdr */ -class SelfElementInfo implements SmartPointerElementInfo { +public class SelfElementInfo implements SmartPointerElementInfo { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.smartPointers.SelfElementInfo"); - protected PsiFile myFile; - private final RangeMarker myMarker; + protected final VirtualFile myVirtualFile; + private Reference myMarkerRef; // create marker only in case of live document private int mySyncStartOffset; private int mySyncEndOffset; - private boolean mySyncMarkerIsValid; + protected boolean mySyncMarkerIsValid; private Class myType; - private final Project myProject; + protected final Project myProject; + private RangeMarker myRangeMarker; //maintain hard reference during modification - public SelfElementInfo(@NotNull PsiElement anchor, @NotNull Document document) { + public SelfElementInfo(@NotNull PsiElement anchor, PsiFile containingFile) { LOG.assertTrue(anchor.isPhysical()); - myFile = anchor.getContainingFile(); + LOG.assertTrue(anchor.isValid()); + PsiFile file = anchor.getContainingFile(); + myVirtualFile = file.getVirtualFile(); TextRange range = anchor.getTextRange(); LOG.assertTrue(range != null, anchor); + range = getPersistentAnchorRange(anchor); - myProject = myFile.getProject(); - final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); - - if (documentManager.isUncommited(document)) { - mySyncMarkerIsValid = false; - myMarker = document.createRangeMarker(0, 0, false); - } - else { - myMarker = document.createRangeMarker(range.getStartOffset(), range.getEndOffset(), true); - range = getPersistentAnchorRange(anchor, document); - - mySyncStartOffset = range.getStartOffset(); - mySyncEndOffset = range.getEndOffset(); - mySyncMarkerIsValid = true; - myType = anchor.getClass(); - } - } - - protected TextRange getPersistentAnchorRange(final PsiElement anchor, final Document document) { - return anchor.getTextRange(); - } - - public Document getDocumentToSynchronize() { - return myMarker.getDocument(); - } - - public void documentAndPsiInSync() { - if (!myMarker.isValid()) { + myProject = file.getProject(); + PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); + Document document = documentManager.getDocument(file); + if (document == null || documentManager.isUncommited(document)) { mySyncMarkerIsValid = false; return; } - mySyncStartOffset = myMarker.getStartOffset(); - mySyncEndOffset = myMarker.getEndOffset(); + //if (file.getTextLength() != document.getTextLength()) { + // final String docText = document.getText(); + // file.accept(new PsiRecursiveElementWalkingVisitor() { + // @Override + // public void visitElement(PsiElement element) { + // super.visitElement(element); + // TextRange elementRange = element.getTextRange(); + // final String rangeText = docText.length() < elementRange.getEndOffset() ? "(IOOBE: "+elementRange +" is out of (0,"+docText.length()+"))" : elementRange.substring(docText); + // final String elemText = element.getText(); + // if (!rangeText.equals(elemText)) { + // throw new AssertionError("PSI text doesn't equal to the document's one: element: " + element + "\ndocText=" + rangeText + "\npsiText: " + elemText); + // } + // } + // }); + // LOG.error("File=" + file); + //} + + if (documentManager.isUncommited(document)) { + mySyncMarkerIsValid = false; + } + else { + mySyncMarkerIsValid = true; + myType = anchor.getClass(); + } + mySyncStartOffset = range.getStartOffset(); + mySyncEndOffset = range.getEndOffset(); + } + + protected TextRange getPersistentAnchorRange(final PsiElement anchor) { + return anchor.getTextRange(); + } + + public Document getDocumentToSynchronize() { + RangeMarker marker = getMarker(); + if (marker != null) { + return marker.getDocument(); + } + return FileDocumentManager.getInstance().getCachedDocument(myVirtualFile); + } + + // before change + @Override + public void fastenBelt(int offset) { + if (!mySyncMarkerIsValid) return; + RangeMarker marker = getMarker(); + int actualEndOffset = marker == null || !marker.isValid() ? getSyncEndOffset() : marker.getEndOffset(); + if (offset > actualEndOffset) { + return; // no need to update, the change is far after + } + if (marker == null) { + Document document = FileDocumentManager.getInstance().getDocument(myVirtualFile); + if (document == null) { + mySyncMarkerIsValid = false; + return; + } + //PsiToDocumentSynchronizer synchronizer = ((PsiDocumentManagerImpl)PsiDocumentManager.getInstance(myProject)).getSynchronizer(); + //boolean inSynchronization = synchronizer.isInSynchronization(document); + + //if (!inSynchronization) { // otherwise doc offsets are incorrect + int start = Math.min(getSyncStartOffset(), document.getTextLength()); + int end = Math.min(Math.max(getSyncEndOffset(), start), document.getTextLength()); + marker = document.createRangeMarker(start, end, true); + setMarker(marker); + myRangeMarker = marker; //make sure marker wont be gced + //} + } + else if (!marker.isValid()) { + mySyncMarkerIsValid = false; + marker.dispose(); + setMarker(null); + } + } + + // after change + @Override + public void unfastenBelt(int offset) { + if (!mySyncMarkerIsValid) return; + RangeMarker marker = getMarker(); + if (marker != null) { + if (marker.isValid()) { + mySyncStartOffset = marker.getStartOffset(); + mySyncEndOffset = marker.getEndOffset(); + assert mySyncEndOffset <= marker.getDocument().getTextLength(); + } + else { + mySyncMarkerIsValid = false; + } + } + myRangeMarker = null; + } + + // commit + public void documentAndPsiInSync() { } public PsiElement restoreElement() { if (!mySyncMarkerIsValid) return null; - myFile = restoreFile(myFile, myProject); - if (myFile == null) return null; + PsiFile file = restoreFileFromVirtual(myVirtualFile, myProject); + if (file == null || !file.isValid()) return null; final int syncStartOffset = getSyncStartOffset(); final int syncEndOffset = getSyncEndOffset(); - PsiElement anchor = myFile.getViewProvider().findElementAt(syncStartOffset, myFile.getLanguage()); + PsiElement anchor = file.getViewProvider().findElementAt(syncStartOffset, file.getLanguage()); if (anchor == null) return null; TextRange range = anchor.getTextRange(); @@ -115,23 +192,46 @@ class SelfElementInfo implements SmartPointerElementInfo { @Override public void dispose() { - if (myMarker != null) { - myMarker.dispose(); + RangeMarker marker = getMarker(); + if (marker != null) { + marker.dispose(); + setMarker(null); } } + private RangeMarker getMarker() { + Reference ref = myMarkerRef; + return ref == null ? null : ref.get(); + } + + private void setMarker(RangeMarker marker) { + myMarkerRef = marker == null ? null : new SoftReference(marker); + } + @Nullable public static PsiFile restoreFile(PsiFile file,@NotNull Project project) { if (file == null) return null; if (file.isValid()) return file; VirtualFile virtualFile = file.getVirtualFile(); + return restoreFileFromVirtual(virtualFile, project); + } + + @Nullable + public static PsiFile restoreFileFromVirtual(VirtualFile virtualFile, @NotNull Project project) { if (virtualFile == null) return null; - VirtualFile vParent = virtualFile.getParent(); - if (vParent == null || !vParent.isDirectory()) return null; - String name = file.getName(); - VirtualFile child = vParent.findChild(name); + + VirtualFile child; + if (virtualFile.isValid()) { + child = virtualFile; + } + else { + VirtualFile vParent = virtualFile.getParent(); + if (vParent == null || !vParent.isDirectory()) return null; + String name = virtualFile.getName(); + child = vParent.findChild(name); + } if (child == null || !child.isValid()) return null; - file = PsiManager.getInstance(project).findFile(child); + PsiFile file = PsiManager.getInstance(project).findFile(child); if (file == null || !file.isValid()) return null; return file; } @@ -143,4 +243,32 @@ class SelfElementInfo implements SmartPointerElementInfo { protected int getSyncStartOffset() { return mySyncStartOffset; } + + @Override + public int elementHashCode() { + return myVirtualFile.hashCode(); + } + + @Override + public boolean pointsToTheSameElementAs(SmartPointerElementInfo other) { + if (other instanceof SelfElementInfo) { + return myVirtualFile == ((SelfElementInfo)other).myVirtualFile + && myType == ((SelfElementInfo)other).myType + && mySyncStartOffset == ((SelfElementInfo)other).mySyncStartOffset + && mySyncEndOffset == ((SelfElementInfo)other).mySyncEndOffset + ; + } + return Comparing.equal(restoreElement(), other.restoreElement()); + } + + @Override + public VirtualFile getVirtualFile() { + return myVirtualFile; + } + + @Override + public Segment getSegment() { + if (!mySyncMarkerIsValid) return null; + return new TextRange(getSyncStartOffset(), getSyncEndOffset()); + } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java index 98435ed3f3ca..6c0e37657cbb 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java @@ -17,6 +17,8 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.util.Segment; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.Nullable; @@ -25,9 +27,17 @@ interface SmartPointerElementInfo { Document getDocumentToSynchronize(); void documentAndPsiInSync(); + void fastenBelt(int offset); + + void unfastenBelt(int offset); @Nullable PsiElement restoreElement(); void dispose(); + int elementHashCode(); // must be immutable + boolean pointsToTheSameElementAs(SmartPointerElementInfo other); + + VirtualFile getVirtualFile(); + Segment getSegment(); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfoFactory.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfoFactory.java index e33fbc48cb25..0cc69adb1972 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfoFactory.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfoFactory.java @@ -18,6 +18,7 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -27,5 +28,5 @@ public interface SmartPointerElementInfoFactory { ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.smartPointerElementInfoFactory"); @Nullable - SmartPointerElementInfo createElementInfo(PsiElement element); + SmartPointerElementInfo createElementInfo(@NotNull PsiElement element); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerEx.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerEx.java index 4ab980b7ef08..c04ba391837d 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerEx.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerEx.java @@ -15,11 +15,14 @@ */ package com.intellij.psi.impl.smartPointers; +import com.intellij.openapi.Disposable; import com.intellij.psi.PsiElement; import com.intellij.psi.SmartPsiElementPointer; -public interface SmartPointerEx extends SmartPsiElementPointer { - void fastenBelt(); +public interface SmartPointerEx extends SmartPsiElementPointer, Disposable { + void fastenBelt(int offset); void documentAndPsiInSync(); void dispose(); + + void unfastenBelt(int offset); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java index 3e1a0f9da35d..70bd6e2f8808 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java @@ -20,21 +20,21 @@ import com.intellij.lang.Language; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.psi.*; -import com.intellij.psi.impl.PsiDocumentManagerImpl; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import org.jetbrains.annotations.NotNull; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.List; import java.util.Set; public class SmartPointerManagerImpl extends SmartPointerManager { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl"); - private static final Key>> SMART_POINTERS_IN_PSI_FILE_KEY = Key.create( - "SMART_POINTERS_IN_DOCUMENT_KEY"); + private static final Key>> SMART_POINTERS_IN_PSI_FILE_KEY = Key.create("SMART_POINTERS_IN_DOCUMENT_KEY"); private static final Key BELTS_ARE_FASTEN_KEY = Key.create("BELTS_ARE_FASTEN_KEY"); private final Project myProject; @@ -43,13 +43,13 @@ public class SmartPointerManagerImpl extends SmartPointerManager { myProject = project; } - public static void fastenBelts(PsiFile file) { + public static void fastenBelts(PsiFile file, int offset) { synchronized (file) { if (areBeltsFastened(file)) return; file.putUserData(BELTS_ARE_FASTEN_KEY, Boolean.TRUE); - ArrayList> pointers = file.getUserData(SMART_POINTERS_IN_PSI_FILE_KEY); + List> pointers = getPointers(file); if (pointers == null) return; int index = 0; @@ -57,7 +57,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager { WeakReference reference = pointers.get(i); SmartPointerEx pointer = reference.get(); if (pointer != null) { - pointer.fastenBelt(); + pointer.fastenBelt(offset); pointers.set(index++, reference); } } @@ -66,22 +66,46 @@ public class SmartPointerManagerImpl extends SmartPointerManager { for(Document document:InjectedLanguageUtil.getCachedInjectedDocuments(file)) { PsiFile injectedfile = psiDocumentManager.getPsiFile(document); if (injectedfile == null) continue; - fastenBelts(injectedfile); + fastenBelts(injectedfile, 0); } int size = pointers.size(); for (int i = size - 1; i >= index; i--) { pointers.remove(i); } + int i = 0; } } - public static void unfastenBelts(PsiFile file) { + public static void unfastenBelts(PsiFile file, int offset) { final Set languages = file.getViewProvider().getLanguages(); for (Language language : languages) { final PsiFile f = file.getViewProvider().getPsi(language); - synchronized (f) { - f.putUserData(BELTS_ARE_FASTEN_KEY, null); + f.putUserData(BELTS_ARE_FASTEN_KEY, null); + + List> pointers = getPointers(file); + if (pointers == null) return; + + int index = 0; + for (int i = 0; i < pointers.size(); i++) { + WeakReference reference = pointers.get(i); + SmartPointerEx pointer = reference.get(); + if (pointer != null) { + pointer.unfastenBelt(offset); + pointers.set(index++, reference); + } + } + + final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(file.getProject()); + for(Document document:InjectedLanguageUtil.getCachedInjectedDocuments(file)) { + PsiFile injectedfile = psiDocumentManager.getPsiFile(document); + if (injectedfile == null) continue; + unfastenBelts(injectedfile, 0); + } + + int size = pointers.size(); + for (int i = size - 1; i >= index; i--) { + pointers.remove(i); } } } @@ -97,7 +121,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager { } private static void _synchronizePointers(final PsiFile file) { - ArrayList> pointers = file.getUserData(SMART_POINTERS_IN_PSI_FILE_KEY); + List> pointers = getPointers(file); if (pointers == null) return; int index = 0; @@ -124,64 +148,71 @@ public class SmartPointerManagerImpl extends SmartPointerManager { } @NotNull - public SmartPsiElementPointer createSmartPsiElementPointer(E element) { + public SmartPsiElementPointer createSmartPsiElementPointer(@NotNull E element) { if (!element.isValid()) { LOG.error("Invalid element:" + element); } - - PsiFile file = element.getContainingFile(); - - if (isSafeReparseable(file)) { - return new IdentitySmartPointer(element); - } - - SmartPointerEx pointer = new SmartPsiElementPointerImpl(myProject, element); - initPointer(element, pointer); + PsiFile containingFile = element.getContainingFile(); + SmartPointerEx pointer = new SmartPsiElementPointerImpl(myProject, element, containingFile); + initPointer(element, pointer, containingFile); return pointer; } - private static boolean isSafeReparseable(final PsiFile file) { - return false; - //return file != null && !(file instanceof CodeFragmentElement); TODO: needs proper processing of foreign chameleons on reparse (like javascript in HTML). - } + private void initPointer(E element, SmartPointerEx pointer, PsiFile containingFile) { + if (containingFile == null) return; + synchronized (containingFile) { + Document document = PsiDocumentManager.getInstance(myProject).getCachedDocument(containingFile); + //todo + //if (document != null) { + // //[ven] this is a really NASTY hack; when no smart pointer is kept on UsageInfo then remove this conditional + // if (!(element instanceof PsiFile)) { + // PsiDocumentManagerImpl documentManager = (PsiDocumentManagerImpl)PsiDocumentManager.getInstance(myProject); + // LOG.assertTrue(!documentManager.isUncommited(document) || documentManager.isCommittingDocument(document), "Document for : " + + // containingFile + " is not committed"); + // } + //} - private void initPointer(E element, SmartPointerEx pointer) { - PsiFile file = element.getContainingFile(); - if (file != null) { - synchronized (file) { - Document document = PsiDocumentManager.getInstance(myProject).getCachedDocument(file); - if (document != null) { - //[ven] this is a really NASTY hack; when no smart pointer is kept on UsageInfo then remove this conditional - if (!(element instanceof PsiFile)) { - PsiDocumentManagerImpl documentManager = (PsiDocumentManagerImpl)PsiDocumentManager.getInstance(myProject); - LOG.assertTrue(!documentManager.isUncommited(document) || documentManager.isCommittingDocument(document), "Document for : " + file + " is not committed"); - } - } + List> pointers = getPointers(containingFile); + if (pointers == null) { + pointers = new ArrayList>(); + containingFile.putUserData(SMART_POINTERS_IN_PSI_FILE_KEY, pointers); + } + pointers.add(new WeakReference(pointer)); - ArrayList> pointers = file.getUserData(SMART_POINTERS_IN_PSI_FILE_KEY); - if (pointers == null) { - pointers = new ArrayList>(); - file.putUserData(SMART_POINTERS_IN_PSI_FILE_KEY, pointers); - } - pointers.add(new WeakReference(pointer)); - - if (areBeltsFastened(file)) { - pointer.fastenBelt(); - } + if (areBeltsFastened(containingFile)) { + pointer.fastenBelt(0); } } } + private static List> getPointers(@NotNull PsiFile containingFile) { + return containingFile.getUserData(SMART_POINTERS_IN_PSI_FILE_KEY); + } + private static boolean areBeltsFastened(final PsiFile file) { return file.getUserData(BELTS_ARE_FASTEN_KEY) == Boolean.TRUE; } @NotNull - public SmartPsiElementPointer createLazyPointer(E element) { - LazyPointerImpl pointer = new LazyPointerImpl(element); - initPointer(element, pointer); - return pointer; + public SmartPsiElementPointer createLazyPointer(@NotNull E element) { + return createSmartPsiElementPointer(element); + //LazyPointerImpl pointer = new LazyPointerImpl(element); + //initPointer(element, pointer, element.getContainingFile()); + //return pointer; + } + + @Override + public boolean pointToTheSameElement(@NotNull SmartPsiElementPointer pointer1, @NotNull SmartPsiElementPointer pointer2) { + if (pointer1 instanceof SmartPsiElementPointerImpl && pointer2 instanceof SmartPsiElementPointerImpl) { + SmartPointerElementInfo elementInfo1 = ((SmartPsiElementPointerImpl)pointer1).getElementInfo(); + SmartPointerElementInfo elementInfo2 = ((SmartPsiElementPointerImpl)pointer2).getElementInfo(); + return elementInfo1.pointsToTheSameElementAs(elementInfo2); + } + if (pointer1 instanceof LazyPointerImpl && pointer2 instanceof LazyPointerImpl) { + return ((LazyPointerImpl)pointer1).pointsToTheSameElementAs((LazyPointerImpl)pointer2); + } + return Comparing.equal(pointer1.getElement(), pointer2.getElement()); } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java index da8b80f07d38..7893c8f4c496 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java @@ -21,50 +21,54 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Segment; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; -import com.intellij.psi.impl.PsiDocumentManagerImpl; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; + class SmartPsiElementPointerImpl implements SmartPointerEx { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.smartPointers.SmartPsiElementPointerImpl"); - private E myElement; - private SmartPointerElementInfo myElementInfo; + private Reference myElement; + private final SmartPointerElementInfo myElementInfo; private final Project myProject; + private final Class myElementClass; - public SmartPsiElementPointerImpl(Project project, E element) { + public SmartPsiElementPointerImpl(@NotNull Project project, @NotNull E element, PsiFile containingFile) { myProject = project; ApplicationManager.getApplication().assertReadAccessAllowed(); - myElement = element; - myElementInfo = null; + myElement = new WeakReference(element); + myElementInfo = createElementInfo(element, containingFile); + myElementClass = element.getClass(); // Assert document committed. - PsiFile file = element.getContainingFile(); - if (file != null) { - final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); - if (psiDocumentManager instanceof PsiDocumentManagerImpl) { - Document doc = psiDocumentManager.getCachedDocument(file); - if (doc != null) { - //[ven] this is a really NASTY hack; when no smart pointer is kept on UsageInfo then remove this conditional - if (!(element instanceof PsiFile)) { - LOG.assertTrue(!psiDocumentManager.isUncommited(doc) || ((PsiDocumentManagerImpl)psiDocumentManager).isCommittingDocument(doc)); - } - } - } - } + //todo + //if (containingFile != null) { + // final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); + // if (psiDocumentManager instanceof PsiDocumentManagerImpl) { + // Document doc = psiDocumentManager.getCachedDocument(containingFile); + // if (doc != null) { + // //[ven] this is a really NASTY hack; when no smart pointer is kept on UsageInfo then remove this conditional + // if (!(element instanceof PsiFile)) { + // LOG.assertTrue(!psiDocumentManager.isUncommited(doc) || ((PsiDocumentManagerImpl)psiDocumentManager).isCommittingDocument(doc)); + // } + // } + // } + //} } public boolean equals(Object obj) { if (!(obj instanceof SmartPsiElementPointer)) return false; SmartPsiElementPointer pointer = (SmartPsiElementPointer)obj; - return Comparing.equal(pointer.getElement(), getElement()); + return SmartPointerManager.getInstance(myProject).pointToTheSameElement(this, pointer); } public int hashCode() { - PsiElement element = getElement(); - return element != null ? element.hashCode() : 0; + return myElementInfo.elementHashCode(); } @NotNull @@ -74,35 +78,38 @@ class SmartPsiElementPointerImpl implements SmartPointerEx @Nullable public E getElement() { - if (myElement != null && !myElement.isValid()) { - if (myElementInfo == null) { - myElement = null; + PsiElement element = getCachedElement(); + if (element != null && !element.isValid()) { + element = null; + } + if (element == null && myElementInfo != null) { + element = myElementInfo.restoreElement(); + if (element != null && (!element.getClass().equals(myElementClass) || !element.isValid())) { + element = null; } - else { - PsiElement restored = myElementInfo.restoreElement(); - if (restored != null && (!areElementKindEqual(restored, myElement) || !restored.isValid())) { - restored = null; - } - myElement = (E) restored; - } + myElement = element == null ? null : new WeakReference(element); } - //if (myElementInfo != null && myElement != null) { - // Document document = myElementInfo.getDocumentToSynchronize(); - // if (document != null && PsiDocumentManager.getInstance(myProject).isUncommited(document)) return myElement; // keep element info if document is modified - //} - // myElementInfo = null; + return (E)element; + } - return myElement; + private E getCachedElement() { + return myElement == null ? null : myElement.get(); } public PsiFile getContainingFile() { - if (myElement != null) { - return myElement.getContainingFile(); + E element = getCachedElement(); + if (element != null) { + return element.getContainingFile(); + } + VirtualFile virtualFile = myElementInfo.getVirtualFile(); + if (virtualFile != null && virtualFile.isValid()) { + PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(virtualFile); + if (psiFile != null) return psiFile; } - final Document doc = myElementInfo == null ? null : myElementInfo.getDocumentToSynchronize(); + final Document doc = myElementInfo.getDocumentToSynchronize(); if (doc == null) { final E resolved = getElement(); return resolved != null ? resolved.getContainingFile() : null; @@ -110,37 +117,37 @@ class SmartPsiElementPointerImpl implements SmartPointerEx return PsiDocumentManager.getInstance(myProject).getPsiFile(doc); } - @Nullable - private SmartPointerElementInfo createElementInfo() { - if (myElement instanceof PsiCompiledElement) return null; + public VirtualFile getVirtualFile() { + return myElementInfo.getVirtualFile(); + } - final PsiFile containingFile = myElement.getContainingFile(); - if (containingFile == null) return null; - if (!myElement.isPhysical()) return null; + @Override + public Segment getSegment() { + return myElementInfo.getSegment(); + } + + @NotNull + private SmartPointerElementInfo createElementInfo(@NotNull E element, PsiFile containingFile) { + if (element instanceof PsiCompiledElement || !element.isPhysical() || containingFile == null || element.getTextRange() == null) { + return new HardElementInfo(element); + } for(SmartPointerElementInfoFactory factory: Extensions.getExtensions(SmartPointerElementInfoFactory.EP_NAME)) { - final SmartPointerElementInfo result = factory.createElementInfo(myElement); + final SmartPointerElementInfo result = factory.createElementInfo(element); if (result != null) { return result; } } - if (myElement instanceof PsiFile) { - return new FileElementInfo((PsiFile)myElement); + if (element instanceof PsiFile) { + return new FileElementInfo((PsiFile)element); } - PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject()); - Document document = documentManager.getDocument(containingFile); - if (document == null) return null; // must be non-text file if (containingFile.getContext() != null) { - return new InjectedSelfElementInfo(myElement, document); + return new InjectedSelfElementInfo(element, containingFile); } - return new SelfElementInfo(myElement, document); - } - - private static boolean areElementKindEqual(PsiElement element1, PsiElement element2) { - return element1.getClass().equals(element2.getClass()); //? + return new SelfElementInfo(element, containingFile); } public void documentAndPsiInSync() { @@ -153,16 +160,20 @@ class SmartPsiElementPointerImpl implements SmartPointerEx public void dispose() { if (myElementInfo != null) { myElementInfo.dispose(); - myElementInfo = null; myElement = null; } } - public void fastenBelt() { - if (myElementInfo != null && myElement != null && myElement.isValid()) return; + @Override + public void unfastenBelt(int offset) { + myElementInfo.unfastenBelt(offset); + } - if (myElementInfo == null && myElement != null && myElement.isValid()) { - myElementInfo = createElementInfo(); - } + public void fastenBelt(int offset) { + myElementInfo.fastenBelt(offset); + } + + SmartPointerElementInfo getElementInfo() { + return myElementInfo; } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/ChangeUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/ChangeUtil.java index d7ec9af5dd73..684d3dae7878 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/ChangeUtil.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/ChangeUtil.java @@ -32,7 +32,6 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.impl.PsiManagerEx; -import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl; import com.intellij.psi.impl.source.DummyHolder; import com.intellij.psi.impl.source.DummyHolderFactory; import com.intellij.psi.impl.source.SourceTreeToPsiMap; @@ -192,9 +191,9 @@ public class ChangeUtil { final PsiManagerEx psiManager = (PsiManagerEx) manager; final PsiFile file = (PsiFile)changedFile.getPsi(); - if (file.isPhysical()) { - SmartPointerManagerImpl.fastenBelts(file); - } + //if (file.isPhysical()) { + // SmartPointerManagerImpl.fastenBelts(file, changedElement.getStartOffset()); + //} action.makeChange(destinationTreeChange); diff --git a/platform/platform-api/src/com/intellij/util/ui/RangeBlinker.java b/platform/platform-api/src/com/intellij/util/ui/RangeBlinker.java index 3ed4e6d7c1c1..952dc7e64869 100644 --- a/platform/platform-api/src/com/intellij/util/ui/RangeBlinker.java +++ b/platform/platform-api/src/com/intellij/util/ui/RangeBlinker.java @@ -18,9 +18,9 @@ package com.intellij.util.ui; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.markup.*; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Segment; import com.intellij.util.Alarm; import com.intellij.util.ArrayUtil; @@ -33,7 +33,7 @@ import java.util.List; public class RangeBlinker { private final Editor myEditor; private int myTimeToLive; - private final List myMarkers = new ArrayList(); + private final List myMarkers = new ArrayList(); private boolean show = true; private final Alarm myBlinkingAlarm = new Alarm(); private final TextAttributes myAttributes; @@ -44,7 +44,8 @@ public class RangeBlinker { myEditor = editor; myTimeToLive = timeToLive; } - public void resetMarkers(final List markers) { + + public void resetMarkers(final List markers) { removeHighlights(); myMarkers.clear(); stopBlinking(); @@ -72,8 +73,7 @@ public class RangeBlinker { MarkupModel markupModel = myEditor.getMarkupModel(); if (show) { - for (final RangeMarker rangeMarker : myMarkers) { - if (!rangeMarker.isValid()) continue; + for (Segment rangeMarker : myMarkers) { RangeHighlighter highlighter = markupModel.addRangeHighlighter(rangeMarker.getStartOffset(), rangeMarker.getEndOffset(), HighlighterLayer.ADDITIONAL_SYNTAX, myAttributes, HighlighterTargetArea.EXACT_RANGE); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java index c667e0e418f2..68d778ffc720 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java @@ -17,7 +17,6 @@ package com.intellij.openapi.fileEditor.impl; import com.intellij.AppTopics; import com.intellij.codeStyle.CodeStyleFacade; -import com.intellij.ide.IdeEventQueue; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.components.ApplicationComponent; @@ -608,6 +607,6 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl } private void fireFileContentLoaded(final VirtualFile file, final DocumentEx document) { - //myBus.asyncPublisher(AppTopics.FILE_DOCUMENT_SYNC).fileContentLoaded(file, document); + myBus.syncPublisher(AppTopics.FILE_DOCUMENT_SYNC).fileContentLoaded(file, document); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/project/FileContentQueue.java b/platform/platform-impl/src/com/intellij/openapi/project/FileContentQueue.java index 7b08c9bb603e..fb79f4e906aa 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/FileContentQueue.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/FileContentQueue.java @@ -43,7 +43,7 @@ public class FileContentQueue { private long myTotalSize; private final ArrayBlockingQueue myQueue = new ArrayBlockingQueue(256); - private Queue myPushbackBuffer = new ArrayDeque(); + private final Queue myPushbackBuffer = new ArrayDeque(); public void queue(final Collection files, @Nullable final ProgressIndicator indicator) { final Runnable contentLoadingRunnable = new Runnable() { diff --git a/platform/testFramework/src/_LastInSuiteTest.java b/platform/testFramework/src/_LastInSuiteTest.java index e9d79552eb78..13cd6b9eff84 100644 --- a/platform/testFramework/src/_LastInSuiteTest.java +++ b/platform/testFramework/src/_LastInSuiteTest.java @@ -18,7 +18,7 @@ import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.util.Disposer; -import com.intellij.testFramework.LeakedProjectHunter; +import com.intellij.testFramework.LeakHunter; import com.intellij.testFramework.LightPlatformTestCase; import com.intellij.util.ui.UIUtil; import junit.framework.TestCase; @@ -37,7 +37,7 @@ public class _LastInSuiteTest extends TestCase { }.execute().throwException(); final Application application = ApplicationManager.getApplication(); - LeakedProjectHunter.checkProjectLeak(application); + LeakHunter.checkProjectLeak(application); UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override diff --git a/platform/testFramework/src/com/intellij/testFramework/LeakedProjectHunter.java b/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java similarity index 87% rename from platform/testFramework/src/com/intellij/testFramework/LeakedProjectHunter.java rename to platform/testFramework/src/com/intellij/testFramework/LeakHunter.java index e726ef17c497..3542b804050f 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LeakedProjectHunter.java +++ b/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java @@ -15,11 +15,12 @@ */ package com.intellij.testFramework; -import com.intellij.openapi.application.impl.ApplicationImpl; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.impl.ProjectImpl; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.UserDataHolder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.impl.source.tree.TreeElement; import com.intellij.util.Processor; import com.intellij.util.containers.Stack; import com.intellij.util.io.PersistentEnumerator; @@ -27,6 +28,7 @@ import com.intellij.util.ui.UIUtil; import gnu.trove.THashMap; import gnu.trove.THashSet; import gnu.trove.TObjectHashingStrategy; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.TestOnly; import javax.swing.*; @@ -40,7 +42,7 @@ import java.util.Set; /** * User: cdr */ -public class LeakedProjectHunter { +public class LeakHunter { private static final Map> allFields = new THashMap>(); private static List getAllFields(Class aClass) { List cached = allFields.get(aClass); @@ -65,13 +67,13 @@ public class LeakedProjectHunter { } private static final Set visited = new THashSet(TObjectHashingStrategy.IDENTITY); - static class BackLink { - Class aClass; - Object value; - Field field; - BackLink backLink; + private static class BackLink { + private final Class aClass; + private final Object value; + private final Field field; + private final BackLink backLink; - BackLink(Class aClass, Object value, Field field, BackLink backLink) { + private BackLink(Class aClass, Object value, Field field, BackLink backLink) { this.aClass = aClass; this.value = value; this.field = field; @@ -89,11 +91,15 @@ public class LeakedProjectHunter { Class rootClass = backLink.aClass; List fields = getAllFields(rootClass); for (Field field : fields) { - if (root instanceof Reference && "referent".equals(field.getName())) continue; // do not follow weak/soft refs + String fieldName = field.getName(); + if (root instanceof Reference && "referent".equals(fieldName)) continue; // do not follow weak/soft refs Object value = field.get(root); if (value == null) continue; + if (value instanceof PsiElement || value instanceof TreeElement) { + int i = 0; + } Class valueClass = value.getClass(); - if (valueClass == lookFor) { + if (lookFor.isAssignableFrom(valueClass)) { BackLink newBackLink = new BackLink(valueClass, value, field, backLink); processor.process(newBackLink); } @@ -146,7 +152,7 @@ public class LeakedProjectHunter { checkLeak(root, ProjectImpl.class); } @TestOnly - public static void checkLeak(Object root, Class suspectClass) throws Exception { + public static void checkLeak(@NotNull Object root, @NotNull Class suspectClass) throws Exception { if (SwingUtilities.isEventDispatchThread()) { UIUtil.dispatchAllInvocationEvents(); } @@ -154,7 +160,9 @@ public class LeakedProjectHunter { UIUtil.pump(); } PersistentEnumerator.clearCacheForTests(); - toVisit.push(new BackLink(ApplicationImpl.class, root, null,null)); + toVisit.clear(); + visited.clear(); + toVisit.push(new BackLink(root.getClass(), root, null,null)); try { walkObjects(new Processor() { @Override diff --git a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java index 9ee5e797ab2c..4d6ea46f2d64 100644 --- a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java +++ b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java @@ -26,20 +26,20 @@ import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.PlainSyntaxHighlighter; import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.util.Segment; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.tree.IElementType; import com.intellij.usageView.UsageTreeColors; import com.intellij.usageView.UsageTreeColorsScheme; +import com.intellij.util.Processor; import com.intellij.util.containers.FactoryMap; import org.jetbrains.annotations.NotNull; import java.awt.*; import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; @@ -60,7 +60,6 @@ public class ChunkExtractor { private final Lexer myLexer; private abstract static class WeakFactory { - private WeakReference myRef; @NotNull @@ -74,7 +73,6 @@ public class ChunkExtractor { myRef = new WeakReference(result); return result; } - } private static final ThreadLocal>> ourExtractors = new ThreadLocal>>() { @@ -95,19 +93,18 @@ public class ChunkExtractor { } }; - public static TextChunk[] extractChunks(PsiElement element, List rangeMarkers) { - return ourExtractors.get().getValue().get(element.getContainingFile()).extractChunks(rangeMarkers); + public static TextChunk[] extractChunks(PsiFile file, UsageInfo2UsageAdapter usageAdapter) { + return ourExtractors.get().getValue().get(file).extractChunks(usageAdapter); } - private ChunkExtractor(PsiFile file) { + private ChunkExtractor(@NotNull PsiFile file) { myColorsScheme = UsageTreeColorsScheme.getInstance().getScheme(); myDocument = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); LOG.assertTrue(myDocument != null); final FileType fileType = file.getFileType(); - final SyntaxHighlighter highlighter = - SyntaxHighlighter.PROVIDER.create(fileType, file.getProject(), file.getVirtualFile()); + final SyntaxHighlighter highlighter = SyntaxHighlighter.PROVIDER.create(fileType, file.getProject(), file.getVirtualFile()); myHighlighter = highlighter == null ? new PlainSyntaxHighlighter() : highlighter; myLexer = myHighlighter.getHighlightingLexer(); myLexer.start(myDocument.getCharsSequence()); @@ -124,18 +121,13 @@ public class ChunkExtractor { return minStart == Integer.MAX_VALUE ? -1 : minStart; } - public TextChunk[] extractChunks(List rangeMarkers) { - final ArrayList markers = new ArrayList(rangeMarkers.size()); - for (RangeMarker rangeMarker : rangeMarkers) { - if (rangeMarker.isValid()) markers.add(rangeMarker); - } - int absoluteStartOffset = getStartOffset(markers); + private TextChunk[] extractChunks(UsageInfo2UsageAdapter usageInfo2UsageAdapter) { + int absoluteStartOffset = usageInfo2UsageAdapter.getNavigationOffset(); assert absoluteStartOffset != -1; final int lineNumber = myDocument.getLineNumber(absoluteStartOffset); final int columnNumber = absoluteStartOffset - myDocument.getLineStartOffset(lineNumber); - Collections.sort(markers, RangeMarker.BY_START_OFFSET); int lineStartOffset = myDocument.getLineStartOffset(lineNumber); int lineEndOffset = lineStartOffset < myDocument.getTextLength() ? myDocument.getLineEndOffset(lineNumber) : 0; if (lineStartOffset > lineEndOffset) return TextChunk.EMPTY_ARRAY; @@ -150,10 +142,10 @@ public class ChunkExtractor { lineStartOffset = Math.max(lineStartOffset, absoluteStartOffset - OFFSET_BEFORE_TO_SHOW_WHEN_LONG_LINE); lineEndOffset = Math.min(lineEndOffset, absoluteStartOffset + OFFSET_AFTER_TO_SHOW_WHEN_LONG_LINE); } - return createTextChunks(markers, chars, lineStartOffset, lineEndOffset, result); + return createTextChunks(usageInfo2UsageAdapter, chars, lineStartOffset, lineEndOffset, result); } - private TextChunk[] createTextChunks(final List markers, + private TextChunk[] createTextChunks(final UsageInfo2UsageAdapter usageInfo2UsageAdapter, final CharSequence chars, int start, int end, @@ -185,7 +177,7 @@ public class ChunkExtractor { IElementType tokenType = lexer.getTokenType(); TextAttributesKey[] tokenHighlights = highlighter.getTokenHighlights(tokenType); - processIntersectingRange(markers, chars, hiStart, hiEnd, tokenHighlights, result); + processIntersectingRange(usageInfo2UsageAdapter, chars, hiStart, hiEnd, tokenHighlights, result); } finally { lexer.advance(); @@ -195,28 +187,32 @@ public class ChunkExtractor { return result.toArray(new TextChunk[result.size()]); } - private void processIntersectingRange(List markers, - CharSequence chars, + private void processIntersectingRange(UsageInfo2UsageAdapter usageInfo2UsageAdapter, + final CharSequence chars, int hiStart, - int hiEnd, + final int hiEnd, TextAttributesKey[] tokenHighlights, - List result) { - TextAttributes originalAttrs = convertAttributes(tokenHighlights); - int lastOffset = hiStart; - for(RangeMarker rangeMarker: markers) { - int usageStart = rangeMarker.getStartOffset(); - int usageEnd = rangeMarker.getEndOffset(); - if (rangeMarker.isValid() && rangeIntersect(lastOffset, hiEnd, usageStart, usageEnd)) { - addChunk(chars, lastOffset, Math.max(lastOffset, usageStart), originalAttrs, false, result); - addChunk(chars, Math.max(lastOffset, usageStart), Math.min(hiEnd, usageEnd), originalAttrs, true, result); - if (usageEnd > hiEnd) { - return; + final List result) { + final TextAttributes originalAttrs = convertAttributes(tokenHighlights); + final int[] lastOffset = {hiStart}; + usageInfo2UsageAdapter.processRangeMarkers(new Processor() { + @Override + public boolean process(Segment segment) { + int usageStart = segment.getStartOffset(); + int usageEnd = segment.getEndOffset(); + if (rangeIntersect(lastOffset[0], hiEnd, usageStart, usageEnd)) { + addChunk(chars, lastOffset[0], Math.max(lastOffset[0], usageStart), originalAttrs, false, result); + addChunk(chars, Math.max(lastOffset[0], usageStart), Math.min(hiEnd, usageEnd), originalAttrs, true, result); + lastOffset[0] = usageEnd; + if (usageEnd > hiEnd) { + return false; + } } - lastOffset = usageEnd; + return true; } - } - if (lastOffset < hiEnd) { - addChunk(chars, lastOffset, hiEnd, originalAttrs, false, result); + }); + if (lastOffset[0] < hiEnd) { + addChunk(chars, lastOffset[0], hiEnd, originalAttrs, false, result); } } diff --git a/platform/usageView/src/com/intellij/usages/UsageDataUtil.java b/platform/usageView/src/com/intellij/usages/UsageDataUtil.java new file mode 100644 index 000000000000..134bee458bae --- /dev/null +++ b/platform/usageView/src/com/intellij/usages/UsageDataUtil.java @@ -0,0 +1,73 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.usages; + +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.usages.rules.UsageInFile; +import com.intellij.usages.rules.UsageInFiles; +import com.intellij.util.containers.ContainerUtil; +import gnu.trove.THashSet; +import org.jetbrains.annotations.Nullable; + +import java.util.Set; + +/** + * User: cdr + */ +public class UsageDataUtil { + @Nullable + public static VirtualFile[] provideVirtualFileArray(Usage[] usages, UsageTarget[] usageTargets) { + if (usages == null && usageTargets == null) { + return null; + } + + final Set result = new THashSet(); + + if (usages != null) { + for (Usage usage : usages) { + if (usage instanceof UsageInFile) { + VirtualFile file = ((UsageInFile)usage).getFile(); + if (file.isValid()) { + result.add(file); + } + } + + if (usage instanceof UsageInFiles) { + VirtualFile[] files = ((UsageInFiles)usage).getFiles(); + for (VirtualFile file : files) { + if (file.isValid()) { + result.add(file); + } + } + } + } + } + + if (usageTargets != null) { + for (UsageTarget usageTarget : usageTargets) { + if (usageTarget.isValid()) { + final VirtualFile[] files = usageTarget.getFiles(); + if (files != null) { + ContainerUtil.addAll(result, files); + } + } + } + } + + return VfsUtil.toVirtualFileArray(result); + } +} diff --git a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java index 4814f7569d62..ebb303d7a190 100644 --- a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java +++ b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java @@ -20,10 +20,8 @@ import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.actionSystem.DataSink; import com.intellij.openapi.actionSystem.TypeSafeDataProvider; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.fileEditor.*; import com.intellij.openapi.module.Module; @@ -31,28 +29,33 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.Segment; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.reference.SoftReference; import com.intellij.ui.ComputableIcon; import com.intellij.usageView.UsageInfo; import com.intellij.usages.rules.*; import com.intellij.util.IncorrectOperationException; import com.intellij.util.NotNullFunction; +import com.intellij.util.Processor; +import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.ArrayList; +import java.lang.ref.Reference; +import java.util.Collections; +import java.util.Comparator; import java.util.List; /** * @author max */ -public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, UsageInFile, PsiElementUsage, MergeableUsage, Comparable, RenameableUsage, - TypeSafeDataProvider { - private static final Logger LOG = Logger.getInstance("#com.intellij.usages.UsageInfo2UsageAdapter"); - +public class UsageInfo2UsageAdapter implements UsageInModule, + UsageInLibrary, UsageInFile, PsiElementUsage, + MergeableUsage, Comparable, + RenameableUsage, TypeSafeDataProvider, UsagePresentation { public static final NotNullFunction CONVERTER = new NotNullFunction() { @NotNull public Usage fun(UsageInfo usageInfo) { @@ -61,40 +64,33 @@ public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, Us }; private final UsageInfo myUsageInfo; + private final List myMergedUsageInfos = new SmartList(); // contains all merged infos, including myUsageInfo private int myLineNumber; private int myOffset = -1; protected ComputableIcon myIcon; private String myTooltipText; - private List myRangeMarkers = new ArrayList(); - private TextChunk[] myTextChunks; - private final UsagePresentation myUsagePresentation; + private Reference myTextChunks; // allow to be gced and recreated on-demand because it requires a lot of memory - public UsageInfo2UsageAdapter(final UsageInfo usageInfo) { + public UsageInfo2UsageAdapter(@NotNull final UsageInfo usageInfo) { myUsageInfo = usageInfo; + myMergedUsageInfos.add(usageInfo); - myUsagePresentation = ApplicationManager.getApplication().runReadAction(new Computable() { - public UsagePresentation compute() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { PsiElement element = getElement(); - PsiFile psiFile = element.getContainingFile(); - Document document = PsiDocumentManager.getInstance(element.getProject()).getDocument(psiFile); - - TextRange range = element.getTextRange(); - int startOffset = range.getStartOffset() + myUsageInfo.startOffset; - int endOffset = range.getStartOffset() + myUsageInfo.endOffset; + Document document = getDocument(); + int startOffset = myUsageInfo.getNavigationOffset(); if (document != null) { myLineNumber = getLineNumber(document, startOffset); - - if (endOffset > document.getTextLength()) { - LOG.error("Invalid usage info, psiElement:" + element + " end offset: " + endOffset + " psiFile: " + psiFile.getName()); - } - - myRangeMarkers.add(document.createRangeMarker(startOffset, endOffset)); initChunks(); - } else { // element over light virtual file - myTextChunks = new TextChunk[] { + } + else { // element over light virtual file + TextChunk[] chunks = { new TextChunk(new TextAttributes(), element.getText()) }; + myTextChunks = new SoftReference(chunks); myOffset = element.getTextOffset(); } @@ -111,11 +107,10 @@ public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, Us }); } - myTooltipText = myUsageInfo.getTooltipText(); - - return new MyUsagePresentation(); + myTooltipText = usageInfo.getTooltipText(); } }); + myModificationStamp = getCurrentModificationStamp(); } private static int getLineNumber(final Document document, final int startOffset) { @@ -124,31 +119,20 @@ public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, Us return document.getLineNumber(startOffset); } - private void initChunks() { - myTextChunks = ChunkExtractor.extractChunks(getElement(), myRangeMarkers); + private TextChunk[] initChunks() { + TextChunk[] chunks = ChunkExtractor.extractChunks(getPsiFile(), this); + myTextChunks = new SoftReference(chunks); + return chunks; } - + @NotNull public UsagePresentation getPresentation() { - return myUsagePresentation; + return this; } public boolean isValid() { PsiElement element = getElement(); - if (element == null || !element.isValid()) { - return false; - } - - return markersValid(); - } - - private boolean markersValid() { - for (RangeMarker rangeMarker : myRangeMarkers) { - if (!rangeMarker.isValid()) { - return false; - } - } - return true; + return element != null && element.isValid(); } public boolean isReadOnly() { @@ -162,31 +146,44 @@ public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, Us FileEditor editor = FileEditorManager.getInstance(getProject()).getSelectedEditor(virtualFile); if (!(editor instanceof TextEditor)) return null; - return new TextEditorLocation(myUsageInfo.startOffset + getElement().getTextRange().getStartOffset(), (TextEditor)editor); + return new TextEditorLocation(getUsageInfo().startOffset + getElement().getTextRange().getStartOffset(), (TextEditor)editor); } public void selectInEditor() { if (!isValid()) return; Editor editor = openTextEditor(true); - RangeMarker marker = getRangeMarker(); + Segment marker = getFirstSegment(); editor.getSelectionModel().setSelection(marker.getStartOffset(), marker.getEndOffset()); } public void highlightInEditor() { if (!isValid()) return; - RangeMarker marker = getRangeMarker(); + Segment marker = getFirstSegment(); SelectInEditorManager.getInstance(getProject()).selectInEditor(getFile(), marker.getStartOffset(), marker.getEndOffset(), false, false); } - public final RangeMarker getRangeMarker() { - return myRangeMarkers.get(0); + private Segment getFirstSegment() { + return getUsageInfo().getSegment(); } - public List getRangeMarkers() { - return myRangeMarkers; + // must iterate in start offset order + public boolean processRangeMarkers(Processor processor) { + for (UsageInfo usageInfo : myMergedUsageInfos) { + if (!processor.process(usageInfo.getSegment())) { + return false; + } + } + return true; } + public Document getDocument() { + PsiFile file = getUsageInfo().getFile(); + if (file == null) return null; + return PsiDocumentManager.getInstance(getProject()).getDocument(file); + } + + public void navigate(boolean focus) { if (canNavigate()) { openTextEditor(focus); @@ -207,18 +204,22 @@ public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, Us @Nullable private OpenFileDescriptor getDescriptor() { - if (markersValid()) { - return new OpenFileDescriptor(getProject(), getFile(), !myRangeMarkers.isEmpty() ? getRangeMarker().getStartOffset() : myOffset); + VirtualFile file = getFile(); + if(file == null) return null; + int offset = getNavigationOffset(); + return new OpenFileDescriptor(getProject(), file, offset); + } + + int getNavigationOffset() { + Document document = getDocument(); + if (document == null) return -1; + int offset = getUsageInfo().getNavigationOffset(); + if (offset == -1) offset = myOffset; + if (offset >= document.getTextLength()) { + int line = Math.max(0, Math.min(myLineNumber, document.getLineCount())); + offset = document.getLineStartOffset(line); } - else if (getFile().isValid()) { - final Document doc = FileDocumentManager.getInstance().getDocument(getFile()); - if (doc != null) { - int line = Math.max(0, Math.min(myLineNumber, doc.getLineCount())); - return new OpenFileDescriptor(getProject(), getFile(), line, 0); - } - } - - return null; + return offset; } private Project getProject() { @@ -239,27 +240,25 @@ public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, Us public Module getModule() { if (!isValid()) return null; - PsiElement element = getElement(); VirtualFile virtualFile = getFile(); if (virtualFile == null) return null; - ProjectRootManager projectRootManager = ProjectRootManager.getInstance(element.getProject()); + ProjectRootManager projectRootManager = ProjectRootManager.getInstance(getProject()); ProjectFileIndex fileIndex = projectRootManager.getFileIndex(); return fileIndex.getModuleForFile(virtualFile); } public OrderEntry getLibraryEntry() { if (!isValid()) return null; - PsiElement element = getElement(); - PsiFile psiFile = element.getContainingFile(); + PsiFile psiFile = getPsiFile(); VirtualFile virtualFile = getFile(); if (virtualFile == null) return null; - ProjectRootManager projectRootManager = ProjectRootManager.getInstance(element.getProject()); + ProjectRootManager projectRootManager = ProjectRootManager.getInstance(getProject()); ProjectFileIndex fileIndex = projectRootManager.getFileIndex(); if (psiFile instanceof PsiCompiledElement || fileIndex.isInLibrarySource(virtualFile)) { - List orders = fileIndex.getOrderEntriesForFile(psiFile.getVirtualFile()); + List orders = fileIndex.getOrderEntriesForFile(virtualFile); for (OrderEntry order : orders) { if (order instanceof LibraryOrderEntry || order instanceof JdkOrderEntry) { return order; @@ -271,12 +270,10 @@ public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, Us } public VirtualFile getFile() { - if (isValid()) { - return getElement().getContainingFile().getVirtualFile(); - } - else { - return myUsageInfo.getVirtualFile(); - } + return getUsageInfo().getVirtualFile(); + } + private PsiFile getPsiFile() { + return getUsageInfo().getFile(); } public int getLine() { @@ -287,22 +284,27 @@ public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, Us if (!(other instanceof UsageInfo2UsageAdapter)) return false; UsageInfo2UsageAdapter u2 = (UsageInfo2UsageAdapter)other; if (myLineNumber != u2.myLineNumber || getFile() != u2.getFile()) return false; - myRangeMarkers.addAll(u2.myRangeMarkers); + myMergedUsageInfos.addAll(u2.myMergedUsageInfos); + Collections.sort(myMergedUsageInfos, new Comparator() { + @Override + public int compare(UsageInfo o1, UsageInfo o2) { + return o1.getNavigationOffset() - o2.getNavigationOffset(); + } + }); initChunks(); return true; } public void reset() { - if (myRangeMarkers.size() > 1) { - RangeMarker marker = getRangeMarker(); - myRangeMarkers = new ArrayList(); - myRangeMarkers.add(marker); + if (!myMergedUsageInfos.isEmpty()) { + myMergedUsageInfos.clear(); + myMergedUsageInfos.add(myUsageInfo); initChunks(); } } public final PsiElement getElement() { - return myUsageInfo.getElement(); + return getUsageInfo().getElement(); } public PsiReference getReference() { @@ -310,7 +312,7 @@ public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, Us } public boolean isNonCodeUsage() { - return myUsageInfo.isNonCodeUsage; + return getUsageInfo().isNonCodeUsage; } public UsageInfo getUsageInfo() { @@ -318,86 +320,20 @@ public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, Us } public int compareTo(final UsageInfo2UsageAdapter o) { - final PsiElement element = getElement(); - final PsiFile containingFile = element == null ? null : element.getContainingFile(); - final PsiElement oElement = o.getElement(); - final PsiFile oContainingFile = oElement == null ? null : oElement.getContainingFile(); - if (containingFile == null && oContainingFile == null - || !Comparing.equal(containingFile, oContainingFile)) { + VirtualFile containingFile = getFile(); + VirtualFile oContainingFile = o.getFile(); + if (containingFile == null && oContainingFile == null || !Comparing.equal(containingFile, oContainingFile)) { return 0; } - return getRangeMarker().getStartOffset() - o.getRangeMarker().getStartOffset(); + return getFirstSegment().getStartOffset() - o.getFirstSegment().getStartOffset(); } public void rename(String newName) throws IncorrectOperationException { - final PsiReference reference = myUsageInfo.getReference(); + final PsiReference reference = getUsageInfo().getReference(); assert reference != null : this; reference.handleElementRename(newName); } - private class MyUsagePresentation implements UsagePresentation { - private long myModificationStamp; - - private MyUsagePresentation() { - myModificationStamp = getCurrentModificationStamp(); - } - - private long getCurrentModificationStamp() { - final PsiFile containingFile = getElement().getContainingFile(); - return containingFile == null? -1L : containingFile.getModificationStamp(); - } - - @NotNull - public TextChunk[] getText() { - if (isValid()) { - // the check below makes sense only for valid PsiElement - final long currentModificationStamp = getCurrentModificationStamp(); - if (currentModificationStamp != myModificationStamp) { - initChunks(); - myModificationStamp = currentModificationStamp; - } - } - return myTextChunks; - } - - @NotNull - public String getPlainText() { - if (myRangeMarkers.isEmpty()) { // element over light virtual file - return myTextChunks[0].getText(); - } - - int startOffset = ChunkExtractor.getStartOffset(myRangeMarkers); - final PsiElement element = getElement(); - if (element != null && startOffset != -1) { - final Document document = PsiDocumentManager.getInstance(element.getProject()).getDocument(element.getContainingFile()); - if (document != null) { - int lineNumber = document.getLineNumber(startOffset); - int lineStart = document.getLineStartOffset(lineNumber); - int lineEnd = document.getLineEndOffset(lineNumber); - String prefixSuffix = null; - - if (lineEnd - lineStart > ChunkExtractor.MAX_LINE_TO_SHOW) { - prefixSuffix = "..."; - lineStart = Math.max(startOffset - ChunkExtractor.OFFSET_BEFORE_TO_SHOW_WHEN_LONG_LINE, lineStart); - lineEnd = Math.min(startOffset + ChunkExtractor.OFFSET_AFTER_TO_SHOW_WHEN_LONG_LINE, lineEnd); - } - String s = document.getCharsSequence().subSequence(lineStart, lineEnd).toString(); - if (prefixSuffix != null) s = prefixSuffix + s + prefixSuffix; - return s; - } - } - return ""; - } - - public Icon getIcon() { - return myIcon != null ? myIcon.getIcon() : null; - } - - public String getTooltipText() { - return myTooltipText; - } - } - public static UsageInfo2UsageAdapter[] convert(UsageInfo[] usageInfos) { UsageInfo2UsageAdapter[] result = new UsageInfo2UsageAdapter[usageInfos.length]; for (int i = 0; i < result.length; i++) { @@ -412,23 +348,78 @@ public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, Us sink.put(UsageView.USAGE_INFO_KEY, getUsageInfo()); } if (key == UsageView.USAGE_INFO_LIST_KEY) { - ArrayList list = getSelectedInfoList(); + List list = getSelectedInfoList(); sink.put(UsageView.USAGE_INFO_LIST_KEY, list); } } - private ArrayList getSelectedInfoList() { - ArrayList list = new ArrayList(); - UsageInfo first = getUsageInfo(); - list.add(first); - for (int i = 1; i < myRangeMarkers.size(); i++) { - RangeMarker rangeMarker = myRangeMarkers.get(i); - PsiElement element = first.getElement(); - if (element == null) continue; - PsiFile file = element.getContainingFile(); - UsageInfo usageInfo = new UsageInfo(file, rangeMarker.getStartOffset(), rangeMarker.getEndOffset()); - list.add(usageInfo); + private List getSelectedInfoList() { + return myMergedUsageInfos; + } + + public void dispose() { + for (UsageInfo usageInfo : myMergedUsageInfos) { + usageInfo.dispose(); } - return list; + } + + private long myModificationStamp; + private long getCurrentModificationStamp() { + final PsiFile containingFile = getPsiFile(); + return containingFile == null ? -1L : containingFile.getModificationStamp(); + } + + @NotNull + public TextChunk[] getText() { + TextChunk[] chunks = myTextChunks.get(); + if (chunks == null) { + myModificationStamp = -1; + } + if (chunks == null || isValid()) { + // the check below makes sense only for valid PsiElement + final long currentModificationStamp = getCurrentModificationStamp(); + if (currentModificationStamp != myModificationStamp) { + chunks = initChunks(); + myModificationStamp = currentModificationStamp; + } + } + return chunks; + } + + @NotNull + public String getPlainText() { + //if (myRangeMarkers.isEmpty()) { // element over light virtual file + // return myTextChunks[0].getText(); + //} + + int startOffset = getNavigationOffset(); + final PsiElement element = getElement(); + if (element != null && startOffset != -1) { + final Document document = getDocument(); + if (document != null) { + int lineNumber = document.getLineNumber(startOffset); + int lineStart = document.getLineStartOffset(lineNumber); + int lineEnd = document.getLineEndOffset(lineNumber); + String prefixSuffix = null; + + if (lineEnd - lineStart > ChunkExtractor.MAX_LINE_TO_SHOW) { + prefixSuffix = "..."; + lineStart = Math.max(startOffset - ChunkExtractor.OFFSET_BEFORE_TO_SHOW_WHEN_LONG_LINE, lineStart); + lineEnd = Math.min(startOffset + ChunkExtractor.OFFSET_AFTER_TO_SHOW_WHEN_LONG_LINE, lineEnd); + } + String s = document.getCharsSequence().subSequence(lineStart, lineEnd).toString(); + if (prefixSuffix != null) s = prefixSuffix + s + prefixSuffix; + return s; + } + } + return ""; + } + + public Icon getIcon() { + return myIcon != null ? myIcon.getIcon() : null; + } + + public String getTooltipText() { + return myTooltipText; } } diff --git a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java b/platform/usageView/src/com/intellij/usages/impl/GroupNode.java index aa5a2bdb3328..cd256daa4a35 100644 --- a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java +++ b/platform/usageView/src/com/intellij/usages/impl/GroupNode.java @@ -23,10 +23,10 @@ import com.intellij.usages.UsageGroup; import com.intellij.usages.UsageView; import com.intellij.usages.UsageViewSettings; import com.intellij.usages.rules.MergeableUsage; +import com.intellij.util.ui.UIUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; -import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeNode; import java.util.*; @@ -67,18 +67,23 @@ public class GroupNode extends Node implements Navigatable, Comparable myUsages = new ConcurrentHashSet(); private final Map myUsageNodes = new ConcurrentHashMap(); public static final UsageNode NULL_NODE = new UsageNode(NullUsage.INSTANCE, new UsageViewTreeModelBuilder(new UsageViewPresentation(), UsageTarget.EMPTY_ARRAY)); private final ButtonPanel myButtonPanel = new ButtonPanel(); private volatile boolean isDisposed; private volatile boolean myChangesDetected = false; - private final Queue myUsagesToFlush = new ConcurrentLinkedQueue(); static final Comparator USAGE_COMPARATOR = new Comparator() { public int compare(final Usage o1, final Usage o2) { if (o1 == NULL_NODE || o2 == NULL_NODE) return -1; @@ -130,7 +126,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra private final GroupNode myRoot; private final UsageViewTreeModelBuilder myModel; - public UsageViewImpl(@NotNull Project project, + public UsageViewImpl(@NotNull final Project project, @NotNull UsageViewPresentation presentation, @NotNull UsageTarget[] targets, Factory usageSearcherFactory) { @@ -173,7 +169,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra }); if (!myPresentation.isDetachedMode()) { - SwingUtilities.invokeLater(new Runnable() { + UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { if (isDisposed) return; myTree.setModel(myModel); @@ -225,6 +221,18 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra } }); } + myTransferToEDTQueue = new TransferToEDTQueue(new Processor() { + @Override + public boolean process(Usage usage) { + appendUsage(usage); + return true; + } + }, new Condition() { + @Override + public boolean value(Object o) { + return isDisposed || project.isDisposed() || com.intellij.usages.UsageViewManager.getInstance(project).searchHasBeenCancelled(); + } + }); } private void setupCentralPanel() { @@ -645,35 +653,13 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra } }); } - - myUsages.clear(); } - public void appendUsageLater(final Usage usage) { - myUsagesToFlush.offer(usage); - if (myUsagesToFlush.size() > 50) { - flush(); - } - myFlushAlarm.cancelAllRequests(); - myFlushAlarm.addRequest(new Runnable() { - public void run() { - flush(); - } - }, 300); + private final TransferToEDTQueue myTransferToEDTQueue; + public void appendUsageLater(Usage usage) { + myTransferToEDTQueue.offer(usage); } - - private void flush() { - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - Usage usage; - while ((usage = myUsagesToFlush.poll()) != null) { - appendUsage(usage); - } - } - }); - } - private volatile boolean myIsFirstVisibleUsageFound = false; public void appendUsage(@NotNull Usage usage) { @@ -684,10 +670,9 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra // invoke in ReadAction to be be sure that usages are not invalidated while the tree is being built ApplicationManager.getApplication().assertReadAccessAllowed(); if (!usage.isValid()) { - // because the view is built incrementally with Alarm, the usage may be already invalid, so need filter such cases + // because the view is built incrementally, the usage may be already invalid, so need to filter such cases return null; } - myUsages.add(usage); UsageNode node = myBuilder.appendUsage(usage); myUsageNodes.put(usage, node == null ? NULL_NODE : node); if (!myIsFirstVisibleUsageFound && node != null) { //first visible usage found; @@ -700,7 +685,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra public void removeUsage(@NotNull Usage usage) { final UsageNode node = myUsageNodes.remove(usage); if (node != NULL_NODE && node != null && !myPresentation.isDetachedMode()) { - SwingUtilities.invokeLater(new Runnable() { + UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { if (isDisposed) return; TreeModel treeModel = myTree.getModel(); @@ -803,6 +788,11 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra UsageViewSettings.getInstance().PREVIEW_USAGES_SPLITTER_PROPORTIONS = ((Splitter)myUsagePreviewPanel.getParent()).getProportion(); myUsagePreviewPanel = null; } + for (Usage usage : getUsages()) { + if (usage instanceof UsageInfo2UsageAdapter) { + ((UsageInfo2UsageAdapter)usage).dispose(); + } + } } public boolean isSearchInProgress() { @@ -811,13 +801,12 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra public void setSearchInProgress(boolean searchInProgress) { mySearchInProgress = searchInProgress; - flush(); if (!myPresentation.isDetachedMode()) { - SwingUtilities.invokeLater(new Runnable() { + UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { if (isDisposed) return; final UsageNode firstUsageNode = myModel.getFirstUsageNode(); - if (firstUsageNode != null) { //first usage; + if (firstUsageNode != null) { showNode(firstUsageNode); } } @@ -827,7 +816,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra private void showNode(final UsageNode node) { if (!myPresentation.isDetachedMode()) { - SwingUtilities.invokeLater(new Runnable() { + UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { if (isDisposed) return; TreePath usagePath = new TreePath(node.getPath()); @@ -840,10 +829,8 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra public void addButtonToLowerPane(@NotNull Runnable runnable, @NotNull String text) { int index = myButtonPanel.getComponentCount(); - if (index > 0 && myPresentation.isShowCancelButton()) index--; - - myButtonPanel.add(index, runnable, text); + myButtonPanel.addButtonRunnable(index, runnable, text); } public void addButtonToLowerPane(@NotNull final Runnable runnable, @NotNull String text, char mnemonic) { @@ -981,12 +968,12 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra @NotNull public Set getUsages() { - return myUsages; + return myUsageNodes.keySet(); } @NotNull public List getSortedUsages() { - List usages = new ArrayList(myUsages); + List usages = new ArrayList(getUsages()); Collections.sort(usages, USAGE_COMPARATOR); return usages; } @@ -995,9 +982,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra if (node instanceof UsageNode) { UsageNode usageNode = (UsageNode)node; final Usage usage = usageNode.getUsage(); - if (usage.isValid()) { - usages.add(usage); - } + usages.add(usage); } Enumeration enumeration = node.children(); @@ -1042,7 +1027,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra if (nodes == null) { return null; } - final ArrayList result = new ArrayList(); + final List result = new ArrayList(); for (final Node node : nodes) { /* if (!node.isDataValid()) { @@ -1138,7 +1123,8 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra else if (key == PlatformDataKeys.VIRTUAL_FILE_ARRAY) { final Set usages = getSelectedUsages(); - VirtualFile[] data = provideVirtualFileArray(usages != null ? usages.toArray(new Usage[usages.size()]) : null, getSelectedUsageTargets()); + Usage[] ua = usages != null ? usages.toArray(new Usage[usages.size()]) : null; + VirtualFile[] data = UsageDataUtil.provideVirtualFileArray(ua, getSelectedUsageTargets()); sink.put(PlatformDataKeys.VIRTUAL_FILE_ARRAY, data); } @@ -1160,43 +1146,6 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra } } } - - @Nullable - private VirtualFile[] provideVirtualFileArray(Usage[] usages, UsageTarget[] usageTargets) { - if (usages == null && usageTargets == null) { - return null; - } - - final Set result = new THashSet(); - - if (usages != null) { - for (Usage usage : usages) { - if (usage.isValid()) { - if (usage instanceof UsageInFile) { - result.add(((UsageInFile)usage).getFile()); - } - - if (usage instanceof UsageInFiles) { - ContainerUtil.addAll(result, ((UsageInFiles)usage).getFiles()); - } - } - } - } - - if (usageTargets != null) { - for (UsageTarget usageTarget : usageTargets) { - if (usageTarget.isValid()) { - final VirtualFile[] files = usageTarget.getFiles(); - if (files != null) { - ContainerUtil.addAll(result, files); - } - } - } - } - - return VfsUtil.toVirtualFileArray(result); - } - } private static class MyAutoScrollToSourceOptionProvider implements AutoScrollToSourceOptionProvider { @@ -1214,7 +1163,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra setLayout(new FlowLayout(FlowLayout.LEFT, 8, 0)); } - public void add(int index, final Runnable runnable, String text) { + public void addButtonRunnable(int index, final Runnable runnable, String text) { if (getBorder() == null) setBorder(IdeBorderFactory.createBorder(SideBorder.TOP)); final JButton button = new JButton(UIUtil.replaceMnemonicAmpersand(text)); @@ -1328,5 +1277,4 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra public boolean isVisible(Usage usage) { return myBuilder != null && myBuilder.isVisible(usage); } - } diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java index 1b04bb297082..d7c3db66c7ea 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java @@ -30,10 +30,7 @@ import com.intellij.openapi.project.DumbModeAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Factory; -import com.intellij.openapi.util.IconLoader; -import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowId; @@ -42,6 +39,7 @@ import com.intellij.ui.content.Content; import com.intellij.usageView.UsageViewBundle; import com.intellij.usages.*; import com.intellij.util.ArrayUtil; +import com.intellij.util.CommonProcessors; import com.intellij.util.Processor; import com.intellij.util.ui.RangeBlinker; import com.intellij.util.ui.UIUtil; @@ -404,7 +402,10 @@ public class UsageViewManagerImpl extends UsageViewManager { TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.BLINKING_HIGHLIGHTS_ATTRIBUTES); RangeBlinker rangeBlinker = new RangeBlinker(editor, attributes, 6); - rangeBlinker.resetMarkers(usageInfo.getRangeMarkers()); + List segments = new ArrayList(); + CommonProcessors.CollectProcessor processor = new CommonProcessors.CollectProcessor(segments); + usageInfo.processRangeMarkers(processor); + rangeBlinker.resetMarkers(segments); rangeBlinker.startBlinking(); } diff --git a/platform/usageView/usageView.iml b/platform/usageView/usageView.iml index 8c425e159519..a29a428de6af 100644 --- a/platform/usageView/usageView.iml +++ b/platform/usageView/usageView.iml @@ -10,6 +10,7 @@ + diff --git a/platform/util/src/com/intellij/openapi/util/TextRange.java b/platform/util/src/com/intellij/openapi/util/TextRange.java index e0d555ba26af..a38fa5788b25 100644 --- a/platform/util/src/com/intellij/openapi/util/TextRange.java +++ b/platform/util/src/com/intellij/openapi/util/TextRange.java @@ -18,7 +18,7 @@ package com.intellij.openapi.util; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class TextRange { +public class TextRange implements Segment{ private final int myStartOffset; private final int myEndOffset; diff --git a/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java b/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java new file mode 100644 index 000000000000..8c51af670634 --- /dev/null +++ b/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.containers; + +import com.intellij.openapi.util.Condition; +import com.intellij.util.Processor; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Allows to process elements in the EDT. + * Processes elements in batches, no longer than 200ms per batch, and reschedules processing later for longer batches. + * Usage: {@link TransferToEDTQueue#offer(Object)} } : schedules element for processing in EDT (via invokeLater) + */ +public class TransferToEDTQueue { + private final Processor myProcessor; + private volatile boolean stopped; + private final Condition myShutUpCondition; + + private final Queue myQueue = new ConcurrentLinkedQueue(); + private final AtomicBoolean invokeLaterScheduled = new AtomicBoolean(); + private static final long MAX_UNIT_OF_WORK_THRESHOLD_MS = 200; // no more than 200 ms delay + private final Runnable myUpdateRunnable = new Runnable() { + @Override + public void run() { + boolean b = invokeLaterScheduled.compareAndSet(true, false); + assert b; + if (stopped || myShutUpCondition.value(null)) { + stop(); + return; + } + long start = System.currentTimeMillis(); + int processed = 0; + while (true) { + T thing = myQueue.poll(); + if (thing == null) break; + if (!myProcessor.process(thing)) { + myQueue.clear(); + return; + } + processed++; + long finish = System.currentTimeMillis(); + if (finish - start > MAX_UNIT_OF_WORK_THRESHOLD_MS) break; + } + if (!myQueue.isEmpty()) { + scheduleUpdate(); + } + } + }; + + public TransferToEDTQueue(@NotNull Processor processorInEDT, @NotNull Condition shutUpCondition) { + myProcessor = processorInEDT; + myShutUpCondition = shutUpCondition; + } + + public void offer(final T thing) { + myQueue.offer(thing); + scheduleUpdate(); + } + + private void scheduleUpdate() { + if (invokeLaterScheduled.compareAndSet(false, true)) { + schedule(myUpdateRunnable); + } + } + + protected void schedule(Runnable updateRunnable) { + SwingUtilities.invokeLater(updateRunnable); + } + + public void stop() { + stopped = true; + myQueue.clear(); + } +} diff --git a/xml/dom-openapi/src/com/intellij/codeInsight/navigation/NavigationGutterIconBuilder.java b/xml/dom-openapi/src/com/intellij/codeInsight/navigation/NavigationGutterIconBuilder.java index 84fa5318bb1b..e3270f208fdf 100644 --- a/xml/dom-openapi/src/com/intellij/codeInsight/navigation/NavigationGutterIconBuilder.java +++ b/xml/dom-openapi/src/com/intellij/codeInsight/navigation/NavigationGutterIconBuilder.java @@ -60,7 +60,7 @@ public class NavigationGutterIconBuilder { }; private final Icon myIcon; - private final NotNullFunction> myConvertor; + private final NotNullFunction> myConverter; private NotNullLazyValue> myTargets; private boolean myLazy; @@ -70,7 +70,7 @@ public class NavigationGutterIconBuilder { private String myTooltipTitle; private GutterIconRenderer.Alignment myAlignment = GutterIconRenderer.Alignment.CENTER; private PsiElementListCellRenderer myCellRenderer; - private NullableFunction myNamer = (NullableFunction)ElementPresentationManager.NAMER; + private NullableFunction myNamer = ElementPresentationManager.namer(); public static final NotNullFunction> DEFAULT_DOM_CONVERTOR = new NotNullFunction>() { @NotNull public Collection fun(final DomElement o) { @@ -78,17 +78,17 @@ public class NavigationGutterIconBuilder { } }; - protected NavigationGutterIconBuilder(@NotNull final Icon icon, @NotNull NotNullFunction> convertor) { + protected NavigationGutterIconBuilder(@NotNull final Icon icon, @NotNull NotNullFunction> converter) { myIcon = icon; - myConvertor = convertor; + myConverter = converter; } public static NavigationGutterIconBuilder create(@NotNull final Icon icon) { return create(icon, DEFAULT_PSI_CONVERTOR); } - public static NavigationGutterIconBuilder create(@NotNull final Icon icon, @NotNull NotNullFunction> convertor) { - return new NavigationGutterIconBuilder(icon, convertor); + public static NavigationGutterIconBuilder create(@NotNull final Icon icon, @NotNull NotNullFunction> converter) { + return new NavigationGutterIconBuilder(icon, converter); } public NavigationGutterIconBuilder setTarget(@Nullable T target) { @@ -193,9 +193,10 @@ public class NavigationGutterIconBuilder { @NotNull public List compute() { Set elements = new THashSet(); - final ArrayList list = new ArrayList(); - for (final T target : myTargets.getValue()) { - for (final PsiElement psiElement : myConvertor.fun(target)) { + Collection targets = myTargets.getValue(); + final List list = new ArrayList(targets.size()); + for (final T target : targets) { + for (final PsiElement psiElement : myConverter.fun(target)) { if (elements.add(psiElement)) { list.add(manager.createSmartPsiElementPointer(psiElement)); } @@ -205,7 +206,7 @@ public class NavigationGutterIconBuilder { } }; - final boolean empty = !myLazy && pointers.getValue().isEmpty(); + final boolean empty = isEmpty(); if (myTooltipText == null && !myLazy) { final SortedSet names = new TreeSet(); @@ -233,6 +234,23 @@ public class NavigationGutterIconBuilder { return new MyNavigationGutterIconRenderer(this, myAlignment, myIcon, myTooltipText, pointers, empty); } + private boolean isEmpty() { + if (myLazy) { + return false; + } + + Set elements = new THashSet(); + Collection targets = myTargets.getValue(); + for (final T target : targets) { + for (final PsiElement psiElement : myConverter.fun(target)) { + if (elements.add(psiElement)) { + return false; + } + } + } + return true; + } + private static class MyNavigationGutterIconRenderer extends NavigationGutterIconRenderer { private final Alignment myAlignment; private final Icon myIcon; diff --git a/xml/dom-openapi/src/com/intellij/util/xml/ElementPresentationManager.java b/xml/dom-openapi/src/com/intellij/util/xml/ElementPresentationManager.java index d3ee30f083a3..393abf90ccc7 100644 --- a/xml/dom-openapi/src/com/intellij/util/xml/ElementPresentationManager.java +++ b/xml/dom-openapi/src/com/intellij/util/xml/ElementPresentationManager.java @@ -132,6 +132,10 @@ public abstract class ElementPresentationManager { return getElementName(o); } }; + public static NullableFunction namer() { + //noinspection unchecked + return (NullableFunction)NAMER; + } @Nullable public static String getElementName(Object element) { From 4ad2539d25a71c7c5e38b3932a120120349e989b Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 4 Feb 2011 21:10:39 +0300 Subject: [PATCH 62/94] DnD builder --- .../com/intellij/ide/dnd/DnDActionInfo.java | 51 ++++ .../ide/dnd/DnDDropActionHandler.java | 23 ++ .../com/intellij/ide/dnd/DnDDropHandler.java | 23 ++ .../src/com/intellij/ide/dnd/DnDImage.java | 43 ++++ .../intellij/ide/dnd/DnDObjectProvider.java | 25 ++ .../src/com/intellij/ide/dnd/DnDSource.java | 12 +- .../src/com/intellij/ide/dnd/DnDSupport.java | 236 ++++++++++++++++++ .../intellij/ide/dnd/DnDSupportBuilder.java | 36 +++ .../src/com/intellij/ide/dnd/DnDTarget.java | 20 +- .../intellij/ide/dnd/DnDTargetChecker.java | 33 +++ 10 files changed, 483 insertions(+), 19 deletions(-) create mode 100644 platform/platform-api/src/com/intellij/ide/dnd/DnDActionInfo.java create mode 100644 platform/platform-api/src/com/intellij/ide/dnd/DnDDropActionHandler.java create mode 100644 platform/platform-api/src/com/intellij/ide/dnd/DnDDropHandler.java create mode 100644 platform/platform-api/src/com/intellij/ide/dnd/DnDImage.java create mode 100644 platform/platform-api/src/com/intellij/ide/dnd/DnDObjectProvider.java create mode 100644 platform/platform-api/src/com/intellij/ide/dnd/DnDSupport.java create mode 100644 platform/platform-api/src/com/intellij/ide/dnd/DnDSupportBuilder.java create mode 100644 platform/platform-api/src/com/intellij/ide/dnd/DnDTargetChecker.java diff --git a/platform/platform-api/src/com/intellij/ide/dnd/DnDActionInfo.java b/platform/platform-api/src/com/intellij/ide/dnd/DnDActionInfo.java new file mode 100644 index 000000000000..9e59b7ab258a --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/dnd/DnDActionInfo.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.dnd; + +import java.awt.*; + +/** + * @author Konstantin Bulenkov + */ +public final class DnDActionInfo { + private final DnDAction myAction; + private final Point myPoint; + + public DnDActionInfo(DnDAction action, Point dragOrigin) { + myAction = action; + myPoint = dragOrigin; + } + + public DnDAction getAction() { + return myAction; + } + + public Point getPoint() { + return myPoint; + } + + public boolean isMove() { + return myAction == DnDAction.MOVE; + } + + public boolean isCopy() { + return myAction == DnDAction.COPY; + } + + public boolean isLink() { + return myAction == DnDAction.LINK; + } +} diff --git a/platform/platform-api/src/com/intellij/ide/dnd/DnDDropActionHandler.java b/platform/platform-api/src/com/intellij/ide/dnd/DnDDropActionHandler.java new file mode 100644 index 000000000000..bb144e5babe9 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/dnd/DnDDropActionHandler.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.dnd; + +/** + * @author Konstantin Bulenkov + */ +public interface DnDDropActionHandler { + void dropActionChanged(final int gestureModifiers); +} diff --git a/platform/platform-api/src/com/intellij/ide/dnd/DnDDropHandler.java b/platform/platform-api/src/com/intellij/ide/dnd/DnDDropHandler.java new file mode 100644 index 000000000000..00faf8dd9916 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/dnd/DnDDropHandler.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.dnd; + +/** + * @author Konstantin Bulenkov + */ +public interface DnDDropHandler { + void drop(DnDEvent event); +} diff --git a/platform/platform-api/src/com/intellij/ide/dnd/DnDImage.java b/platform/platform-api/src/com/intellij/ide/dnd/DnDImage.java new file mode 100644 index 000000000000..5773286e6c5a --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/dnd/DnDImage.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.dnd; + +import java.awt.*; + +/** + * @author Konstantin Bulenkov + */ +public class DnDImage { + private final Image myImage; + private final Point myPoint; + + public DnDImage(Image image, Point point) { + myImage = image; + myPoint = point; + } + + public DnDImage(Image image) { + this(image, null); + } + + public Image getImage() { + return myImage; + } + + public Point getPoint() { + return myPoint; + } +} diff --git a/platform/platform-api/src/com/intellij/ide/dnd/DnDObjectProvider.java b/platform/platform-api/src/com/intellij/ide/dnd/DnDObjectProvider.java new file mode 100644 index 000000000000..b750246f3067 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/dnd/DnDObjectProvider.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.dnd; + +/** + * @author Konstantin Bulenkov + */ +public interface DnDObjectProvider { + Object getDnDObject(); + + boolean isAvailable(DnDEvent event); +} diff --git a/platform/platform-api/src/com/intellij/ide/dnd/DnDSource.java b/platform/platform-api/src/com/intellij/ide/dnd/DnDSource.java index de0b7dfa4b26..57f221250397 100644 --- a/platform/platform-api/src/com/intellij/ide/dnd/DnDSource.java +++ b/platform/platform-api/src/com/intellij/ide/dnd/DnDSource.java @@ -20,23 +20,25 @@ import org.jetbrains.annotations.Nullable; import java.awt.*; -public interface DnDSource { +/** + * @author Konstantin Bulenkov + */ +public interface DnDSource extends DnDDropActionHandler { boolean canStartDragging(DnDAction action, Point dragOrigin); + DnDDragStartBean startDragging(DnDAction action, Point dragOrigin); /** * Image to be drawn on screen while dragging and the point of the offset to position cursor * in the proper place * - * @param action - * @param dragOrigin + * @param action drag-n-drop action + * @param dragOrigin origin drag point * @return Pair of image and cursor offset at the image */ @Nullable Pair createDraggedImage(DnDAction action, Point dragOrigin); void dragDropEnd(); - - void dropActionChanged(final int gestureModifiers); } diff --git a/platform/platform-api/src/com/intellij/ide/dnd/DnDSupport.java b/platform/platform-api/src/com/intellij/ide/dnd/DnDSupport.java new file mode 100644 index 000000000000..082bae8ec32c --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/dnd/DnDSupport.java @@ -0,0 +1,236 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.dnd; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.Ref; +import com.intellij.util.Function; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Konstantin Bulenkov + */ +public class DnDSupport implements DnDTarget, DnDSource, Disposable { + private final JComponent myComponent; + private final Function myBeanProvider; + private final Function myImageProvider; + private final DnDDropHandler myHandler; + private final DnDTargetChecker myChecker; + private final Runnable myDropEndedCallback; + private final DnDDropActionHandler myDropActionHandler; + private final Runnable myCleanUpCallback; + private boolean myAsTarget; + private boolean myAsSource; + + private DnDSupport(JComponent component, + @NotNull Function beanProvider, + Function imageProvider, + DnDDropHandler handler, + DnDTargetChecker checker, + Runnable dropEndedCallback, + Disposable parent, + DnDDropActionHandler dropActionHandler, + Runnable cleanUpCallback, + boolean asTarget, + boolean asSource) { + myComponent = component; + myBeanProvider = beanProvider; + myImageProvider = imageProvider; + myHandler = handler; + myChecker = checker; + myDropEndedCallback = dropEndedCallback; + myDropActionHandler = dropActionHandler; + myCleanUpCallback = cleanUpCallback; + myAsTarget = asTarget; + myAsSource = asSource; + if (myAsTarget) { + DnDManager.getInstance().registerTarget(this, myComponent); + } + if (myAsSource) { + DnDManager.getInstance().registerSource(this, myComponent); + } + if (parent != null) { + Disposer.register(parent, this); + } + } + + @Override + public boolean canStartDragging(DnDAction action, Point dragOrigin) { + return myBeanProvider.fun(new DnDActionInfo(action, dragOrigin)) != null; + } + + + @Override + public DnDDragStartBean startDragging(DnDAction action, Point dragOrigin) { + return myBeanProvider.fun(new DnDActionInfo(action, dragOrigin)); + } + + @Override + public Pair createDraggedImage(DnDAction action, Point dragOrigin) { + final DnDImage image = myImageProvider.fun(new DnDActionInfo(action, dragOrigin)); + if (image != null) { + final Point point = image.getPoint(); + return new Pair(image.getImage(), point == null ? dragOrigin : point); + } + return null; + } + + @Override + public void dragDropEnd() { + if (myDropEndedCallback != null) { + myDropEndedCallback.run(); + } + } + + @Override + public void dropActionChanged(int gestureModifiers) { + if (myDropActionHandler != null) { + myDropActionHandler.dropActionChanged(gestureModifiers); + } + } + + @Override + public boolean update(DnDEvent event) { + if (myChecker == null) { + event.setDropPossible(true, null); + return false; + } + return myChecker.update(event); + } + + @Override + public void drop(DnDEvent aEvent) { + myHandler.drop(aEvent); + } + + @Override + public void cleanUpOnLeave() { + if (myCleanUpCallback != null) { + myCleanUpCallback.run(); + } + } + + @Override + public void updateDraggedImage(Image image, Point dropPoint, Point imageOffset) { + //TODO[kb] Create DnDDraggedImageUpdater interface + } + + @Override + public void dispose() { + if (myAsSource) { + DnDManager.getInstance().unregisterSource(this, myComponent); + } + if (myAsTarget) { + DnDManager.getInstance().unregisterTarget(this, myComponent); + } + } + + public static DnDSupportBuilder createBuilder(JComponent component) { + final JComponent myComponent = component; + final Ref asTarget = Ref.create(true); + final Ref asSource = Ref.create(true); + final Ref> imageProvider = Ref.create(null); + final Ref> beanProvider = Ref.create(null); + final Ref dropEnded = Ref.create(null); + final Ref disposable = Ref.create(null); + final Ref dropHandler = Ref.create(null); + final Ref targetChecker = Ref.create(null); + final Ref dropActionHandler = Ref.create(null); + final Ref cleanUp = Ref.create(null); + + return new DnDSupportBuilder() { + @Override + public DnDSupportBuilder disableAsTarget() { + asTarget.set(false); + return this; + } + + @Override + public DnDSupportBuilder disableAsSource() { + asSource.set(false); + return this; + } + + @Override + public DnDSupportBuilder setImageProvider(Function fun) { + imageProvider.set(fun); + return this; + } + + @Override + public DnDSupportBuilder setBeanProvider(Function fun) { + beanProvider.set(fun); + return this; + } + + @Override + public DnDSupportBuilder setDropHandler(DnDDropHandler handler) { + dropHandler.set(handler); + return this; + } + + @Override + public DnDSupportBuilder setTargetChecker(DnDTargetChecker checker) { + targetChecker.set(checker); + return this; + } + + @Override + public DnDSupportBuilder setDropActionHandler(DnDDropActionHandler handler) { + dropActionHandler.set(handler); + return this; + } + + @Override + public DnDSupportBuilder setDisposableParent(Disposable parent) { + disposable.set(parent); + return this; + } + + @Override + public DnDSupportBuilder setCleanUpOnLeaveCallback(Runnable callback) { + cleanUp.set(callback); + return this; + } + + @Override + public DnDSupportBuilder setDropEndedCallback(Runnable callback) { + dropEnded.set(callback); + return this; + } + + @Override + public void install() { + new DnDSupport(myComponent, + beanProvider.get(), + imageProvider.get(), + dropHandler.get(), + targetChecker.get(), + dropEnded.get(), + disposable.get(), + dropActionHandler.get(), + cleanUp.get(), + asSource.get(), + asTarget.get()); + } + }; + } +} diff --git a/platform/platform-api/src/com/intellij/ide/dnd/DnDSupportBuilder.java b/platform/platform-api/src/com/intellij/ide/dnd/DnDSupportBuilder.java new file mode 100644 index 000000000000..0bcf8bde6652 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/dnd/DnDSupportBuilder.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.dnd; + +import com.intellij.openapi.Disposable; +import com.intellij.util.Function; + +/** + * @author Konstantin Bulenkov + */ +public interface DnDSupportBuilder { + DnDSupportBuilder disableAsTarget(); + DnDSupportBuilder disableAsSource(); + DnDSupportBuilder setImageProvider(Function provider); + DnDSupportBuilder setBeanProvider(Function provider); + DnDSupportBuilder setDropHandler(DnDDropHandler handler); + DnDSupportBuilder setTargetChecker(DnDTargetChecker checker); + DnDSupportBuilder setDropActionHandler(DnDDropActionHandler handler); + DnDSupportBuilder setDropEndedCallback(Runnable callback); + DnDSupportBuilder setCleanUpOnLeaveCallback(Runnable callback); + DnDSupportBuilder setDisposableParent(Disposable parent); + void install(); +} diff --git a/platform/platform-api/src/com/intellij/ide/dnd/DnDTarget.java b/platform/platform-api/src/com/intellij/ide/dnd/DnDTarget.java index 3ad8f4ebe02b..6e99d00cd07d 100644 --- a/platform/platform-api/src/com/intellij/ide/dnd/DnDTarget.java +++ b/platform/platform-api/src/com/intellij/ide/dnd/DnDTarget.java @@ -15,21 +15,13 @@ */ package com.intellij.ide.dnd; -import java.awt.*; - -public interface DnDTarget { - - /** - * @return - * true - if this target is unable to handle the event and parent component should be asked to process it. - * false - if this target is unable to handle the event and parent component should NOT be asked to process it. - */ - boolean update(DnDEvent aEvent); - - void drop(DnDEvent aEvent); +import java.awt.Point; +import java.awt.Image; +/** + * @author Konstantin Bulenkov + */ +public interface DnDTarget extends DnDDropHandler, DnDTargetChecker { void cleanUpOnLeave(); - void updateDraggedImage(Image image, Point dropPoint, Point imageOffset); - } diff --git a/platform/platform-api/src/com/intellij/ide/dnd/DnDTargetChecker.java b/platform/platform-api/src/com/intellij/ide/dnd/DnDTargetChecker.java new file mode 100644 index 000000000000..16246b2d0e7a --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/dnd/DnDTargetChecker.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.dnd; + +/** + * @author Konstantin Bulenkov + */ +public interface DnDTargetChecker { + /** + * All + * + * @param event Drag-n-Drop event + * @return true - if this target is unable to handle the event and parent component should be asked to process it. + * false - if this target is unable to handle the event and parent component should NOT be asked to process it. + * + * @see DnDEvent#setDropPossible(boolean, String) + * @see DnDEvent#setDropPossible(String, DropActionHandler) + */ + boolean update(DnDEvent event); +} From 240c87b1d9bc638570514c874dce442376370117 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 4 Feb 2011 21:12:17 +0300 Subject: [PATCH 63/94] use DnDSupport instead of DnDSource and DnDTarget implementation --- .../impl/EditorGutterComponentImpl.java | 92 ++++++++----------- 1 file changed, 37 insertions(+), 55 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java index 1fb75bc9dda8..5b2c5e465ab0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java @@ -44,11 +44,11 @@ import com.intellij.openapi.editor.markup.*; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; import com.intellij.ui.HintHint; import com.intellij.ui.awt.RelativePoint; +import com.intellij.util.Function; import com.intellij.util.IconUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.ui.UIUtil; @@ -67,7 +67,7 @@ import java.awt.geom.AffineTransform; import java.util.*; import java.util.List; -class EditorGutterComponentImpl extends EditorGutterComponentEx implements MouseListener, MouseMotionListener, DnDTarget, DnDSource { +class EditorGutterComponentImpl extends EditorGutterComponentEx implements MouseListener, MouseMotionListener { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.EditorGutterComponentImpl"); private static final int START_ICON_AREA_WIDTH = 15; private static final int FREE_PAINTERS_AREA_WIDTH = 3; @@ -92,12 +92,45 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse public EditorGutterComponentImpl(EditorImpl editor) { myEditor = editor; if (!ApplicationManager.getApplication().isHeadlessEnvironment()) { - DnDManager.getInstance().registerSource(this, this); - DnDManager.getInstance().registerTarget(this, this); + installDnD(); } setOpaque(true); } + @SuppressWarnings({"ConstantConditions"}) + private void installDnD() { + DnDSupport.createBuilder(this) + .setBeanProvider(new Function() { + @Override + public DnDDragStartBean fun(DnDActionInfo info) { + final GutterIconRenderer renderer = getGutterRenderer(info.getPoint()); + return renderer != null && (info.isCopy() || info.isMove()) ? new DnDDragStartBean(renderer) : null; + } + }) + .setDropHandler(new DnDDropHandler() { + @Override + public void drop(DnDEvent e) { + final Object attachedObject = e.getAttachedObject(); + if (attachedObject instanceof GutterIconRenderer) { + final GutterDraggableObject draggableObject = ((GutterIconRenderer)attachedObject).getDraggableObject(); + if (draggableObject != null) { + final int line = convertPointToLineNumber(e.getPoint()); + if (line != -1) { + draggableObject.copy(line, myEditor.getVirtualFile()); + } + } + } + } + }) + .setImageProvider(new Function() { + @Override + public DnDImage fun(DnDActionInfo info) { + return new DnDImage(IconUtil.toImage(getGutterRenderer(info.getPoint()).getIcon())); + } + }) + .install(); + } + private void fireResized() { processComponentEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED)); } @@ -340,57 +373,6 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse g2.setTransform(old); } - @Override - public boolean update(DnDEvent aEvent) { - aEvent.setDropPossible(true, null); - return false; - } - - @Override - public void drop(DnDEvent aEvent) { - final Object attachedObject = aEvent.getAttachedObject(); - if (attachedObject instanceof GutterIconRenderer) { - final GutterDraggableObject draggableObject = ((GutterIconRenderer)attachedObject).getDraggableObject(); - if (draggableObject != null) { - final int line = convertPointToLineNumber(aEvent.getPoint()); - if (line != -1) { - draggableObject.copy(line, myEditor.getVirtualFile()); - } - } - } - } - - @Override - public void cleanUpOnLeave() { - } - - @Override - public void updateDraggedImage(Image image, Point dropPoint, Point imageOffset) { - } - - @Override - public boolean canStartDragging(DnDAction action, Point dragOrigin) { - return (action == DnDAction.MOVE || action == DnDAction.COPY) && getGutterRenderer(dragOrigin) != null; - } - - @Override - public DnDDragStartBean startDragging(DnDAction action, Point dragOrigin) { - return new DnDDragStartBean(getGutterRenderer(dragOrigin)); - } - - @Override - public Pair createDraggedImage(DnDAction action, Point dragOrigin) { - return new Pair(IconUtil.toImage(getGutterRenderer(dragOrigin).getIcon()), dragOrigin); - } - - @Override - public void dragDropEnd() { - } - - @Override - public void dropActionChanged(int gestureModifiers) { - } - private interface RangeHighlighterProcessor { void process(RangeHighlighter highlighter); } From f9080539fe4f34b8c259f79cf632f48f1a2f00bb Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 5 Feb 2011 16:11:07 +0100 Subject: [PATCH 64/94] better inspection messages --- .../siyeh/InspectionGadgetsBundle.properties | 6 ++- .../UnnecessaryJavaDocLinkInspection.java | 51 +++++++++++++------ .../UnnecessaryJavaDocLink.java | 6 +++ .../unnecessary_javadoc_link/expected.xml | 10 ++-- 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index 33ec73beb919..4df0b02e1574 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -1752,8 +1752,10 @@ multiple.exceptions.declared.on.test.method.display.name=Multiple exceptions dec multiple.exceptions.declared.on.test.method.problem.descriptor=#ref could be replaced with 'throws Exception' #loc multiple.exceptions.declared.on.test.method.quickfix=Replace with 'throws Exception' unnecessary.javadoc.link.display.name=Unnecessary JavaDoc link -unnecessary.javadoc.link.problem.descriptor=#ref is unnecessary #loc -unnecessary.javadoc.link.quickfix=Remove unnecessary {0} +unnecessary.javadoc.link.super.method.problem.descriptor=#ref pointing to super method is unnecessary #loc +unnecessary.javadoc.link.this.method.problem.descriptor=#ref pointing to this method is unnecessary #loc +unnecessary.javadoc.link.this.class.problem.descriptor=#ref pointing to containing class is unnecessary #loc +unnecessary.javadoc.link.quickfix=Remove unnecessary '{0}' thread.local.not.static.final.display.name=ThreadLocal field not declared static final thread.local.not.static.final.problem.descriptor=ThreadLocal #ref is not declared 'static final' #loc remove.try.finally.block.quickfix=Remove try-finally block diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryJavaDocLinkInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryJavaDocLinkInspection.java index 6efbda0e3adf..818053c4e1d8 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryJavaDocLinkInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryJavaDocLinkInspection.java @@ -39,6 +39,10 @@ import javax.swing.*; public class UnnecessaryJavaDocLinkInspection extends BaseInspection { + private static final int THIS_METHOD = 1; + private static final int THIS_CLASS = 2; + private static final int SUPER_METHOD = 3; + @SuppressWarnings({"PublicField"}) public boolean ignoreInlineLinkToSuper = false; @@ -53,14 +57,24 @@ public class UnnecessaryJavaDocLinkInspection extends BaseInspection { @NotNull @Override protected String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "unnecessary.javadoc.link.problem.descriptor"); + final int n = ((Integer) infos[1]).intValue(); + if (n == THIS_METHOD) { + return InspectionGadgetsBundle.message( + "unnecessary.javadoc.link.this.method.problem.descriptor"); + } else if (n == THIS_CLASS) { + return InspectionGadgetsBundle.message( + "unnecessary.javadoc.link.this.class.problem.descriptor"); + } else { + return InspectionGadgetsBundle.message( + "unnecessary.javadoc.link.super.method.problem.descriptor"); + } } @Override public JComponent createOptionsPanel() { return new SingleCheckboxOptionsPanel( - InspectionGadgetsBundle.message("unnecessary.javadoc.link.option"), + InspectionGadgetsBundle.message( + "unnecessary.javadoc.link.option"), this, "ignoreInlineLinkToSuper"); } @@ -88,10 +102,11 @@ public class UnnecessaryJavaDocLinkInspection extends BaseInspection { protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement element = descriptor.getPsiElement(); - if (!(element instanceof PsiDocTag)) { + final PsiElement parent = element.getParent(); + if (!(parent instanceof PsiDocTag)) { return; } - final PsiDocTag docTag = (PsiDocTag) element; + final PsiDocTag docTag = (PsiDocTag) parent; final PsiDocComment docComment = docTag.getContainingComment(); if (docComment != null) { if (shouldDeleteEntireComment(docComment)) { @@ -157,13 +172,15 @@ public class UnnecessaryJavaDocLinkInspection extends BaseInspection { return; } if (target.equals(containingMethod)) { - registerError(tag, '@' + name); + registerError(tag.getNameElement(), '@' + name, + Integer.valueOf(THIS_METHOD)); return; } final PsiClass containingClass = PsiTreeUtil.getParentOfType(tag, PsiClass.class); if (target.equals(containingClass)) { - registerError(tag, '@' + name); + registerError(tag.getNameElement(), '@' + name, + Integer.valueOf(THIS_CLASS)); return; } if (!(target instanceof PsiMethod)) { @@ -176,7 +193,8 @@ public class UnnecessaryJavaDocLinkInspection extends BaseInspection { if (ignoreInlineLinkToSuper && tag instanceof PsiInlineDocTag) { return; } - registerError(tag, '@' + name); + registerError(tag.getNameElement(), '@' + name, + Integer.valueOf(SUPER_METHOD)); } private PsiReference extractReference(PsiDocTag tag) { @@ -190,16 +208,17 @@ public class UnnecessaryJavaDocLinkInspection extends BaseInspection { if (dataElements.length == 0) { return null; } - final PsiElement lastElement = - dataElements[dataElements.length - 1]; - if (lastElement == null) { + PsiElement salientElement = null; + for (PsiElement dataElement : dataElements) { + if (!(dataElement instanceof PsiWhiteSpace)) { + salientElement = dataElement; + break; + } + } + if (salientElement == null) { return null; } - final PsiElement[] children = lastElement.getChildren(); - if (children.length == 0) { - return null; - } - final PsiElement child = children[0]; + final PsiElement child = salientElement.getFirstChild(); if (!(child instanceof PsiReference)) { return null; } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_javadoc_link/UnnecessaryJavaDocLink.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_javadoc_link/UnnecessaryJavaDocLink.java index baaf5c740fee..9a1882fbf974 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_javadoc_link/UnnecessaryJavaDocLink.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_javadoc_link/UnnecessaryJavaDocLink.java @@ -19,4 +19,10 @@ public class UnnecessaryJavaDocLink { void foo() { } + + /** + * @see com.siyeh.igtest.style.unnecessary_javadoc_link.UnnecessaryJavaDocLink + * something + */ + void bar() {} } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_javadoc_link/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_javadoc_link/expected.xml index a30c514efbf0..d8e1a99fad21 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_javadoc_link/expected.xml +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_javadoc_link/expected.xml @@ -5,7 +5,7 @@ UnnecessaryJavaDocLink.java 6 Unnecessary JavaDoc link - <code>{@link UnnecessaryJavaDocLink}</code> is unnecessary #loc + <code>@link</code> pointing to containing class is unnecessary #loc @@ -13,7 +13,7 @@ UnnecessaryJavaDocLink.java 7 Unnecessary JavaDoc link - <code>{@linkplain UnnecessaryJavaDocLink#equals(Object)}</code> is unnecessary #loc + <code>@linkplain</code> pointing to this method is unnecessary #loc @@ -21,21 +21,21 @@ UnnecessaryJavaDocLink.java 8 Unnecessary JavaDoc link - <code>@see Object#equals(Object)</code> is unnecessary #loc + <code>@see</code> pointing to super method is unnecessary #loc UnnecessaryJavaDocLink.java 16 Unnecessary JavaDoc link - <code>{@link #foo()}</code> is unnecessary #loc + <code>@link</code> pointing to this method is unnecessary #loc UnnecessaryJavaDocLink.java 17 Unnecessary JavaDoc link - <code>@see #foo()</code> is unnecessary #loc + <code>@see</code> pointing to this method is unnecessary #loc \ No newline at end of file From 9758cafe2ccbae5df68238ba4a46ef0064b659b8 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 5 Feb 2011 16:11:41 +0100 Subject: [PATCH 65/94] enable "Boxing of already boxed value" inspection by default --- .../com/siyeh/ig/performance/BoxingBoxedValueInspection.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/BoxingBoxedValueInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/BoxingBoxedValueInspection.java index b6f9eeac5d2c..a873e6b430a1 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/BoxingBoxedValueInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/BoxingBoxedValueInspection.java @@ -49,6 +49,11 @@ public class BoxingBoxedValueInspection extends BaseInspection { boxedPrimitiveMap.put(CommonClassNames.JAVA_LANG_CHARACTER, "char"); } + @Override + public boolean isEnabledByDefault() { + return true; + } + @Nls @NotNull @Override From 1694d261dadd7134b8ae656484d7b94b56d64988 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Sun, 6 Feb 2011 00:52:19 +0300 Subject: [PATCH 66/94] Common Info.plist for all products. --- build/conf/mac/Contents/Info.plist | 33 ++++-------- build/scripts/dist.gant | 80 ++++++++++-------------------- build/scripts/utils.gant | 80 ++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 76 deletions(-) diff --git a/build/conf/mac/Contents/Info.plist b/build/conf/mac/Contents/Info.plist index 6236c5336cc6..ea216539100c 100644 --- a/build/conf/mac/Contents/Info.plist +++ b/build/conf/mac/Contents/Info.plist @@ -4,37 +4,23 @@ CFBundleDevelopmentRegion English - CFBundleDocumentTypes - - - CFBundleTypeExtensions - - ipr - - CFBundleTypeIconFile - idea.icns - CFBundleTypeName - IntelliJ IDEA Project File - CFBundleTypeRole - Editor - - + @@doc_types@@ CFBundleExecutable - idea + @@executable@@ CFBundleIconFile - idea.icns + @@icns@@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - IntelliJ IDEA + @@bundle_name@@ CFBundlePackageType APPL CFBundleIdentifier - com.jetbrains.intellij + @@bundle_identifier@@ CFBundleSignature ???? CFBundleGetInfoString - IntelliJ IDEA @@version@@, build @@build@@. Copyright JetBrains s.r.o., (c) 2000-@@year@@ + @@bundle_name@@ @@version@@, build @@build@@. Copyright JetBrains s.r.o., (c) 2000-@@year@@ CFBundleShortVersionString @@version@@ CFBundleVersion @@ -49,12 +35,12 @@ YES Java - + ClassPath $APP_PACKAGE/lib/bootstrap.jar:$APP_PACKAGE/lib/extensions.jar:$APP_PACKAGE/lib/util.jar:$APP_PACKAGE/lib/jdom.jar:$APP_PACKAGE/lib/log4j.jar JVMVersion - @@jdk_req@@ + 1.6* MainClass com.intellij.idea.Main @@ -82,6 +68,7 @@ true apple.awt.fullscreencapturealldisplays false + @@platform@@ VMOptions @@ -89,6 +76,6 @@ WorkingDirectory $APP_PACKAGE/bin - + diff --git a/build/scripts/dist.gant b/build/scripts/dist.gant index 689a3b95098a..9a29437eae32 100644 --- a/build/scripts/dist.gant +++ b/build/scripts/dist.gant @@ -93,35 +93,6 @@ public def layoutAll(Map args, String home, String out) { layoutWin(args, home, paths) } -boolean isEap() { - return "true" == p("component.version.eap") -} - -private def patchPropertiesFile(String where) { - ant.echo(file: "$where/bin/idea.properties", append: "true", message: - isEap() ? -""" - -#----------------------------------------------------------------------- -# Change to 'disabled' if you need not to receive instant visual notifications about -# fatal errors that happen to IDEA or plugins installed. -#----------------------------------------------------------------------- -idea.fatal.error.notification=enabled -""" - - : - -""" - -#----------------------------------------------------------------------- -# Change to 'eanbled' if you need to receive instant visual notifications about -# fatal errors that happen to IDEA or plugins installed. -#----------------------------------------------------------------------- -idea.fatal.error.notification=disabled -""" - ) -} - private def layoutWin(Map args, String home, Paths paths) { layout("$paths.distWin") { dir("bin") { @@ -143,35 +114,38 @@ private def layoutWin(Map args, String home, Paths paths) { private def layoutMac(Map args, String home, Paths paths) { project.stage("Cleaning up sandbox folder") + args["executable"] = "idea" + args["bundle_name"] = "IntelliJ IDEA" + args["bundleIdentifier"] = "com.jetbrains.intellij.ce" + args["platform_prefix"] = "Idea" + args["doc_types"] = """ + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + ipr + + CFBundleTypeIconFile + idea.icns + CFBundleTypeName + IntelliJ IDEA Project File + CFBundleTypeRole + Editor + + + """ - ant.copy(todir: "$paths.distMac/bin") { - fileset(dir: "$home/bin") { include(name: "*.*") } - fileset(dir: "$home/bin/nix") - fileset(dir: "$home/bin/mac") + layoutMacApp(paths.distMac, home, args) + + layout(paths.distMac) { + dir("bin") { + fileset(dir: "$home/bin") { include(name: "*.*") } + } } patchPropertiesFile(paths.distMac) - ant.copy(todir: paths.distMac) { - fileset(dir: "$home/build/conf/mac") - } - - def version = isEap() ? p("component.version.codename") : p("component.version.major") + "." + p("component.version.minor") - - ant.tstamp() { - format(property: "todayYear", pattern: "yyyy") - } - - ant.replace(file: "${paths.distMac}/Contents/Info.plist") { - replacefilter(token: "@@build@@", value: args.buildNumber) - replacefilter(token: "@@year@@", value: "$todayYear") - - replacefilter(token: "@@version@@", value: version) - replacefilter(token: "@@vmoptions@@", value: args.vmoptions + " -Xverify:none -XX:+UseCompressedOOPS") - replacefilter(token: "@@system_selector@@", value: args.system_selector) - replacefilter(token: "@@jdk_req@@", value: args.jdk_req) - } - def root = isEap() ? "${p("component.version.codename")}-${args.buildNumber}.app" : "IntelliJ IDEA ${p("component.version.major")} CE.app" def macZipPath = "$paths.artifacts/idea${args.buildNumber}.mac.zip" diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index 0a5c1c7163a6..c6e9524b3e39 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -21,6 +21,10 @@ binding.setVariable("isMac", { return System.getProperty("os.name").toLowerCase().startsWith("mac") }) +binding.setVariable("isEap", { + return "true" == p("component.version.eap") +}) + binding.setVariable("isDefined", {String key -> try { this[key] @@ -109,3 +113,79 @@ binding.setVariable("commonJvmArgs", { "-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5555"] }) + +binding.setVariable("layoutMacApp", { String path, String ch, Map args -> + ant.copy(todir: "$path/bin") { + fileset(dir: "$ch/bin/nix") + fileset(dir: "$ch/bin/mac") + } + + ant.copy(todir: path) { + fileset(dir: "$ch/build/conf/mac") + } + + ant.tstamp() { + format(property: "todayYear", pattern: "yyyy") + } + + String icns = "idea.icns" + if (args.icns != null) { + ant.delete(file: "$path/Contents/Resources/idea.icns") + ant.copy(file: args.icns, todir: "$path/Contents/Resources") + icns = new File((String)args.icns).getName(); + } + + String platform = args.get("platform_prefix", null) != null ? + """ + idea.platform.prefix + $args.platform_prefix + """ : "" + + def version = isEap() ? "EAP " + args.buildNumber : p("component.version.major") + "." + p("component.version.minor") + + ant.replace(file: "$path/Contents/Info.plist") { + replacefilter(token: "@@build@@", value: args.buildNumber) + replacefilter(token: "@@doc_types@@", value: args.get("doc_types", "")) + replacefilter(token: "@@executable@@", value: args.executable) + replacefilter(token: "@@icns@@", value: icns) + replacefilter(token: "@@bundle_name@@", value: args.bundle_name) + replacefilter(token: "@@bundle_identifier@@", value: args.bundleIdentifier) + replacefilter(token: "@@year@@", value: "$todayYear") + + replacefilter(token: "@@version@@", value: version) + replacefilter(token: "@@vmoptions@@", value: args.vmoptions + " -Xverify:none -XX:+UseCompressedOOPS") + replacefilter(token: "@@system_selector@@", value: args.system_selector) + replacefilter(token: "@@platform@@", value: platform) + } + + if (args.executable != "idea") { + ant.move(file: "$path/Contents/MacOS/idea", tofile: "$path/Contents/MacOS/$args.executable") + } + +}) + +binding.setVariable("patchPropertiesFile", { String where -> + ant.echo(file: "$where/bin/idea.properties", append: "true", message: + isEap() ? +""" + +#----------------------------------------------------------------------- +# Change to 'disabled' if you do not need to receive instant visual notifications about +# fatal errors that happen to an IDE or plugins installed. +#----------------------------------------------------------------------- +idea.fatal.error.notification=enabled +""" + + : + +""" + +#----------------------------------------------------------------------- +# Change to 'eanbled' if you need to receive instant visual notifications about +# fatal errors that happen to an IDE or plugins installed. +#----------------------------------------------------------------------- +idea.fatal.error.notification=disabled +""" +) +}) + From 624c74bd62067e2c86790f36a5eebe53c7416110 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Mon, 7 Feb 2011 00:49:49 +0300 Subject: [PATCH 67/94] Normalize memory defaults across products build scripts. --- build/conf/mac/Contents/Info.plist | 6 ++++++ build/scripts/dist.gant | 6 ++---- build/scripts/utils.gant | 11 ++++++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/build/conf/mac/Contents/Info.plist b/build/conf/mac/Contents/Info.plist index ea216539100c..ff4e84643833 100644 --- a/build/conf/mac/Contents/Info.plist +++ b/build/conf/mac/Contents/Info.plist @@ -74,6 +74,12 @@ VMOptions @@vmoptions@@ -Xbootclasspath/a:../lib/boot.jar + VMOptions.i386 + @@vmoptions32@@ + + VMOptions.x86_64 + @@vmoptions64@@ + WorkingDirectory $APP_PACKAGE/bin diff --git a/build/scripts/dist.gant b/build/scripts/dist.gant index 9a29437eae32..a3b367df69e6 100644 --- a/build/scripts/dist.gant +++ b/build/scripts/dist.gant @@ -67,8 +67,6 @@ target('default': 'The default target') { buildNumber: "IC-104.SNAPSHOT", version: "IdeaX", system_selector: "IntelliJIdeaCE10", - jdk_req: "1.6*", - vmoptions: "-Xms128m -Xmx512m -XX:MaxPermSize=250m -ea", home, out) } @@ -102,7 +100,7 @@ private def layoutWin(Map args, String home, Paths paths) { } patchPropertiesFile(paths.distWin) - ant.echo(file: "$paths.distWin/bin/idea.exe.vmoptions", message: args.vmoptions.replace(' ', '\n')) + ant.echo(file: "$paths.distWin/bin/idea.exe.vmoptions", message: vmoptions32().replace(' ', '\n')) def winZipPath = "$paths.artifacts/idea${args.buildNumber}.win.zip" ant.zip(zipfile: winZipPath) { @@ -179,7 +177,7 @@ def layoutLinux(Map args, String home, Paths paths) { patchPropertiesFile(paths.distUnix) - ant.echo(file: "$paths.distUnix/bin/idea.vmoptions", message: args.vmoptions.replace(' ', '\n') ) + ant.echo(file: "$paths.distUnix/bin/idea.vmoptions", message: vmoptions32().replace(' ', '\n') ) ant.fixcrlf(srcdir: "$paths.distUnix/bin", includes: "idea.vmoptions", eol: "unix") ant.fixcrlf(srcdir: "$paths.distUnix/bin", includes: "*.sh", eol: "unix") diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index c6e9524b3e39..9731d695c165 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -25,6 +25,13 @@ binding.setVariable("isEap", { return "true" == p("component.version.eap") }) +binding.setVariable("mem32", "-Xms128m -Xmx512m -XX:MaxPermSize=250m") +binding.setVariable("mem64", "-Xms128m -Xmx800m -XX:MaxPermSize=350m") +binding.setVariable("common_vmoptions", "-ea") + +binding.setVariable("vmoptions32", {"$mem32 $common_vmoptions"}) +binding.setVariable("vmoptions64", {"$mem64 $common_vmoptions"}) + binding.setVariable("isDefined", {String key -> try { this[key] @@ -153,7 +160,9 @@ binding.setVariable("layoutMacApp", { String path, String ch, Map args -> replacefilter(token: "@@year@@", value: "$todayYear") replacefilter(token: "@@version@@", value: version) - replacefilter(token: "@@vmoptions@@", value: args.vmoptions + " -Xverify:none -XX:+UseCompressedOOPS") + replacefilter(token: "@@vmoptions@@", value: "$common_vmoptions -Xverify:none") + replacefilter(token: "@@vmoptions32@@", value: "$mem32") + replacefilter(token: "@@vmoptions64@@", value: "$mem64 -XX:+UseCompressedOOPS") replacefilter(token: "@@system_selector@@", value: args.system_selector) replacefilter(token: "@@platform@@", value: platform) } From cdc0ba9ce0e98f876e57e92858837ced984880c6 Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 7 Feb 2011 10:30:28 +0300 Subject: [PATCH 68/94] compiler-api.jar removed because it is included into jdk6 --- java/compiler/impl/compiler-impl.iml | 9 --------- lib/dev/compilerapi.jar | Bin 72275 -> 0 bytes 2 files changed, 9 deletions(-) delete mode 100644 lib/dev/compilerapi.jar diff --git a/java/compiler/impl/compiler-impl.iml b/java/compiler/impl/compiler-impl.iml index a65d7e10171d..a247d6b5abef 100644 --- a/java/compiler/impl/compiler-impl.iml +++ b/java/compiler/impl/compiler-impl.iml @@ -18,15 +18,6 @@ - - - - - - - - - diff --git a/lib/dev/compilerapi.jar b/lib/dev/compilerapi.jar deleted file mode 100644 index b5bf1f3d8ed7ad3e0337c6d0a33081c4d10ad540..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72275 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 z 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%0Dup zXkcS&^kWz3KD|3WU=Mr(h{PfQ<*ry@KXHHMA{ju~imBO&uK;q206?a{(^^E- z|9}dVI&r{R)9)G#geJC?V59&LLLWegyU-?pERKI7=RXbpKWOIPx7s^IHG>%d&G!rR z2IhYY&GLI_g1MH1Lx7$Q0`!FW4ndr7{#$5(CynEeL&e){1XAUq+eSVg(EklC5D?ls z_?>`Z`M;vduMG#9jVxtRJqiFPSAn+Z4sZ|ae*y-K|G(oR5H|O^Y*-&aYF+@T@4||+ z|2MF|;UEx}pll7JilTAChz1qEoU6hN5os-B?Oe*(2P zGIIDG4S=`xwwm)F7aRC{)PxZTwbEQ6ySE@Dgc+^4iT=U{wrKT8(XvA z2^tVwMLeOA955bYGv2os$g=+p`0q)KU-B`?13=ycK*%-QohAqC{25i%UeDGR5H|!= z?qA%@ZX5E%e}QUbgKRNWc&?A(8k)) z$i6q9fj{txM0PMR0F>LskCjP*dH2M?nh285*fTB$SG~@1= zN@)C_aew6)(BLd0#6?d7+W7$>WGp|40C=;p{0pX#k+GhWrQ9nr3K(<+@6_h& z^uN`nU}WNCsb>%5+il08+Y$_98udJ%Ryu%^F;D>0ey75gm;YOZimq1rHkNwFznrWhP?i_$^aRg|5}r$9DLRgpj-NYDX8$RdO$#q{Qu{gfHV}hHZ*ei zYn8WCQv*hsThEh_|Nkog6aQ}K$h^zH=GgzQTK^_2w{J=TrrrGc6s7)8mHn#O!0T3S z-ve^j>S6T$1^&+EE4K%c-`ybcv&nINKm4U`m-*d|B0tO2{$H7&YmXmmK;U=)n(^~C z2jZW_0B@`JO8)k~k=x1%gu8vy05B^0=My#fqw(Jx@)Pb?(gGdDZik+e|AYa&i46Y< z>E1mB_ZxRRn49blx4Z+^?S?QdEEjOM%@=XqC>kSFdT z{V|sLc7K7Gw0;kruBU>KbVUX|Q zU0h%@1^*gbbekAJ?Au`%faS`q2W|P!*uTmq5bJiN!rlH4ul$MyWc}~MHtx6aw!8UV zW!zr(6Iy`!3pVd|q!84=9wk-I(rb(8sTL!T#)LdK(kiz}wz2cbAZchxai5<_>iq_O`Rd zT|=aI{Cn6R4i>+g$pRaC`>2%UCm8{6W~YBg{5@xGA24Fv!MnP+iwE3+{}lsx6nT3` zpY#p}=GCtlKX&nN9ZcRP8xZjJe(_xu{_^0#9cv40)DOTPje~#$wm}H+M;FkeS+ECy G-~JzOo6`dT From 6ca2f620f77c978fb4f4a188dc9262b23f7f5f4e Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 7 Feb 2011 10:34:07 +0300 Subject: [PATCH 69/94] more licenses for libs & maven libraries arranged --- build/scripts/libLicenses.gant | 11 ++++- .../maven/facade-impl/maven-facade-impl.iml | 44 +++---------------- 2 files changed, 16 insertions(+), 39 deletions(-) diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant index 2449222cde3a..a1eed990ad33 100644 --- a/build/scripts/libLicenses.gant +++ b/build/scripts/libLicenses.gant @@ -103,20 +103,27 @@ libraryLicense(name: "Ant", version: "1.7", license: "Apache 2.0", url: "http:// libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm", version: "3.3", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html") libraryLicense(name: "Axis", libraryName: "axis-1.4", version: "1.4", license: "Apache 2.0", url: "http://ws.apache.org/axis/", licenseUrl: "http://svn.jetbrains.org/idea/Trunk/bundled/WebServices/resources/lib/axis-1.4.0/axis.LICENSE") libraryLicense(name: "CGLib", libraryName: "CGLIB", version: "2.2", license: "Apache", url: "http://cglib.sourceforge.net/", licenseUrl: "http://www.apache.org/foundation/licence-FAQ.html") +libraryLicense(name: "classworlds", libraryName: "classworlds-1.1.jar", version: "1.1", license: "codehaus", url: "http://classworlds.codehaus.org/", licenseUrl: "http://classworlds.codehaus.org/license.html") +libraryLicense(name: "Apache Commons BeanUtils", libraryName: "commons-beanutils.jar", version: "1.6", license: "Apache 2.0", url: "http://commons.apache.org/beanutils/") libraryLicense(name: "Apache Commons Codec", libraryName: "commons-codec", version: "1.3", license: "Apache 2.0", url: "http://commons.apache.org/codec/", licenseUrl: "http://commons.apache.org/license.html") libraryLicense(name: "Apache Commons Collections", libraryName: "commons-collections", version: "3.1", license: "Apache 2.0", url: "http://commons.apache.org/collections/", licenseUrl: "http://commons.apache.org/license.html") libraryLicense(name: "Apache Commons HTTPClient", libraryName: "http-client-3.1", version: "3.1  (with patch by JetBrains)", license: "Apache 2.0", url: "http://hc.apache.org/httpclient-3.x") libraryLicense(name: "Apache Commons Lang", libraryName: "commons-lang", version: "2.4", license: "Apache 2.0", url: "http://commons.apache.org/lang/", licenseUrl: "http://commons.apache.org/lang/license.html") -libraryLicense(name: "Apache Commons Logging", libraryName: "commons-logging", version: "1.1.1", license: "Apache 2.0", url: "http://commons.apache.org/logging/", licenseUrl: "http://svn.jetbrains.org/idea/Trunk/bundled/WebServices/resources/lib/axis-1.4.0/commons-logging-1.0.4.LICENSE") +libraryLicense(name: "Apache Commons Logging", libraryName: "commons-logging", version: "1.1.1", license: "Apache 2.0", url: "http://commons.apache.org/logging/") +libraryLicense(name: "Apache Lucene", libraryName: "lucene-core-2.3.0.jar", version: "2.3.0", license: "Apache 2.0", url: "http://lucene.apache.org/java") libraryLicense(name: "Automaton", libraryName: "automaton.jar", version: "1.11", license: "BSD", url: "http://www.brics.dk/automaton/", licenseUrl: "http://www.opensource.org/licenses/bsd-license.php") libraryLicense(name: "DTDParser", version: "1.13", license: "LGPL", url: "http://sourceforge.net/projects/dtdparser/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1") libraryLicense(name: "Ganymed", version: "bundled with SVNKit", license: "BSD", url: "http://www.ganymed.ethz.ch/ssh2/", licenseUrl: "http://www.ganymed.ethz.ch/ssh2/LICENSE.txt") libraryLicense(name: "Guava", version: "R6", license: "Apache 2.0", url: "http://code.google.com/p/guava-libraries/", licenseUrl: "http://ant.apache.org/license.html") libraryLicense(name: "Gradle API", libraryName: "gradle-open-api-0.8.jar", version: "0.8", license: "Apache 2.0", url: "http://www.gradle.org/") libraryLicense(name: "Groovy", version: "1.7.3", license: "Apache 2.0", url: "http://groovy.codehaus.org/") +libraryLicense(name: "Gson", libraryName: "gson-1.3.jar", license: "Apache 2.0", url: "http://code.google.com/p/google-gson/") +libraryLicense(name: "ISO RELAX", libraryName: "isorelax.jar", license: "MIT License", url: "http://sourceforge.net/projects/iso-relax/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html") libraryLicense(name: "JavaCVS", version: "no version number available (with patches by JetBrains)", license: "Sun Public License", url: "http://javacvs.netbeans.org/library/", licenseUrl: "http://www.netbeans.org/about/legal/spl.html") +libraryLicense(name: "JAXB", libraryName: "JAXB", version: "2.1.10", license: "CDDL 1.1 & GPL 2", url: "http://jaxb.java.net/", licenseUrl: "http://glassfish.java.net/public/CDDL+GPL_1_1.html") libraryLicense(name: "Jaxen", version: "", license: "modified Apache", url: "http://www.jaxen.org/", licenseUrl: "http://www.jaxen.org/license.html") libraryLicense(name: "JavaHelp", version: "2.0_02", license: "included as license/javahelp_license.html in IntelliJ IDEA distribution", url: "http://java.sun.com/products/javahelp/") +libraryLicense(name: "JCIP Annotations", libraryName: "jcip-annotations.jar", license: "Creative Commons Attribution License", url: "http://www.jcip.net", licenseUrl: "http://creativecommons.org/licenses/by/2.5") libraryLicense(name: "JDOM", version: "1.1 (with patches by JetBrains)", license: "modified Apache", url: "http://www.jdom.org/", licenseUrl: "http://www.jdom.org/docs/faq.html#a0030") libraryLicense(name: "JGoodies Forms", libraryName: "jgoodies-forms", version: "CVS snapshot as of 5 May 2006", license: "BSD ", url: "http://www.jgoodies.com/freeware/forms/", licenseUrl: "http://www.jgoodies.com/downloads/libraries.html") libraryLicense(name: "JNA", libraryName: "jna", version: "3.2.4", license: "LGPL 2.1", url: "https://jna.dev.java.net/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1.php") @@ -130,6 +137,8 @@ libraryLicense(name: "NanoXML", version: "2.2.3", license: "zlib/libpng", url: " libraryLicense(name: "Eclipse JDT Core", libraryName: "Eclipse", version: "3.3", license: "CPL 1.0", url: "http://www.eclipse.org/jdt/core/index.php") libraryLicense(name: "Jakarta ORO", libraryName: "OroMatcher", version: "2.0.8", license: "Apache", url: "http://jakarta.apache.org/oro/", licenseUrl: "http://svn.apache.org/repos/asf/jakarta/oro/trunk/LICENSE") libraryLicense(name: "PicoContainer", libraryName: "picocontainer", version: "1.2", license: "BSD", url: "http://www.picocontainer.org/", licenseUrl: "http://docs.codehaus.org/display/PICO/License") +libraryLicense(name: "Plexus Utils", libraryName: "plexus-utils-1.5.5.jar", version: "1.5.5", license: "Apache 2.0", url: "http://plexus.codehaus.org/plexus-utils") +libraryLicense(name: "Relax NG Object Model", libraryName: "rngom-20051226-patched.jar", license: "MIT", url: "http://java.net/projects/rngom/", licenseUrl: "http://www.opensource.org/licenses/mit-license.php") libraryLicense(name: "SVNKit", libraryName: "svnkit.jar", version: "SVN version, 1.1 branch as of 1 Oct 2007", license: "link (commercial license)", url: "http://www.svnkit.com/", licenseUrl: "http://svnkit.com/license.html") libraryLicense(name: "TestNG", version: "5.7 snapshot", license: "Apache 2.0", url: "http://testng.org/doc/", licenseUrl: "http://code.google.com/p/testng/") libraryLicense(name: "Trilead SSH", libraryName: "trilead-ssh2-build213.jar", version: "build 213", license: "BSD style (see LICENSE.txt in trilead-ssh-build213.jar)", url: "http://www.trilead.com/SSH_Library/") diff --git a/plugins/maven/facade-impl/maven-facade-impl.iml b/plugins/maven/facade-impl/maven-facade-impl.iml index d6356b9cf3f3..85676062dd81 100644 --- a/plugins/maven/facade-impl/maven-facade-impl.iml +++ b/plugins/maven/facade-impl/maven-facade-impl.iml @@ -12,26 +12,9 @@ - + - - - - - - - - - - - - - - - - - @@ -41,7 +24,7 @@ - + @@ -75,23 +58,17 @@ - + + + + - - - - - - - - - @@ -101,15 +78,6 @@ - - - - - - - - - From 9414e45716cb427bbda098c4be7d2fde8a37b74a Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 7 Feb 2011 10:33:14 +0300 Subject: [PATCH 70/94] migrate to TransferToEdtQueue --- .../HighlightSuppressedWarningsHandler.java | 6 +- .../daemon/impl/DaemonCodeAnalyzerImpl.java | 3 +- .../daemon/impl/LocalInspectionsPass.java | 147 +++++++++--------- .../impl/LocalInspectionsPassFactory.java | 2 +- .../WholeFileLocalInspectionsPassFactory.java | 2 +- .../ex/GlobalInspectionContextImpl.java | 5 +- .../impl/TransferToPooledThreadQueue.java | 40 +++++ .../vfs/encoding/EncodingManagerImpl.java | 44 ++---- .../testFramework/LightPlatformTestCase.java | 2 +- .../usages/impl/UsageViewMemoryTest.java | 58 +++++++ .../util/xml/ui/DomUIFactoryImpl.java | 3 +- 11 files changed, 198 insertions(+), 114 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/openapi/application/impl/TransferToPooledThreadQueue.java create mode 100644 platform/usageView/testSrc/com/intellij/usages/impl/UsageViewMemoryTest.java diff --git a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsHandler.java b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsHandler.java index 731956ee956d..6022b512656a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsHandler.java @@ -108,7 +108,9 @@ public class HighlightSuppressedWarningsHandler extends HighlightUsagesHandlerBa public void computeUsages(List targets) { final Project project = myTarget.getProject(); final PsiElement parent = myTarget.getParent().getParent(); - final LocalInspectionsPass pass = new LocalInspectionsPass(myFile, myFile.getViewProvider().getDocument(), parent.getTextRange().getStartOffset(), parent.getTextRange().getEndOffset()); + final LocalInspectionsPass pass = new LocalInspectionsPass(myFile, myFile.getViewProvider().getDocument(), + parent.getTextRange().getStartOffset(), parent.getTextRange().getEndOffset(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, + false); final InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile(); for (PsiLiteralExpression target : targets) { @@ -128,7 +130,7 @@ public class HighlightSuppressedWarningsHandler extends HighlightUsagesHandlerBa ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); Runnable inspect = new Runnable() { public void run() { - pass.doInspectInBatch(managerEx, Collections.singletonList(tool), false); + pass.doInspectInBatch(managerEx, Collections.singletonList(tool)); } }; if (indicator == null) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java index 832fb318eab1..8a665afa2fa4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java @@ -159,7 +159,8 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx List result = new ArrayList(); result.addAll(action1.getHighlights()); - LocalInspectionsPass action3 = new LocalInspectionsPass(psiFile, document, 0, psiFile.getTextLength()); + LocalInspectionsPass action3 = new LocalInspectionsPass(psiFile, document, 0, + psiFile.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true); action3.doCollectInformation(progress); result.addAll(action3.getHighlights()); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java index 503cd00a3c53..76a6ce8f008b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java @@ -46,7 +46,6 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.Trinity; import com.intellij.openapi.util.text.StringUtil; @@ -58,7 +57,7 @@ import com.intellij.util.ConcurrencyUtil; import com.intellij.util.Function; import com.intellij.util.Processor; import com.intellij.util.containers.ConcurrentHashMap; -import com.intellij.util.ui.UIUtil; +import com.intellij.util.containers.TransferToEDTQueue; import com.intellij.xml.util.XmlStringUtil; import gnu.trove.THashMap; import gnu.trove.THashSet; @@ -67,9 +66,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; /** * @author max @@ -77,9 +74,11 @@ import java.util.concurrent.atomic.AtomicBoolean; public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass implements DumbAware { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.LocalInspectionsPass"); private static final int NUM_ELEMENTS_PER_CHECK_CANCELLED = 5; + public static final TextRange EMPTY_PRIORITY_RANGE = new TextRange(0, 0); private final int myStartOffset; private final int myEndOffset; private final TextRange myPriorityRange; + private final boolean myIgnoreSuppressed; private final ConcurrentMap> result = new ConcurrentHashMap>(); static final String PRESENTABLE_NAME = DaemonBundle.message("pass.inspection"); private volatile List myInfos = Collections.emptyList(); @@ -88,14 +87,17 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass private final InspectionProfileWrapper myProfileWrapper; private boolean myFailFastOnAcquireReadAction; - public LocalInspectionsPass(@NotNull PsiFile file, @Nullable Document document, int startOffset, int endOffset) { - this(file, document, startOffset, endOffset, new TextRange(0, 0)); - } - public LocalInspectionsPass(@NotNull PsiFile file, @Nullable Document document, int startOffset, int endOffset, @NotNull TextRange priorityRange) { + public LocalInspectionsPass(@NotNull PsiFile file, + @Nullable Document document, + int startOffset, + int endOffset, + @NotNull TextRange priorityRange, + boolean ignoreSuppressed) { super(file.getProject(), document, PRESENTABLE_NAME, file, true); myStartOffset = startOffset; myEndOffset = endOffset; myPriorityRange = priorityRange; + myIgnoreSuppressed = ignoreSuppressed; setId(Pass.LOCAL_INSPECTIONS); final KeymapManager keymapManager = KeymapManager.getInstance(); @@ -113,7 +115,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass if (customizationStrategy != null) { profileToUse = customizationStrategy.fun(profileToUse); } - + myProfileWrapper = profileToUse; mySeverityRegistrar = ((SeverityProvider)myProfileWrapper.getInspectionProfile().getProfileManager()).getSeverityRegistrar(); LOG.assertTrue(mySeverityRegistrar != null); @@ -128,7 +130,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass final InspectionManagerEx iManager = (InspectionManagerEx)InspectionManager.getInstance(myProject); final InspectionProfileWrapper profile = myProfileWrapper; final List tools = DumbService.getInstance(myProject).filterByDumbAwareness(getInspectionTools(profile)); - inspect(tools, iManager, true, true, true, progress); + inspect(tools, iManager, true, true, progress); } finally { disposeDescriptors(); @@ -146,7 +148,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass result.clear(); } - public void doInspectInBatch(final InspectionManagerEx iManager, List toolWrappers, boolean ignoreSuppressed) { + public void doInspectInBatch(final InspectionManagerEx iManager, List toolWrappers) { Map tool2Wrapper = new THashMap(toolWrappers.size()); for (InspectionProfileEntry toolWrapper : toolWrappers) { tool2Wrapper.put(((LocalInspectionToolWrapper)toolWrapper).getTool(), (LocalInspectionToolWrapper)toolWrapper); @@ -154,7 +156,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass List tools = new ArrayList(tool2Wrapper.keySet()); ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); - inspect(tools, iManager, false, ignoreSuppressed, false, progress); + inspect(tools, iManager, false, false, progress); addDescriptorsFromInjectedResults(tool2Wrapper, iManager); List resultList = result.get(myFile); if (resultList == null) return; @@ -163,7 +165,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass LocalInspectionToolWrapper toolWrapper = tool2Wrapper.get(tool); if (toolWrapper == null) continue; for (ProblemDescriptor descriptor : inspectionResult.foundProblems) { - toolWrapper.addProblemDescriptors(Collections.singletonList(descriptor), ignoreSuppressed); + toolWrapper.addProblemDescriptors(Collections.singletonList(descriptor), myIgnoreSuppressed); } } } @@ -214,7 +216,6 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass private void inspect(final List tools, final InspectionManagerEx iManager, final boolean isOnTheFly, - final boolean ignoreSuppressed, boolean failFastOnAcquireReadAction, @NotNull final ProgressIndicator indicator) { myFailFastOnAcquireReadAction = failFastOnAcquireReadAction; @@ -231,8 +232,8 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass List> init = new ArrayList>(); boolean finished = false; try { - visitPriorityElementsAndInit(tools, iManager, isOnTheFly, ignoreSuppressed, indicator, inside, session, init); - visitRestElementsAndCleanup(tools,iManager,isOnTheFly,ignoreSuppressed, indicator, outside, session, init); + visitPriorityElementsAndInit(tools, iManager, isOnTheFly, indicator, inside, session, init); + visitRestElementsAndCleanup(tools,iManager,isOnTheFly, indicator, outside, session, init); finished = true; } finally { @@ -253,13 +254,12 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass indicator.checkCanceled(); myInfos = new ArrayList(); - addHighlightsFromResults(myInfos, ignoreSuppressed); + addHighlightsFromResults(myInfos); } private void visitPriorityElementsAndInit(@NotNull List tools, @NotNull final InspectionManagerEx iManager, final boolean isOnTheFly, - final boolean ignoreSuppressed, @NotNull final ProgressIndicator indicator, @NotNull final List elements, @NotNull final LocalInspectionToolSession session, @@ -276,7 +276,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass public void registerProblem(@NotNull ProblemDescriptor descriptor) { super.registerProblem(descriptor); if (applyIncrementally[0]) { - addDescriptorIncrementally(descriptor, tool, ignoreSuppressed, indicator); + addDescriptorIncrementally(descriptor, tool, indicator); } } }; @@ -295,7 +295,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass } }, myFailFastOnAcquireReadAction, indicator); if (!result) throw new ProcessCanceledException(); - inspectInjectedPsi(elements, tools, isOnTheFly, ignoreSuppressed, indicator, iManager, true); + inspectInjectedPsi(elements, tools, isOnTheFly, indicator, iManager, true); } private static PsiElementVisitor createVisitorAndAcceptElements(@NotNull LocalInspectionTool tool, @@ -324,7 +324,6 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass private void visitRestElementsAndCleanup(@NotNull List tools, @NotNull InspectionManagerEx iManager, final boolean isOnTheFly, - final boolean ignoreSuppressed, @NotNull final ProgressIndicator indicator, @NotNull final List elements, @NotNull final LocalInspectionToolSession session, @@ -341,7 +340,8 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass ProblemsHolder holder = trinity.second; PsiElementVisitor elementVisitor = trinity.third; for (int i = 0, elementsSize = elements.size(); i < elementsSize; i++) { - elements.get(i).accept(elementVisitor); + PsiElement element = elements.get(i); + element.accept(elementVisitor); if (i % NUM_ELEMENTS_PER_CHECK_CANCELLED == 0) indicator.checkCanceled(); } @@ -359,13 +359,12 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass if (!result) { throw new ProcessCanceledException(); } - inspectInjectedPsi(elements, tools, isOnTheFly, ignoreSuppressed, indicator, iManager, false); + inspectInjectedPsi(elements, tools, isOnTheFly, indicator, iManager, false); } private void inspectInjectedPsi(@NotNull final List elements, @NotNull final List tools, final boolean onTheFly, - final boolean ignoreSuppressed, @NotNull final ProgressIndicator indicator, @NotNull final InspectionManagerEx iManager, final boolean inVisibleRange) { @@ -380,7 +379,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass if (injected.isEmpty()) return; if (!JobUtil.invokeConcurrentlyUnderProgress(new ArrayList(injected), new Processor() { public boolean process(final PsiFile injectedPsi) { - doInspectInjectedPsi(injectedPsi, tools, onTheFly, ignoreSuppressed, indicator, iManager, inVisibleRange); + doInspectInjectedPsi(injectedPsi, tools, onTheFly, indicator, iManager, inVisibleRange); return true; } }, myFailFastOnAcquireReadAction, indicator)) throw new ProcessCanceledException(); @@ -389,7 +388,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass public Collection getHighlights() { List highlights = new ArrayList(); - addHighlightsFromResults(highlights, true); + addHighlightsFromResults(highlights); return highlights; } @@ -410,56 +409,52 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass severity, problemDescriptor.isAfterEndOfLine(), null, isFileLevel); } - private final AtomicBoolean haveInfosToProcess = new AtomicBoolean(); - private final ConcurrentLinkedQueue> infosToAdd = new ConcurrentLinkedQueue>(); + private final TransferToEDTQueue> myTransferToEDTQueue; + { + myTransferToEDTQueue = + new TransferToEDTQueue>(new Processor>() { + private final InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(myProject).getInspectionProfile(); + private final InjectedLanguageManager ilManager = InjectedLanguageManager.getInstance(myProject); + private final List infos = new ArrayList(2); + private final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); + @Override + public boolean process(Trinity trinity) { + ProgressIndicator indicator = trinity.getThird(); + if (indicator.isCanceled()) { + return false; + } + + ProblemDescriptor descriptor = trinity.first; + LocalInspectionTool tool = trinity.second; + PsiElement psiElement = descriptor.getPsiElement(); + if (psiElement == null) return true; + PsiFile file = psiElement.getContainingFile(); + Document thisDocument = documentManager.getDocument(file); + + HighlightSeverity severity = inspectionProfile.getErrorLevel(HighlightDisplayKey.find(tool.getShortName()), file).getSeverity(); + + infos.clear(); + createHighlightsForDescriptor(infos, emptyActionRegistered, ilManager, file, thisDocument, tool, severity, descriptor); + for (HighlightInfo info : infos) { + final EditorColorsScheme colorsScheme = getColorsScheme(); + UpdateHighlightersUtil.addHighlighterToEditorIncrementally(myProject, myDocument, myFile, myStartOffset, myEndOffset, + info, colorsScheme, getId()); + } + + return true; + } + }, myProject.getDisposed()); + } + private final Set emptyActionRegistered = Collections.synchronizedSet(new HashSet()); private void addDescriptorIncrementally(@NotNull final ProblemDescriptor descriptor, @NotNull final LocalInspectionTool tool, - final boolean ignoreSuppressed, @NotNull final ProgressIndicator indicator) { - if (ignoreSuppressed && InspectionManagerEx.inspectionResultSuppressed(descriptor.getPsiElement(), tool)) { + if (myIgnoreSuppressed && InspectionManagerEx.inspectionResultSuppressed(descriptor.getPsiElement(), tool)) { return; } - - infosToAdd.offer(Pair.create(descriptor, tool)); - if (haveInfosToProcess.getAndSet(true)) return; - final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); - // extra invoke later is harmless, missing invoke is not - UIUtil.invokeLaterIfNeeded(new Runnable() { - public void run() { - if (myProject.isDisposed()) return; - InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(myProject).getInspectionProfile(); - InjectedLanguageManager ilManager = InjectedLanguageManager.getInstance(myProject); - List infos = new ArrayList(2); - while (haveInfosToProcess.compareAndSet(true, false)) { - for (Pair pair = infosToAdd.poll(); pair != null; pair = infosToAdd.poll()) { - if (indicator.isCanceled()) { - infosToAdd.clear(); - return; - } - - ProblemDescriptor descriptor = pair.first; - LocalInspectionTool tool = pair.second; - PsiElement psiElement = descriptor.getPsiElement(); - if (psiElement == null) continue; - PsiFile file = psiElement.getContainingFile(); - Document thisDocument = documentManager.getDocument(file); - - HighlightSeverity severity = inspectionProfile.getErrorLevel(HighlightDisplayKey.find(tool.getShortName()), file).getSeverity(); - - infos.clear(); - createHighlightsForDescriptor(infos, emptyActionRegistered, ilManager, file, thisDocument, tool, severity, descriptor, ignoreSuppressed); - for (HighlightInfo info : infos) { - final EditorColorsScheme colorsScheme = getColorsScheme(); - - UpdateHighlightersUtil.addHighlighterToEditorIncrementally(myProject, myDocument, myFile, myStartOffset, myEndOffset, - info, colorsScheme, getId()); - } - } - } - } - }); + myTransferToEDTQueue.offer(Trinity.create(descriptor, tool, indicator)); } private void appendDescriptors(PsiFile file, List descriptors, LocalInspectionTool tool) { @@ -519,7 +514,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument, myStartOffset, myEndOffset, myInfos, getColorsScheme(), getId()); } - private void addHighlightsFromResults(final List outInfos, boolean ignoreSuppressed) { + private void addHighlightsFromResults(final List outInfos) { InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(myProject).getInspectionProfile(); PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); InjectedLanguageManager ilManager = InjectedLanguageManager.getInstance(myProject); @@ -534,8 +529,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass LocalInspectionTool tool = inspectionResult.tool; HighlightSeverity severity = inspectionProfile.getErrorLevel(HighlightDisplayKey.find(tool.getShortName()), file).getSeverity(); for (ProblemDescriptor descriptor : inspectionResult.foundProblems) { - createHighlightsForDescriptor(outInfos, emptyActionRegistered, ilManager, file, documentRange, tool, severity, descriptor, - ignoreSuppressed); + createHighlightsForDescriptor(outInfos, emptyActionRegistered, ilManager, file, documentRange, tool, severity, descriptor); } } } @@ -548,10 +542,10 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass Document documentRange, LocalInspectionTool tool, HighlightSeverity severity, - ProblemDescriptor descriptor, boolean ignoreSuppressed) { + ProblemDescriptor descriptor) { PsiElement psiElement = descriptor.getPsiElement(); if (psiElement == null) return; - if (ignoreSuppressed && InspectionManagerEx.inspectionResultSuppressed(psiElement, tool)) return; + if (myIgnoreSuppressed && InspectionManagerEx.inspectionResultSuppressed(psiElement, tool)) return; HighlightInfoType level = highlightTypeFromDescriptor(descriptor, severity); HighlightInfo info = createHighlightInfo(descriptor, tool, level, emptyActionRegistered); if (info == null) return; @@ -677,7 +671,6 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass private void doInspectInjectedPsi(@NotNull PsiFile injectedPsi, @NotNull List tools, final boolean isOnTheFly, - final boolean ignoreSuppressed, @NotNull final ProgressIndicator indicator, @NotNull InspectionManagerEx iManager, final boolean inVisibleRange) { @@ -689,7 +682,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass } for (final LocalInspectionTool tool : tools) { indicator.checkCanceled(); - if (host != null && ignoreSuppressed && InspectionManagerEx.inspectionResultSuppressed(host, tool)) { + if (host != null && myIgnoreSuppressed && InspectionManagerEx.inspectionResultSuppressed(host, tool)) { continue; } ProblemsHolder holder = new ProblemsHolder(iManager, injectedPsi, isOnTheFly) { @@ -697,7 +690,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass public void registerProblem(@NotNull ProblemDescriptor descriptor) { super.registerProblem(descriptor); if (isOnTheFly && inVisibleRange) { - addDescriptorIncrementally(descriptor, tool, ignoreSuppressed, indicator); + addDescriptorIncrementally(descriptor, tool, indicator); } } }; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java index 327772a905a3..368be146dd9b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java @@ -55,7 +55,7 @@ public class LocalInspectionsPassFactory extends AbstractProjectComponent implem if (textRange == null) return new ProgressableTextEditorHighlightingPass.EmptyPass(myProject, editor.getDocument() ); TextRange visibleRange = VisibleHighlightingPassFactory.calculateVisibleRange(editor); - return new LocalInspectionsPass(file, editor.getDocument(), textRange.getStartOffset(), textRange.getEndOffset(), visibleRange){ + return new LocalInspectionsPass(file, editor.getDocument(), textRange.getStartOffset(), textRange.getEndOffset(), visibleRange, true){ List getInspectionTools(InspectionProfileWrapper profile) { List tools = super.getInspectionTools(profile); List result = new ArrayList(tools.size()); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java index c77f7236f3e3..2216b24dcbcf 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java @@ -90,7 +90,7 @@ public class WholeFileLocalInspectionsPassFactory extends AbstractProjectCompone public TextEditorHighlightingPass createHighlightingPass(@NotNull final PsiFile file, @NotNull final Editor editor) { TextRange textRange = FileStatusMap.getDirtyTextRange(editor, Pass.LOCAL_INSPECTIONS); if (textRange == null || myFileTools.containsKey(file) && !myFileTools.get(file)) return null; - return new LocalInspectionsPass(file, editor.getDocument(), 0, file.getTextLength()) { + return new LocalInspectionsPass(file, editor.getDocument(), 0, file.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true) { List getInspectionTools(InspectionProfileWrapper profile) { List tools = super.getInspectionTools(profile); List result = new ArrayList(); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java index 731cc9c3faf9..639610151560 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java @@ -537,7 +537,8 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext { final FileViewProvider viewProvider = psiManager.findViewProvider(virtualFile); final com.intellij.openapi.editor.Document document = viewProvider == null ? null : viewProvider.getDocument(); if (document == null || virtualFile.getFileType().isBinary()) return; //do not inspect binary files - final LocalInspectionsPass pass = new LocalInspectionsPass(file, document, 0, file.getTextLength()); + final LocalInspectionsPass pass = new LocalInspectionsPass(file, document, 0, + file.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true); try { final List lTools = new ArrayList(); for (Tools tool : localTools) { @@ -546,7 +547,7 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext { lTools.add(enabledTool); } } - pass.doInspectInBatch((InspectionManagerEx)manager, lTools, true); + pass.doInspectInBatch((InspectionManagerEx)manager, lTools); } catch (ProcessCanceledException e) { throw e; diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/TransferToPooledThreadQueue.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/TransferToPooledThreadQueue.java new file mode 100644 index 000000000000..93cd04f40196 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/TransferToPooledThreadQueue.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.application.impl; + +import com.intellij.concurrency.JobScheduler; +import com.intellij.openapi.util.Condition; +import com.intellij.util.Processor; +import com.intellij.util.containers.TransferToEDTQueue; +import org.jetbrains.annotations.NotNull; + +/** + * Allows to process elements in the Application pooled thread. + * Processes elements in batches, no longer than 200ms per batch, and reschedules processing later for longer batches. + * Usage: {@link #offer(Object)} } : schedules element for processing in a pooled thread + */ +public class TransferToPooledThreadQueue extends TransferToEDTQueue { + + public TransferToPooledThreadQueue(@NotNull Processor processorInEDT, @NotNull Condition shutUpCondition) { + super(processorInEDT, shutUpCondition); + } + + @Override + protected void schedule(Runnable updateRunnable) { + JobScheduler.getScheduler().execute(updateRunnable); + //ApplicationManager.getApplication().executeOnPooledThread(updateRunnable); + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java index efe9acd263ff..2eaa2ddab020 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java @@ -24,6 +24,7 @@ package com.intellij.openapi.vfs.encoding; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.impl.TransferToPooledThreadQueue; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; @@ -44,6 +45,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Alarm; +import com.intellij.util.Processor; import gnu.trove.THashSet; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -54,9 +56,7 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.nio.charset.Charset; import java.util.Collection; -import java.util.Queue; import java.util.Set; -import java.util.concurrent.ConcurrentLinkedQueue; @State( @@ -72,16 +72,14 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt private final Alarm updateEncodingFromContent = new Alarm(Alarm.ThreadToUse.OWN_THREAD, this); private static final Key CACHED_CHARSET_FROM_CONTENT = Key.create("CACHED_CHARSET_FROM_CONTENT"); - private final Queue myChangedDocuments = new ConcurrentLinkedQueue(); - private final Runnable myEncodingUpdateRunnable = new Runnable() { - public void run() { - for (int i=0; i<50;i++) { - if (!pollAndHandleDocument()) return; - } - // requeue myself to handle the tail of the queue in next request - addCacheEncodingAlarm(); + + private final TransferToPooledThreadQueue myChangedDocuments = new TransferToPooledThreadQueue(new Processor() { + @Override + public boolean process(Document document) { + handleDocument(document); + return true; } - }; + }, ApplicationManager.getApplication().getDisposed()); public EncodingManagerImpl(EditorFactory editorFactory) { editorFactory.getEventMulticaster().addDocumentListener(new DocumentAdapter() { @@ -99,9 +97,8 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt } @NonNls public static final String PROP_CACHED_ENCODING_CHANGED = "cachedEncoding"; - private boolean pollAndHandleDocument() { - final Document document = myChangedDocuments.poll(); - if (document == null) return false; + + private void handleDocument(final Document document) { ApplicationManager.getApplication().runReadAction(new Runnable(){ public void run() { VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document); @@ -114,28 +111,15 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt ((EncodingManagerImpl)EncodingManager.getInstance()).firePropertyChange(PROP_CACHED_ENCODING_CHANGED, oldCached, charset); } }); - return true; } public void dispose() { updateEncodingFromContent.cancelAllRequests(); - drainDocumentQueue(); - } - - public void drainDocumentQueue() { - while (pollAndHandleDocument()) { - // loop until empty - } + clearDocumentQueue(); } public void queueUpdateEncodingFromContent(@NotNull Document document) { myChangedDocuments.offer(document); - addCacheEncodingAlarm(); - } - - private void addCacheEncodingAlarm() { - updateEncodingFromContent.cancelAllRequests(); - updateEncodingFromContent.addRequest(myEncodingUpdateRunnable, 400); } public Charset getCachedCharsetFromContent(@NotNull Document document) { @@ -172,6 +156,10 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt return encodingManager.getEncoding(virtualFile, useParentDefaults); } + public void clearDocumentQueue() { + myChangedDocuments.stop(); + } + @Nullable private static Project guessProject(final VirtualFile virtualFile) { return ProjectLocator.getInstance().guessProjectForFile(virtualFile); diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java index e301bf877394..cd1da081ce42 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java @@ -469,7 +469,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da } } EncodingManager encodingManager = EncodingManager.getInstance(); - if (encodingManager instanceof EncodingManagerImpl) ((EncodingManagerImpl)encodingManager).drainDocumentQueue(); + if (encodingManager instanceof EncodingManagerImpl) ((EncodingManagerImpl)encodingManager).clearDocumentQueue(); FileDocumentManager manager = FileDocumentManager.getInstance(); if (manager instanceof FileDocumentManagerImpl) { diff --git a/platform/usageView/testSrc/com/intellij/usages/impl/UsageViewMemoryTest.java b/platform/usageView/testSrc/com/intellij/usages/impl/UsageViewMemoryTest.java new file mode 100644 index 000000000000..7d56cc69b840 --- /dev/null +++ b/platform/usageView/testSrc/com/intellij/usages/impl/UsageViewMemoryTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.usages.impl; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.vfs.encoding.EncodingManager; +import com.intellij.openapi.vfs.encoding.EncodingManagerImpl; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.testFramework.LeakHunter; +import com.intellij.testFramework.LightPlatformCodeInsightTestCase; +import com.intellij.usageView.UsageInfo; +import com.intellij.usages.*; +import com.intellij.util.ui.UIUtil; + +/** + * User: cdr + */ +public class UsageViewMemoryTest extends LightPlatformCodeInsightTestCase{ + public void testUsageViewDoesNotHoldPsiFilesOrDocuments() throws Exception { + PsiFile psiFile = createFile("X.java", "public class X{} //iuggjhfg"); + Usage[] usages = new Usage[100]; + for (int i = 0; i < usages.length; i++) { + usages[i] = createUsage(psiFile,i); + } + + UsageView usageView = UsageViewManager.getInstance(getProject()).createUsageView(UsageTarget.EMPTY_ARRAY, usages, new UsageViewPresentation(), null); + + Disposer.register(getTestRootDisposable(), usageView); + + UIUtil.dispatchAllInvocationEvents(); + ((EncodingManagerImpl)EncodingManager.getInstance()).clearDocumentQueue(); + + LeakHunter.checkLeak(usageView, PsiFileImpl.class); + LeakHunter.checkLeak(usageView, Document.class); + } + + private static Usage createUsage(PsiFile psiFile, int offset) { + PsiElement element = psiFile.findElementAt(offset % psiFile.getTextLength()); + assertNotNull(element); + return new UsageInfo2UsageAdapter(new UsageInfo(element)); + } +} diff --git a/xml/dom-impl/src/com/intellij/util/xml/ui/DomUIFactoryImpl.java b/xml/dom-impl/src/com/intellij/util/xml/ui/DomUIFactoryImpl.java index 4a241fe4550b..a03014ba0953 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/ui/DomUIFactoryImpl.java +++ b/xml/dom-impl/src/com/intellij/util/xml/ui/DomUIFactoryImpl.java @@ -151,7 +151,8 @@ public class DomUIFactoryImpl extends DomUIFactory { psiDocumentManager.commitAllDocuments(); GeneralHighlightingPass ghp = new GeneralHighlightingPass(project, psiFile, document, 0, document.getTextLength(), true); - LocalInspectionsPass lip = new LocalInspectionsPass(psiFile, document, 0, document.getTextLength()); + LocalInspectionsPass lip = new LocalInspectionsPass(psiFile, document, 0, + document.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true); return new HighlightingPass[]{ghp, lip}; } From a58554e6d65103a657e95093306f944b93e25f75 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Mon, 7 Feb 2011 11:25:36 +0300 Subject: [PATCH 71/94] IDEA-65108 Inserting line break in text file can cause incorrect formatting and cursor placement on new line if the original line starts with an asterisk Javadoc-like processing is corrected for plain text files --- .../intellij/codeInsight/editorActions/EnterHandler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java index 904372541275..a43924d10098 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java @@ -259,8 +259,8 @@ public class EnterHandler extends BaseEnterHandler { final PsiElement parent = element.getParent(); if (text.equals(commentContext.commenter.getDocumentationCommentPrefix()) && isDocComment(parent, commentContext.commenter) || - text.startsWith(commentContext.commenter.getDocumentationCommentPrefix()) && element instanceof PsiComment - ) { + text.startsWith(commentContext.commenter.getDocumentationCommentPrefix()) && element instanceof PsiComment) + { PsiComment comment = isDocComment(parent, commentContext.commenter) ? (PsiComment)parent:(PsiComment)element; int commentEnd = comment.getTextRange().getEndOffset(); @@ -321,7 +321,7 @@ public class EnterHandler extends BaseEnterHandler { String indentInsideJavadoc = null; int line = myDocument.getLineNumber(myOffset); - if (line > 0) { + if (line > 0 && (commentContext.docAsterisk || commentContext.docStart)) { indentInsideJavadoc = CodeDocumentationUtil.getIndentInsideJavadoc(myDocument, myDocument.getLineStartOffset(line - 1)); } From 3dd076536c6220ae7c49e6c19884f50afada9238 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 7 Feb 2011 10:08:45 +0100 Subject: [PATCH 72/94] IDEA-64873 (Auto-fix for inspection "Instance field access not qualified with 'this'" creates broken code.) --- .../UnqualifiedFieldAccessInspection.java | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java index 69f12b130689..ea0fc190fa50 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2010 Bas Leijdekkers + * Copyright 2006-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package com.siyeh.ig.style; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; @@ -74,18 +75,32 @@ public class UnqualifiedFieldAccessInspection extends BaseInspection { if (field == null) { return; } - final PsiClass containingClass = field.getContainingClass(); - if (containingClass == null) { + final PsiClass fieldClass = field.getContainingClass(); + if (fieldClass == null) { return; } - final PsiClass parentClass = + PsiClass containingClass = ClassUtils.getContainingClass(expression); @NonNls final String newExpression; - if (!containingClass.equals(parentClass)) { + if (InheritanceUtil.isInheritorOrSelf(containingClass, fieldClass, + true)) { + newExpression = "this." + expression.getText(); + } else { + containingClass = + ClassUtils.getContainingClass(containingClass); + if (containingClass == null) { + return; + } + while (!InheritanceUtil.isInheritorOrSelf(containingClass, + fieldClass, true)) { + containingClass = + ClassUtils.getContainingClass(containingClass); + if (containingClass == null) { + return; + } + } newExpression = containingClass.getQualifiedName() + ".this." + expression.getText(); - } else { - newExpression = "this." + expression.getText(); } replaceExpressionAndShorten(expression, newExpression); } From 3b7a92db4f675126ce8f27836c411875d7614333 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Mon, 7 Feb 2011 12:17:46 +0300 Subject: [PATCH 73/94] IDEA-64896 Enter Handler doesn't generate JavaDoc in specific case 1. Improved 'is doc complete' algorithm for the reported corner-case; 2. Corresponding test is added; --- .../editorActions/EnterHandler.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java index a43924d10098..c4aa0f10e9e4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java @@ -49,6 +49,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.util.IncorrectOperationException; import com.intellij.util.text.CharArrayUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class EnterHandler extends BaseEnterHandler { @@ -196,6 +197,9 @@ public class EnterHandler extends BaseEnterHandler { lexer.advance(); continue; } + else if (isInvalidPsi(comment)) { + return false; + } return lexer.getTokenEnd() - lexer.getTokenStart() == 1; } if (tokenType == commenter.getDocumentationCommentTokenType() || tokenType == commenter.getBlockCommentTokenType()) { @@ -205,6 +209,48 @@ public class EnterHandler extends BaseEnterHandler { } } + /** + * There is a following possible use-case: + *
+   * 
    + *
  • + * Particular document has valid text: + *
    +   *       [caret]
    +   *       class A {
    +   *           int foo() {
    +   *             return 1 */*comment*/ 1;
    +   *           }
    +   *       }
    +   *     
    + *
  • + *
  • + * The user starts comment (inserts comment start symbols): + *
    +   *       /**[caret]
    +   *       class A {
    +   *           int foo() {
    +   *             return 1 */*comment*/ 1;
    +   *           }
    +   *       }
    +   *     
    + *
  • + *
  • The user presses 'enter';
  • + *
+ *
+ * We want to understand that doc comment is incomplete now, i.e. don't want to consider '*/' before + * '*comment*/ 1;' as comment end. Current approach is to check if next PSI sibling to the current PSI comment is invalid. + * This method allows to perform such an examination. + */ + private static boolean isInvalidPsi(@NotNull PsiElement base) { + for (PsiElement current = base.getNextSibling(); current != null; current = current.getNextSibling()) { + if (current.getTextLength() != 0) { + return current instanceof PsiErrorElement; + } + } + return false; + } + private static boolean isDocComment(final PsiElement element, final CodeDocumentationAwareCommenter commenter) { if (!(element instanceof PsiComment)) return false; PsiComment comment = (PsiComment) element; From 83d3644a1fe63db8a7a45b9acf004f4eddda5df5 Mon Sep 17 00:00:00 2001 From: "sergey.vasiliev" Date: Mon, 7 Feb 2011 12:25:47 +0300 Subject: [PATCH 74/94] idea statistics --- .../LibrariesDownloadConnectionService.java | 60 +--- .../frameworks/SettingsConnectionService.java | 112 ++++++++ .../FrameworkStatisticsPersistence.java | 2 +- ...ameworkStatisticsPersistenceComponent.java | 4 +- .../statistics/FrameworkUsagesCollector.java | 26 +- platform/platform-impl/platform-impl.iml | 1 + .../FeaturesUsageCollector.java | 14 +- .../ide/plugins/PluginsUsagesCollector.java | 19 +- .../statistic/StatisticsUploadAssistant.java | 168 +++++++++++ .../statistic/UsagesCollector.java | 6 +- .../statistic/beans/ConvertUsagesUtil.java | 164 +++++++++++ .../statistic/beans/GroupDescriptor.java | 81 ++++++ .../statistic/beans/PatchedUsage.java | 8 +- .../statistic/beans/UsageDescriptor.java | 73 +++++ ...RemotelyConfigurableStatisticsService.java | 48 ++++ .../connect/StatServiceException.java | 36 +++ .../connect/StatisticsConnectionService.java | 72 +++++ .../connect/StatisticsDataSender.java | 25 ++ .../connect/StatisticsHttpClientSender.java | 62 ++++ .../statistic/connect/StatisticsResult.java | 38 +++ .../statistic/connect/StatisticsService.java | 22 ++ .../BasicSentUsagesPersistenceComponent.java | 11 +- .../persistence/SentUsagesPersistence.java | 6 +- .../SentUsagesPersistenceComponent.java | 14 +- .../statistic/tmp/SendStatisticsAction.java | 38 +++ .../updateSettings/impl/UpdateChecker.java | 37 ++- .../statistic/StatisticsUploadAssistant.java | 267 ------------------ .../statistic/beans/GroupDescriptor.java | 81 ------ .../statistic/beans/UsageDescriptor.java | 81 ------ .../src/META-INF/PlatformExtensionPoints.xml | 2 +- .../src/componentSets/Platform.xml | 4 +- .../statistics/VcsStatisticsPersistence.java | 2 +- .../VcsStatisticsPersistenceComponent.java | 4 +- .../vcs/statistics/VcsUsagesCollector.java | 23 +- resources/src/idea/IdeaActions.xml | 1 + 35 files changed, 1047 insertions(+), 565 deletions(-) create mode 100644 platform/lang-api/src/com/intellij/facet/frameworks/SettingsConnectionService.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java rename platform/platform-impl/src/com/intellij/{ => internal}/statistic/UsagesCollector.java (87%) create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/beans/GroupDescriptor.java rename platform/platform-impl/src/com/intellij/{ => internal}/statistic/beans/PatchedUsage.java (80%) create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/RemotelyConfigurableStatisticsService.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/StatServiceException.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsConnectionService.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsDataSender.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsHttpClientSender.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsResult.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsService.java rename platform/platform-impl/src/com/intellij/{ => internal}/statistic/persistence/BasicSentUsagesPersistenceComponent.java (80%) rename platform/platform-impl/src/com/intellij/{ => internal}/statistic/persistence/SentUsagesPersistence.java (83%) rename platform/platform-impl/src/com/intellij/{ => internal}/statistic/persistence/SentUsagesPersistenceComponent.java (86%) create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/tmp/SendStatisticsAction.java delete mode 100644 platform/platform-impl/src/com/intellij/statistic/StatisticsUploadAssistant.java delete mode 100644 platform/platform-impl/src/com/intellij/statistic/beans/GroupDescriptor.java delete mode 100644 platform/platform-impl/src/com/intellij/statistic/beans/UsageDescriptor.java diff --git a/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadConnectionService.java b/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadConnectionService.java index 4c43bcccab22..2d5a3ddc9685 100644 --- a/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadConnectionService.java +++ b/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadConnectionService.java @@ -15,72 +15,16 @@ */ package com.intellij.facet.frameworks; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.JDOMUtil; -import com.intellij.openapi.util.text.StringUtil; -import org.jdom.Document; -import org.jdom.Element; -import org.jetbrains.annotations.Nullable; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; - -public class LibrariesDownloadConnectionService { - private static final Logger LOG = Logger.getInstance("com.intellij.facet.frameworks.LibrariesDownloadConnectionService"); - - private static final String DOWNLOAD_SERVICE_SETTINGS_URL = "http://jetbrains.com/idea/download-assistant.xml "; - private static final String SERVICE_URL_ATTR_NAME = "url"; - - private static final String myAgentID = "IntelliJ IDEA"; +public class LibrariesDownloadConnectionService extends SettingsConnectionService { private static final LibrariesDownloadConnectionService myInstance = new LibrariesDownloadConnectionService(); - private String myServiceUrl; public static LibrariesDownloadConnectionService getInstance() { return myInstance; } private LibrariesDownloadConnectionService() { + super("http://jetbrains.com/idea/download-assistant.xml", "http://frameworks.jetbrains.com"); } - private static String readServiceUrl() { - try { - final URL url = new URL(DOWNLOAD_SERVICE_SETTINGS_URL); - final InputStream is = getStream(url); - final Document document = JDOMUtil.loadDocument(is); - final Element root = document.getRootElement(); - return StringUtil.notNullize(root.getAttributeValue(SERVICE_URL_ATTR_NAME), ""); - } - catch (MalformedURLException e) { - LOG.error(e); - } - catch (IOException e) { - // no route to host, unknown host, etc. - } - catch (Exception e) { - LOG.error(e); - } - // default - return "http://frameworks.jetbrains.com"; - } - - private static InputStream getStream(URL url) throws IOException { - final URLConnection connection = url.openConnection(); - if (connection instanceof HttpURLConnection) { - connection.setRequestProperty("User-agent", myAgentID); - } - return connection.getInputStream(); - } - - @Nullable - public String getServiceUrl() { - if (myServiceUrl == null) { - myServiceUrl = readServiceUrl(); - } - return myServiceUrl; - } } diff --git a/platform/lang-api/src/com/intellij/facet/frameworks/SettingsConnectionService.java b/platform/lang-api/src/com/intellij/facet/frameworks/SettingsConnectionService.java new file mode 100644 index 000000000000..cd638d426536 --- /dev/null +++ b/platform/lang-api/src/com/intellij/facet/frameworks/SettingsConnectionService.java @@ -0,0 +1,112 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.facet.frameworks; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.util.containers.hash.HashMap; +import org.jdom.Document; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Map; + +public abstract class SettingsConnectionService { + private static final Logger LOG = Logger.getInstance("com.intellij.facet.frameworks.SettingsConnectionService"); + + protected static final String SERVICE_URL_ATTR_NAME = "url"; + + private static final String myAgentID = "IntelliJ IDEA"; + + private Map myAttributesMap; + + @NotNull + protected String[] getAttributeNames() { + return new String[] {SERVICE_URL_ATTR_NAME}; + } + + private String mySettingsUrl; + @Nullable private String myDefaultServiceUrl; + + protected SettingsConnectionService(@NotNull String settingsUrl, @Nullable String defaultServiceUrl) { + mySettingsUrl = settingsUrl; + myDefaultServiceUrl = defaultServiceUrl; + } + + public String getSettingsUrl() { + return mySettingsUrl; + } + + @Nullable + public String getDefaultServiceUrl() { + return myDefaultServiceUrl; + } + + @Nullable + private Map readSettings(String... attributes) { + Map settings = new HashMap(); + try { + final URL url = new URL(getSettingsUrl()); + final InputStream is = getStream(url); + final Document document = JDOMUtil.loadDocument(is); + final Element root = document.getRootElement(); + for (String s : attributes) { + settings.put(s, root.getAttributeValue(s)); + } + } + catch (MalformedURLException e) { + LOG.error(e); + } + catch (IOException e) { + // no route to host, unknown host, etc. + } + catch (Exception e) { + LOG.error(e); + } + + return settings; + } + + private static InputStream getStream(URL url) throws IOException { + final URLConnection connection = url.openConnection(); + if (connection instanceof HttpURLConnection) { + connection.setRequestProperty("User-agent", myAgentID); + } + return connection.getInputStream(); + } + + @Nullable + public String getServiceUrl() { + final String serviceUrl = getSettingValue(SERVICE_URL_ATTR_NAME); + + return serviceUrl == null ? getDefaultServiceUrl() : serviceUrl; + } + + @Nullable + protected String getSettingValue(@NotNull String attributeValue) { + if (myAttributesMap == null) { + myAttributesMap = readSettings(getAttributeNames()); + } + return myAttributesMap != null ? myAttributesMap.get(attributeValue) : null; + } +} diff --git a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java index e26ed8fb5932..b1d9a0894c75 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java @@ -17,7 +17,7 @@ package com.intellij.facet.impl.statistics; import com.intellij.openapi.project.Project; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; diff --git a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java index 0c18a17355b7..717dabff6e15 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java @@ -16,6 +16,7 @@ package com.intellij.facet.impl.statistics; +import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.components.ApplicationComponent; @@ -25,7 +26,6 @@ import com.intellij.openapi.components.Storage; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectManagerListener; -import com.intellij.statistic.beans.UsageDescriptor; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Function; import com.intellij.util.containers.HashSet; @@ -70,7 +70,7 @@ public class FrameworkStatisticsPersistenceComponent extends FrameworkStatistics if (!StringUtil.isEmptyOrSpaces(projectId) && !StringUtil.isEmptyOrSpaces(frameworks)) { Set frameworkDescriptors = new HashSet(); for (String key : StringUtil.split(frameworks, TOKENIZER)) { - frameworkDescriptors.add(new UsageDescriptor(FrameworkUsagesCollector.getGroupId(), key, 1)); + frameworkDescriptors.add(new UsageDescriptor(FrameworkUsagesCollector.getGroupDescriptor(), key, 1)); } getFrameworks().put(projectId, frameworkDescriptors); } diff --git a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkUsagesCollector.java b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkUsagesCollector.java index 15e24c38ed6c..abad35157269 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkUsagesCollector.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkUsagesCollector.java @@ -20,9 +20,9 @@ import com.intellij.facet.FacetManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; -import com.intellij.statistic.UsagesCollector; -import com.intellij.statistic.beans.GroupDescriptor; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; @@ -34,7 +34,7 @@ import java.util.Map; import java.util.Set; public class FrameworkUsagesCollector extends UsagesCollector { - private static final String GROUP_ID = "frameworks"; + public static final String GROUP_ID = "frameworks"; public static void persistProjectUsages(@NotNull Project project) { persistProjectUsages(project, getProjectUsages(project)); @@ -51,12 +51,12 @@ public class FrameworkUsagesCollector extends UsagesCollector { } @NotNull - public static Set getApplicationUsages() { + public Set getApplicationUsages() { return getApplicationUsages(FrameworkStatisticsPersistenceComponent.getInstance()); } @NotNull - public static Set getApplicationUsages(@NotNull final FrameworkStatisticsPersistence persistence) { + public Set getApplicationUsages(@NotNull final FrameworkStatisticsPersistence persistence) { final Map facets = new HashMap(); for (Set frameworks : persistence.getFrameworks().values()) { @@ -70,12 +70,18 @@ public class FrameworkUsagesCollector extends UsagesCollector { return ContainerUtil.map2Set(facets.entrySet(), new Function, UsageDescriptor>() { @Override public UsageDescriptor fun(Map.Entry facet) { - return new UsageDescriptor(getGroupId(), facet.getKey(), facet.getValue()); + return new UsageDescriptor(getGroupDescriptor(), facet.getKey(), facet.getValue()); } }); } - public static GroupDescriptor getGroupId() { + @NotNull + @Override + public String getGroupId() { + return GROUP_ID; + } + + public static GroupDescriptor getGroupDescriptor() { return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); } @@ -92,14 +98,14 @@ public class FrameworkUsagesCollector extends UsagesCollector { final Set facets = new HashSet(); for (Module module : ModuleManager.getInstance(project).getModules()) { for (Facet facet : FacetManager.getInstance(module).getAllFacets()) { - facets.add(facet.getName()); + facets.add(facet.getType().getStringId()); } } return ContainerUtil.map2Set(facets, new Function() { @Override public UsageDescriptor fun(String facet) { - return new UsageDescriptor(getGroupId(), facet, 1); + return new UsageDescriptor(getGroupDescriptor(), facet, 1); } }); } diff --git a/platform/platform-impl/platform-impl.iml b/platform/platform-impl/platform-impl.iml index 68fc2731b7bd..e2ea144cc57b 100644 --- a/platform/platform-impl/platform-impl.iml +++ b/platform/platform-impl/platform-impl.iml @@ -27,6 +27,7 @@ + diff --git a/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java b/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java index 7d8707e88b5c..fcbf518cda18 100644 --- a/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java +++ b/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java @@ -16,9 +16,9 @@ package com.intellij.featureStatistics; import com.intellij.openapi.project.Project; -import com.intellij.statistic.UsagesCollector; -import com.intellij.statistic.beans.*; -import com.intellij.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.*; +import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,6 +27,12 @@ import java.util.Set; public class FeaturesUsageCollector extends UsagesCollector { + @NotNull + @Override + public String getGroupId() { + return "productivity"; + } + @NotNull @Override public Set getUsages(@Nullable Project project) { @@ -37,7 +43,7 @@ public class FeaturesUsageCollector extends UsagesCollector { final FeatureDescriptor featureDescriptor = registry.getFeatureDescriptor(featureId); if (featureDescriptor != null) { usages.add(new UsageDescriptor( - GroupDescriptor.create("productivity", GroupDescriptor.LOWER_PRIORITY), featureId, featureDescriptor.getUsageCount())); + GroupDescriptor.create(getGroupId(), GroupDescriptor.LOWER_PRIORITY), featureId, featureDescriptor.getUsageCount())); } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java index 560fac29c488..006b58967ada 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java @@ -16,9 +16,9 @@ package com.intellij.ide.plugins; import com.intellij.openapi.project.Project; -import com.intellij.statistic.UsagesCollector; -import com.intellij.statistic.beans.GroupDescriptor; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -27,18 +27,19 @@ import org.jetbrains.annotations.Nullable; import java.util.Set; public class PluginsUsagesCollector extends UsagesCollector { - private static final String GROUP_ID = "plugins"; + private static final String GROUP_ID = "disabled-plugins"; - public static GroupDescriptor getGroupId() { - return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); + @NotNull + public String getGroupId() { + return GROUP_ID; } @NotNull public Set getUsages(@Nullable Project project) { - return ContainerUtil.map2Set(PluginManager.getPlugins(), new Function() { + return ContainerUtil.map2Set(PluginManager.getDisabledPlugins(), new Function() { @Override - public UsageDescriptor fun(IdeaPluginDescriptor descriptor) { - return new UsageDescriptor(getGroupId(), descriptor.getName(), 1); + public UsageDescriptor fun(String descriptor) { + return new UsageDescriptor(GroupDescriptor.create(getGroupId(), GroupDescriptor.HIGHER_PRIORITY), descriptor, 1); } }); } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java b/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java new file mode 100644 index 000000000000..a8fe0a736cec --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java @@ -0,0 +1,168 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.statistic; + +import com.intellij.internal.statistic.beans.ConvertUsagesUtil; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.PatchedUsage; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.persistence.SentUsagesPersistence; +import com.intellij.internal.statistic.persistence.SentUsagesPersistenceComponent; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Pair; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.HashSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class StatisticsUploadAssistant { + + public String getData() { + return getData(Collections.emptySet()); + } + + public String getData(@NotNull Set disabledGroups) { + return getStringPatch(disabledGroups, ProjectManager.getInstance().getOpenProjects()); + } + + public void persistSentPatch(@NotNull String patchStr) { + persistSentPatch(patchStr, SentUsagesPersistenceComponent.getInstance()); + } + + public static void persistSentPatch(@NotNull String patchStr, @NotNull SentUsagesPersistence persistenceComponent) { + Set patchedUsages = + ContainerUtil.map2Set(ConvertUsagesUtil.convertString(patchStr), new Function() { + @Override + public PatchedUsage fun(UsageDescriptor usageDescriptor) { + return new PatchedUsage(usageDescriptor); + } + }); + + if (patchedUsages.size() > 0) persistenceComponent.persistPatch(patchedUsages); + } + + @NotNull + public static String getStringPatch(@NotNull Set disabledGroups, Project... project) { + return getStringPatch(disabledGroups, project, SentUsagesPersistenceComponent.getInstance(), 0); + } + + @NotNull + public static String getStringPatch(@NotNull Set disabledGroups, + @NotNull Project[] projects, + @NotNull SentUsagesPersistence usagesPersistence, + int maxSize) { + final Set patchedUsages = getPatchedUsages(disabledGroups, projects, usagesPersistence); + + return getStringPatch(patchedUsages, maxSize); + } + + public static String getStringPatch(@NotNull Set patchedUsages, int maxSize) { + if (patchedUsages.size() == 0) return ""; + + String patchStr = ConvertUsagesUtil.convertUsages(patchedUsages); + if (maxSize > 0 && patchStr.getBytes().length > maxSize) { + patchStr = ConvertUsagesUtil.cutPatchString(patchStr, maxSize); + } + + return patchStr; + } + + @NotNull + public static Set getPatchedUsages(@NotNull Set disabledGroups, + @NotNull Project[] projects, + @NotNull SentUsagesPersistence usagesPersistence) { + Set usages = new HashSet(); + + for (Project project : projects) { + usages.addAll(getPatchedUsages(getAllUsages(project, disabledGroups), usagesPersistence.getSentUsages())); + } + return usages; + } + + @NotNull + public static Set getPatchedUsages(@NotNull final Set allUsages, + @NotNull SentUsagesPersistence usagesPersistence) { + return getPatchedUsages(allUsages, usagesPersistence.getSentUsages()); + } + + @NotNull + public static Set getPatchedUsages(@NotNull final Set allUsages, final Set sentUsages) { + final Set patchedUsages = ContainerUtil.map2Set(allUsages, new Function() { + @Override + public PatchedUsage fun(UsageDescriptor usageDescriptor) { + return new PatchedUsage(usageDescriptor); + } + }); + + for (UsageDescriptor sentUsage : sentUsages) { + final PatchedUsage descriptor = findDescriptor(patchedUsages, Pair.create(sentUsage.getGroup(), sentUsage.getKey())); + if (descriptor == null) { + patchedUsages.add(new PatchedUsage(sentUsage.getGroup(), sentUsage.getKey(), -sentUsage.getValue())); + } + else { + descriptor.subValue(sentUsage.getValue()); + } + } + + return packCollection(patchedUsages, new Condition() { + @Override + public boolean value(PatchedUsage patchedUsage) { + return patchedUsage.getDelta() != 0; + } + }); + } + + @NotNull + private static Set packCollection(@NotNull Collection set, @NotNull Condition condition) { + final Set result = new LinkedHashSet(); + for (T t : set) { + if (condition.value(t)) { + result.add(t); + } + } + return result; + } + + @Nullable + public static T findDescriptor(@NotNull Set descriptors, + @NotNull final Pair id) { + return ContainerUtil.find(descriptors, new Condition() { + @Override + public boolean value(T t) { + return id.getFirst().equals(t.getGroup()) && id.getSecond().equals(t.getKey()); + } + }); + } + + @NotNull + public static Set getAllUsages(@Nullable Project project, @NotNull Set disabledGroups) { + final Set usageDescriptors = new TreeSet(); + + for (UsagesCollector usagesCollector : Extensions.getExtensions(UsagesCollector.EP_NAME)) { + if (!disabledGroups.contains(usagesCollector.getGroupId())) { + usageDescriptors.addAll(usagesCollector.getUsages(project)); + } + } + + return usageDescriptors; + } +} diff --git a/platform/platform-impl/src/com/intellij/statistic/UsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java similarity index 87% rename from platform/platform-impl/src/com/intellij/statistic/UsagesCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java index e0320bc0b2ca..e07246e0556a 100644 --- a/platform/platform-impl/src/com/intellij/statistic/UsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.statistic; +package com.intellij.internal.statistic; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,4 +27,6 @@ public abstract class UsagesCollector { public static ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.statistics.usagesCollector"); public abstract @NotNull Set getUsages(@Nullable Project project); + + public abstract @NotNull String getGroupId(); } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java b/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java new file mode 100644 index 000000000000..8fd58411e437 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java @@ -0,0 +1,164 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.statistic.beans; + + +import java.util.*; + +public class ConvertUsagesUtil { + private static final Character GROUP_SEPARATOR = ':'; + private static final Character GROUPS_SEPARATOR = ';'; + private static final Character GROUP_VALUE_SEPARATOR = ','; + + private ConvertUsagesUtil() { + } + + // @NotNull + public static String convertUsages(Set descriptors) { + assert descriptors != null; + final Map> descriptorGroups = groupDescriptors(descriptors); + + return convertUsages(descriptorGroups); + } + + // @NotNull + public static String convertUsages(Map> map) { + assert map != null; + StringBuffer buffer = new StringBuffer(); + for (Map.Entry> entry : map.entrySet()) { + buffer.append(entry.getKey().getId()); + buffer.append(GROUP_SEPARATOR); + buffer.append(convertValueMap(entry.getValue())); + buffer.append(GROUPS_SEPARATOR); + } + + return buffer.toString(); + } + + //@NotNull + public static String convertValueMap(Set descriptors) { + assert descriptors != null; + final StringBuffer buffer = new StringBuffer(); + for (UsageDescriptor usageDescriptor : descriptors) { + buffer.append(usageDescriptor.getKey()); + buffer.append("="); + buffer.append(usageDescriptor.getValue()); + buffer.append(GROUP_VALUE_SEPARATOR); + } + buffer.deleteCharAt(buffer.length() - 1); + + return buffer.toString(); + } + + //@NotNull + public static String cutPatchString(String patchStr, int maxSize) { + assert patchStr != null; + for (int i = maxSize - 1; i >= 0; i--) { + final char c = patchStr.charAt(i); + if (c == GROUPS_SEPARATOR || c == GROUP_VALUE_SEPARATOR) { + return patchStr.substring(0, i); + } + } + return ""; + } + + //@NotNull + public static Set convertString(String usages) { + assert usages != null; + Set descriptors = new LinkedHashSet(); + for (String groupStr : usages.split(GROUPS_SEPARATOR.toString())) { + if (!isEmptyOrSpaces(groupStr)) { + final StringPair group = getPair(groupStr, GROUP_SEPARATOR.toString()); + if (group != null) { + descriptors.addAll(convertValueString(GroupDescriptor.create(group.first), group.second)); + } + } + } + return descriptors; + } + + //@NotNull + public static Set convertValueString(GroupDescriptor groupId, String valueData) { + assert groupId != null; + final Set descriptors = new LinkedHashSet(); + for (String value : valueData.split(GROUP_VALUE_SEPARATOR.toString())) { + if (!isEmptyOrSpaces(value)) { + final StringPair pair = getPair(value, "="); + if (pair != null) { + final String count = pair.second; + if (!isEmptyOrSpaces(count)) { + try { + final int i = Integer.parseInt(count); + descriptors.add(new UsageDescriptor(groupId, pair.first, i)); + } catch (NumberFormatException ignored) { + } + } + } + } + } + + return descriptors; + } + + //@Nullable + public static StringPair getPair(String str, String separator) { + assert str != null; + assert separator != null; + final int i = str.indexOf(separator); + if (i > 0 && i < str.length() - 1) { + String key = str.substring(0, i).trim(); + String value = str.substring(i + 1).trim(); + if (!isEmptyOrSpaces(key) && !isEmptyOrSpaces(value)) { + return new StringPair(key, value); + } + } + return null; + } + + //@NotNull + public static Map> groupDescriptors(Set descriptors) { + assert descriptors != null; + final SortedMap> map = new TreeMap>(new Comparator() { + public int compare(GroupDescriptor g1, GroupDescriptor g2) { + final int priority = (int) (g2.getPriority() - g1.getPriority()); + return priority == 0 ? g1.getId().compareTo(g2.getId()) : priority; + } + }); + + for (UsageDescriptor descriptor : descriptors) { + final GroupDescriptor group = descriptor.getGroup(); + if (!map.containsKey(group)) { + map.put(group, new HashSet()); + } + map.get(group).add(descriptor); + } + return map; + } + + private static class StringPair { + public final String first; + public final String second; + + public StringPair(String first, String second) { + this.first = first; + this.second = second; + } + } + + public static boolean isEmptyOrSpaces(final String s) { + return s == null || s.trim().length() == 0; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/beans/GroupDescriptor.java b/platform/platform-impl/src/com/intellij/internal/statistic/beans/GroupDescriptor.java new file mode 100644 index 000000000000..fcbff6c4f6a2 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/GroupDescriptor.java @@ -0,0 +1,81 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.statistic.beans; + +public class GroupDescriptor implements Comparable { + public static final double DEFAULT_PRIORITY = 0.0; + public static final double HIGHER_PRIORITY = 100.0; + public static final double LOWER_PRIORITY = -100.0; + + private final String myId; + private double myPriority; + + public static GroupDescriptor create(String id) { + assert id != null; + return new GroupDescriptor(id); + } + + public static GroupDescriptor create(String id, double priority) { + assert id != null; + return new GroupDescriptor(id, priority); + } + + private GroupDescriptor(String id) { + this(id, DEFAULT_PRIORITY); + } + + private GroupDescriptor(String id, double priority) { + assert id != null; + myId = id; + myPriority = priority; + } + + + public String getId() { + return myId; + } + + public double getPriority() { + return myPriority; + } + + public void setPriority(double priority) { + myPriority = priority; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof GroupDescriptor)) return false; + + GroupDescriptor that = (GroupDescriptor) o; + + if (myId != null ? !myId.equals(that.myId) : that.myId != null) return false; + + return true; + } + + @Override + public int hashCode() { + return myId != null ? myId.hashCode() : 0; + } + + public int compareTo(GroupDescriptor gd) { + final int priority = (int) (this.getPriority() - gd.getPriority()); + return priority == 0 ? gd.getId().compareTo(gd.getId()) : priority; + } +} + diff --git a/platform/platform-impl/src/com/intellij/statistic/beans/PatchedUsage.java b/platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java similarity index 80% rename from platform/platform-impl/src/com/intellij/statistic/beans/PatchedUsage.java rename to platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java index d5c0ea3c53ec..f91433e4b6bb 100644 --- a/platform/platform-impl/src/com/intellij/statistic/beans/PatchedUsage.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java @@ -13,17 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.statistic.beans; - -import org.jetbrains.annotations.NotNull; +package com.intellij.internal.statistic.beans; public class PatchedUsage extends UsageDescriptor { - public PatchedUsage(@NotNull UsageDescriptor descriptor) { + public PatchedUsage(UsageDescriptor descriptor) { super(descriptor.getGroup(), descriptor.getKey(), descriptor.getValue()); } - public PatchedUsage(@NotNull GroupDescriptor group, @NotNull String key, int value) { + public PatchedUsage(GroupDescriptor group, String key, int value) { super(group, key, value); } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java b/platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java new file mode 100644 index 000000000000..2ec188afa17d --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java @@ -0,0 +1,73 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.statistic.beans; +public class UsageDescriptor implements Comparable { + + private final GroupDescriptor myGroup; + private final String myKey; + private int myValue; + + public UsageDescriptor(GroupDescriptor group, String key, int value) { + assert group != null; + assert key != null; + + myGroup = group; + myKey = key; + myValue = value; + } + + public String getKey() { + return myKey; + } + + public GroupDescriptor getGroup() { + return myGroup; + } + + public int getValue() { + return myValue; + } + + public void setValue(int i) { + myValue = i; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof UsageDescriptor)) return false; + + UsageDescriptor that = (UsageDescriptor) o; + + if (!myGroup.equals(that.myGroup)) return false; + if (!myKey.equals(that.myKey)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = myGroup.hashCode(); + result = 31 * result + myKey.hashCode(); + return result; + } + + public int compareTo(UsageDescriptor ud) { + final int byGroup = this.getGroup().compareTo(ud.getGroup()); + + return byGroup == 0 ? this.getKey().compareTo(ud.myKey) : byGroup; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/RemotelyConfigurableStatisticsService.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/RemotelyConfigurableStatisticsService.java new file mode 100644 index 000000000000..90877592027f --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/RemotelyConfigurableStatisticsService.java @@ -0,0 +1,48 @@ +package com.intellij.internal.statistic.connect; + +import com.intellij.internal.statistic.StatisticsUploadAssistant; +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; + +public class RemotelyConfigurableStatisticsService implements StatisticsService { + + private StatisticsConnectionService myConnectionService; + private StatisticsDataSender sender; + private StatisticsUploadAssistant myAssistant; + + public RemotelyConfigurableStatisticsService(@NotNull StatisticsConnectionService connectionService, + @NotNull StatisticsDataSender sender, + @NotNull StatisticsUploadAssistant assistant) { + myConnectionService = connectionService; + this.sender = sender; + myAssistant = assistant; + } + + public StatisticsResult send() { + final String serviceUrl = myConnectionService.getServiceUrl(); + + if (serviceUrl == null) { + return new StatisticsResult(StatisticsResult.ResultCode.ERROR_IN_CONFIG, "ERROR"); + } + + if (!myConnectionService.isTransmissionPermitted()) { + return new StatisticsResult(StatisticsResult.ResultCode.NOT_PERMITTED, "NOT_PERMITTED"); + } + + String content = myAssistant.getData(); + + if (StringUtil.isEmptyOrSpaces(content)) { + return new StatisticsResult(StatisticsResult.ResultCode.NOTHING_TO_SEND, "NOTHING_TO_SEND"); + } + + try { + sender.send(serviceUrl, content); + myAssistant.persistSentPatch(content); + + return new StatisticsResult(StatisticsResult.ResultCode.SEND, "SUCCESS"); + } + catch (Exception e) { + return new StatisticsResult(StatisticsResult.ResultCode.SEND_WITH_ERRORS, e.getMessage() != null ? e.getMessage() : "NPE"); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatServiceException.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatServiceException.java new file mode 100644 index 000000000000..2964db2021ce --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatServiceException.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.statistic.connect; + + +public class StatServiceException extends RuntimeException { + + public StatServiceException() { + super(); + } + + public StatServiceException(String s) { + super(s); + } + + public StatServiceException(String s, Throwable throwable) { + super(s, throwable); + } + + public StatServiceException(Throwable throwable) { + super(throwable); + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsConnectionService.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsConnectionService.java new file mode 100644 index 000000000000..6a0df42f96eb --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsConnectionService.java @@ -0,0 +1,72 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.statistic.connect; + +import com.intellij.facet.frameworks.SettingsConnectionService; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +public class StatisticsConnectionService extends SettingsConnectionService { + + private static final String SETTINGS_URL = "http://jetbrains.com/idea/statistics/stat-assistant.xml"; + private static final String DEFAULT_SERVICE_URL = "http://jetbrains.com/idea/statistics/index.jsp"; + + private static final String PERMISSION_ATTR_NAME = "permitted"; + private static final String DISABLED = "disabled"; + + public StatisticsConnectionService() { + this(SETTINGS_URL, DEFAULT_SERVICE_URL); + } + + public StatisticsConnectionService(@NotNull String settingsUrl, @Nullable String defaultServiceUrl) { + super(settingsUrl, defaultServiceUrl); + } + + @NotNull + @Override + public String[] getAttributeNames() { + return ArrayUtil.append(super.getAttributeNames(), PERMISSION_ATTR_NAME); + } + + public Boolean isTransmissionPermitted() { + final String permitted = getSettingValue(PERMISSION_ATTR_NAME); + + return permitted == null ? true : Boolean.parseBoolean(permitted); + } + + @NotNull + public Set getDisabledGroups() { + final String disabledGroupsString = getSettingValue(DISABLED); + + if (disabledGroupsString == null) return Collections.emptySet(); + + final List disabledGroupsList = StringUtil.split(disabledGroupsString, ","); + return ContainerUtil.map2Set(disabledGroupsList, new Function() { + @Override + public String fun(String s) { + return s.trim(); + } + }); + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsDataSender.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsDataSender.java new file mode 100644 index 000000000000..0018ce34bf8a --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsDataSender.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.statistic.connect; + + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface StatisticsDataSender { + + void send(@NotNull String url, @NotNull String content) throws StatServiceException; +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsHttpClientSender.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsHttpClientSender.java new file mode 100644 index 000000000000..ee1971138b1d --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsHttpClientSender.java @@ -0,0 +1,62 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.statistic.connect; + +import com.intellij.openapi.updateSettings.impl.UpdateChecker; +import com.intellij.openapi.util.text.StringUtil; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.NameValuePair; +import org.apache.commons.httpclient.methods.PostMethod; +import org.jetbrains.annotations.NotNull; + +public class StatisticsHttpClientSender implements StatisticsDataSender { + + public void send(@NotNull String url, @NotNull String content) throws StatServiceException { + PostMethod post = null; + + try { + HttpClient httpclient = new HttpClient(); + post = new PostMethod(url); + + post.setRequestBody(new NameValuePair[]{ + new NameValuePair("content", content), + new NameValuePair("uuid", UpdateChecker.getInstallationUID())}); + + httpclient.executeMethod(post); + + if (post.getStatusCode() != HttpStatus.SC_OK) { + throw new StatServiceException("Error during data sending... Code: " + post.getStatusCode()); + } + + final Header errors = post.getResponseHeader("errors"); + if (errors != null) { + final String value = errors.getValue(); + + throw new StatServiceException("Error during updating statistics " + (!StringUtil.isEmptyOrSpaces(value) ? " : " + value : "")); + } + } + catch (Exception e) { + throw new StatServiceException("Error during data sending...", e); + } + finally { + if (post != null) { + post.releaseConnection(); + } + } + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsResult.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsResult.java new file mode 100644 index 000000000000..20d447e52534 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsResult.java @@ -0,0 +1,38 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.statistic.connect; + +public class StatisticsResult { + private ResultCode code; + private String description; + + public StatisticsResult(ResultCode code, String description) { + this.code = code; + this.description = description; + } + + public String getDescription() { + return description; + } + + public ResultCode getCode() { + return code; + } + + public enum ResultCode {SEND, NOT_PERMITTED, ERROR_IN_CONFIG, NOTHING_TO_SEND, SEND_WITH_ERRORS} + + +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsService.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsService.java new file mode 100644 index 000000000000..3fe21714ecf1 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsService.java @@ -0,0 +1,22 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.statistic.connect; + + +public interface StatisticsService { + + StatisticsResult send(); +} diff --git a/platform/platform-impl/src/com/intellij/statistic/persistence/BasicSentUsagesPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java similarity index 80% rename from platform/platform-impl/src/com/intellij/statistic/persistence/BasicSentUsagesPersistenceComponent.java rename to platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java index 63219377632d..a0f4d7499e57 100644 --- a/platform/platform-impl/src/com/intellij/statistic/persistence/BasicSentUsagesPersistenceComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java @@ -14,11 +14,12 @@ * limitations under the License. */ -package com.intellij.statistic.persistence; +package com.intellij.internal.statistic.persistence; -import com.intellij.statistic.StatisticsUploadAssistant; -import com.intellij.statistic.beans.PatchedUsage; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.StatisticsUploadAssistant; +import com.intellij.internal.statistic.beans.PatchedUsage; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.openapi.util.Pair; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; @@ -33,7 +34,7 @@ public class BasicSentUsagesPersistenceComponent extends SentUsagesPersistence { public void persistPatch(@NotNull Set patchedDescriptors) { for (PatchedUsage patchedUsage : patchedDescriptors) { - UsageDescriptor usageDescriptor = StatisticsUploadAssistant.findDescriptor(mySentDescriptors, patchedUsage.getId()); + UsageDescriptor usageDescriptor = StatisticsUploadAssistant.findDescriptor(mySentDescriptors, Pair.create(patchedUsage.getGroup(), patchedUsage.getKey())); if (usageDescriptor != null) { usageDescriptor.setValue(usageDescriptor.getValue() + patchedUsage.getDelta()); } diff --git a/platform/platform-impl/src/com/intellij/statistic/persistence/SentUsagesPersistence.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java similarity index 83% rename from platform/platform-impl/src/com/intellij/statistic/persistence/SentUsagesPersistence.java rename to platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java index 41d490797012..9d2c55fb762a 100644 --- a/platform/platform-impl/src/com/intellij/statistic/persistence/SentUsagesPersistence.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.intellij.statistic.persistence; +package com.intellij.internal.statistic.persistence; -import com.intellij.statistic.beans.PatchedUsage; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.beans.PatchedUsage; +import com.intellij.internal.statistic.beans.UsageDescriptor; import org.jetbrains.annotations.NotNull; import java.util.Set; diff --git a/platform/platform-impl/src/com/intellij/statistic/persistence/SentUsagesPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistenceComponent.java similarity index 86% rename from platform/platform-impl/src/com/intellij/statistic/persistence/SentUsagesPersistenceComponent.java rename to platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistenceComponent.java index 7e2318475c1e..114949d6632c 100644 --- a/platform/platform-impl/src/com/intellij/statistic/persistence/SentUsagesPersistenceComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistenceComponent.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.intellij.statistic.persistence; +package com.intellij.internal.statistic.persistence; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; -import com.intellij.statistic.StatisticsUploadAssistant; -import com.intellij.statistic.beans.GroupDescriptor; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.beans.ConvertUsagesUtil; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.openapi.util.text.StringUtil; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -66,7 +66,7 @@ public class SentUsagesPersistenceComponent extends BasicSentUsagesPersistenceCo String valueData = groupElement.getAttributeValue(DATA_ATTR); if (!StringUtil.isEmptyOrSpaces(groupId) && !StringUtil.isEmptyOrSpaces(valueData)) { - getSentUsages().addAll(StatisticsUploadAssistant.convertValueString(GroupDescriptor.create(groupId, groupPriority), valueData)); + getSentUsages().addAll(ConvertUsagesUtil.convertValueString(GroupDescriptor.create(groupId, groupPriority), valueData)); } } } @@ -80,12 +80,12 @@ public class SentUsagesPersistenceComponent extends BasicSentUsagesPersistenceCo public Element getState() { Element element = new Element("state"); - for (Map.Entry> entry : StatisticsUploadAssistant.groupDescriptors(getSentUsages()) + for (Map.Entry> entry : ConvertUsagesUtil.groupDescriptors(getSentUsages()) .entrySet()) { Element projectElement = new Element(GROUP_TAG); projectElement.setAttribute(GROUP_ID_ATTR, entry.getKey().getId()); projectElement.setAttribute(GROUP_PRIORITY_ATTR, Double.toString(entry.getKey().getPriority())); - projectElement.setAttribute(DATA_ATTR, StatisticsUploadAssistant.convertValueMap(entry.getValue())); + projectElement.setAttribute(DATA_ATTR, ConvertUsagesUtil.convertValueMap(entry.getValue())); element.addContent(projectElement); } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/tmp/SendStatisticsAction.java b/platform/platform-impl/src/com/intellij/internal/statistic/tmp/SendStatisticsAction.java new file mode 100644 index 000000000000..eef096eadfae --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/tmp/SendStatisticsAction.java @@ -0,0 +1,38 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.statistic.tmp; + +import com.intellij.internal.statistic.StatisticsUploadAssistant; +import com.intellij.internal.statistic.connect.StatisticsHttpClientSender; +import com.intellij.internal.statistic.connect.RemotelyConfigurableStatisticsService; +import com.intellij.internal.statistic.connect.StatisticsConnectionService; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.project.Project; + +public class SendStatisticsAction extends AnAction { + + @Override + public void actionPerformed(AnActionEvent e) { + final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + if (project != null) { + final RemotelyConfigurableStatisticsService service = new RemotelyConfigurableStatisticsService(new StatisticsConnectionService(), new StatisticsHttpClientSender(), new StatisticsUploadAssistant()); + + service.send(); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java index be7eed7685b6..3d926199ca88 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java @@ -347,21 +347,9 @@ public final class UpdateChecker { public void run() { try { HttpConfigurable.getInstance().prepareURL(url); - final PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(); - String uid = ""; - if (!propertiesComponent.isValueSet(INSTALLATION_UID)) { - try { - uid = UUID.randomUUID().toString(); - } - catch (Exception ignored) { - } - catch (InternalError ignored) { - } - propertiesComponent.setValue(INSTALLATION_UID, uid); - } - else { - uid = propertiesComponent.getValue(INSTALLATION_UID); - } + + String uid = getInstallationUID(); + final URL requestUrl = new URL(url + "?build=" + ApplicationInfo.getInstance().getBuild().asString() + "&uid=" + uid + ADDITIONAL_REQUEST_OPTIONS); final InputStream inputStream = requestUrl.openStream(); try { @@ -396,6 +384,25 @@ public final class UpdateChecker { return document[0]; } + public static String getInstallationUID() { + final PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(); + String uid = ""; + if (!propertiesComponent.isValueSet(INSTALLATION_UID)) { + try { + uid = UUID.randomUUID().toString(); + } + catch (Exception ignored) { + } + catch (InternalError ignored) { + } + propertiesComponent.setValue(INSTALLATION_UID, uid); + } + else { + uid = propertiesComponent.getValue(INSTALLATION_UID); + } + return uid; + } + public static void showNoUpdatesDialog(boolean enableLink, final List updatePlugins, boolean showConfirmation) { NoUpdatesDialog dialog = new NoUpdatesDialog(true, updatePlugins, enableLink); dialog.setShowConfirmation(showConfirmation); diff --git a/platform/platform-impl/src/com/intellij/statistic/StatisticsUploadAssistant.java b/platform/platform-impl/src/com/intellij/statistic/StatisticsUploadAssistant.java deleted file mode 100644 index 1dc60bb6535d..000000000000 --- a/platform/platform-impl/src/com/intellij/statistic/StatisticsUploadAssistant.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.statistic; - -import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.project.Project; -import com.intellij.statistic.beans.GroupDescriptor; -import com.intellij.statistic.beans.PatchedUsage; -import com.intellij.statistic.beans.UsageDescriptor; -import com.intellij.statistic.persistence.SentUsagesPersistence; -import com.intellij.statistic.persistence.SentUsagesPersistenceComponent; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.Function; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.HashSet; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; - -public class StatisticsUploadAssistant { - - private static final Character GROUP_SEPARATOR = ':'; - private static final Character GROUPS_SEPARATOR = ';'; - private static final Character GROUP_VALUE_SEPARATOR = ','; - - private StatisticsUploadAssistant() { - } - - @NotNull - public static String getStringPatch(@Nullable Project project) { - return getStringPatch(project, 0); - } - - @NotNull - public static String getStringPatch(@Nullable Project project, int maxSize) { - return getStringPatch(project, SentUsagesPersistenceComponent.getInstance(), maxSize); - } - - @NotNull - public static String getStringPatch(@Nullable Project project, @NotNull SentUsagesPersistence usagesPersistence, int maxSize) { - final Set patchedUsages = getPatchedUsages(project, usagesPersistence); - - return getStringPatch(patchedUsages, usagesPersistence, maxSize); - } - - @NotNull - public static String getStringPatch(@NotNull Set patchedUsages, - @NotNull SentUsagesPersistence usagesPersistence, - int maxSize) { - if (patchedUsages.size() == 0) return ""; - - String patchStr = convertUsages(patchedUsages); - if (maxSize > 0 && patchStr.getBytes().length > maxSize) { - patchStr = cutPatchString(patchStr, maxSize); - - patchedUsages = ContainerUtil.map2Set(convertString(patchStr), new Function() { - @Override - public PatchedUsage fun(UsageDescriptor usageDescriptor) { - return new PatchedUsage(usageDescriptor); - } - }); - } - - if (patchedUsages.size() > 0) usagesPersistence.persistPatch(patchedUsages); - - return patchStr; - } - - @NotNull - public static Set getPatchedUsages(@Nullable Project project, @NotNull SentUsagesPersistence usagesPersistence) { - return getPatchedUsages(getAllUsages(project), usagesPersistence.getSentUsages()); - } - - @NotNull - public static Set getPatchedUsages(@NotNull final Set allUsages, @NotNull SentUsagesPersistence usagesPersistence) { - return getPatchedUsages(allUsages, usagesPersistence.getSentUsages()); - } - - @NotNull - public static Set getPatchedUsages(@NotNull final Set allUsages, final Set sentUsages ) { - final Set patchedUsages = ContainerUtil.map2Set(allUsages, new Function() { - @Override - public PatchedUsage fun(UsageDescriptor usageDescriptor) { - return new PatchedUsage(usageDescriptor); - } - }); - - for (UsageDescriptor sentUsage : sentUsages) { - final PatchedUsage descriptor = findDescriptor(patchedUsages, sentUsage.getId()); - if (descriptor == null) { - patchedUsages.add(new PatchedUsage(sentUsage.getGroup(), sentUsage.getKey(), - sentUsage.getValue())); - } - else { - descriptor.subValue(sentUsage.getValue()); - } - } - - return packCollection(patchedUsages, new Condition() { - @Override - public boolean value(PatchedUsage patchedUsage) { - return patchedUsage.getDelta() != 0; - } - }); - } - - @NotNull - private static Set packCollection(@NotNull Collection set, @NotNull Condition condition) { - final Set result = new LinkedHashSet(); - for (T t : set) { - if (condition.value(t)) { - result.add(t); - } - } - return result; - } - - @NotNull - private static String cutPatchString(@NotNull String patchStr, int maxSize) { - for (int i = maxSize - 1; i >= 0; i--) { - final char c = patchStr.charAt(i); - if (c == GROUPS_SEPARATOR || c == GROUP_VALUE_SEPARATOR) { - return patchStr.substring(0, i); - } - } - return ""; - } - - @Nullable - public static T findDescriptor(@NotNull Set descriptors, - @NotNull final Pair id) { - return ContainerUtil.find(descriptors, new Condition() { - @Override - public boolean value(T t) { - return id.equals(t.getId()); - } - }); - } - - @NotNull - public static Set getAllUsages(@Nullable Project project) { - final Set usageDescriptors = new TreeSet(); - - for (UsagesCollector usagesCollector : Extensions.getExtensions(UsagesCollector.EP_NAME)) { - usageDescriptors.addAll(usagesCollector.getUsages(project)); - } - - return usageDescriptors; - } - - @NotNull - public static String convertUsages(@NotNull Set descriptors) { - final Map> descriptorGroups = groupDescriptors(descriptors); - - return convertUsages(descriptorGroups); - } - - @NotNull - public static Map> groupDescriptors(@NotNull Set descriptors) { - final SortedMap> map = new TreeMap>(new Comparator() { - @Override - public int compare(GroupDescriptor g1, GroupDescriptor g2) { - final int priority = (int)(g2.getPriority() - g1.getPriority()); - return priority == 0 ? g1.getId().compareTo(g2.getId()) : priority; - } - }); - - for (UsageDescriptor descriptor : descriptors) { - final GroupDescriptor group = descriptor.getGroup(); - if (!map.containsKey(group)) { - map.put(group, new HashSet()); - } - map.get(group).add(descriptor); - } - return map; - } - - @NotNull - private static String convertUsages(@NotNull Map> map) { - StringBuffer buffer = new StringBuffer(); - for (Map.Entry> entry : map.entrySet()) { - buffer.append(entry.getKey().getId()); - buffer.append(GROUP_SEPARATOR); - buffer.append(convertValueMap(entry.getValue())); - buffer.append(GROUPS_SEPARATOR); - } - - return buffer.toString(); - } - - @NotNull - public static Set convertString(@NotNull String usages) { - Set descriptors = new LinkedHashSet(); - for (String groupStr : StringUtil.split(usages, GROUPS_SEPARATOR.toString())) { - if (!StringUtil.isEmptyOrSpaces(groupStr)) { - final Pair group = getPair(groupStr, GROUP_SEPARATOR.toString()); - if (group != null) { - descriptors.addAll(convertValueString(GroupDescriptor.create(group.getFirst()), group.getSecond())); - } - } - } - return descriptors; - } - - @NotNull - public static String convertValueMap(@NotNull Set descriptors) { - final StringBuffer buffer = new StringBuffer(); - for (UsageDescriptor usageDescriptor : descriptors) { - buffer.append(usageDescriptor.getKey()); - buffer.append("="); - buffer.append(usageDescriptor.getValue()); - buffer.append(GROUP_VALUE_SEPARATOR); - } - buffer.deleteCharAt(buffer.length() - 1); - - return buffer.toString(); - } - - @NotNull - public static Set convertValueString(@NotNull GroupDescriptor groupId, String valueData) { - final Set descriptors = new LinkedHashSet(); - for (String value : StringUtil.split(valueData, GROUP_VALUE_SEPARATOR.toString())) { - if (!StringUtil.isEmptyOrSpaces(value)) { - final Pair pair = getPair(value, "="); - if (pair != null) { - final String count = pair.getSecond(); - if (!StringUtil.isEmptyOrSpaces(count)) { - try { - final int i = Integer.parseInt(count); - descriptors.add(new UsageDescriptor(groupId, pair.getFirst(), i)); - } catch (NumberFormatException ignored) {} - } - } - } - } - - return descriptors; - } - - @Nullable - private static Pair getPair(@NotNull String str, @NotNull String separator) { - final int i = str.indexOf(separator); - if (i > 0 && i < str.length() - 1) { - String key = str.substring(0, i).trim(); - String value = str.substring(i + 1).trim(); - if (!StringUtil.isEmptyOrSpaces(key) && !StringUtil.isEmptyOrSpaces(value)) { - return Pair.create(key, value); - } - } - return null; - } -} diff --git a/platform/platform-impl/src/com/intellij/statistic/beans/GroupDescriptor.java b/platform/platform-impl/src/com/intellij/statistic/beans/GroupDescriptor.java deleted file mode 100644 index 326769adf724..000000000000 --- a/platform/platform-impl/src/com/intellij/statistic/beans/GroupDescriptor.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.statistic.beans; - -import org.jetbrains.annotations.NotNull; - -public class GroupDescriptor implements Comparable { - public static final double DEFAULT_PRIORITY = 0.0; - public static final double HIGHER_PRIORITY = 100.0; - public static final double LOWER_PRIORITY = -100.0; - - private final String myId; - private double myPriority; - - public static GroupDescriptor create(@NotNull String id) { - return new GroupDescriptor(id); - } - - public static GroupDescriptor create(@NotNull String id, double priority) { - return new GroupDescriptor(id, priority); - } - - private GroupDescriptor(@NotNull String id) { - this(id, DEFAULT_PRIORITY); - } - - private GroupDescriptor(@NotNull String id, double priority) { - myId = id; - myPriority = priority; - } - - - public String getId() { - return myId; - } - - public double getPriority() { - return myPriority; - } - - public void setPriority(double priority) { - myPriority = priority; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof GroupDescriptor)) return false; - - GroupDescriptor that = (GroupDescriptor)o; - - if (myId != null ? !myId.equals(that.myId) : that.myId != null) return false; - - return true; - } - - @Override - public int hashCode() { - return myId != null ? myId.hashCode() : 0; - } - - @Override - public int compareTo(GroupDescriptor gd) { - final int priority = (int)(this.getPriority() - gd.getPriority()); - return priority == 0 ? gd.getId().compareTo(gd.getId()) : priority; - } -} - diff --git a/platform/platform-impl/src/com/intellij/statistic/beans/UsageDescriptor.java b/platform/platform-impl/src/com/intellij/statistic/beans/UsageDescriptor.java deleted file mode 100644 index e31a924be4f5..000000000000 --- a/platform/platform-impl/src/com/intellij/statistic/beans/UsageDescriptor.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.statistic.beans; - -import com.intellij.openapi.util.Pair; -import org.jetbrains.annotations.NotNull; - -public class UsageDescriptor implements Comparable { - - private final GroupDescriptor myGroup; - private final String myKey; - private int myValue; - - public UsageDescriptor(@NotNull GroupDescriptor group, @NotNull String key, int value) { - myGroup = group; - myKey = key; - myValue = value; - } - - public Pair getId() { - return Pair.create(getGroup(), getKey()); - } - - @NotNull - public String getKey() { - return myKey; - } - - @NotNull - public GroupDescriptor getGroup() { - return myGroup; - } - - public int getValue() { - return myValue; - } - - public void setValue(int i) { - myValue = i; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof UsageDescriptor)) return false; - - UsageDescriptor that = (UsageDescriptor)o; - - if (!myGroup.equals(that.myGroup)) return false; - if (!myKey.equals(that.myKey)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = myGroup.hashCode(); - result = 31 * result + myKey.hashCode(); - return result; - } - - @Override - public int compareTo(UsageDescriptor ud) { - final int byGroup = this.getGroup().compareTo(ud.getGroup()); - - return byGroup == 0 ? this.getKey().compareTo(ud.myKey) : byGroup; - } -} diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml index 3f7291cee545..dcbdc60e0cb7 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml @@ -109,7 +109,7 @@ - + diff --git a/platform/platform-resources/src/componentSets/Platform.xml b/platform/platform-resources/src/componentSets/Platform.xml index a99994ac7cfd..262f9d54c624 100644 --- a/platform/platform-resources/src/componentSets/Platform.xml +++ b/platform/platform-resources/src/componentSets/Platform.xml @@ -114,8 +114,8 @@ - com.intellij.statistic.persistence.SentUsagesPersistenceComponent - com.intellij.statistic.persistence.SentUsagesPersistenceComponent + com.intellij.internal.statistic.persistence.SentUsagesPersistenceComponent + com.intellij.internal.statistic.persistence.SentUsagesPersistenceComponent diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java index 0850d38c3749..968e52aae1a8 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java @@ -17,7 +17,7 @@ package com.intellij.openapi.vcs.statistics; import com.intellij.openapi.project.Project; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java index 3cff5584312c..1e095cd4f677 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java @@ -26,7 +26,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectManagerListener; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.util.Function; import com.intellij.util.containers.HashSet; import org.jdom.Element; @@ -71,7 +71,7 @@ public class VcsStatisticsPersistenceComponent extends VcsStatisticsPersistence if (!StringUtil.isEmptyOrSpaces(projectId) && !StringUtil.isEmptyOrSpaces(vcs)) { Set vcsDescriptors = new HashSet(); for (String key : StringUtil.split(vcs, TOKENIZER)) { - vcsDescriptors.add(new UsageDescriptor(VcsUsagesCollector.getGroupId(), key, 1)); + vcsDescriptors.add(new UsageDescriptor(VcsUsagesCollector.createGroupDescriptor(), key, 1)); } getVcsUsageMap().put(projectId, vcsDescriptors); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java index b534312e3b82..602a62853521 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java @@ -18,9 +18,9 @@ package com.intellij.openapi.vcs.statistics; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.impl.VcsDescriptor; -import com.intellij.statistic.UsagesCollector; -import com.intellij.statistic.beans.GroupDescriptor; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.hash.HashMap; @@ -49,12 +49,12 @@ public class VcsUsagesCollector extends UsagesCollector { } @NotNull - public static Set getApplicationUsages() { + public Set getApplicationUsages() { return getApplicationUsages(VcsStatisticsPersistenceComponent.getInstance()); } @NotNull - public static Set getApplicationUsages(@NotNull final VcsStatisticsPersistenceComponent persistence) { + public Set getApplicationUsages(@NotNull final VcsStatisticsPersistenceComponent persistence) { final Map vcsUsagesMap = new HashMap(); for (Set descriptors : persistence.getVcsUsageMap().values()) { @@ -68,13 +68,14 @@ public class VcsUsagesCollector extends UsagesCollector { return ContainerUtil.map2Set(vcsUsagesMap.entrySet(), new Function, UsageDescriptor>() { @Override public UsageDescriptor fun(Map.Entry vcsUsage) { - return new UsageDescriptor(getGroupId(), vcsUsage.getKey(), vcsUsage.getValue()); + return new UsageDescriptor(createGroupDescriptor(), vcsUsage.getKey(), vcsUsage.getValue()); } }); } - public static GroupDescriptor getGroupId() { - return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); + @NotNull + public String getGroupId() { + return GROUP_ID; } @NotNull @@ -90,9 +91,13 @@ public class VcsUsagesCollector extends UsagesCollector { return ContainerUtil.map2Set(ProjectLevelVcsManager.getInstance(project).getAllVcss(), new Function() { @Override public UsageDescriptor fun(VcsDescriptor descriptor) { - return new UsageDescriptor(getGroupId(), descriptor.getName(), 1); + return new UsageDescriptor(createGroupDescriptor(), descriptor.getName(), 1); } }); } + + public static GroupDescriptor createGroupDescriptor() { + return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); + } } diff --git a/resources/src/idea/IdeaActions.xml b/resources/src/idea/IdeaActions.xml index 838d33b3ec5d..ab01fb606c8a 100644 --- a/resources/src/idea/IdeaActions.xml +++ b/resources/src/idea/IdeaActions.xml @@ -262,6 +262,7 @@ + From 45d604351ed94428a9f777bfe8ebecf94536a93d Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 7 Feb 2011 11:12:26 +0300 Subject: [PATCH 75/94] fixed scope for 'mocks' library --- platform/extensions/extensions.iml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/extensions/extensions.iml b/platform/extensions/extensions.iml index 8648132b4918..40f44967ffeb 100644 --- a/platform/extensions/extensions.iml +++ b/platform/extensions/extensions.iml @@ -16,7 +16,7 @@ - + From 3053cfe89ba41f78b66241e6e35002862a9ba379 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 7 Feb 2011 10:36:31 +0300 Subject: [PATCH 76/94] javadoc --- .../lang-api/src/com/intellij/openapi/roots/ContentEntry.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ContentEntry.java b/platform/lang-api/src/com/intellij/openapi/roots/ContentEntry.java index de4f462f57a8..a7802c4fcb62 100644 --- a/platform/lang-api/src/com/intellij/openapi/roots/ContentEntry.java +++ b/platform/lang-api/src/com/intellij/openapi/roots/ContentEntry.java @@ -21,9 +21,12 @@ import org.jetbrains.annotations.Nullable; /** * Represents a module content root. + * You can get existing entries with {@link com.intellij.openapi.roots.ModuleRootModel#getContentEntries()} or + * create a new one with {@link ModifiableRootModel#addContentEntry(com.intellij.openapi.vfs.VirtualFile)}. * * @author dsl * @see ModuleRootModel#getContentEntries() + * @see ModifiableRootModel#addContentEntry(com.intellij.openapi.vfs.VirtualFile) */ public interface ContentEntry extends Synthetic { /** From cb8a7746e3469b8278a7ef32859204cb24637206 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 7 Feb 2011 13:13:47 +0300 Subject: [PATCH 77/94] IDEA-65071 Spring integration: context files in the test hierarchy no longer use test classpath --- .../com/intellij/util/xml/PsiClassConverter.java | 16 +++++++++++++++- .../src/com/intellij/util/xml/DomJavaUtil.java | 15 +++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/util/xml/PsiClassConverter.java b/java/java-impl/src/com/intellij/util/xml/PsiClassConverter.java index 32785e7a44c3..06f3f70cd596 100644 --- a/java/java-impl/src/com/intellij/util/xml/PsiClassConverter.java +++ b/java/java-impl/src/com/intellij/util/xml/PsiClassConverter.java @@ -17,13 +17,18 @@ package com.intellij.util.xml; import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceProvider; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.ClassKind; +import com.intellij.psi.xml.XmlElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -97,7 +102,16 @@ public class PsiClassConverter extends Converter implements CustomRefe @Nullable protected GlobalSearchScope getScope(final GenericDomValue domValue) { final Module module = domValue.getModule(); - return module == null ? null : GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, false); + if (module == null) return null; + XmlElement element = domValue.getXmlElement(); + if (element == null) return null; + PsiFile file = element.getContainingFile(); + if (file == null) return null; + file = file.getOriginalFile(); + VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile == null) return null; + ProjectFileIndex fileIndex = ProjectRootManager.getInstance(file.getProject()).getFileIndex(); + return GlobalSearchScope.moduleRuntimeScope(module, fileIndex.isInTestSourceContent(virtualFile)); } public static class AnnotationType extends PsiClassConverter { diff --git a/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java b/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java index ca98d5d046bd..996af38a3a63 100644 --- a/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java +++ b/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java @@ -16,6 +16,9 @@ package com.intellij.util.xml; import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiFile; @@ -32,7 +35,7 @@ public class DomJavaUtil { } @Nullable - public static PsiClass findClass(@Nullable String name, @NotNull final PsiFile file, @Nullable final Module module, @Nullable final GlobalSearchScope searchScope) { + public static PsiClass findClass(@Nullable String name, @NotNull PsiFile file, @Nullable final Module module, @Nullable final GlobalSearchScope searchScope) { if (name == null) return null; if (name.indexOf('$')>=0) name = name.replace('$', '.'); @@ -40,7 +43,15 @@ public class DomJavaUtil { if (searchScope == null) { if (module != null) { - scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, false); + file = file.getOriginalFile(); + VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile == null) { + scope = GlobalSearchScope.moduleRuntimeScope(module, true); + } + else { + ProjectFileIndex fileIndex = ProjectRootManager.getInstance(file.getProject()).getFileIndex(); + scope = GlobalSearchScope.moduleRuntimeScope(module, fileIndex.isInTestSourceContent(virtualFile)); + } } else { scope = file.getResolveScope(); From 2353560d6ff03e98d6c0460d9cca861009699142 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Mon, 7 Feb 2011 13:34:24 +0300 Subject: [PATCH 78/94] tabs: stretching tab fixes --- .../src/com/intellij/ui/tabs/impl/DragHelper.java | 4 ++++ .../src/com/intellij/ui/tabs/impl/JBTabsImpl.java | 4 +++- .../src/com/intellij/ui/tabs/impl/table/TableLayout.java | 2 -- .../src/com/intellij/ide/IdeTooltipManager.java | 2 +- .../com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java | 9 +++++++++ 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java index 15e5aeb70f76..cf07559631d9 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java @@ -257,4 +257,8 @@ class DragHelper extends MouseDragHelper { myTabs.revalidate(); } + + public TabInfo getDragSource() { + return myDragSource; + } } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java index a3c3d7192c40..e8f6b0c2920e 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java @@ -1590,7 +1590,9 @@ public class JBTabsImpl extends JComponent boolean leftEdge = !isSingleRow() && first && border.left == 0; boolean rightEdge = !isSingleRow() && last && Boolean.TRUE.equals(myInfo2Label.get(selected).getClientProperty(STRETCHED_BY_WIDTH)) && border.right == 0; - if (leftEdge) { + boolean isDraggedNow = selected != null && myDragHelper != null && selected.equals(myDragHelper.getDragSource()); + + if (leftEdge && !isDraggedNow) { shape.path.moveTo(shape.insets.left, shape.labelTopY + shape.labelPath.deltaY(getEdgeArcSize())); shape.path.quadTo(shape.labelLeftX, shape.labelTopY, shape.labelLeftX + shape.labelPath.deltaX(getEdgeArcSize()), shape.labelTopY); shape.path.lineTo(shape.labelRightX - shape.labelPath.deltaX(getArcSize()), shape.labelTopY); diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/table/TableLayout.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/table/TableLayout.java index 0602d22eeb42..5be2d06810f5 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/table/TableLayout.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/table/TableLayout.java @@ -128,8 +128,6 @@ public class TableLayout extends TabLayout { toAjust = true; } - toAjust |= myTabs.myForcedRelayout; - for (int i = 0; i < eachRow.myColumns.size(); i++) { TabInfo tabInfo = eachRow.myColumns.get(i); final TabLabel label = myTabs.myInfo2Label.get(tabInfo); diff --git a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java index 6090897642b6..d55c36a1de47 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java @@ -341,7 +341,7 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener return useSystem; } - private boolean hideCurrent(@Nullable MouseEvent me, AnAction action, AnActionEvent event) { + public boolean hideCurrent(@Nullable MouseEvent me, AnAction action, AnActionEvent event) { myShowRequest = null; myQueuedComponent = null; myQueuedTooltip = null; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java index bf5656656216..27836ada7e5d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java @@ -16,8 +16,10 @@ package com.intellij.openapi.wm.impl; import com.intellij.ide.IdeEventQueue; +import com.intellij.ide.IdeTooltipManager; import com.intellij.ide.dnd.DnDAware; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.ui.Painter; import com.intellij.openapi.ui.impl.GlassPaneDialogWrapperPeer; import com.intellij.openapi.util.Disposer; @@ -63,6 +65,13 @@ public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEvent if (eventWindow != thisGlassWindow) return false; } + + if (e.getID() == MouseEvent.MOUSE_DRAGGED) { + if (ApplicationManager.getApplication() != null) { + IdeTooltipManager.getInstance().hideCurrent((MouseEvent)e, null, null); + } + } + boolean dispatched; if (e.getID() == MouseEvent.MOUSE_PRESSED || e.getID() == MouseEvent.MOUSE_RELEASED || e.getID() == MouseEvent.MOUSE_CLICKED) { dispatched = preprocess((MouseEvent)e, false); From 50c08b9283de32498f18b3339a54bbeef7fef425 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Mon, 7 Feb 2011 13:35:46 +0300 Subject: [PATCH 79/94] Update proper section in Info.plist on OutOfMemoryError. --- .../platform-impl/src/com/intellij/diagnostic/VMOptions.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/VMOptions.java b/platform/platform-impl/src/com/intellij/diagnostic/VMOptions.java index 0aff01def2c9..00f4cb9ea63d 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/VMOptions.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/VMOptions.java @@ -41,7 +41,8 @@ public class VMOptions { @NonNls private static final Pattern XMX_PATTERN = Pattern.compile(XMX_OPTION + MEM_SIZE_EXPR); @NonNls private static final Pattern PERM_GEN_PATTERN = Pattern.compile(PERM_GEN_OPTION + MEM_SIZE_EXPR); - @NonNls private static final Pattern MAC_OS_VM_OPTIONS_PATTERN = Pattern.compile("(VMOptions(?:(?:\\s*)(?:(?:\\s*))*))(.*)()"); + @NonNls public static final String MAC_ARCH_VMOPTIONS = SystemInfo.is64Bit ? "VMOptions.x86_64" : "VMOptions.i386"; + @NonNls private static final Pattern MAC_OS_VM_OPTIONS_PATTERN = Pattern.compile("(" + MAC_ARCH_VMOPTIONS + "(?:(?:\\s*)(?:(?:\\s*))*))(.*)()"); @NonNls private static final String INFO_PLIST = "/Contents/Info.plist"; From e2de104dcd7cbe4f66cea56424c6310bbfbd02b8 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 7 Feb 2011 11:49:27 +0100 Subject: [PATCH 80/94] remove unnecessary method and unnecessary class and cleanup --- .../siyeh/InspectionGadgetsBundle.properties | 23 ++-- .../com/siyeh/ig/BaseInspectionVisitor.java | 6 +- .../bugs/CollectionAddedToSelfInspection.java | 8 +- .../ig/bugs/IgnoreResultOfCallInspection.java | 9 +- ...tringBufferWithCharArgumentInspection.java | 6 +- ...tenationInMessageFormatCallInspection.java | 5 +- .../bugs/SuspiciousToArrayCallInspection.java | 6 +- ...leResultOfMethodCallIgnoredInspection.java | 19 +-- .../UseOfPropertiesAsHashtableInspection.java | 7 +- .../MissingOverrideAnnotationInspection.java | 6 +- ...ForLoopWithMissingComponentInspection.java | 8 +- .../CheckedExceptionClassInspection.java | 8 +- .../ErrorRethrownInspection.java | 6 +- .../NonFinalFieldOfExceptionInspection.java | 6 +- .../UncheckedExceptionClassInspection.java | 10 +- .../ExtractParameterAsLocalVariableFix.java | 9 +- ...allDuringObjectConstructionInspection.java | 7 +- .../ClassWithoutConstructorInspection.java | 13 ++- .../EnumerationCanBeIterationInspection.java | 29 ++--- .../ig/jdk/VarargParameterInspection.java | 19 ++- .../ig/jdk15/ForCanBeForeachInspection.java | 13 ++- .../ig/jdk15/WhileCanBeForeachInspection.java | 11 +- ...lsBetweenInconvertibleTypesInspection.java | 12 +- .../AssertsWithoutMessagesInspection.java | 15 ++- ...ConstantJUnitAssertArgumentInspection.java | 30 +++-- ...xpectedExceptionNeverThrownInspection.java | 6 +- ...ctTestClassNamingConventionInspection.java | 23 ++-- ...itTestClassNamingConventionInspection.java | 15 +-- ...deredAssertEqualsParametersInspection.java | 22 ++-- .../ig/junit/MisspelledSetUpInspection.java | 12 +- .../junit/MisspelledTearDownInspection.java | 12 +- .../junit/SetupCallsSuperSetupInspection.java | 18 ++- .../SetupIsPublicVoidNoArgInspection.java | 18 +-- .../SimplifiableJUnitAssertionInspection.java | 37 +++--- .../siyeh/ig/junit/StaticSuiteInspection.java | 11 +- .../TeardownCallsSuperTeardownInspection.java | 27 +++-- .../TeardownIsPublicVoidNoArgInspection.java | 20 ++-- .../TestCaseInProductCodeInspection.java | 13 ++- .../TestCaseWithNoTestMethodsInspection.java | 19 ++- ...TestMethodIsPublicVoidNoArgInspection.java | 6 +- .../TestMethodWithoutAssertionInspection.java | 13 ++- .../UnconstructableTestCaseInspection.java | 10 +- ...nNameDoesntEndWithExceptionInspection.java | 6 +- ...eptionNameEndsWithExceptionInspection.java | 9 +- .../InnerClassReferenceVisitor.java | 7 +- ...ManualArrayToCollectionCopyInspection.java | 10 +- .../performance/MethodReferenceVisitor.java | 11 +- .../performance/TailRecursionInspection.java | 24 ++-- ...WithZeroLengthArrayArgumentInspection.java | 8 +- .../UseOfAWTPeerClassInspection.java | 15 ++- .../UseOfJDBCDriverClassInspection.java | 11 +- .../src/com/siyeh/ig/psiutils/ClassUtils.java | 19 +-- .../src/com/siyeh/ig/psiutils/CloneUtils.java | 9 +- .../com/siyeh/ig/psiutils/ImportUtils.java | 13 +-- .../com/siyeh/ig/psiutils/IteratorUtils.java | 11 +- .../com/siyeh/ig/psiutils/MethodUtils.java | 12 +- .../siyeh/ig/psiutils/SerializationUtils.java | 12 +- .../src/com/siyeh/ig/psiutils/TestUtils.java | 12 +- .../src/com/siyeh/ig/psiutils/TypeUtils.java | 13 ++- .../siyeh/ig/psiutils/WeakestTypeFinder.java | 10 +- .../security/CustomClassloaderInspection.java | 12 +- .../CustomSecurityManagerInspection.java | 10 +- ...xecuteWithNonConstantStringInspection.java | 6 +- ...tementWithNonConstantStringInspection.java | 6 +- ...ibraryWithNonConstantStringInspection.java | 6 +- ...ecureRandomNumberGenerationInspection.java | 12 +- .../ComparatorNotSerializableInspection.java | 6 +- .../serialization/SerializableInspection.java | 15 +-- .../style/ImplicitCallToSuperInspection.java | 8 +- .../threading/ConditionSignalInspection.java | 15 ++- .../SleepWhileHoldingLockInspection.java | 13 ++- .../SynchronizedMethodInspection.java | 14 ++- .../ThreadLocalNotStaticFinalInspection.java | 9 +- .../ig/threading/ThreadRunInspection.java | 13 ++- .../ThreadStartInConstructionInspection.java | 12 +- .../siyeh/ig/threading/ThreadingUtils.java | 25 ++-- .../siyeh/ig/ui/TreeClassChooserAction.java | 109 ------------------ .../src/com/siyeh/ig/ui/UiUtils.java | 6 +- 78 files changed, 559 insertions(+), 523 deletions(-) delete mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/ui/TreeClassChooserAction.java diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index 4df0b02e1574..8948f9e10095 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -628,7 +628,7 @@ manual.array.copy.display.name=Manual array copy manual.array.to.collection.copy.display.name=Manual array to collection copy long.literals.ending.with.lowercase.l.display.name='long' literal ending with 'l' instead of 'L' overly.complex.arithmetic.expression.display.name=Overly complex arithmetic expression -j.unit.abstract.test.class.naming.convention.display.name=JUnit abstract test class naming convention +junit.abstract.test.class.naming.convention.display.name=JUnit abstract test class naming convention unnecessary.parentheses.display.name=Unnecessary parentheses test.case.in.product.code.display.name=JUnit TestCase in product source test.method.in.product.code.display.name=JUnit test method in product source @@ -805,7 +805,7 @@ class.in.top.level.package.display.name=Class without package statement confusing.else.display.name=Confusing 'else' branch public.field.accessed.in.synchronized.context.display.name=Non-private field accessed in synchronized context string.replaceable.by.string.buffer.display.name=Non-constant String should be StringBuilder -j.unit.test.class.naming.convention.display.name=JUnit test class naming convention +junit.test.class.naming.convention.display.name=JUnit test class naming convention method.coupling.display.name=Overly coupled method collections.must.have.initial.capacity.display.name=Collection without initial capacity anonymous.inner.class.display.name=Anonymous inner class @@ -1131,12 +1131,12 @@ instance.variable.name.convention.problem.descriptor.regex.mismatch=Instance fie interface.name.convention.problem.descriptor.short=Interface name #ref is too short #loc interface.name.convention.problem.descriptor.long=Interface name #ref is too long #loc interface.name.convention.problem.descriptor.regex.mismatch=Interface name #ref doesn''t match regex ''{0}'' #loc -j.unit.abstract.test.class.naming.convention.problem.descriptor.short=Abstract JUnit test class name #ref is too short #loc -j.unit.abstract.test.class.naming.convention.problem.descriptor.long=Abstract JUnit test class name #ref is too long #loc -j.unit.abstract.test.class.naming.convention.problem.descriptor.regex.mismatch=Abstract JUnit test class name #ref doesn''t match regex ''{0}'' #loc -j.unit.test.class.naming.convention.problem.descriptor.short=JUnit test class name #ref is too short #loc -j.unit.test.class.naming.convention.problem.descriptor.long=JUnit test class name #ref is too long #loc -j.unit.test.class.naming.convention.problem.descriptor.regex.mismatch=JUnit test class name #ref doesn''t match regex ''{0}'' #loc +junit.abstract.test.class.naming.convention.problem.descriptor.short=Abstract JUnit test class name #ref is too short #loc +junit.abstract.test.class.naming.convention.problem.descriptor.long=Abstract JUnit test class name #ref is too long #loc +junit.abstract.test.class.naming.convention.problem.descriptor.regex.mismatch=Abstract JUnit test class name #ref doesn''t match regex ''{0}'' #loc +junit.test.class.naming.convention.problem.descriptor.short=JUnit test class name #ref is too short #loc +junit.test.class.naming.convention.problem.descriptor.long=JUnit test class name #ref is too long #loc +junit.test.class.naming.convention.problem.descriptor.regex.mismatch=JUnit test class name #ref doesn''t match regex ''{0}'' #loc local.variable.naming.convention.problem.descriptor.short=Local variable name #ref is too short #loc local.variable.naming.convention.problem.descriptor.long=Local variable name #ref is too long #loc local.variable.naming.convention.problem.descriptor.regex.mismatch=Local variable name #ref doesn''t match regex ''{0}'' #loc @@ -1182,7 +1182,7 @@ unnecessary.boxing.remove.quickfix=Remove boxing unnecessary.unboxing.remove.quickfix=Remove unboxing misordered.assert.equals.parameters.flip.quickfix=Flip compared parameters setup.calls.super.setup.add.quickfix=Add call to 'super.setUp()' -simplify.j.unit.assertion.simplify.quickfix=Simplify assertion +simplify.junit.assertion.simplify.quickfix=Simplify assertion teardown.calls.super.teardown.add.quickfix=Add call to 'super.tearDown()' test.method.is.public.void.no.arg.problem.descriptor1=Test method #ref() should probably not have parameters #loc test.method.is.public.void.no.arg.problem.descriptor2=Test method #ref() is not declared 'public void' #loc @@ -1831,4 +1831,7 @@ shift.out.of.range.quickfix=Replace ''{0}'' with ''{1}'' boxing.boxed.value.display.name=Boxing of already boxed value boxing.boxed.value.problem.descriptor=Boxing of already boxed #ref boxing.boxed.value.quickfix=Remove unnecessary boxing -unnecessary.javadoc.link.option=Ignore inline links to super methods \ No newline at end of file +unnecessary.javadoc.link.option=Ignore inline links to super methods +constant.junit.assert.argument.display.name=Constant JUnit assert argument +constant.junit.assert.argument.problem.descriptor=Argument #ref is constant +test.case.with.no.test.methods.option=Ignore test cases which have super classes with test methods \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspectionVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspectionVisitor.java index 09cb9f13dea3..c365f9e72c54 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspectionVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspectionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.siyeh.ig; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.psi.*; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public abstract class BaseInspectionVisitor extends JavaElementVisitor{ @@ -49,7 +50,8 @@ public abstract class BaseInspectionVisitor extends JavaElementVisitor{ } protected final void registerMethodCallError( - @NotNull PsiMethodCallExpression expression, Object... infos) { + @NotNull PsiMethodCallExpression expression, + @NonNls Object... infos) { final PsiReferenceExpression methodExpression = expression.getMethodExpression(); final PsiElement nameToken = methodExpression.getReferenceNameElement(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionAddedToSelfInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionAddedToSelfInspection.java index dc5ff5783f1f..aab48ff11ff4 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionAddedToSelfInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionAddedToSelfInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.siyeh.ig.bugs; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.EquivalenceChecker; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -91,9 +91,9 @@ public class CollectionAddedToSelfInspection extends BaseInspection { if(qualifierClass == null){ return; } - if(!ClassUtils.isSubclass(qualifierClass, + if(!InheritanceUtil.isInheritor(qualifierClass, CommonClassNames.JAVA_UTIL_COLLECTION) && - !ClassUtils.isSubclass(qualifierClass, + !InheritanceUtil.isInheritor(qualifierClass, CommonClassNames.JAVA_UTIL_MAP)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspection.java index 77b68fe582cb..8b1f23cdcccb 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,12 +22,12 @@ import com.intellij.codeInspection.ui.RemoveAction; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.LibraryUtil; -import com.siyeh.ig.ui.*; +import com.siyeh.ig.ui.ToggleAction; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -154,7 +154,7 @@ public class IgnoreResultOfCallInspection extends BaseInspection { continue; } final String className = classNames.get(i); - if (!ClassUtils.isSubclass(aClass, className)) { + if (!InheritanceUtil.isInheritor(aClass, className)) { continue; } registerMethodCallError(call, aClass); @@ -198,7 +198,6 @@ public class IgnoreResultOfCallInspection extends BaseInspection { JCheckBox nonLibraryCheckbox; Form(){ - super(); addButton.setAction(new AddAction(table)); removeButton.setAction(new RemoveAction(table)); nonLibraryCheckbox.setAction(new ToggleAction( diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/NewStringBufferWithCharArgumentInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/NewStringBufferWithCharArgumentInspection.java index e0934e695584..f46502d5c2b6 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/NewStringBufferWithCharArgumentInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/NewStringBufferWithCharArgumentInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2007-2010 Bas Leijdekkers + * Copyright 2007-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,12 @@ package com.siyeh.ig.bugs; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -120,7 +120,7 @@ public class NewStringBufferWithCharArgumentInspection extends BaseInspection { return; } final PsiClass aClass = constructor.getContainingClass(); - if (!ClassUtils.isSubclass(aClass, + if (!InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_ABSTRACT_STRING_BUILDER)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/StringConcatenationInMessageFormatCallInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/StringConcatenationInMessageFormatCallInspection.java index f30e49d16092..0d6a94accf16 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/StringConcatenationInMessageFormatCallInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/StringConcatenationInMessageFormatCallInspection.java @@ -18,13 +18,13 @@ package com.siyeh.ig.bugs; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.ExpressionUtils; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; @@ -224,7 +224,8 @@ public class StringConcatenationInMessageFormatCallInspection return false; } final PsiClass aClass = (PsiClass) target; - return ClassUtils.isSubclass(aClass, "java.text.MessageFormat"); + return InheritanceUtil.isInheritor(aClass, + "java.text.MessageFormat"); } } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/SuspiciousToArrayCallInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/SuspiciousToArrayCallInspection.java index 8410adc1703a..bc97a8b76689 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/SuspiciousToArrayCallInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/SuspiciousToArrayCallInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2010 Bas Leijdekkers + * Copyright 2005-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.siyeh.ig.bugs; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -76,7 +76,7 @@ public class SuspiciousToArrayCallInspection extends BaseInspection { final PsiClassType classType = (PsiClassType)type; final PsiClass aClass = classType.resolve(); if (aClass == null || - !ClassUtils.isSubclass(aClass, + !InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_UTIL_COLLECTION)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspection.java index fc98f3ed36f7..3c83d5286c68 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2008 Bas Leijdekkers + * Copyright 2008-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,24 +17,26 @@ package com.siyeh.ig.bugs; import com.intellij.psi.*; import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Query; +import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.psiutils.TypeUtils; -import com.siyeh.ig.psiutils.ClassUtils; -import com.siyeh.InspectionGadgetsBundle; import org.jetbrains.annotations.NotNull; public class ThrowableResultOfMethodCallIgnoredInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "throwable.result.of.method.call.ignored.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( @@ -46,6 +48,7 @@ public class ThrowableResultOfMethodCallIgnoredInspection return true; } + @Override public BaseInspectionVisitor buildVisitor() { return new ThrowableResultOfMethodCallIgnoredVisitor(); } @@ -75,7 +78,7 @@ public class ThrowableResultOfMethodCallIgnoredInspection } if (!method.hasModifierProperty(PsiModifier.STATIC)) { final PsiClass containingClass = method.getContainingClass(); - if (ClassUtils.isSubclass(containingClass, + if (InheritanceUtil.isInheritor(containingClass, CommonClassNames.JAVA_LANG_THROWABLE)) { return; } @@ -117,11 +120,9 @@ public class ThrowableResultOfMethodCallIgnoredInspection while (usageParent instanceof PsiParenthesizedExpression) { usageParent = usageParent.getParent(); } - if (usageParent instanceof PsiThrowStatement) { - return; - } else if (usageParent instanceof PsiReturnStatement) { - return; - } else if (usageParent instanceof PsiExpressionList) { + if (usageParent instanceof PsiThrowStatement || + usageParent instanceof PsiReturnStatement || + usageParent instanceof PsiExpressionList) { return; } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/UseOfPropertiesAsHashtableInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/UseOfPropertiesAsHashtableInspection.java index 37dc74eb8c17..f9db480acbd3 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/UseOfPropertiesAsHashtableInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/UseOfPropertiesAsHashtableInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,11 @@ package com.siyeh.ig.bugs; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.HardcodedMethodConstants; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.TypeUtils; import org.jetbrains.annotations.NotNull; @@ -65,7 +65,8 @@ public class UseOfPropertiesAsHashtableInspection extends BaseInspection { if(containingClass == null){ return; } - if(!ClassUtils.isSubclass(containingClass, "java.util.Hashtable")){ + if(!InheritanceUtil.isInheritor(containingClass, + "java.util.Hashtable")){ return; } final PsiExpression qualifier = diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/MissingOverrideAnnotationInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/MissingOverrideAnnotationInspection.java index 449827a75c3f..190adb30e6bd 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/MissingOverrideAnnotationInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/MissingOverrideAnnotationInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -218,8 +218,8 @@ public class MissingOverrideAnnotationInspection extends BaseInspection { final List toExclude = new SmartList(); for (PsiMethod superMethod : superMethods) { final PsiClass superClass = superMethod.getContainingClass(); - if (!InheritanceUtil.isCorrectDescendant(methodClass, - superClass, true)) { + if (!InheritanceUtil.isInheritorOrSelf(methodClass, superClass, + true)) { toExclude.add(superMethod); } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/controlflow/ForLoopWithMissingComponentInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/controlflow/ForLoopWithMissingComponentInspection.java index 0c5997151f1d..1651cb9eeffe 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/controlflow/ForLoopWithMissingComponentInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/controlflow/ForLoopWithMissingComponentInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +15,13 @@ */ package com.siyeh.ig.controlflow; +import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.HardcodedMethodConstants; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; -import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -144,7 +144,7 @@ public class ForLoopWithMissingComponentInspection extends BaseInspection { if(declaredClass == null){ continue; } - if(!ClassUtils.isSubclass(declaredClass, + if(!InheritanceUtil.isInheritor(declaredClass, CommonClassNames.JAVA_UTIL_ITERATOR)){ continue; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/CheckedExceptionClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/CheckedExceptionClassInspection.java index 7cd6b3e43d57..669577fcb923 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/CheckedExceptionClassInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/CheckedExceptionClassInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ package com.siyeh.ig.errorhandling; import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiClass; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NotNull; public class CheckedExceptionClassInspection extends BaseInspection { @@ -47,11 +47,11 @@ public class CheckedExceptionClassInspection extends BaseInspection { private static class CheckedExceptionClassVisitor extends BaseInspectionVisitor { @Override public void visitClass(@NotNull PsiClass aClass) { - if (!ClassUtils.isSubclass(aClass, + if (!InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_THROWABLE)) { return; } - if (ClassUtils.isSubclass(aClass, + if (InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/ErrorRethrownInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/ErrorRethrownInspection.java index 79377f6cb729..57c58eccd991 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/ErrorRethrownInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/ErrorRethrownInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,11 @@ package com.siyeh.ig.errorhandling; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.TypeUtils; import org.jetbrains.annotations.NotNull; @@ -73,7 +73,7 @@ public class ErrorRethrownInspection extends BaseInspection { if (aClass == null) { return; } - if (!ClassUtils.isSubclass(aClass, + if (!InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_ERROR)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/NonFinalFieldOfExceptionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/NonFinalFieldOfExceptionInspection.java index 3cbe78119b15..cf5598164f7d 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/NonFinalFieldOfExceptionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/NonFinalFieldOfExceptionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,12 +19,12 @@ import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiField; import com.intellij.psi.PsiModifier; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.MakeFieldFinalFix; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -69,7 +69,7 @@ public class NonFinalFieldOfExceptionInspection extends BaseInspection { if (containingClass == null) { return; } - if (!ClassUtils.isSubclass(containingClass, + if (!InheritanceUtil.isInheritor(containingClass, CommonClassNames.JAVA_LANG_EXCEPTION)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/UncheckedExceptionClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/UncheckedExceptionClassInspection.java index b6469ffe0b1b..07e1de3eb35c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/UncheckedExceptionClassInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/UncheckedExceptionClassInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ package com.siyeh.ig.errorhandling; import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiClass; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NotNull; public class UncheckedExceptionClassInspection extends BaseInspection { @@ -48,13 +48,13 @@ public class UncheckedExceptionClassInspection extends BaseInspection { extends BaseInspectionVisitor { @Override public void visitClass(@NotNull PsiClass aClass) { - if (!ClassUtils.isSubclass(aClass, + if (!InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_THROWABLE)) { return; } - if (ClassUtils.isSubclass(aClass, + if (InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_EXCEPTION) && - !ClassUtils.isSubclass(aClass, + !InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java index d0b8b8623e65..91989e14ac8c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009 Bas Leijdekkers + * Copyright 2008-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,11 +18,11 @@ package com.siyeh.ig.fixes; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; -import com.intellij.psi.tree.IElementType; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.search.SearchScope; import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.tree.IElementType; import com.intellij.util.IncorrectOperationException; import com.intellij.util.Query; import com.siyeh.InspectionGadgetsBundle; @@ -74,9 +74,8 @@ public class ExtractParameterAsLocalVariableFix if (body == null) { return; } - final PsiManager manager = PsiManager.getInstance(project); final CodeStyleManager codeStyleManager = - manager.getCodeStyleManager(); + CodeStyleManager.getInstance(project); final String parameterName = parameterReference.getText(); final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project); @@ -192,7 +191,7 @@ public class ExtractParameterAsLocalVariableFix (PsiAssignmentExpression)parent; final IElementType tokenType = assignmentExpression.getOperationTokenType(); - if (tokenType != JavaTokenType.EQ) { + if (!JavaTokenType.EQ.equals(tokenType)) { return false; } final PsiExpression lExpression = diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/OverriddenMethodCallDuringObjectConstructionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/OverriddenMethodCallDuringObjectConstructionInspection.java index 453cd1143070..4cf19a897d62 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/OverriddenMethodCallDuringObjectConstructionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/OverriddenMethodCallDuringObjectConstructionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,18 +29,21 @@ import org.jetbrains.annotations.NotNull; public class OverriddenMethodCallDuringObjectConstructionInspection extends BaseInspection{ + @Override @NotNull public String getDisplayName(){ return InspectionGadgetsBundle.message( "overridden.method.call.in.constructor.display.name"); } + @Override @NotNull public String buildErrorString(Object... infos){ return InspectionGadgetsBundle.message( "overridden.method.call.in.constructor.problem.descriptor"); } + @Override public BaseInspectionVisitor buildVisitor(){ return new OverriddenMethodCallInConstructorVisitor(); } @@ -90,7 +93,7 @@ public class OverriddenMethodCallDuringObjectConstructionInspection } final PsiClass calledMethodClass = calledMethod.getContainingClass(); - if(!InheritanceUtil.isCorrectDescendant(containingClass, + if(!InheritanceUtil.isInheritorOrSelf(containingClass, calledMethodClass, true)){ return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java index fbd9866a28e4..2abb541aecdb 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,18 +28,21 @@ import org.jetbrains.annotations.NotNull; public class ClassWithoutConstructorInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "class.without.constructor.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "class.without.constructor.problem.descriptor"); } + @Override protected InspectionGadgetsFix buildFix(Object... infos) { return new ClassWithoutConstructorFix(); } @@ -53,12 +56,13 @@ public class ClassWithoutConstructorInspection extends BaseInspection { "class.without.constructor.create.quickfix"); } + @Override public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement classIdentifier = descriptor.getPsiElement(); final PsiClass aClass = (PsiClass)classIdentifier.getParent(); - final PsiManager psiManager = PsiManager.getInstance(project); - final PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory(); + final PsiElementFactory factory = + JavaPsiFacade.getElementFactory(project); final PsiMethod constructor = factory.createConstructor(); final PsiModifierList modifierList = constructor.getModifierList(); if (aClass == null) { @@ -78,11 +82,12 @@ public class ClassWithoutConstructorInspection extends BaseInspection { } aClass.add(constructor); final CodeStyleManager styleManager = - psiManager.getCodeStyleManager(); + CodeStyleManager.getInstance(project); styleManager.reformat(constructor); } } + @Override public BaseInspectionVisitor buildVisitor() { return new ClassWithoutConstructorVisitor(); } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/EnumerationCanBeIterationInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/EnumerationCanBeIterationInspection.java index 19a715a24013..057ce0509bf3 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/EnumerationCanBeIterationInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/EnumerationCanBeIterationInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Bas Leijdekkers + * Copyright 2007-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import com.intellij.psi.*; import com.intellij.psi.codeStyle.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.Query; @@ -28,7 +29,6 @@ import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.PsiElementOrderComparator; import com.siyeh.ig.psiutils.TypeUtils; import org.jetbrains.annotations.NonNls; @@ -179,8 +179,7 @@ public class EnumerationCanBeIterationInspection extends BaseInspection { PsiMethodCallExpression methodCallExpression, String variableName, PsiType parameterType) throws IncorrectOperationException { - final StringBuilder newStatementText = - new StringBuilder(); + @NonNls final StringBuilder newStatementText = new StringBuilder(); final Project project = methodCallExpression.getProject(); final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project); @@ -231,12 +230,13 @@ public class EnumerationCanBeIterationInspection extends BaseInspection { return null; } newStatementText.append(';'); - final PsiManager manager = methodCallExpression.getManager(); - final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + final PsiElementFactory factory = + JavaPsiFacade.getElementFactory(project); final PsiStatement statement = factory.createStatementFromText(newStatementText.toString(), methodExpression); - final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project); + final JavaCodeStyleManager styleManager = + JavaCodeStyleManager.getInstance(project); styleManager.shortenClassReferences(statement); return statement; } @@ -293,9 +293,9 @@ public class EnumerationCanBeIterationInspection extends BaseInspection { (PsiMethodCallExpression) referenceGrandParent; final PsiReferenceExpression foundReferenceExpression = callExpression.getMethodExpression(); - final String foundName = + @NonNls final String foundName = foundReferenceExpression.getReferenceName(); - final String newExpressionText; + @NonNls final String newExpressionText; if ("hasMoreElements".equals(foundName)) { newExpressionText = newVariableName + ".hasNext()"; } else if ("nextElement".equals(foundName)) { @@ -312,6 +312,7 @@ public class EnumerationCanBeIterationInspection extends BaseInspection { return result; } + @NonNls private static String createVariableName(PsiElement context) { final Project project = context.getProject(); final JavaPsiFacade facade = JavaPsiFacade.getInstance(project); @@ -339,6 +340,7 @@ public class EnumerationCanBeIterationInspection extends BaseInspection { } } + @Override public BaseInspectionVisitor buildVisitor() { return new EnumerationCanBeIterationVisitor(); } @@ -400,10 +402,10 @@ public class EnumerationCanBeIterationInspection extends BaseInspection { return; } final PsiClass containingClass = method.getContainingClass(); - if (ClassUtils.isSubclass(containingClass, + if (InheritanceUtil.isInheritor(containingClass, "java.util.Vector")) { registerMethodCallError(expression, ITERATOR_TEXT); - } else if (ClassUtils.isSubclass(containingClass, + } else if (InheritanceUtil.isInheritor(containingClass, "java.util.Hashtable")) { registerMethodCallError(expression, VALUES_ITERATOR_TEXT); } @@ -413,7 +415,7 @@ public class EnumerationCanBeIterationInspection extends BaseInspection { return; } final PsiClass containingClass = method.getContainingClass(); - if (ClassUtils.isSubclass(containingClass, + if (InheritanceUtil.isInheritor(containingClass, "java.util.Hashtable")) { registerMethodCallError(expression, KEY_SET_ITERATOR_TEXT); } @@ -446,7 +448,8 @@ public class EnumerationCanBeIterationInspection extends BaseInspection { super.visitMethodCallExpression(expression); final PsiReferenceExpression methodExpression = expression.getMethodExpression(); - final String methodName = methodExpression.getReferenceName(); + @NonNls final String methodName = + methodExpression.getReferenceName(); if (!"hasMoreElements".equals(methodName) && !"nextElement".equals(methodName)) { return; diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/VarargParameterInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/VarargParameterInspection.java index 4ce271fd5929..1bde06bdb43c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/VarargParameterInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/VarargParameterInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,23 +35,27 @@ import java.util.Collection; public class VarargParameterInspection extends BaseInspection { + @Override @NotNull public String getID(){ return "VariableArgumentMethod"; } + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "variable.argument.method.display.name"); } + @Override @NotNull public String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "variable.argument.method.problem.descriptor"); } + @Override @Nullable protected InspectionGadgetsFix buildFix(Object... infos) { return new VarargParameterFix(); @@ -65,6 +69,7 @@ public class VarargParameterInspection extends BaseInspection { "variable.argument.method.quickfix"); } + @Override protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement element = descriptor.getPsiElement(); @@ -121,8 +126,9 @@ public class VarargParameterInspection extends BaseInspection { } } builder.append('}'); - final PsiManager manager = referenceExpression.getManager(); - final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + final Project project = referenceExpression.getProject(); + final PsiElementFactory factory = + JavaPsiFacade.getElementFactory(project); final PsiExpression arrayExpression = factory.createExpressionFromText(builder.toString(), referenceExpression); @@ -136,12 +142,15 @@ public class VarargParameterInspection extends BaseInspection { argumentList.add(arrayExpression); } final CodeStyleManager codeStyleManager = - manager.getCodeStyleManager(); - JavaCodeStyleManager.getInstance(manager.getProject()).shortenClassReferences(argumentList); + CodeStyleManager.getInstance(project); + final JavaCodeStyleManager javaCodeStyleManager = + JavaCodeStyleManager.getInstance(project); + javaCodeStyleManager.shortenClassReferences(argumentList); codeStyleManager.reformat(argumentList); } } + @Override public BaseInspectionVisitor buildVisitor() { return new VarargParameterVisitor(); } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk15/ForCanBeForeachInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk15/ForCanBeForeachInspection.java index 4add13d05f19..f8f3b37f7a87 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk15/ForCanBeForeachInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk15/ForCanBeForeachInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1066,7 +1066,7 @@ public class ForCanBeForeachInspection extends BaseInspection{ if(declaredClass == null){ return false; } - if(!ClassUtils.isSubclass(declaredClass, + if(!InheritanceUtil.isInheritor(declaredClass, CommonClassNames.JAVA_UTIL_ITERATOR)){ return false; } @@ -1107,9 +1107,9 @@ public class ForCanBeForeachInspection extends BaseInspection{ if(qualifierClass == null){ return false; } - if(!ClassUtils.isSubclass(qualifierClass, + if(!InheritanceUtil.isInheritor(qualifierClass, CommonClassNames.JAVA_LANG_ITERABLE) && - !ClassUtils.isSubclass(qualifierClass, + !InheritanceUtil.isInheritor(qualifierClass, CommonClassNames.JAVA_UTIL_COLLECTION)){ return false; } @@ -1288,7 +1288,8 @@ public class ForCanBeForeachInspection extends BaseInspection{ return false; } final PsiClass aClass = method.getContainingClass(); - return ClassUtils.isSubclass(aClass, CommonClassNames.JAVA_UTIL_LIST); + return InheritanceUtil.isInheritor(aClass, + CommonClassNames.JAVA_UTIL_LIST); } private static Holder getCollectionFromListMethodCall( @@ -1319,7 +1320,7 @@ public class ForCanBeForeachInspection extends BaseInspection{ return null; } final PsiClass containingClass = method.getContainingClass(); - if (!ClassUtils.isSubclass(containingClass, + if (!InheritanceUtil.isInheritor(containingClass, CommonClassNames.JAVA_UTIL_LIST)) { return null; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk15/WhileCanBeForeachInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk15/WhileCanBeForeachInspection.java index de4d5b3e6670..3472dff50aba 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk15/WhileCanBeForeachInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk15/WhileCanBeForeachInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import com.intellij.psi.*; import com.intellij.psi.codeStyle.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; @@ -31,7 +32,6 @@ import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.StringUtils; import com.siyeh.ig.psiutils.TypeUtils; import com.siyeh.ig.psiutils.VariableAccessUtils; @@ -467,9 +467,9 @@ public class WhileCanBeForeachInspection extends BaseInspection { if (qualifierClass == null) { return false; } - if (!ClassUtils.isSubclass(qualifierClass, + if (!InheritanceUtil.isInheritor(qualifierClass, CommonClassNames.JAVA_LANG_ITERABLE) && - !ClassUtils.isSubclass(qualifierClass, + !InheritanceUtil.isInheritor(qualifierClass, CommonClassNames.JAVA_UTIL_COLLECTION)) { return false; } @@ -586,7 +586,6 @@ public class WhileCanBeForeachInspection extends BaseInspection { private final PsiVariable iterator; private NumCallsToIteratorNextVisitor(PsiVariable iterator) { - super(); this.iterator = iterator; } @@ -626,7 +625,6 @@ public class WhileCanBeForeachInspection extends BaseInspection { private final PsiVariable iterator; private IteratorRemoveVisitor(@NotNull PsiVariable iterator) { - super(); this.iterator = iterator; } @@ -670,7 +668,6 @@ public class WhileCanBeForeachInspection extends BaseInspection { private final PsiVariable iterator; private IteratorHasNextVisitor(PsiVariable iterator) { - super(); this.iterator = iterator; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/AssertEqualsBetweenInconvertibleTypesInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/AssertEqualsBetweenInconvertibleTypesInspection.java index 808e63ceceb5..bab32cc29680 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/AssertEqualsBetweenInconvertibleTypesInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/AssertEqualsBetweenInconvertibleTypesInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2007-2010 Bas Leijdekkers + * Copyright 2007-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,14 +15,14 @@ */ package com.siyeh.ig.junit; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.TypeConversionUtil; -import com.intellij.openapi.util.text.StringUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -77,8 +77,10 @@ public class AssertEqualsBetweenInconvertibleTypesInspection return; } final PsiClass containingClass = method.getContainingClass(); - if (!ClassUtils.isSubclass(containingClass, "junit.framework.Assert") && - !ClassUtils.isSubclass(containingClass, "org.junit.Assert")) { + if (!InheritanceUtil.isInheritor(containingClass, + "junit.framework.Assert") && + !InheritanceUtil.isInheritor(containingClass, + "org.junit.Assert")) { return; } final PsiParameterList parameterList = method.getParameterList(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/AssertsWithoutMessagesInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/AssertsWithoutMessagesInspection.java index 2249f0dede0e..1e2398cd9170 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/AssertsWithoutMessagesInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/AssertsWithoutMessagesInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,10 +18,10 @@ package com.siyeh.ig.junit; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -30,23 +30,27 @@ import java.util.Set; public class AssertsWithoutMessagesInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "asserts.without.messages.display.name"); } + @Override @NotNull public String getID() { return "MessageMissingOnJUnitAssertion"; } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "asserts.without.messages.problem.descriptor"); } + @Override public BaseInspectionVisitor buildVisitor() { return new AssertionsWithoutMessagesVisitor(); } @@ -123,9 +127,10 @@ public class AssertsWithoutMessagesInspection extends BaseInspection { return false; } final PsiClass targetClass = method.getContainingClass(); - return targetClass != null && - (ClassUtils.isSubclass(targetClass, "junit.framework.Assert") || - ClassUtils.isSubclass(targetClass, "org.junit.Assert")); + return InheritanceUtil.isInheritor(targetClass, + "junit.framework.Assert") || + InheritanceUtil.isInheritor(targetClass, + "org.junit.Assert"); } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/ConstantJUnitAssertArgumentInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/ConstantJUnitAssertArgumentInspection.java index 9d48846b082a..19eb4d8e936e 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/ConstantJUnitAssertArgumentInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/ConstantJUnitAssertArgumentInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2009 Bas Leijdekkers + * Copyright 2009-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,20 +15,22 @@ */ package com.siyeh.ig.junit; +import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiUtil; +import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; -import com.intellij.psi.*; -import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; -import java.util.Set; import java.util.HashSet; +import java.util.Set; public class ConstantJUnitAssertArgumentInspection extends BaseInspection { + @NonNls private static final Set ASSERT_METHODS = new HashSet(); static { @@ -42,21 +44,23 @@ public class ConstantJUnitAssertArgumentInspection extends BaseInspection { @Nls @NotNull public String getDisplayName() { - return "Constant JUnit assert argument"; + return InspectionGadgetsBundle.message( + "constant.junit.assert.argument.display.name"); } @Override @NotNull protected String buildErrorString(Object... infos) { - return "Argument #ref is constant"; + return InspectionGadgetsBundle.message( + "constant.junit.assert.argument.problem.descriptor"); } @Override public BaseInspectionVisitor buildVisitor() { - return new ConstantJUnitAssertArugmentVisitor(); + return new ConstantJUnitAssertArgumentVisitor(); } - private static class ConstantJUnitAssertArugmentVisitor + private static class ConstantJUnitAssertArgumentVisitor extends BaseInspectionVisitor { @Override @@ -74,8 +78,10 @@ public class ConstantJUnitAssertArgumentInspection extends BaseInspection { return; } final PsiClass containingClass = method.getContainingClass(); - if (!ClassUtils.isSubclass(containingClass, "junit.framework.Assert") && - !ClassUtils.isSubclass(containingClass, "org.junit.Assert")) { + if (!InheritanceUtil.isInheritor(containingClass, + "junit.framework.Assert") && + !InheritanceUtil.isInheritor(containingClass, + "org.junit.Assert")) { return; } final PsiExpressionList argumentList = expression.getArgumentList(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/ExpectedExceptionNeverThrownInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/ExpectedExceptionNeverThrownInspection.java index 9e4a87d1a1c6..fc370c35a49e 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/ExpectedExceptionNeverThrownInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/ExpectedExceptionNeverThrownInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2010 Bas Leijdekkers + * Copyright 2010-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ package com.siyeh.ig.junit; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.ExceptionUtils; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -89,7 +89,7 @@ public class ExpectedExceptionNeverThrownInspection } final PsiClassType classType = (PsiClassType) type; final PsiClass aClass = classType.resolve(); - if (ClassUtils.isSubclass(aClass, + if (InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnitAbstractTestClassNamingConventionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnitAbstractTestClassNamingConventionInspection.java index 0837e6773b75..502b44a68634 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnitAbstractTestClassNamingConventionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnitAbstractTestClassNamingConventionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,12 @@ package com.siyeh.ig.junit; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiTypeParameter; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.RenameFix; import com.siyeh.ig.naming.ConventionInspection; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NotNull; public class JUnitAbstractTestClassNamingConventionInspection @@ -32,47 +32,55 @@ public class JUnitAbstractTestClassNamingConventionInspection private static final int DEFAULT_MIN_LENGTH = 12; private static final int DEFAULT_MAX_LENGTH = 64; + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( - "j.unit.abstract.test.class.naming.convention.display.name"); + "junit.abstract.test.class.naming.convention.display.name"); } + @Override protected InspectionGadgetsFix buildFix(Object... infos) { return new RenameFix(); } + @Override protected boolean buildQuickFixesOnlyForOnTheFlyErrors() { return true; } + @Override @NotNull public String buildErrorString(Object... infos) { final String className = (String)infos[0]; if (className.length() < getMinLength()) { return InspectionGadgetsBundle.message( - "j.unit.abstract.test.class.naming.convention.problem.descriptor.short"); + "junit.abstract.test.class.naming.convention.problem.descriptor.short"); } else if (className.length() > getMaxLength()) { return InspectionGadgetsBundle.message( - "j.unit.abstract.test.class.naming.convention.problem.descriptor.long"); + "junit.abstract.test.class.naming.convention.problem.descriptor.long"); } return InspectionGadgetsBundle.message( - "j.unit.abstract.test.class.naming.convention.problem.descriptor.regex.mismatch", + "junit.abstract.test.class.naming.convention.problem.descriptor.regex.mismatch", getRegex()); } + @Override protected String getDefaultRegex() { return "[A-Z][A-Za-z\\d]*TestCase"; } + @Override protected int getDefaultMinLength() { return DEFAULT_MIN_LENGTH; } + @Override protected int getDefaultMaxLength() { return DEFAULT_MAX_LENGTH; } + @Override public BaseInspectionVisitor buildVisitor() { return new NamingConventionsVisitor(); } @@ -90,7 +98,8 @@ public class JUnitAbstractTestClassNamingConventionInspection if(!aClass.hasModifierProperty(PsiModifier.ABSTRACT)) { return; } - if(!ClassUtils.isSubclass(aClass, "junit.framework.TestCase")) { + if(!InheritanceUtil.isInheritor(aClass, + "junit.framework.TestCase")) { return; } final String name = aClass.getName(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnitTestClassNamingConventionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnitTestClassNamingConventionInspection.java index fc84b0dc47ae..31131daaef03 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnitTestClassNamingConventionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnitTestClassNamingConventionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,12 +19,12 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiTypeParameter; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.RenameFix; import com.siyeh.ig.naming.ConventionInspection; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.TestUtils; import org.jetbrains.annotations.NotNull; @@ -38,7 +38,7 @@ public class JUnitTestClassNamingConventionInspection @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( - "j.unit.test.class.naming.convention.display.name"); + "junit.test.class.naming.convention.display.name"); } @Override @@ -57,13 +57,13 @@ public class JUnitTestClassNamingConventionInspection final String className = (String)infos[0]; if (className.length() < getMinLength()) { return InspectionGadgetsBundle.message( - "j.unit.test.class.naming.convention.problem.descriptor.short"); + "junit.test.class.naming.convention.problem.descriptor.short"); } else if (className.length() > getMaxLength()) { return InspectionGadgetsBundle.message( - "j.unit.test.class.naming.convention.problem.descriptor.long"); + "junit.test.class.naming.convention.problem.descriptor.long"); } return InspectionGadgetsBundle.message( - "j.unit.test.class.naming.convention.problem.descriptor.regex.mismatch", + "junit.test.class.naming.convention.problem.descriptor.regex.mismatch", getRegex()); } @@ -100,7 +100,8 @@ public class JUnitTestClassNamingConventionInspection if(aClass.hasModifierProperty(PsiModifier.ABSTRACT)) { return; } - if(!ClassUtils.isSubclass(aClass, "junit.framework.TestCase")) { + if(!InheritanceUtil.isInheritor(aClass, + "junit.framework.TestCase")) { if (!hasJUnit4TestMethods(aClass)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/MisorderedAssertEqualsParametersInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/MisorderedAssertEqualsParametersInspection.java index 3cdc336c67c0..34efb304e567 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/MisorderedAssertEqualsParametersInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/MisorderedAssertEqualsParametersInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,30 +19,33 @@ import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class MisorderedAssertEqualsParametersInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "misordered.assert.equals.parameters.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "misordered.assert.equals.parameters.problem.descriptor"); } + @Override public InspectionGadgetsFix buildFix(Object... infos) { return new FlipParametersFix(); } @@ -55,6 +58,7 @@ public class MisorderedAssertEqualsParametersInspection "misordered.assert.equals.parameters.flip.quickfix"); } + @Override public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement methodNameIdentifier = descriptor.getPsiElement(); @@ -95,6 +99,7 @@ public class MisorderedAssertEqualsParametersInspection } } + @Override public BaseInspectionVisitor buildVisitor() { return new MisorderedAssertEqualsParametersVisitor(); } @@ -167,8 +172,8 @@ public class MisorderedAssertEqualsParametersInspection return false; } final PsiField field = (PsiField) target; - return !(!field.hasModifierProperty(PsiModifier.STATIC) || - !field.hasModifierProperty(PsiModifier.FINAL)); + return field.hasModifierProperty(PsiModifier.STATIC) && + field.hasModifierProperty(PsiModifier.FINAL); } private static boolean isAssertEquals( @@ -185,11 +190,10 @@ public class MisorderedAssertEqualsParametersInspection return false; } final PsiClass targetClass = method.getContainingClass(); - if (targetClass == null) { - return false; - } - return ClassUtils.isSubclass(targetClass, "junit.framework.Assert") - || ClassUtils.isSubclass(targetClass, "org.junit.Assert"); + return InheritanceUtil.isInheritor(targetClass, + "junit.framework.Assert") || + InheritanceUtil.isInheritor(targetClass, + "org.junit.Assert"); } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/MisspelledSetUpInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/MisspelledSetUpInspection.java index d49baa10a2ae..9383be30dff0 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/MisspelledSetUpInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/MisspelledSetUpInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,37 +17,42 @@ package com.siyeh.ig.junit; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.RenameFix; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class MisspelledSetUpInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "misspelled.set.up.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "misspelled.set.up.problem.descriptor"); } + @Override protected InspectionGadgetsFix buildFix(Object... infos) { return new RenameFix("setUp"); } + @Override public BaseInspectionVisitor buildVisitor() { return new MisspelledSetUpVisitor(); } + @Override protected boolean buildQuickFixesOnlyForOnTheFlyErrors() { return true; } @@ -64,7 +69,8 @@ public class MisspelledSetUpInspection extends BaseInspection { if (aClass == null) { return; } - if (!ClassUtils.isSubclass(aClass, "junit.framework.TestCase")) { + if (!InheritanceUtil.isInheritor(aClass, + "junit.framework.TestCase")) { return; } registerMethodError(method); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/MisspelledTearDownInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/MisspelledTearDownInspection.java index 9e8b5da63f9e..97a556b12d60 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/MisspelledTearDownInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/MisspelledTearDownInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,37 +17,42 @@ package com.siyeh.ig.junit; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.RenameFix; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class MisspelledTearDownInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "misspelled.tear.down.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "misspelled.tear.down.problem.descriptor"); } + @Override protected InspectionGadgetsFix buildFix(Object... infos) { return new RenameFix("tearDown"); } + @Override public BaseInspectionVisitor buildVisitor() { return new MisspelledSetUpVisitor(); } + @Override protected boolean buildQuickFixesOnlyForOnTheFlyErrors() { return true; } @@ -64,7 +69,8 @@ public class MisspelledTearDownInspection extends BaseInspection { if (aClass == null) { return; } - if (!ClassUtils.isSubclass(aClass, "junit.framework.TestCase")) { + if (!InheritanceUtil.isInheritor(aClass, + "junit.framework.TestCase")) { return; } registerMethodError(method); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/SetupCallsSuperSetupInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/SetupCallsSuperSetupInspection.java index 6fdcf5f74067..5bdbb661369c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/SetupCallsSuperSetupInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/SetupCallsSuperSetupInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,28 +19,31 @@ import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class SetupCallsSuperSetupInspection extends BaseInspection { + @Override @NotNull public String getID() { return "SetUpDoesntCallSuperSetUp"; } + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "setup.calls.super.setup.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( @@ -55,6 +58,7 @@ public class SetupCallsSuperSetupInspection extends BaseInspection { "setup.calls.super.setup.add.quickfix"); } + @Override public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement methodName = descriptor.getPsiElement(); @@ -64,22 +68,24 @@ public class SetupCallsSuperSetupInspection extends BaseInspection { if (body == null) { return; } - final PsiManager psiManager = PsiManager.getInstance(project); - final PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory(); + final PsiElementFactory factory = + JavaPsiFacade.getElementFactory(project); final PsiStatement newStatement = factory.createStatementFromText("super.setUp();", null); final CodeStyleManager styleManager = - psiManager.getCodeStyleManager(); + CodeStyleManager.getInstance(project); final PsiJavaToken brace = body.getLBrace(); body.addAfter(newStatement, brace); styleManager.reformat(body); } } + @Override protected InspectionGadgetsFix buildFix(Object... infos) { return new AddSuperSetUpCall(); } + @Override public BaseInspectionVisitor buildVisitor() { return new SetupCallsSuperSetupVisitor(); } @@ -107,7 +113,7 @@ public class SetupCallsSuperSetupInspection extends BaseInspection { if (targetClass == null) { return; } - if (!ClassUtils.isSubclass(targetClass, + if (!InheritanceUtil.isInheritor(targetClass, "junit.framework.TestCase")) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/SetupIsPublicVoidNoArgInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/SetupIsPublicVoidNoArgInspection.java index fffe3808727d..9526e3cb5d59 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/SetupIsPublicVoidNoArgInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/SetupIsPublicVoidNoArgInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,32 +16,36 @@ package com.siyeh.ig.junit; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class SetupIsPublicVoidNoArgInspection extends BaseInspection { + @Override @NotNull public String getID() { return "SetUpWithIncorrectSignature"; } + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "setup.is.public.void.no.arg.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "setup.is.public.void.no.arg.problem.descriptor"); } + @Override public BaseInspectionVisitor buildVisitor() { return new SetupIsPublicVoidNoArgVisitor(); } @@ -63,16 +67,14 @@ public class SetupIsPublicVoidNoArgInspection extends BaseInspection { if (targetClass == null) { return; } - if (!ClassUtils.isSubclass(targetClass, + if (!InheritanceUtil.isInheritor(targetClass, "junit.framework.TestCase")) { return; } final PsiParameterList parameterList = method.getParameterList(); - if (parameterList.getParametersCount() != 0) { - registerMethodError(method); - } else if (!returnType.equals(PsiType.VOID)) { - registerMethodError(method); - } else if (!method.hasModifierProperty(PsiModifier.PUBLIC) && + if (parameterList.getParametersCount() != 0 || + !returnType.equals(PsiType.VOID) || + !method.hasModifierProperty(PsiModifier.PUBLIC) && !method.hasModifierProperty(PsiModifier.PROTECTED)) { registerMethodError(method); } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/SimplifiableJUnitAssertionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/SimplifiableJUnitAssertionInspection.java index 71ce06fe07a8..1feb199cc7d7 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/SimplifiableJUnitAssertionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/SimplifiableJUnitAssertionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection { @NotNull public String getName() { return InspectionGadgetsBundle.message( - "simplify.j.unit.assertion.simplify.quickfix"); + "simplify.junit.assertion.simplify.quickfix"); } @Override @@ -163,7 +163,8 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection { return; } @NonNls final StringBuilder newExpression = new StringBuilder(); - addStaticImportIfPossible(callExpression, "assertEquals", newExpression); + addStaticImportIfPossible(callExpression, "assertEquals", + newExpression); newExpression.append("assertEquals("); if (message != null) { newExpression.append(message.getText()); @@ -222,9 +223,11 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection { @NonNls final StringBuilder newExpression = new StringBuilder(); final PsiReferenceExpression methodExpression = callExpression.getMethodExpression(); - final String methodName = methodExpression.getReferenceName(); - final String memberName; - if ("assertFalse".equals(methodName) ^ tokenType.equals(JavaTokenType.NE)) { + @NonNls final String methodName = + methodExpression.getReferenceName(); + @NonNls final String memberName; + if ("assertFalse".equals(methodName) ^ + tokenType.equals(JavaTokenType.NE)) { memberName = "assertNotNull"; } else { memberName = "assertNull"; @@ -286,8 +289,9 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection { @NonNls final StringBuilder newExpression = new StringBuilder(); final PsiReferenceExpression methodExpression = callExpression.getMethodExpression(); - final String methodName = methodExpression.getReferenceName(); - final String memberName; + @NonNls final String methodName = + methodExpression.getReferenceName(); + @NonNls final String memberName; if ("assertFalse".equals(methodName) ^ tokenType.equals(JavaTokenType.NE)) { memberName = "assertNotSame"; @@ -338,8 +342,10 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection { secondTestPosition = 1; message = null; } - final PsiExpression firstTestArgument = arguments[firstTestPosition]; - final PsiExpression secondTestArgument = arguments[secondTestPosition]; + final PsiExpression firstTestArgument = + arguments[firstTestPosition]; + final PsiExpression secondTestArgument = + arguments[secondTestPosition]; final String literalValue; final String compareValue; if (isSimpleLiteral(firstTestArgument, secondTestArgument)) { @@ -353,7 +359,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection { Character.toUpperCase(literalValue.charAt(0)) + literalValue.substring(1); @NonNls final StringBuilder newExpression = new StringBuilder(); - final String methodName = "assert" + uppercaseLiteralValue; + @NonNls final String methodName = "assert" + uppercaseLiteralValue; addStaticImportIfPossible(callExpression, methodName, newExpression); newExpression.append(methodName); newExpression.append('('); @@ -367,8 +373,9 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection { newExpression.toString()); } - private static void addStaticImportIfPossible(PsiMethodCallExpression context, - String memberName, StringBuilder out) { + private static void addStaticImportIfPossible( + PsiMethodCallExpression context, @NonNls String memberName, + @NonNls StringBuilder out) { final PsiMethod containingMethod = PsiTreeUtil.getParentOfType( context, PsiMethod.class); if (TestUtils.isJUnit4TestMethod(containingMethod)) { @@ -470,7 +477,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection { (PsiBinaryExpression) argument; final IElementType tokenType = binaryExpression.getOperationTokenType(); - return tokenType == JavaTokenType.EQEQ; + return JavaTokenType.EQEQ.equals(tokenType); } } @@ -768,7 +775,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection { private static boolean isAssertMethodCall( @NotNull PsiMethodCallExpression expression, - @NotNull String assertMethodName) { + @NonNls @NotNull String assertMethodName) { final PsiReferenceExpression methodExpression = expression.getMethodExpression(); @NonNls final String methodName = methodExpression.getReferenceName(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/StaticSuiteInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/StaticSuiteInspection.java index c5c888851988..f2c2b036d52c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/StaticSuiteInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/StaticSuiteInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,31 +19,35 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiParameterList; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class StaticSuiteInspection extends BaseInspection { + @Override @NotNull public String getID() { return "SuiteNotDeclaredStatic"; } + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message("static.suite.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "static.suite.problem.descriptor"); } + @Override public BaseInspectionVisitor buildVisitor() { return new StaticSuiteVisitor(); } @@ -60,7 +64,8 @@ public class StaticSuiteInspection extends BaseInspection { if (aClass == null) { return; } - if (!ClassUtils.isSubclass(aClass, "junit.framework.TestCase")) { + if (!InheritanceUtil.isInheritor(aClass, + "junit.framework.TestCase")) { return; } final PsiParameterList parameterList = method.getParameterList(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TeardownCallsSuperTeardownInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TeardownCallsSuperTeardownInspection.java index 5fdb4575e98a..520908a3e6d4 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TeardownCallsSuperTeardownInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TeardownCallsSuperTeardownInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,34 +19,42 @@ import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class TeardownCallsSuperTeardownInspection extends BaseInspection { + @Override @NotNull public String getID() { return "TearDownDoesntCallSuperTearDown"; } + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "teardown.calls.super.teardown.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "teardown.calls.super.teardown.problem.descriptor"); } + @Override + protected InspectionGadgetsFix buildFix(Object... infos) { + return new AddSuperTearDownCall(); + } + private static class AddSuperTearDownCall extends InspectionGadgetsFix { @NotNull @@ -54,7 +62,7 @@ public class TeardownCallsSuperTeardownInspection extends BaseInspection { return InspectionGadgetsBundle.message( "teardown.calls.super.teardown.add.quickfix"); } - + @Override public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement methodName = descriptor.getPsiElement(); @@ -66,22 +74,19 @@ public class TeardownCallsSuperTeardownInspection extends BaseInspection { if (body == null) { return; } - final PsiManager psiManager = PsiManager.getInstance(project); - final PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory(); + final PsiElementFactory factory = + JavaPsiFacade.getElementFactory(project); final PsiStatement newStatement = factory.createStatementFromText("super.tearDown();", null); final CodeStyleManager styleManager = - psiManager.getCodeStyleManager(); + CodeStyleManager.getInstance(project); final PsiJavaToken brace = body.getRBrace(); body.addBefore(newStatement, brace); styleManager.reformat(body); } } - protected InspectionGadgetsFix buildFix(Object... infos) { - return new AddSuperTearDownCall(); - } - + @Override public BaseInspectionVisitor buildVisitor() { return new TeardownCallsSuperTeardownVisitor(); } @@ -109,7 +114,7 @@ public class TeardownCallsSuperTeardownInspection extends BaseInspection { if (targetClass == null) { return; } - if (!ClassUtils.isSubclass(targetClass, + if (!InheritanceUtil.isInheritor(targetClass, "junit.framework.TestCase")) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TeardownIsPublicVoidNoArgInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TeardownIsPublicVoidNoArgInspection.java index 04f72d2dd5dd..e1939c49a48a 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TeardownIsPublicVoidNoArgInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TeardownIsPublicVoidNoArgInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,32 +16,36 @@ package com.siyeh.ig.junit; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class TeardownIsPublicVoidNoArgInspection extends BaseInspection { + @Override @NotNull public String getID() { return "TearDownWithIncorrectSignature"; } + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "teardown.is.public.void.no.arg.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "teardown.is.public.void.no.arg.problem.descriptor"); } + @Override public BaseInspectionVisitor buildVisitor() { return new TeardownIsPublicVoidNoArgVisitor(); } @@ -63,18 +67,14 @@ public class TeardownIsPublicVoidNoArgInspection extends BaseInspection { if (targetClass == null) { return; } - if (!ClassUtils.isSubclass(targetClass, + if (!InheritanceUtil.isInheritor(targetClass, "junit.framework.TestCase")) { return; } final PsiParameterList parameterList = method.getParameterList(); - if (parameterList.getParametersCount() != 0) { - registerMethodError(method); - } - else if (!returnType.equals(PsiType.VOID)) { - registerMethodError(method); - } - else if (!method.hasModifierProperty(PsiModifier.PUBLIC) && + if (parameterList.getParametersCount() != 0 || + !returnType.equals(PsiType.VOID) || + !method.hasModifierProperty(PsiModifier.PUBLIC) && !method.hasModifierProperty(PsiModifier.PROTECTED)) { registerMethodError(method); } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestCaseInProductCodeInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestCaseInProductCodeInspection.java index 3418c02921a5..874dc12f4e31 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestCaseInProductCodeInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestCaseInProductCodeInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,42 +16,48 @@ package com.siyeh.ig.junit; import com.intellij.psi.PsiClass; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.MoveClassFix; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.TestUtils; import org.jetbrains.annotations.NotNull; public class TestCaseInProductCodeInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "test.case.in.product.code.display.name"); } + @Override @NotNull public String getID() { return "JUnitTestCaseInProductSource"; } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "test.case.in.product.code.problem.descriptor"); } + @Override protected InspectionGadgetsFix buildFix(Object... infos) { return new MoveClassFix(); } + @Override protected boolean buildQuickFixesOnlyForOnTheFlyErrors() { return true; } + @Override public BaseInspectionVisitor buildVisitor() { return new TestCaseInProductCodeVisitor(); } @@ -63,7 +69,8 @@ public class TestCaseInProductCodeInspection extends BaseInspection { if (TestUtils.isTest(aClass)) { return; } - if (!ClassUtils.isSubclass(aClass, "junit.framework.TestCase")) { + if (!InheritanceUtil.isInheritor(aClass, + "junit.framework.TestCase")) { return; } registerClassError(aClass); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestCaseWithNoTestMethodsInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestCaseWithNoTestMethodsInspection.java index 9f16b6d4f3ca..74b12e135e43 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestCaseWithNoTestMethodsInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestCaseWithNoTestMethodsInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,15 @@ */ package com.siyeh.ig.junit; +import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiTypeParameter; -import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.TestUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,28 +35,36 @@ public class TestCaseWithNoTestMethodsInspection extends BaseInspection { @SuppressWarnings({"PublicField"}) public boolean ignoreSupers = false; + @Override @NotNull public String getID() { return "JUnitTestCaseWithNoTests"; } + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "test.case.with.no.test.methods.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "test.case.with.no.test.methods.problem.descriptor"); } + @Override @Nullable public JComponent createOptionsPanel() { - return new SingleCheckboxOptionsPanel("Ignore test cases which have super classes with test methods", this, "ignoreSupers"); + return new SingleCheckboxOptionsPanel( + InspectionGadgetsBundle.message( + "test.case.with.no.test.methods.option"), this, + "ignoreSupers"); } + @Override public BaseInspectionVisitor buildVisitor() { return new TestCaseWithNoTestMethodsVisitor(); } @@ -74,7 +82,8 @@ public class TestCaseWithNoTestMethodsInspection extends BaseInspection { if (aClass instanceof PsiTypeParameter) { return; } - if (!ClassUtils.isSubclass(aClass, "junit.framework.TestCase")) { + if (!InheritanceUtil.isInheritor(aClass, + "junit.framework.TestCase")) { return; } final PsiMethod[] methods = aClass.getMethods(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestMethodIsPublicVoidNoArgInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestMethodIsPublicVoidNoArgInspection.java index 2a1e669a6aa0..d7d0e27e8f13 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestMethodIsPublicVoidNoArgInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestMethodIsPublicVoidNoArgInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ package com.siyeh.ig.junit; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.TestUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -94,7 +94,7 @@ public class TestMethodIsPublicVoidNoArgInspection extends BaseInspection { final PsiClass targetClass = method.getContainingClass(); if (!AnnotationUtil.isAnnotated(method, "org.junit.Test", true)) { if (targetClass == null || - !ClassUtils.isSubclass(targetClass, + !InheritanceUtil.isInheritor(targetClass, "junit.framework.TestCase")) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestMethodWithoutAssertionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestMethodWithoutAssertionInspection.java index 34f9037f511d..aa810246d46c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestMethodWithoutAssertionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/TestMethodWithoutAssertionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,17 +16,17 @@ package com.siyeh.ig.junit; import com.intellij.codeInspection.ui.ListTable; +import com.intellij.codeInspection.ui.ListWrappingTableModel; import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.ui.ScrollPaneFactory; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.TestUtils; -import com.intellij.codeInspection.ui.ListWrappingTableModel; import com.siyeh.ig.ui.CheckBox; import com.siyeh.ig.ui.UiUtils; import org.jdom.Element; @@ -53,6 +53,7 @@ public class TestMethodWithoutAssertionInspection extends BaseInspection { private final List classNames = new ArrayList(); private Map patternCache = null; + @SuppressWarnings({"PublicField"}) public boolean assertKeywordIsAssertion = false; public TestMethodWithoutAssertionInspection() { @@ -197,8 +198,8 @@ public class TestMethodWithoutAssertionInspection extends BaseInspection { if (methodName == null) { return; } - for (int i = 0, methodNamesSize = methodNamePatterns.size(); - i < methodNamesSize; i++) { + final int methodNamesSize = methodNamePatterns.size(); + for (int i = 0; i < methodNamesSize; i++) { final String pattern = methodNamePatterns.get(i); if (!methodNamesMatch(methodName, pattern)) { continue; @@ -208,7 +209,7 @@ public class TestMethodWithoutAssertionInspection extends BaseInspection { continue; } final PsiClass aClass = method.getContainingClass(); - if (!ClassUtils.isSubclass(aClass, classNames.get(i))) { + if (!InheritanceUtil.isInheritor(aClass, classNames.get(i))) { continue; } containsAssertion = true; diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/UnconstructableTestCaseInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/UnconstructableTestCaseInspection.java index f7cd60625381..f02031dba664 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/UnconstructableTestCaseInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/UnconstructableTestCaseInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.siyeh.ig.junit; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.TypeUtils; import org.jetbrains.annotations.NotNull; @@ -62,7 +62,8 @@ public class UnconstructableTestCaseInspection extends BaseInspection { if (aClass instanceof PsiTypeParameter) { return; } - if (!ClassUtils.isSubclass(aClass, "junit.framework.TestCase")) { + if (!InheritanceUtil.isInheritor(aClass, + "junit.framework.TestCase")) { return; } final PsiMethod[] constructors = aClass.getConstructors(); @@ -81,7 +82,8 @@ public class UnconstructableTestCaseInspection extends BaseInspection { hasNoArgConstructor = true; } if (parametersCount == 1) { - final PsiParameter[] parameters = parameterList.getParameters(); + final PsiParameter[] parameters = + parameterList.getParameters(); final PsiType type = parameters[0].getType(); if (TypeUtils.typeEquals(CommonClassNames.JAVA_LANG_STRING, type)) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/naming/ExceptionNameDoesntEndWithExceptionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/naming/ExceptionNameDoesntEndWithExceptionInspection.java index 161ed2333a67..5476cd868d2a 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/naming/ExceptionNameDoesntEndWithExceptionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/naming/ExceptionNameDoesntEndWithExceptionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,12 @@ package com.siyeh.ig.naming; import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiTypeParameter; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.RenameFix; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -81,7 +81,7 @@ public class ExceptionNameDoesntEndWithExceptionInspection if (className.endsWith(exception)) { return; } - if (!ClassUtils.isSubclass(aClass, + if (!InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_EXCEPTION)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/naming/NonExceptionNameEndsWithExceptionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/naming/NonExceptionNameEndsWithExceptionInspection.java index ed0e58e1db38..c4a6a676ab90 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/naming/NonExceptionNameEndsWithExceptionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/naming/NonExceptionNameEndsWithExceptionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,13 +19,13 @@ import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.RenameFix; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -123,11 +123,12 @@ public class NonExceptionNameEndsWithExceptionInspection if (!className.endsWith(exception)) { return; } - if (ClassUtils.isSubclass(aClass, + if (InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_EXCEPTION)) { return; } - registerClassError(aClass, className, Boolean.valueOf(isOnTheFly())); + registerClassError(aClass, className, + Boolean.valueOf(isOnTheFly())); } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/InnerClassReferenceVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/InnerClassReferenceVisitor.java index 1851742e87ba..fdac6edef080 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/InnerClassReferenceVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/InnerClassReferenceVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,6 @@ public class InnerClassReferenceVisitor extends JavaRecursiveElementVisitor { private boolean referencesStaticallyAccessible = true; public InnerClassReferenceVisitor(PsiClass innerClass) { - super(); this.innerClass = innerClass; } @@ -42,14 +41,14 @@ public class InnerClassReferenceVisitor extends JavaRecursiveElementVisitor { return true; } } - if (InheritanceUtil.isCorrectDescendant(innerClass, aClass, true)) { + if (InheritanceUtil.isInheritorOrSelf(innerClass, aClass, true)) { return true; } PsiClass classScope = aClass; final PsiClass outerClass = ClassUtils.getContainingClass(innerClass); while (classScope != null) { - if (InheritanceUtil.isCorrectDescendant(outerClass, classScope, + if (InheritanceUtil.isInheritorOrSelf(outerClass, classScope, true)) { return false; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/ManualArrayToCollectionCopyInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/ManualArrayToCollectionCopyInspection.java index a05b1233ee26..040d0ecfe925 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/ManualArrayToCollectionCopyInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/ManualArrayToCollectionCopyInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2010 Bas Leijdekkers + * Copyright 2006-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,12 +19,16 @@ import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.*; +import com.siyeh.ig.psiutils.ExpressionUtils; +import com.siyeh.ig.psiutils.ParenthesesUtils; +import com.siyeh.ig.psiutils.SideEffectChecker; +import com.siyeh.ig.psiutils.VariableAccessUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -563,7 +567,7 @@ public class ManualArrayToCollectionCopyInspection extends BaseInspection { return false; } final PsiClass containingClass = method.getContainingClass(); - return ClassUtils.isSubclass(containingClass, + return InheritanceUtil.isInheritor(containingClass, CommonClassNames.JAVA_UTIL_COLLECTION); } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/MethodReferenceVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/MethodReferenceVisitor.java index fb30cf14be3f..41d751c462a4 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/MethodReferenceVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/MethodReferenceVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Dave Griffith + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ class MethodReferenceVisitor extends JavaRecursiveElementVisitor{ private final PsiMember m_method; MethodReferenceVisitor(PsiMember method){ - super(); m_method = method; } @@ -40,7 +39,8 @@ class MethodReferenceVisitor extends JavaRecursiveElementVisitor{ super.visitElement(element); } - @Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference){ + @Override public void visitReferenceElement( + PsiJavaCodeReferenceElement reference){ super.visitReferenceElement(reference); final PsiElement resolvedElement = reference.resolve(); if(!(resolvedElement instanceof PsiClass)){ @@ -77,7 +77,8 @@ class MethodReferenceVisitor extends JavaRecursiveElementVisitor{ m_referencesStaticallyAccessible = false; } - @Override public void visitThisExpression(@NotNull PsiThisExpression expression){ + @Override public void visitThisExpression( + @NotNull PsiThisExpression expression){ super.visitThisExpression(expression); m_referencesStaticallyAccessible = false; } @@ -91,7 +92,7 @@ class MethodReferenceVisitor extends JavaRecursiveElementVisitor{ } final PsiClass referenceContainingClass = m_method.getContainingClass(); final PsiClass containingClass = member.getContainingClass(); - return !InheritanceUtil.isCorrectDescendant(referenceContainingClass, + return !InheritanceUtil.isInheritorOrSelf(referenceContainingClass, containingClass, true); } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/TailRecursionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/TailRecursionInspection.java index 2ddff0d1affa..1756be7fda7c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/TailRecursionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/TailRecursionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,17 +33,20 @@ import org.jetbrains.annotations.Nullable; public class TailRecursionInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message("tail.recursion.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "tail.recursion.problem.descriptor"); } + @Override @Nullable protected InspectionGadgetsFix buildFix(Object... infos) { final PsiMethod containingMethod = (PsiMethod) infos[0]; @@ -74,6 +77,7 @@ public class TailRecursionInspection extends BaseInspection { "tail.recursion.replace.quickfix"); } + @Override public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement tailCallToken = descriptor.getPsiElement(); @@ -87,9 +91,12 @@ public class TailRecursionInspection extends BaseInspection { if (body == null) { return; } - final StringBuilder builder = new StringBuilder(); + @NonNls final StringBuilder builder = new StringBuilder(); builder.append('{'); final PsiClass containingClass = method.getContainingClass(); + if (containingClass == null) { + return; + } final String thisVariableName; final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project); @@ -121,9 +128,8 @@ public class TailRecursionInspection extends BaseInspection { tailCallIsContainedInLoop = false; } builder.append("while(true)"); - final PsiManager psiManager = PsiManager.getInstance(project); final CodeStyleManager codeStyleManager = - psiManager.getCodeStyleManager(); + CodeStyleManager.getInstance(project); replaceTailCalls(body, method, thisVariableName, tailCallIsContainedInLoop, builder); builder.append('}'); @@ -222,13 +228,8 @@ public class TailRecursionInspection extends BaseInspection { out.append('.'); } out.append(text); - } else if (element instanceof PsiThisExpression) { - if (thisVariableName == null) { - out.append(text); - } else { - out.append(thisVariableName); - } - } else if (element instanceof PsiSuperExpression) { + } else if (element instanceof PsiThisExpression || + element instanceof PsiSuperExpression) { if (thisVariableName == null) { out.append(text); } else { @@ -358,6 +359,7 @@ public class TailRecursionInspection extends BaseInspection { } } + @Override public BaseInspectionVisitor buildVisitor() { return new TailRecursionVisitor(); } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/ToArrayCallWithZeroLengthArrayArgumentInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/ToArrayCallWithZeroLengthArrayArgumentInspection.java index bbcfa234ee1c..1a5088351af8 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/ToArrayCallWithZeroLengthArrayArgumentInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/ToArrayCallWithZeroLengthArrayArgumentInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2007-2010 Bas Leijdekkers + * Copyright 2007-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,12 @@ package com.siyeh.ig.performance; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.CollectionUtils; import com.siyeh.ig.psiutils.ExpressionUtils; import org.jetbrains.annotations.Nls; @@ -135,7 +135,7 @@ public class ToArrayCallWithZeroLengthArrayArgumentInspection final PsiType componentType = type.getComponentType(); final String typeText = componentType.getCanonicalText(); @NonNls final String replacementText = - "new " + typeText + "[" + qualifierText + ".size()]"; + "new " + typeText + '[' + qualifierText + ".size()]"; return getElementText(expression, referenceExpression, replacementText); } @@ -191,7 +191,7 @@ public class ToArrayCallWithZeroLengthArrayArgumentInspection return; } final PsiClass containingClass = method.getContainingClass(); - if (!ClassUtils.isSubclass(containingClass, + if (!InheritanceUtil.isInheritor(containingClass, CommonClassNames.JAVA_UTIL_COLLECTION)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/portability/UseOfAWTPeerClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/portability/UseOfAWTPeerClassInspection.java index e4575fc777b9..08aa49f703a3 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/portability/UseOfAWTPeerClassInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/portability/UseOfAWTPeerClassInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,32 +16,35 @@ package com.siyeh.ig.portability; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NotNull; public class UseOfAWTPeerClassInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "use.of.awt.peer.class.display.name"); } + @Override @NotNull public String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "use.of.awt.peer.class.problem.descriptor"); } + @Override public BaseInspectionVisitor buildVisitor() { return new UseOfAWTPeerClassVisitor(); } - private static class UseOfAWTPeerClassVisitor extends BaseInspectionVisitor { - + private static class UseOfAWTPeerClassVisitor + extends BaseInspectionVisitor { @Override public void visitVariable(@NotNull PsiVariable variable) { super.visitVariable(variable); @@ -65,7 +68,7 @@ public class UseOfAWTPeerClassInspection extends BaseInspection { if(resolveClass instanceof PsiTypeParameter){ return; } - if(!ClassUtils.isSubclass(resolveClass, + if(!InheritanceUtil.isInheritor(resolveClass, "java.awt.peer.ComponentPeer")) { return; } @@ -97,7 +100,7 @@ public class UseOfAWTPeerClassInspection extends BaseInspection { if(resolveClass instanceof PsiTypeParameter) { return; } - if(!ClassUtils.isSubclass(resolveClass, + if(!InheritanceUtil.isInheritor(resolveClass, "java.awt.peer.ComponentPeer")) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/portability/UseOfJDBCDriverClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/portability/UseOfJDBCDriverClassInspection.java index b26ece8ae58a..9fd737a56b35 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/portability/UseOfJDBCDriverClassInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/portability/UseOfJDBCDriverClassInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,26 +16,29 @@ package com.siyeh.ig.portability; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NotNull; public class UseOfJDBCDriverClassInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "use.of.concrete.jdbc.driver.class.display.name"); } + @Override @NotNull public String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "use.of.concrete.jdbc.driver.class.problem.descriptor"); } + @Override public BaseInspectionVisitor buildVisitor() { return new UseOfJDBCDriverClassVisitor(); } @@ -65,7 +68,7 @@ public class UseOfJDBCDriverClassInspection extends BaseInspection { if(resolveClass instanceof PsiTypeParameter){ return; } - if(!ClassUtils.isSubclass(resolveClass, "java.sql.Driver")) { + if(!InheritanceUtil.isInheritor(resolveClass, "java.sql.Driver")) { return; } final PsiTypeElement typeElement = variable.getTypeElement(); @@ -96,7 +99,7 @@ public class UseOfJDBCDriverClassInspection extends BaseInspection { if(resolveClass instanceof PsiTypeParameter){ return; } - if(!ClassUtils.isSubclass(resolveClass, "java.sql.Driver")) { + if(!InheritanceUtil.isInheritor(resolveClass, "java.sql.Driver")) { return; } registerNewExpressionError(newExpression); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ClassUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ClassUtils.java index 751b5b4c6cb2..1898696cb975 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ClassUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ClassUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,11 @@ */ package com.siyeh.ig.psiutils; -import com.intellij.openapi.project.Project; import com.intellij.psi.*; -import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ClassInheritorsSearch; -import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.Query; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; import java.util.HashSet; @@ -81,19 +77,6 @@ public class ClassUtils { private ClassUtils() { } - public static boolean isSubclass(@Nullable PsiClass aClass, - @NonNls String ancestorName) { - if (aClass == null) { - return false; - } - final PsiManager psiManager = aClass.getManager(); - final Project project = psiManager.getProject(); - final GlobalSearchScope scope = GlobalSearchScope.allScope(project); - final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); - final PsiClass ancestorClass = psiFacade.findClass(ancestorName, scope); - return InheritanceUtil.isCorrectDescendant(aClass, ancestorClass, true); - } - public static boolean isPrimitive(PsiType type) { return TypeConversionUtil.isPrimitiveAndNotNull(type); } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/CloneUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/CloneUtils.java index 3d7a244d43d6..552af71556ef 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/CloneUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/CloneUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,18 +16,17 @@ package com.siyeh.ig.psiutils; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiUtil; import com.siyeh.HardcodedMethodConstants; import org.jetbrains.annotations.NotNull; public class CloneUtils{ - private CloneUtils(){ - super(); - } + private CloneUtils(){} public static boolean isCloneable(@NotNull PsiClass aClass){ - return ClassUtils.isSubclass(aClass, + return InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_CLONEABLE); } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ImportUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ImportUtils.java index 5eeeac20ebb8..c05ffab36204 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ImportUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ImportUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,10 +30,9 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -public class ImportUtils{ +public class ImportUtils { - private ImportUtils(){ - } + private ImportUtils() {} public static void addImportIfNeeded(PsiJavaFile file, PsiClass aClass) { final PsiFile containingFile = aClass.getContainingFile(); @@ -78,7 +77,7 @@ public class ImportUtils{ if (containingClass == null) { return false; } - if (ClassUtils.isSubclass(containingClass, fqName)) { + if (InheritanceUtil.isInheritor(containingClass, fqName)) { return true; } final PsiField field = @@ -424,7 +423,7 @@ public class ImportUtils{ throws IncorrectOperationException { final PsiClass containingClass = PsiTreeUtil.getParentOfType(context, PsiClass.class); - if (ClassUtils.isSubclass(containingClass, qualifierClass)) { + if (InheritanceUtil.isInheritor(containingClass, qualifierClass)) { return; } final PsiFile psiFile = context.getContainingFile(); @@ -524,7 +523,7 @@ public class ImportUtils{ } final PsiClass containingClass = PsiTreeUtil.getParentOfType(context, PsiClass.class); - if (InheritanceUtil.isCorrectDescendant(containingClass, memberClass, + if (InheritanceUtil.isInheritorOrSelf(containingClass, memberClass, true)) { return false; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/IteratorUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/IteratorUtils.java index 2be1ad75404d..7ca1cf7bfec9 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/IteratorUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/IteratorUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Bas Leijdekkers + * Copyright 2003-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,10 +55,6 @@ public class IteratorUtils { CommonClassNames.JAVA_UTIL_ITERATOR, PsiType.BOOLEAN, "hasNext"); } - public static boolean isIterator(PsiClass aClass) { - return ClassUtils.isSubclass(aClass, CommonClassNames.JAVA_UTIL_ITERATOR); - } - private static class CallsIteratorNextVisitor extends JavaRecursiveElementVisitor { @@ -91,7 +87,8 @@ public class IteratorUtils { super.visitMethodCallExpression(expression); if (checkScanner) { if (!MethodCallUtils.isCallToMethod(expression, - CommonClassNames.JAVA_UTIL_ITERATOR, null, SCANNER_PATTERN)) { + CommonClassNames.JAVA_UTIL_ITERATOR, null, + SCANNER_PATTERN)) { return; } } else { @@ -119,7 +116,7 @@ public class IteratorUtils { final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) qualifier; final PsiElement element = referenceExpression.resolve(); - if (target != element) { + if (!target.equals(element)) { return; } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/MethodUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/MethodUtils.java index 8dc1f47c8ed4..1ce3326f6f22 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/MethodUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/MethodUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -130,7 +130,8 @@ public class MethodUtils{ } if (containingClassName != null) { final PsiClass containingClass = method.getContainingClass(); - return ClassUtils.isSubclass(containingClass, containingClassName); + return InheritanceUtil.isInheritor(containingClass, + containingClassName); } return true; } @@ -186,7 +187,8 @@ public class MethodUtils{ } if (containingClassName != null) { final PsiClass containingClass = method.getContainingClass(); - return ClassUtils.isSubclass(containingClass, containingClassName); + return InheritanceUtil.isInheritor(containingClass, + containingClassName); } return true; } @@ -335,7 +337,7 @@ public class MethodUtils{ } final PsiClass fieldContainingClass = field.getContainingClass(); final PsiClass methodContainingClass = method.getContainingClass(); - if (InheritanceUtil.isCorrectDescendant(methodContainingClass, + if (InheritanceUtil.isInheritorOrSelf(methodContainingClass, fieldContainingClass, true)) { return field; } else { @@ -408,7 +410,7 @@ public class MethodUtils{ final PsiField field = (PsiField) referent; final PsiClass fieldContainingClass = field.getContainingClass(); final PsiClass methodContainingClass = method.getContainingClass(); - if(!InheritanceUtil.isCorrectDescendant(methodContainingClass, + if(!InheritanceUtil.isInheritorOrSelf(methodContainingClass, fieldContainingClass, true)){ return null; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/SerializationUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/SerializationUtils.java index 24f804d6fa41..a79afaae9967 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/SerializationUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/SerializationUtils.java @@ -18,6 +18,7 @@ package com.siyeh.ig.psiutils; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.InheritanceUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,12 +27,12 @@ public class SerializationUtils { private SerializationUtils() {} public static boolean isSerializable(@Nullable PsiClass aClass) { - return ClassUtils.isSubclass(aClass, + return InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_IO_SERIALIZABLE); } public static boolean isExternalizable(@Nullable PsiClass aClass) { - return ClassUtils.isSubclass(aClass, + return InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_IO_EXTERNALIZABLE); } @@ -56,7 +57,8 @@ public class SerializationUtils { } public static boolean hasReadObject(@NotNull PsiClass aClass) { - final PsiMethod[] methods = aClass.findMethodsByName("readObject", false); + final PsiMethod[] methods = + aClass.findMethodsByName("readObject", false); for (final PsiMethod method : methods) { if (isReadObject(method)) { return true; @@ -130,9 +132,9 @@ public class SerializationUtils { if (isExternalizable(psiClass)) { return true; } - if (ClassUtils.isSubclass(psiClass, + if (InheritanceUtil.isInheritor(psiClass, CommonClassNames.JAVA_UTIL_COLLECTION) || - ClassUtils.isSubclass(psiClass, + InheritanceUtil.isInheritor(psiClass, CommonClassNames.JAVA_UTIL_MAP)) { final PsiType[] parameters = classTYpe.getParameters(); for (PsiType parameter : parameters) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/TestUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/TestUtils.java index da09ad52e032..4276b02dcaa3 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/TestUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/TestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,16 +21,15 @@ import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; -import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.*; +import com.intellij.psi.util.InheritanceUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class TestUtils { - private TestUtils() { - super(); - } + private TestUtils() {} public static boolean isTest(@Nullable PsiClass aClass) { if (aClass == null) { @@ -104,6 +103,7 @@ public class TestUtils { public static boolean isJUnitTestClass(@Nullable PsiClass targetClass){ return targetClass != null && - ClassUtils.isSubclass(targetClass, "junit.framework.TestCase"); + InheritanceUtil.isInheritor(targetClass, + "junit.framework.TestCase"); } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/TypeUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/TypeUtils.java index 3bf1c26e149e..989262a3fc45 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/TypeUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/TypeUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,8 @@ package com.siyeh.ig.psiutils; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.*; +import com.intellij.psi.util.InheritanceUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,7 +31,8 @@ public class TypeUtils { private TypeUtils() {} public static boolean expressionHasType( - @Nullable PsiExpression expression, @NonNls @NotNull String typeName) { + @Nullable PsiExpression expression, + @NonNls @NotNull String typeName) { if (expression == null) { return false; } @@ -79,7 +82,7 @@ public class TypeUtils { } final PsiClassType classType = (PsiClassType) type; final PsiClass aClass = classType.resolve(); - return aClass != null && ClassUtils.isSubclass(aClass, typeName); + return aClass != null && InheritanceUtil.isInheritor(aClass, typeName); } //getTypeIfOneOfOrSubtype @@ -102,7 +105,7 @@ public class TypeUtils { return null; } for (String typeName : typeNames) { - if (ClassUtils.isSubclass(aClass, typeName)) { + if (InheritanceUtil.isInheritor(aClass, typeName)) { return typeName; } } @@ -128,7 +131,7 @@ public class TypeUtils { return false; } for (String typeName : typeNames) { - if (ClassUtils.isSubclass(aClass, typeName)) { + if (InheritanceUtil.isInheritor(aClass, typeName)) { return true; } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/WeakestTypeFinder.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/WeakestTypeFinder.java index 571e45796e65..50ae091a5efd 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/WeakestTypeFinder.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/WeakestTypeFinder.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2010 Bas Leijdekkers + * Copyright 2008-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -305,9 +305,9 @@ public class WeakestTypeFinder { HardcodedMethodConstants.INDEX_OF.equals(methodName) || HardcodedMethodConstants.LAST_INDEX_OF.equals(methodName)) { final PsiClass containingClass = method.getContainingClass(); - if (ClassUtils.isSubclass(containingClass, + if (InheritanceUtil.isInheritor(containingClass, CommonClassNames.JAVA_UTIL_MAP) || - ClassUtils.isSubclass(containingClass, + InheritanceUtil.isInheritor(containingClass, CommonClassNames.JAVA_UTIL_COLLECTION)) { final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); @@ -521,9 +521,9 @@ public class WeakestTypeFinder { if (aClass == null) { return true; } - if (!ClassUtils.isSubclass(aClass, + if (!InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION) && - !ClassUtils.isSubclass(aClass, + !InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_LANG_ERROR)) { return true; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/security/CustomClassloaderInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/security/CustomClassloaderInspection.java index 4b22cdd0c2f2..4f8261e42314 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/security/CustomClassloaderInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/security/CustomClassloaderInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,34 +16,38 @@ package com.siyeh.ig.security; import com.intellij.psi.PsiClass; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NotNull; public class CustomClassloaderInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "custom.classloader.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "custom.classloader.problem.descriptor"); } + @Override public BaseInspectionVisitor buildVisitor() { return new CustomClassloaderVisitor(); } - private static class CustomClassloaderVisitor extends BaseInspectionVisitor { + private static class CustomClassloaderVisitor + extends BaseInspectionVisitor { @Override public void visitClass(@NotNull PsiClass aClass) { - if (!ClassUtils.isSubclass(aClass, "java.lang.ClassLoader")) { + if (!InheritanceUtil.isInheritor(aClass, "java.lang.ClassLoader")) { return; } if ("java.lang.ClassLoader".equals(aClass.getQualifiedName())) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/security/CustomSecurityManagerInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/security/CustomSecurityManagerInspection.java index ece9f3a26dfd..77976d22d576 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/security/CustomSecurityManagerInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/security/CustomSecurityManagerInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,26 +16,29 @@ package com.siyeh.ig.security; import com.intellij.psi.PsiClass; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NotNull; public class CustomSecurityManagerInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "custom.security.manager.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "custom.security.manager.problem.descriptor"); } + @Override public BaseInspectionVisitor buildVisitor() { return new CustomSecurityManagerVisitor(); } @@ -44,7 +47,8 @@ public class CustomSecurityManagerInspection extends BaseInspection { extends BaseInspectionVisitor { @Override public void visitClass(@NotNull PsiClass aClass) { - if (!ClassUtils.isSubclass(aClass, "java.lang.SecurityManager")) { + if (!InheritanceUtil.isInheritor(aClass, + "java.lang.SecurityManager")) { return; } if ("java.lang.SecurityManager".equals(aClass.getQualifiedName())) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/security/JDBCExecuteWithNonConstantStringInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/security/JDBCExecuteWithNonConstantStringInspection.java index 9672698927fb..0c2cae24b5c6 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/security/JDBCExecuteWithNonConstantStringInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/security/JDBCExecuteWithNonConstantStringInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ package com.siyeh.ig.security; import com.intellij.psi.*; import com.intellij.psi.util.ConstantExpressionUtil; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -82,7 +82,7 @@ public class JDBCExecuteWithNonConstantStringInspection if (aClass == null) { return; } - if (!ClassUtils.isSubclass(aClass, "java.sql.Statement")) { + if (!InheritanceUtil.isInheritor(aClass, "java.sql.Statement")) { return; } final PsiExpressionList argumentList = expression.getArgumentList(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/security/JDBCPrepareStatementWithNonConstantStringInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/security/JDBCPrepareStatementWithNonConstantStringInspection.java index 45e7be17045b..480307a66650 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/security/JDBCPrepareStatementWithNonConstantStringInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/security/JDBCPrepareStatementWithNonConstantStringInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ package com.siyeh.ig.security; import com.intellij.psi.*; import com.intellij.psi.util.ConstantExpressionUtil; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -80,7 +80,7 @@ public class JDBCPrepareStatementWithNonConstantStringInspection if (aClass == null) { return; } - if (!ClassUtils.isSubclass(aClass, "java.sql.Connection")) { + if (!InheritanceUtil.isInheritor(aClass, "java.sql.Connection")) { return; } final PsiExpressionList argumentList = expression.getArgumentList(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/security/LoadLibraryWithNonConstantStringInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/security/LoadLibraryWithNonConstantStringInspection.java index aa7d1882eb3a..5405d5ea548f 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/security/LoadLibraryWithNonConstantStringInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/security/LoadLibraryWithNonConstantStringInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ package com.siyeh.ig.security; import com.intellij.psi.*; import com.intellij.psi.util.ConstantExpressionUtil; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -66,7 +66,7 @@ public class LoadLibraryWithNonConstantStringInspection if (aClass == null) { return; } - if (!ClassUtils.isSubclass(aClass, "java.lang.System")) { + if (!InheritanceUtil.isInheritor(aClass, "java.lang.System")) { return; } final PsiExpressionList argumentList = expression.getArgumentList(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/security/UnsecureRandomNumberGenerationInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/security/UnsecureRandomNumberGenerationInspection.java index 9f46ee14edd2..bdc2eeb2f49c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/security/UnsecureRandomNumberGenerationInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/security/UnsecureRandomNumberGenerationInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,22 +16,24 @@ package com.siyeh.ig.security; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class UnsecureRandomNumberGenerationInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "unsecure.random.number.generation.display.name"); } + @Override @NotNull public String buildErrorString(Object... infos) { @NonNls final String text = ((PsiElement)infos[0]).getText(); @@ -47,6 +49,7 @@ public class UnsecureRandomNumberGenerationInspection } } + @Override public BaseInspectionVisitor buildVisitor() { return new InsecureRandomNumberGenerationVisitor(); } @@ -54,7 +57,8 @@ public class UnsecureRandomNumberGenerationInspection private static class InsecureRandomNumberGenerationVisitor extends BaseInspectionVisitor { - @Override public void visitNewExpression(@NotNull PsiNewExpression expression) { + @Override public void visitNewExpression( + @NotNull PsiNewExpression expression) { super.visitNewExpression(expression); final PsiJavaCodeReferenceElement reference = expression.getClassReference(); @@ -66,7 +70,7 @@ public class UnsecureRandomNumberGenerationInspection return; } final PsiClass aClass = (PsiClass) element; - if (!ClassUtils.isSubclass(aClass, "java.util.Random")) { + if (!InheritanceUtil.isInheritor(aClass, "java.util.Random")) { return; } final String qualifiedName = aClass.getQualifiedName(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/ComparatorNotSerializableInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/ComparatorNotSerializableInspection.java index 382f61343232..ea9174a44eaa 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/ComparatorNotSerializableInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/ComparatorNotSerializableInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2006-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,12 @@ package com.siyeh.ig.serialization; import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiAnonymousClass; import com.intellij.psi.PsiClass; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.MakeSerializableFix; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.SerializationUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -63,7 +63,7 @@ public class ComparatorNotSerializableInspection extends BaseInspection { if (aClass instanceof PsiAnonymousClass) { return; } - if (!ClassUtils.isSubclass(aClass, + if (!InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_UTIL_COMPARATOR)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInspection.java index fd11cb0eb5c4..dfecdac65843 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Bas Leijdekkers + * Copyright 2007-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,22 +15,20 @@ */ package com.siyeh.ig.serialization; +import com.intellij.codeInspection.ui.AddAction; import com.intellij.codeInspection.ui.ListTable; import com.intellij.codeInspection.ui.ListWrappingTableModel; import com.intellij.codeInspection.ui.RemoveAction; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.PsiClass; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; -import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.SerializationUtils; -import com.intellij.codeInspection.ui.AddAction; import org.jdom.Element; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JPanel; +import javax.swing.*; import java.util.ArrayList; import java.util.List; @@ -44,16 +42,19 @@ public abstract class SerializableInspection extends BaseInspection { parseString(superClassString, superClassList); } + @Override public JComponent createOptionsPanel() { final Form form = new Form(); return form.getContentPanel(); } + @Override public void readSettings(Element node) throws InvalidDataException { super.readSettings(node); parseString(superClassString, superClassList); } + @Override public void writeSettings(Element node) throws WriteExternalException { superClassString = formatString(superClassList); super.writeSettings(node); @@ -64,7 +65,7 @@ public abstract class SerializableInspection extends BaseInspection { return false; } for (String superClassName : superClassList) { - if (ClassUtils.isSubclass(aClass, superClassName)) { + if (InheritanceUtil.isInheritor(aClass, superClassName)) { return true; } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/ImplicitCallToSuperInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/ImplicitCallToSuperInspection.java index 20d592f9fbbe..80557649207e 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/ImplicitCallToSuperInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/ImplicitCallToSuperInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -81,9 +81,8 @@ public class ImplicitCallToSuperInspection extends BaseInspection { JavaPsiFacade.getElementFactory(project); final PsiStatement newStatement = factory.createStatementFromText("super();", null); - final PsiManager psiManager = PsiManager.getInstance(project); final CodeStyleManager styleManager = - psiManager.getCodeStyleManager(); + CodeStyleManager.getInstance(project); if (body == null) { return; } @@ -116,7 +115,8 @@ public class ImplicitCallToSuperInspection extends BaseInspection { final PsiClass superClass = containingClass.getSuperClass(); if (superClass != null) { final String superClassName = superClass.getQualifiedName(); - if (CommonClassNames.JAVA_LANG_OBJECT.equals(superClassName)) { + if (CommonClassNames.JAVA_LANG_OBJECT.equals( + superClassName)) { return; } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ConditionSignalInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ConditionSignalInspection.java index bd557b4f42ff..bc875905351f 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ConditionSignalInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ConditionSignalInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,37 +18,42 @@ package com.siyeh.ig.threading; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class ConditionSignalInspection extends BaseInspection { + @Override @NotNull public String getID() { return "CallToSignalInsteadOfSignalAll"; } + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message("condition.signal.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "condition.signal.problem.descriptor"); } + @Override public BaseInspectionVisitor buildVisitor() { return new ConditionSignalVisitor(); } + @Override public InspectionGadgetsFix buildFix(Object... infos) { return new ConditionSignalFix(); } @@ -61,6 +66,7 @@ public class ConditionSignalInspection extends BaseInspection { "condition.signal.replace.quickfix"); } + @Override public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement methodNameElement = descriptor.getPsiElement(); @@ -105,9 +111,8 @@ public class ConditionSignalInspection extends BaseInspection { if (containingClass == null) { return; } - if (!ClassUtils - .isSubclass(containingClass, - "java.util.concurrent.locks.Condition")) { + if (!InheritanceUtil.isInheritor(containingClass, + "java.util.concurrent.locks.Condition")) { return; } registerMethodCallError(expression); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/SleepWhileHoldingLockInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/SleepWhileHoldingLockInspection.java index 850d19a61efb..429264eadf69 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/SleepWhileHoldingLockInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/SleepWhileHoldingLockInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,28 +16,31 @@ package com.siyeh.ig.threading; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class SleepWhileHoldingLockInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "sleep.while.holding.lock.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "sleep.while.holding.lock.problem.descriptor"); } + @Override public BaseInspectionVisitor buildVisitor() { return new SleepWhileHoldingLockVisitor(); } @@ -50,7 +53,8 @@ public class SleepWhileHoldingLockInspection extends BaseInspection { super.visitMethodCallExpression(expression); final PsiReferenceExpression methodExpression = expression.getMethodExpression(); - @NonNls final String methodName = methodExpression.getReferenceName(); + @NonNls final String methodName = + methodExpression.getReferenceName(); if (!"sleep".equals(methodName)) { return; } @@ -76,7 +80,8 @@ public class SleepWhileHoldingLockInspection extends BaseInspection { } final PsiClass methodClass = method.getContainingClass(); if (methodClass == null || - !ClassUtils.isSubclass(methodClass, "java.lang.Thread")) { + !InheritanceUtil.isInheritor(methodClass, + "java.lang.Thread")) { return; } registerMethodCallError(expression); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/SynchronizedMethodInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/SynchronizedMethodInspection.java index 65d0fb982cce..1cdbb6eceea9 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/SynchronizedMethodInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/SynchronizedMethodInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,12 +36,14 @@ public class SynchronizedMethodInspection extends BaseInspection { public boolean m_includeNativeMethods = true; + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "synchronized.method.display.name"); } + @Override @NotNull public String buildErrorString(Object... infos) { final PsiMethod method = (PsiMethod)infos[0]; @@ -49,6 +51,7 @@ public class SynchronizedMethodInspection extends BaseInspection { "synchronized.method.problem.descriptor", method.getName()); } + @Override protected InspectionGadgetsFix buildFix(Object... infos) { final PsiMethod method = (PsiMethod)infos[0]; if (method.getBody() == null) { @@ -57,10 +60,12 @@ public class SynchronizedMethodInspection extends BaseInspection { return new SynchronizedMethodFix(); } + @Override public BaseInspectionVisitor buildVisitor() { return new SynchronizedMethodVisitor(); } + @Override public JComponent createOptionsPanel() { return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message( "synchronized.method.include.option"), @@ -75,6 +80,7 @@ public class SynchronizedMethodInspection extends BaseInspection { "synchronized.method.move.quickfix"); } + @Override public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement nameElement = descriptor.getPsiElement(); @@ -100,14 +106,14 @@ public class SynchronizedMethodInspection extends BaseInspection { replacementText = "{ synchronized(this){" + text.substring(1) + '}'; } - final PsiManager psiManager = PsiManager.getInstance(project); - final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory(); + final PsiElementFactory elementFactory = + JavaPsiFacade.getElementFactory(project); final PsiCodeBlock block = elementFactory.createCodeBlockFromText(replacementText, null); body.replace(block); final CodeStyleManager codeStyleManager = - psiManager.getCodeStyleManager(); + CodeStyleManager.getInstance(project); codeStyleManager.reformat(method); } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadLocalNotStaticFinalInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadLocalNotStaticFinalInspection.java index df7ed165308e..90c60113ec7b 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadLocalNotStaticFinalInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadLocalNotStaticFinalInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2009 Bas Leijdekkers + * Copyright 2009-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,12 @@ package com.siyeh.ig.threading; import com.intellij.psi.*; -import com.siyeh.InspectionGadgetsBundle;import com.siyeh.ig.BaseInspection; +import com.intellij.psi.util.InheritanceUtil; +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.MakeFieldStaticFinalFix; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -66,7 +67,7 @@ public class ThreadLocalNotStaticFinalInspection extends BaseInspection { if (aClass == null) { return; } - if (!ClassUtils.isSubclass(aClass, "java.lang.ThreadLocal")) { + if (!InheritanceUtil.isInheritor(aClass, "java.lang.ThreadLocal")) { return; } final PsiModifierList modifierList = field.getModifierList(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadRunInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadRunInspection.java index e5c2edbb5ee3..5e156a0bec18 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadRunInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadRunInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package com.siyeh.ig.threading; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.HardcodedMethodConstants; @@ -25,26 +26,29 @@ import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NotNull; public class ThreadRunInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message("thread.run.display.name"); } + @Override @NotNull public String getID() { return "CallToThreadRun"; } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message("thread.run.problem.descriptor"); } + @Override public InspectionGadgetsFix buildFix(Object... infos) { return new ThreadRunFix(); } @@ -57,6 +61,7 @@ public class ThreadRunInspection extends BaseInspection { "thread.run.replace.quickfix"); } + @Override public void doFix(@NotNull Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement methodNameIdentifier = descriptor.getPsiElement(); @@ -101,7 +106,7 @@ public class ThreadRunInspection extends BaseInspection { if (methodClass == null) { return; } - if (!ClassUtils.isSubclass(methodClass, "java.lang.Thread")) { + if (!InheritanceUtil.isInheritor(methodClass, "java.lang.Thread")) { return; } if (isInsideThreadRun(expression)) { @@ -125,7 +130,7 @@ public class ThreadRunInspection extends BaseInspection { if (methodClass == null) { return false; } - return ClassUtils.isSubclass(methodClass, "java.lang.Thread"); + return InheritanceUtil.isInheritor(methodClass, "java.lang.Thread"); } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadStartInConstructionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadStartInConstructionInspection.java index e1d0f296c0b9..bc55c7d33d94 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadStartInConstructionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadStartInConstructionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.siyeh.ig.threading; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -25,23 +26,27 @@ import org.jetbrains.annotations.NotNull; public class ThreadStartInConstructionInspection extends BaseInspection { + @Override @NotNull public String getID() { return "CallToThreadStartDuringObjectConstruction"; } + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "thread.start.in.construction.display.name"); } + @Override @NotNull public String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "thread.start.in.construction.problem.descriptor"); } + @Override public BaseInspectionVisitor buildVisitor() { return new ThreadStartInConstructionVisitor(); } @@ -83,13 +88,14 @@ public class ThreadStartInConstructionInspection extends BaseInspection { if (method == null) { return; } - final PsiParameterList parameterList = method.getParameterList(); + final PsiParameterList parameterList = + method.getParameterList(); if (parameterList.getParametersCount() != 0) { return; } final PsiClass methodClass = method.getContainingClass(); if (methodClass == null || - !ClassUtils.isSubclass(methodClass, + !InheritanceUtil.isInheritor(methodClass, "java.lang.Thread")) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadingUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadingUtils.java index de07d7af82ad..4f0e523165bb 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadingUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ThreadingUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,20 +16,19 @@ package com.siyeh.ig.threading; import com.intellij.psi.*; -import com.siyeh.ig.psiutils.ClassUtils; +import com.intellij.psi.util.InheritanceUtil; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; class ThreadingUtils { - private ThreadingUtils() { - super(); - } + private ThreadingUtils() {} public static boolean isWaitCall( @NotNull PsiMethodCallExpression expression) { final PsiReferenceExpression methodExpression = expression.getMethodExpression(); - final String methodName = methodExpression.getReferenceName(); + @NonNls final String methodName = methodExpression.getReferenceName(); if (!"wait".equals(methodName)) { return false; } @@ -62,7 +61,7 @@ class ThreadingUtils { @NotNull PsiMethodCallExpression expression) { final PsiReferenceExpression methodExpression = expression.getMethodExpression(); - final String methodName = methodExpression.getReferenceName(); + @NonNls final String methodName = methodExpression.getReferenceName(); if (!"notify".equals(methodName) && !"notifyAll".equals(methodName)) { return false; } @@ -75,7 +74,7 @@ class ThreadingUtils { @NotNull PsiMethodCallExpression expression) { final PsiReferenceExpression methodExpression = expression.getMethodExpression(); - final String methodName = methodExpression.getReferenceName(); + @NonNls final String methodName = methodExpression.getReferenceName(); if (!"signal".equals(methodName) && !"signalAll".equals(methodName)) { return false; } @@ -92,15 +91,15 @@ class ThreadingUtils { if (containingClass == null) { return false; } - return ClassUtils.isSubclass(containingClass, - "java.util.concurrent.locks.Condition"); + return InheritanceUtil.isInheritor(containingClass, + "java.util.concurrent.locks.Condition"); } public static boolean isAwaitCall( @NotNull PsiMethodCallExpression expression) { final PsiReferenceExpression methodExpression = expression.getMethodExpression(); - final String methodName = methodExpression.getReferenceName(); + @NonNls final String methodName = methodExpression.getReferenceName(); if (!"await".equals(methodName) && !"awaitUntil".equals(methodName) && !"awaitUninterruptibly".equals(methodName) @@ -115,7 +114,7 @@ class ThreadingUtils { if (containingClass == null) { return false; } - return ClassUtils.isSubclass(containingClass, - "java.util.concurrent.locks.Condition"); + return InheritanceUtil.isInheritor(containingClass, + "java.util.concurrent.locks.Condition"); } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/ui/TreeClassChooserAction.java b/plugins/InspectionGadgets/src/com/siyeh/ig/ui/TreeClassChooserAction.java deleted file mode 100644 index 7aeb1b7e8764..000000000000 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/ui/TreeClassChooserAction.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2010 Bas Leijdekkers - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.siyeh.ig.ui; - -import com.intellij.codeInspection.ui.ListTable; -import com.intellij.codeInspection.ui.ListWrappingTableModel; -import com.intellij.ide.DataManager; -import com.intellij.ide.util.ClassFilter; -import com.intellij.ide.util.TreeClassChooser; -import com.intellij.ide.util.TreeClassChooserFactory; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.DataKeys; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiClass; -import com.intellij.psi.search.GlobalSearchScope; -import com.siyeh.InspectionGadgetsBundle; -import com.siyeh.ig.psiutils.ClassUtils; -import org.jetbrains.annotations.NonNls; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; - -public class TreeClassChooserAction extends AbstractAction { - - private final ListTable table; - private final String chooserTitle; - private final String[] ancestorClasses; - - public TreeClassChooserAction(ListTable table, String chooserTitle, - @NonNls String... ancestorClasses) { - this.table = table; - this.chooserTitle = chooserTitle; - this.ancestorClasses = ancestorClasses; - putValue(NAME, InspectionGadgetsBundle.message("button.add")); - } - - public void actionPerformed(ActionEvent e) { - final DataManager dataManager = DataManager.getInstance(); - final Object source = e.getSource(); - if (!(source instanceof Component)) { - return; - } - final DataContext dataContext = - dataManager.getDataContext((Component) source); - final Project project = DataKeys.PROJECT.getData(dataContext); - if (project == null) { - return; - } - final TreeClassChooserFactory chooserFactory = - TreeClassChooserFactory.getInstance(project); - final ClassFilter filter; - if (ancestorClasses.length == 0) { - filter = ClassFilter.ALL; - } else { - filter = new ClassFilter() { - public boolean isAccepted(PsiClass aClass) { - for (String ancestorClass : ancestorClasses) { - if (ClassUtils.isSubclass(aClass, ancestorClass)) { - return true; - } - } - return false; - } - }; - } - final TreeClassChooser classChooser = - chooserFactory.createWithInnerClassesScopeChooser(chooserTitle, - GlobalSearchScope.allScope(project), filter, null); - classChooser.showDialog(); - final PsiClass selectedClass = classChooser.getSelected(); - if (selectedClass == null) { - return; - } - final String qualifiedName = selectedClass.getQualifiedName(); - final ListWrappingTableModel tableModel = table.getModel(); - final int index = tableModel.indexOf(qualifiedName, 0); - final int rowIndex; - if (index < 0) { - tableModel.addRow(qualifiedName); - rowIndex = tableModel.getRowCount() - 1; - } else { - rowIndex = index; - } - final ListSelectionModel selectionModel = - table.getSelectionModel(); - selectionModel.setSelectionInterval(rowIndex, rowIndex); - EventQueue.invokeLater(new Runnable() { - public void run() { - final Rectangle rectangle = - table.getCellRect(rowIndex, 0, true); - table.scrollRectToVisible(rectangle); - } - }); - } -} diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/ui/UiUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/ui/UiUtils.java index a5fe7c1521d5..e6f2efe99e14 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/ui/UiUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/ui/UiUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2010 Bas Leijdekkers + * Copyright 2010-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,9 +24,9 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.util.Icons; import com.siyeh.InspectionGadgetsBundle; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -251,7 +251,7 @@ public class UiUtils { public boolean isAccepted(PsiClass aClass) { for (String ancestorClass : ancestorClasses) { - if (ClassUtils.isSubclass(aClass, ancestorClass)) { + if (InheritanceUtil.isInheritor(aClass, ancestorClass)) { return true; } } From 1a582e3943c64250850d2f3a51594ea6aec00ac7 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 7 Feb 2011 14:18:40 +0300 Subject: [PATCH 81/94] mem leaks in tests --- .../intellij/ui/switcher/SwitchManager.java | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/switcher/SwitchManager.java b/platform/platform-api/src/com/intellij/ui/switcher/SwitchManager.java index 4df13d60182c..703d55e3f019 100644 --- a/platform/platform-api/src/com/intellij/ui/switcher/SwitchManager.java +++ b/platform/platform-api/src/com/intellij/ui/switcher/SwitchManager.java @@ -16,6 +16,7 @@ package com.intellij.ui.switcher; import com.intellij.ide.DataManager; +import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.AnActionListener; import com.intellij.openapi.components.ProjectComponent; @@ -32,24 +33,24 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.awt.*; +import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.util.HashSet; import java.util.Set; public class SwitchManager implements ProjectComponent, KeyEventDispatcher, AnActionListener { - - private Project myProject; + private final Project myProject; private QuickAccessSettings myQa; private SwitchingSession mySession; private boolean myWaitingForAutoInitSession; - private Alarm myInitSessionAlarm = new Alarm(); + private final Alarm myInitSessionAlarm = new Alarm(); private KeyEvent myAutoInitSessionEvent; - private Set mySwitchActions = new HashSet(); + private final Set mySwitchActions = new HashSet(); - private Set myFadingWay = new HashSet(); + private final Set myFadingAway = new HashSet(); public SwitchManager(Project project, QuickAccessSettings quickAccess, ActionManager actionManager) { myProject = project; @@ -62,6 +63,14 @@ public class SwitchManager implements ProjectComponent, KeyEventDispatcher, AnAc mySwitchActions.add(actionManager.getAction(QuickAccessSettings.SWITCH_LEFT)); mySwitchActions.add(actionManager.getAction(QuickAccessSettings.SWITCH_RIGHT)); mySwitchActions.add(actionManager.getAction(QuickAccessSettings.SWITCH_APPLY)); + + KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this); + Disposer.register(project, new Disposable() { + @Override + public void dispose() { + KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(SwitchManager.this); + } + }); } public void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) { @@ -77,7 +86,7 @@ public class SwitchManager implements ProjectComponent, KeyEventDispatcher, AnAc } public boolean dispatchKeyEvent(KeyEvent e) { - if (!myQa.isEnabled()) return false; + if (!myQa.isEnabled()) return false; if (mySession != null && !mySession.isFinished()) return false; @@ -109,13 +118,15 @@ public class SwitchManager implements ProjectComponent, KeyEventDispatcher, AnAc }); } }; - if (myFadingWay.size() == 0) { + if (myFadingAway.isEmpty()) { myInitSessionAlarm.addRequest(initRunnable, Registry.intValue("actionSystem.keyGestureHoldTime")); - } else { + } + else { initRunnable.run(); } } - } else { + } + else { if (myWaitingForAutoInitSession) { cancelWaitingForAutoInit(); } @@ -147,33 +158,30 @@ public class SwitchManager implements ProjectComponent, KeyEventDispatcher, AnAc int mask = 0; for (Integer each : modifierCodes) { if (each == KeyEvent.VK_SHIFT) { - mask |= KeyEvent.SHIFT_MASK; + mask |= InputEvent.SHIFT_MASK; } if (each == KeyEvent.VK_CONTROL) { - mask |= KeyEvent.CTRL_MASK; + mask |= InputEvent.CTRL_MASK; } if (each == KeyEvent.VK_META) { - mask |= KeyEvent.META_MASK; + mask |= InputEvent.META_MASK; } if (each == KeyEvent.VK_ALT) { - mask |= KeyEvent.ALT_MASK; + mask |= InputEvent.ALT_MASK; } } return (modifiers ^ mask) == 0; } - public void initComponent() { - KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this); } public void disposeComponent() { - KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this); myQa = null; } @@ -234,7 +242,8 @@ public class SwitchManager implements ProjectComponent, KeyEventDispatcher, AnAc }); } }); - } else { + } + else { result.setDone(); } @@ -246,15 +255,14 @@ public class SwitchManager implements ProjectComponent, KeyEventDispatcher, AnAc } public boolean isSelectionWasMoved() { - if (!isSessionActive()) return false; - return mySession.isSelectionWasMoved(); + return isSessionActive() && mySession.isSelectionWasMoved(); } public void addFadingAway(SwitchingSession session) { - myFadingWay.add(session); + myFadingAway.add(session); } public void removeFadingAway(SwitchingSession session) { - myFadingWay.remove(session); + myFadingAway.remove(session); } } From 5e731d5a160d66a0369adc71bca6a52a3b64dd74 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 7 Feb 2011 14:30:04 +0300 Subject: [PATCH 82/94] wait till default project disposal --- .../src/com/intellij/openapi/project/impl/DefaultProject.java | 3 +-- platform/testFramework/src/_LastInSuiteTest.java | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/DefaultProject.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/DefaultProject.java index e9247d2823ed..05a8fa79a460 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/DefaultProject.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/DefaultProject.java @@ -19,8 +19,7 @@ package com.intellij.openapi.project.impl; * @author peter */ public class DefaultProject extends ProjectImpl { - protected DefaultProject(ProjectManagerImpl manager, String filePath, boolean isOptimiseTestLoadSpeed, - String projectName) { + protected DefaultProject(ProjectManagerImpl manager, String filePath, boolean isOptimiseTestLoadSpeed, String projectName) { super(manager, filePath, isOptimiseTestLoadSpeed, projectName); } diff --git a/platform/testFramework/src/_LastInSuiteTest.java b/platform/testFramework/src/_LastInSuiteTest.java index 13cd6b9eff84..6ef2c2afd273 100644 --- a/platform/testFramework/src/_LastInSuiteTest.java +++ b/platform/testFramework/src/_LastInSuiteTest.java @@ -37,8 +37,8 @@ public class _LastInSuiteTest extends TestCase { }.execute().throwException(); final Application application = ApplicationManager.getApplication(); - LeakHunter.checkProjectLeak(application); + // disposes default project too UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { @@ -51,6 +51,7 @@ public class _LastInSuiteTest extends TestCase { } }); + LeakHunter.checkProjectLeak(application); Disposer.assertIsEmpty(); } } From 44931b44889dd9cad9749b05292263faf111fce2 Mon Sep 17 00:00:00 2001 From: andrey zaytsev Date: Mon, 7 Feb 2011 14:00:15 +0300 Subject: [PATCH 83/94] xibs: open them as native files --- .../navigation/NavigationUtil.java | 10 +++++++- .../impl/NativeFileIconProvider.java | 3 ++- .../fileEditor/OpenFileDescriptor.java | 7 +++++- .../openapi/fileEditor/OpenFileHelper.java | 25 +++++++++++++++++++ .../src/META-INF/PlatformExtensionPoints.xml | 2 ++ 5 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileHelper.java diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java index 244616a1f111..4cf18f7cfb13 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java @@ -23,6 +23,7 @@ import com.intellij.navigation.NavigationItem; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileHelper; import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.fileEditor.impl.EditorHistoryManager; import com.intellij.openapi.ui.popup.JBPopup; @@ -89,11 +90,18 @@ public final class NavigationUtil { } public static void activateFileWithPsiElement(@NotNull PsiElement elt) { - if (!activatePsiElementIfOpen(elt)) { + boolean openAsNative = false; + if (elt instanceof PsiFile) { + VirtualFile virtualFile = ((PsiFile)elt).getVirtualFile(); + openAsNative = OpenFileHelper.openAsNative(virtualFile); + } + if (openAsNative || !activatePsiElementIfOpen(elt)) { ((NavigationItem)elt).navigate(true); } } + + private static boolean activatePsiElementIfOpen(@NotNull PsiElement elt) { if (!elt.isValid()) return false; elt = elt.getNavigationElement(); diff --git a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java index 1e2c24b65b1c..4772cf5cfccf 100644 --- a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java +++ b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java @@ -17,6 +17,7 @@ package com.intellij.openapi.fileTypes.impl; import com.intellij.ide.FileIconProvider; +import com.intellij.openapi.fileEditor.OpenFileHelper; import com.intellij.openapi.fileTypes.NativeFileType; import com.intellij.openapi.fileTypes.UnknownFileType; import com.intellij.openapi.project.Project; @@ -92,7 +93,7 @@ public class NativeFileIconProvider implements FileIconProvider { } protected boolean isNativeFileType(VirtualFile file) { - return ElementBase.isNativeFileType(file.getFileType()); + return OpenFileHelper.openAsNative(file) || ElementBase.isNativeFileType(file.getFileType()); } private static class Ext extends ComparableObject.Impl { diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java index 23ac76ea5acf..cd183e8b078d 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java +++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java @@ -119,7 +119,12 @@ public class OpenFileDescriptor implements Navigatable { FileType type = FileTypeManager.getInstance().getKnownFileTypeOrAssociate(myFile); if (type == null || !myFile.isValid()) return false; - if (type instanceof NativeFileType) { + boolean openAsNative = OpenFileHelper.openAsNative(myFile); + + if (!openAsNative) { + openAsNative = type instanceof NativeFileType; + } + if (openAsNative) { return NativeFileType.openAssociatedApplication(myFile); } diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileHelper.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileHelper.java new file mode 100644 index 000000000000..af673d55da24 --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileHelper.java @@ -0,0 +1,25 @@ +package com.intellij.openapi.fileEditor; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.vfs.VirtualFile; + +public abstract class OpenFileHelper { + + public static boolean openAsNative(VirtualFile virtualFile) { + boolean openAsNative = false; + for (OpenFileHelper h : Extensions.getExtensions(EP_NAME)) { + if (h.canHelp(virtualFile)) { + openAsNative = h.doOpenAsNative(virtualFile); + break; + } + } + return openAsNative; + } + + public static ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.openFileDescriptorHelper"); + + public abstract boolean canHelp(VirtualFile file); + + public abstract boolean doOpenAsNative(VirtualFile file); +} diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml index dcbdc60e0cb7..df18eb604e2d 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml @@ -112,4 +112,6 @@ + + From 087b10728639362c8584fa2ad3c5bcb81cdb09fe Mon Sep 17 00:00:00 2001 From: andrey zaytsev Date: Mon, 7 Feb 2011 14:33:34 +0300 Subject: [PATCH 84/94] open as native via empty interface INativeFileType --- .../com/intellij/psi/impl/ElementBase.java | 4 +-- .../navigation/NavigationUtil.java | 6 +++-- .../impl/NativeFileIconProvider.java | 5 +--- .../fileEditor/OpenFileDescriptor.java | 8 ++---- .../openapi/fileEditor/OpenFileHelper.java | 25 ------------------- .../openapi/fileTypes/INativeFileType.java | 4 +++ .../openapi/fileTypes/NativeFileType.java | 2 +- .../src/META-INF/PlatformExtensionPoints.xml | 1 - 8 files changed, 14 insertions(+), 41 deletions(-) delete mode 100644 platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileHelper.java create mode 100644 platform/platform-api/src/com/intellij/openapi/fileTypes/INativeFileType.java diff --git a/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java b/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java index d3676670a0ca..0a6439579472 100644 --- a/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java +++ b/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java @@ -19,7 +19,7 @@ package com.intellij.psi.impl; import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.fileTypes.NativeFileType; +import com.intellij.openapi.fileTypes.INativeFileType; import com.intellij.openapi.fileTypes.UnknownFileType; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.IndexNotReadyException; @@ -136,7 +136,7 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable } public static boolean isNativeFileType(FileType fileType) { - return fileType instanceof NativeFileType || fileType instanceof UnknownFileType; + return fileType instanceof INativeFileType || fileType instanceof UnknownFileType; } protected Icon getAdjustedBaseIcon(Icon icon, int flags) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java index 4cf18f7cfb13..fff8e27635a3 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java @@ -23,7 +23,6 @@ import com.intellij.navigation.NavigationItem; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.fileEditor.OpenFileHelper; import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.fileEditor.impl.EditorHistoryManager; import com.intellij.openapi.ui.popup.JBPopup; @@ -33,6 +32,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.Navigatable; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.ElementBase; import com.intellij.psi.search.PsiElementProcessor; import com.intellij.ui.components.JBList; import org.jetbrains.annotations.NotNull; @@ -93,7 +93,9 @@ public final class NavigationUtil { boolean openAsNative = false; if (elt instanceof PsiFile) { VirtualFile virtualFile = ((PsiFile)elt).getVirtualFile(); - openAsNative = OpenFileHelper.openAsNative(virtualFile); + if (virtualFile != null) { + openAsNative = ElementBase.isNativeFileType(virtualFile.getFileType()); + } } if (openAsNative || !activatePsiElementIfOpen(elt)) { ((NavigationItem)elt).navigate(true); diff --git a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java index 4772cf5cfccf..bd0627b22552 100644 --- a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java +++ b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/NativeFileIconProvider.java @@ -17,9 +17,6 @@ package com.intellij.openapi.fileTypes.impl; import com.intellij.ide.FileIconProvider; -import com.intellij.openapi.fileEditor.OpenFileHelper; -import com.intellij.openapi.fileTypes.NativeFileType; -import com.intellij.openapi.fileTypes.UnknownFileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vfs.VirtualFile; @@ -93,7 +90,7 @@ public class NativeFileIconProvider implements FileIconProvider { } protected boolean isNativeFileType(VirtualFile file) { - return OpenFileHelper.openAsNative(file) || ElementBase.isNativeFileType(file.getFileType()); + return ElementBase.isNativeFileType(file.getFileType()); } private static class Ext extends ComparableObject.Impl { diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java index cd183e8b078d..24c8ad2fb104 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java +++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java @@ -22,6 +22,7 @@ import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.editor.*; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.INativeFileType; import com.intellij.openapi.fileTypes.NativeFileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; @@ -119,12 +120,7 @@ public class OpenFileDescriptor implements Navigatable { FileType type = FileTypeManager.getInstance().getKnownFileTypeOrAssociate(myFile); if (type == null || !myFile.isValid()) return false; - boolean openAsNative = OpenFileHelper.openAsNative(myFile); - - if (!openAsNative) { - openAsNative = type instanceof NativeFileType; - } - if (openAsNative) { + if (type instanceof INativeFileType) { return NativeFileType.openAssociatedApplication(myFile); } diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileHelper.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileHelper.java deleted file mode 100644 index af673d55da24..000000000000 --- a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileHelper.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.intellij.openapi.fileEditor; - -import com.intellij.openapi.extensions.ExtensionPointName; -import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.vfs.VirtualFile; - -public abstract class OpenFileHelper { - - public static boolean openAsNative(VirtualFile virtualFile) { - boolean openAsNative = false; - for (OpenFileHelper h : Extensions.getExtensions(EP_NAME)) { - if (h.canHelp(virtualFile)) { - openAsNative = h.doOpenAsNative(virtualFile); - break; - } - } - return openAsNative; - } - - public static ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.openFileDescriptorHelper"); - - public abstract boolean canHelp(VirtualFile file); - - public abstract boolean doOpenAsNative(VirtualFile file); -} diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/INativeFileType.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/INativeFileType.java new file mode 100644 index 000000000000..842b009da270 --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/fileTypes/INativeFileType.java @@ -0,0 +1,4 @@ +package com.intellij.openapi.fileTypes; + +public interface INativeFileType extends FileType { +} diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/NativeFileType.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/NativeFileType.java index 63054d33e92a..57a2c754d9f9 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileTypes/NativeFileType.java +++ b/platform/platform-api/src/com/intellij/openapi/fileTypes/NativeFileType.java @@ -29,7 +29,7 @@ import java.util.List; /** * @author yole */ -public class NativeFileType implements FileType { +public class NativeFileType implements INativeFileType { private static final Icon ICON = IconLoader.getIcon("/fileTypes/custom.png"); private NativeFileType() { } diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml index df18eb604e2d..84a0e91e4ab8 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml @@ -113,5 +113,4 @@ - From 158364953bc22926692222f73f7b9248a82cf4c0 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 18:43:47 +0100 Subject: [PATCH 85/94] don't cache ignored file names --- .../fileTypes/impl/FileTypeManagerImpl.java | 73 +++---------------- .../fileTypes/impl/IgnoredPatternSet.java | 72 ++++++++++++++++++ .../intellij/openapi/util/io/FileUtil.java | 3 +- 3 files changed, 86 insertions(+), 62 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredPatternSet.java diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java index 64262238af3a..0bfe3de7e8e9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java @@ -36,9 +36,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.testFramework.LightVirtualFile; import com.intellij.util.ArrayUtil; -import com.intellij.util.PatternUtil; import com.intellij.util.PlatformUtils; -import com.intellij.util.containers.ConcurrentHashSet; import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusConnection; import gnu.trove.THashMap; @@ -52,7 +50,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.io.File; import java.util.*; -import java.util.regex.Pattern; /** * @author Yura Cangea @@ -63,12 +60,9 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME private final Set myDefaultTypes = new THashSet(); private final ArrayList mySpecialFileTypes = new ArrayList(); - private final ArrayList myIgnorePatterns = new ArrayList(); private FileTypeAssocTable myPatternsTable = new FileTypeAssocTable(); - private final Set myIgnoredFileMasksSet = new LinkedHashSet(); - private final Set myNotIgnoredFiles = new ConcurrentHashSet(); - private final Set myIgnoredFiles = new ConcurrentHashSet(); + private final IgnoredPatternSet myIgnoredPatterns = new IgnoredPatternSet(); private final FileTypeAssocTable myInitialAssociations = new FileTypeAssocTable(); private final Map myUnresolvedMappings = new THashMap(); private final Map myUnresolvedRemovedMappings = new THashMap(); @@ -352,67 +346,31 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME @NotNull public String getIgnoredFilesList() { - StringBuilder sb = new StringBuilder(); - for (String ignoreMask : myIgnoredFileMasksSet) { - sb.append(ignoreMask); - sb.append(';'); + final Set masks = myIgnoredPatterns.getIgnoreMasks(); + if (masks.isEmpty()) { + return ""; } - return sb.toString(); + + return StringUtil.join(masks, ";") + ";"; } public void setIgnoredFilesList(@NotNull String list) { fireBeforeFileTypesChanged(); - setIgnoredFilesListWithoutNotification(list); - + myIgnoredPatterns.setIgnoreMasks(list); fireFileTypesChanged(); } - private void setIgnoredFilesListWithoutNotification(String list) { - myIgnoredFileMasksSet.clear(); - myIgnorePatterns.clear(); - - StringTokenizer tokenizer = new StringTokenizer(list, ";"); - while (tokenizer.hasMoreTokens()) { - String ignoredFile = tokenizer.nextToken(); - if (ignoredFile != null && !myIgnoredFileMasksSet.contains(ignoredFile)) { - if (!myIgnoredFileMasksSet.contains(ignoredFile)) { - myIgnorePatterns.add(PatternUtil.fromMask(ignoredFile)); - } - myIgnoredFileMasksSet.add(ignoredFile); - } - } - - //[mike] - //To make async delete work. See FileUtil.asyncDelete. - //Quite a hack, but still we need to have some name, which - //won't be catched by VF for sure. - //noinspection HardCodedStringLiteral - Pattern p = Pattern.compile(".*\\.__del__"); - myIgnorePatterns.add(p); - } - public boolean isIgnoredFilesListEqualToCurrent(String list) { Set tempSet = new THashSet(); StringTokenizer tokenizer = new StringTokenizer(list, ";"); while (tokenizer.hasMoreTokens()) { tempSet.add(tokenizer.nextToken()); } - return tempSet.equals(myIgnoredFileMasksSet); + return tempSet.equals(myIgnoredPatterns.getIgnoreMasks()); } public boolean isFileIgnored(@NotNull String name) { - if (myNotIgnoredFiles.contains(name)) return false; - if (myIgnoredFiles.contains(name)) return true; - - for (Pattern pattern : myIgnorePatterns) { - if (pattern.matcher(name).matches()) { - myIgnoredFiles.add(name); - return true; - } - } - - myNotIgnoredFiles.add(name); - return false; + return myIgnoredPatterns.isIgnored(name); } @Override @@ -453,11 +411,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME } public void fireFileTypesChanged() { - myNotIgnoredFiles.clear(); - myIgnoredFiles.clear(); - - final FileTypeEvent event = new FileTypeEvent(this); - myMessageBus.syncPublisher(AppTopics.FILE_TYPES).fileTypesChanged(event); + myMessageBus.syncPublisher(AppTopics.FILE_TYPES).fileTypesChanged(new FileTypeEvent(this)); } private final Map myAdapters = new HashMap(); @@ -504,7 +458,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME } } else if (ELEMENT_IGNOREFILES.equals(e.getName())) { - setIgnoredFilesListWithoutNotification(e.getAttributeValue(ATTRIBUTE_LIST)); + myIgnoredPatterns.setIgnoreMasks(e.getAttributeValue(ATTRIBUTE_LIST)); } else if (AbstractFileType.ELEMENT_EXTENSIONMAP.equals(e.getName())) { readGlobalMappings(e); @@ -583,10 +537,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME } private void addIgnore(@NonNls final String ignoreMask) { - if (!myIgnoredFileMasksSet.contains(ignoreMask)) { - myIgnorePatterns.add(PatternUtil.fromMask(ignoreMask)); - myIgnoredFileMasksSet.add(ignoreMask); - } + myIgnoredPatterns.addIgnoreMask(ignoreMask); } private void restoreStandardFileExtensions() { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredPatternSet.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredPatternSet.java new file mode 100644 index 000000000000..47ad35498d9a --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredPatternSet.java @@ -0,0 +1,72 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.fileTypes.impl; + +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.StringTokenizer; + +/** + * @author peter + */ +public class IgnoredPatternSet { + private final Set myMasks = new LinkedHashSet(); + private final FileTypeAssocTable myIgnorePatterns = new FileTypeAssocTable().copy(); + + Set getIgnoreMasks() { + return Collections.unmodifiableSet(myMasks); + } + + void setIgnoreMasks(@NotNull String list) { + clearPatterns(); + + StringTokenizer tokenizer = new StringTokenizer(list, ";"); + while (tokenizer.hasMoreTokens()) { + String ignoredFile = tokenizer.nextToken(); + if (ignoredFile != null) { + addIgnoreMask(ignoredFile); + } + } + + } + + void addIgnoreMask(@NotNull String ignoredFile) { + if (myIgnorePatterns.findAssociatedFileType(ignoredFile) == null) { + myMasks.add(ignoredFile); + myIgnorePatterns.addAssociation(FileTypeManager.parseFromString(ignoredFile), Boolean.TRUE); + } + } + + boolean isIgnored(@NotNull String fileName) { + if (myIgnorePatterns.findAssociatedFileType(fileName) == Boolean.TRUE) { + return true; + } + + //Quite a hack, but still we need to have some name, which + //won't be catched by VFS for sure. + return fileName.endsWith(FileUtil.ASYNC_DELETE_EXTENSION); + } + + void clearPatterns() { + myMasks.clear(); + myIgnorePatterns.removeAllAssociations(Boolean.TRUE); + } +} diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index 2407d5463010..2b11d89dd871 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -53,6 +53,7 @@ public class FileUtil { // do not use channels to copy files larger than 5 Mb because of possible MapFailed error private static final long CHANNELS_COPYING_LIMIT = 5L * 1024L * 1024L; private static String ourCanonicalTempPathCache = null; + public static final String ASYNC_DELETE_EXTENSION = ".__del__"; @Nullable public static String getRelativePath(File base, File file) { @@ -488,7 +489,7 @@ public class FileUtil { private static File getTempFile(String originalFileName, File parent) { int randomSuffix = (int)(System.currentTimeMillis() % 1000); for (int i = randomSuffix; ; i++) { - @NonNls String name = "___" + originalFileName + i + ".__del__"; + @NonNls String name = "___" + originalFileName + i + ASYNC_DELETE_EXTENSION; File tempFile = new File(parent, name); if (!tempFile.exists()) return tempFile; } From 456b8d23568db529d500fdaf48d516c778c25ec7 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 20:20:15 +0100 Subject: [PATCH 86/94] members declared in the qualifier class go first in the completion list (IDEA-13030) --- .../completion/JavaCompletionUtil.java | 6 +++--- .../completion/SmartCompletionDecorator.java | 14 +++++--------- .../normalSorting/DeclaredMembersGoFirst.java | 15 +++++++++++++++ .../completion/NormalCompletionOrderingTest.java | 5 +++++ .../intellij/codeInsight/lookup/LookupItem.java | 2 +- 5 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normalSorting/DeclaredMembersGoFirst.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java index 878cbe3e3501..e06d2bec4832 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -728,14 +728,14 @@ public class JavaCompletionUtil { return item; } - private static LookupElementDecorator highlight(LookupElement decorator) { - return LookupElementDecorator.withRenderer(decorator, new LookupElementRenderer>() { + private static LookupElement highlight(LookupElement decorator) { + return PrioritizedLookupElement.withGrouping(LookupElementDecorator.withRenderer(decorator, new LookupElementRenderer>() { @Override public void renderElement(LookupElementDecorator element, LookupElementPresentation presentation) { element.getDelegate().renderElement(presentation); presentation.setItemTextBold(true); } - }); + }), 1); } private static LookupItem createLookupElement(CompletionElement completionElement, PsiType qualifierType) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java b/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java index 2479f3a520fc..281827fac929 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java @@ -58,8 +58,9 @@ public class SmartCompletionDecorator extends TailTypeDecorator { return defType; } - LookupElement item = getDelegate(); - Object object = item.getObject(); + LookupElement delegate = getDelegate(); + LookupItem item = as(LookupItem.class); + Object object = delegate.getObject(); if (!CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET && (object instanceof PsiMethod || object instanceof PsiClass)) { return TailType.NONE; } @@ -67,8 +68,8 @@ public class SmartCompletionDecorator extends TailTypeDecorator { final PsiExpression enclosing = PsiTreeUtil.getContextOfType(myPosition, PsiExpression.class, true); if (enclosing != null && object instanceof PsiElement) { - final PsiType type = getItemType(item); - final TailType itemType = item instanceof LookupItem ? ((LookupItem)item).getTailType() : TailType.NONE; + final PsiType type = JavaCompletionUtil.getLookupElementType(delegate); + final TailType itemType = item != null ? item.getTailType() : TailType.NONE; TailType cached = itemType; int cachedPrior = 0; if (type != null && type.isValid()) { @@ -108,11 +109,6 @@ public class SmartCompletionDecorator extends TailTypeDecorator { return null; } - @Nullable - private PsiType getItemType(LookupElement element) { - return JavaCompletionUtil.getLookupElementType(element); - } - @Override public void handleInsert(InsertionContext context) { myPosition = getPosition(context, this); diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/DeclaredMembersGoFirst.java b/java/java-tests/testData/codeInsight/completion/normalSorting/DeclaredMembersGoFirst.java new file mode 100644 index 000000000000..1f6474ada926 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/DeclaredMembersGoFirst.java @@ -0,0 +1,15 @@ +class Foo { + void fromSuper() {} + void overridden() {} +} + +class FooImpl extends Foo { + void overridden() {} + void fromThis() {} +} + +class Bar { + { + new FooImpl(). + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java index 3449fb725e8e..1467f74060d1 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java @@ -170,4 +170,9 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { assertEquals("foo.Foo", ((JavaPsiClassReferenceElement)getLookup().getCurrentItem()).getQualifiedName()); } + public void testDeclaredMembersGoFirst() throws Exception { + invokeCompletion(getBasePath() + "/" + getTestName(false) + ".java"); + assertStringItems("fromThis", "overridden", "fromSuper", "equals", "getClass", "hashCode", "notify", "notifyAll", "toString", "wait", "wait", "wait"); + } + } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java index 2583e8b97c13..13dd3f790f53 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java @@ -372,7 +372,7 @@ public class LookupItem extends MutableLookupElement implements Comparable } public static @Nullable LookupItem from(LookupElement lookupElement) { - if (lookupElement instanceof LookupElementDecorator) { + while (lookupElement instanceof LookupElementDecorator) { lookupElement = ((LookupElementDecorator)lookupElement).getDelegate(); } if (lookupElement instanceof LookupItem) return (LookupItem)lookupElement; From 8c69c69acf434e6845003a1db1f0242add58c194 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 20:35:47 +0100 Subject: [PATCH 87/94] cheaper LookupElement.as --- .../CastingLookupElementDecorator.java | 3 ++ .../completion/JavaChainLookupElement.java | 4 +- .../completion/JavaCompletionContributor.java | 2 +- .../completion/JavaCompletionUtil.java | 2 +- .../completion/JavaMethodCallElement.java | 2 + .../JavaMethodMergingContributor.java | 2 +- .../completion/PreferNonGenericWeigher.java | 6 +-- ...erenceExpressionCompletionContributor.java | 2 +- .../completion/SmartCompletionDecorator.java | 2 +- .../completion/PrioritizedLookupElement.java | 2 + .../lookup/AutoCompletionPolicy.java | 4 +- .../codeInsight/lookup/LookupElement.java | 15 +++++-- .../lookup/LookupElementDecorator.java | 7 +-- .../completion/CodeCompletionHandlerBase.java | 6 +-- .../completion/GroupingWeigher.java | 6 +-- .../codeInsight/lookup/LookupItem.java | 11 ++--- .../codeInsight/lookup/TailTypeDecorator.java | 2 +- .../codeInsight/lookup/impl/LookupImpl.java | 4 +- .../openapi/util/ClassConditionKey.java | 44 +++++++++++++++++++ .../GrMethodMergingContributor.java | 2 +- 20 files changed, 90 insertions(+), 38 deletions(-) create mode 100644 platform/platform-api/src/com/intellij/openapi/util/ClassConditionKey.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/CastingLookupElementDecorator.java b/java/java-impl/src/com/intellij/codeInsight/completion/CastingLookupElementDecorator.java index c9e5c70a7bfd..9b97a9451a2b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/CastingLookupElementDecorator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/CastingLookupElementDecorator.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.lookup.*; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.util.ClassConditionKey; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiType; import com.intellij.psi.codeStyle.CodeStyleSettings; @@ -27,6 +28,8 @@ import org.jetbrains.annotations.Nullable; * @author peter */ public class CastingLookupElementDecorator extends LookupElementDecorator implements TypedLookupItem { + public static final ClassConditionKey CLASS_CONDITION_KEY = ClassConditionKey.create(CastingLookupElementDecorator.class); + private final LookupElement myCastItem; private final PsiType myCastType; diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java index e2afa96bbdfe..62c4e060a265 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.lookup.*; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.util.ClassConditionKey; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.util.PsiTreeUtil; @@ -30,6 +31,7 @@ import java.util.Set; * @author peter */ public class JavaChainLookupElement extends LookupElementDecorator implements TypedLookupItem { + public static final ClassConditionKey CLASS_CONDITION_KEY = ClassConditionKey.create(JavaChainLookupElement.class); private final LookupElement myQualifier; private JavaChainLookupElement(LookupElement qualifier, LookupElement main) { @@ -72,7 +74,7 @@ public class JavaChainLookupElement extends LookupElementDecorator implements TypedLookupItem, StaticallyImportable { + public static final ClassConditionKey CLASS_CONDITION_KEY = ClassConditionKey.create(JavaMethodCallElement.class); private static final Key INFERENCE_SUBSTITUTOR = Key.create("INFERENCE_SUBSTITUTOR"); @Nullable private final PsiClass myContainingClass; private final PsiMethod myMethod; diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java index 513302500f98..74bdc7ccc0a5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java @@ -49,7 +49,7 @@ public class JavaMethodMergingContributor extends CompletionContributor { } final PsiMethod method = (PsiMethod)o; - final JavaChainLookupElement chain = item.as(JavaChainLookupElement.class); + final JavaChainLookupElement chain = item.as(JavaChainLookupElement.CLASS_CONDITION_KEY); final String name = method.getName() + "#" + (chain == null ? "" : chain.getQualifier().getLookupString()); if (commonName != null && !commonName.equals(name)) { return AutoCompletionDecision.SHOW_LOOKUP; diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferNonGenericWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferNonGenericWeigher.java index 4a9c69361352..a3f8154cca60 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferNonGenericWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferNonGenericWeigher.java @@ -21,7 +21,6 @@ import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiType; import com.intellij.psi.PsiTypeParameter; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author peter @@ -29,13 +28,10 @@ import org.jetbrains.annotations.Nullable; public class PreferNonGenericWeigher extends CompletionWeigher { public Comparable weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) { - if (location == null) { - return null; - } final Object object = item.getObject(); if (object instanceof PsiMethod) { PsiType type = ((PsiMethod)object).getReturnType(); - final JavaMethodCallElement callItem = item.as(JavaMethodCallElement.class); + final JavaMethodCallElement callItem = item.as(JavaMethodCallElement.CLASS_CONDITION_KEY); if (callItem != null) { type = callItem.getSubstitutor().substitute(type); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java index a420ee3fd001..1f92244fec69 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java @@ -167,7 +167,7 @@ public class ReferenceExpressionCompletionContributor { }), false, parameters); for (LookupElement lookupElement : elements) { if (lookupElement.getObject() instanceof PsiMethod) { - final JavaMethodCallElement item = lookupElement.as(JavaMethodCallElement.class); + final JavaMethodCallElement item = lookupElement.as(JavaMethodCallElement.CLASS_CONDITION_KEY); assert item != null; final PsiMethod method = (PsiMethod)lookupElement.getObject(); if (SmartCompletionDecorator.hasUnboundTypeParams(method)) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java b/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java index 281827fac929..ef32d2520c77 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java @@ -59,7 +59,7 @@ public class SmartCompletionDecorator extends TailTypeDecorator { } LookupElement delegate = getDelegate(); - LookupItem item = as(LookupItem.class); + LookupItem item = as(LookupItem.CLASS_CONDITION_KEY); Object object = delegate.getObject(); if (!CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET && (object instanceof PsiMethod || object instanceof PsiClass)) { return TailType.NONE; diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/PrioritizedLookupElement.java b/platform/lang-api/src/com/intellij/codeInsight/completion/PrioritizedLookupElement.java index 13df562fcc7b..07718c7181fd 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/PrioritizedLookupElement.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/PrioritizedLookupElement.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementDecorator; +import com.intellij.openapi.util.ClassConditionKey; import org.jetbrains.annotations.Nullable; /** @@ -28,6 +29,7 @@ import org.jetbrains.annotations.Nullable; * @author peter */ public class PrioritizedLookupElement extends LookupElementDecorator { + public static final ClassConditionKey CLASS_CONDITION_KEY = ClassConditionKey.create(PrioritizedLookupElement.class); private final double myPriority; private final int myGrouping; diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/AutoCompletionPolicy.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/AutoCompletionPolicy.java index 96c7ac02fc49..e9b76972dcde 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/lookup/AutoCompletionPolicy.java +++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/AutoCompletionPolicy.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.lookup; +import com.intellij.openapi.util.ClassConditionKey; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -56,7 +57,7 @@ public enum AutoCompletionPolicy { @Nullable public static AutoCompletionPolicy getPolicy(LookupElement element) { - final PolicyDecorator decorator = element.as(PolicyDecorator.class); + final PolicyDecorator decorator = element.as(PolicyDecorator.CLASS_CONDITION_KEY); if (decorator != null) { return decorator.myPolicy; } @@ -64,6 +65,7 @@ public enum AutoCompletionPolicy { } private static class PolicyDecorator extends LookupElementDecorator { + public static final ClassConditionKey CLASS_CONDITION_KEY = ClassConditionKey.create(PolicyDecorator.class); private final AutoCompletionPolicy myPolicy; public PolicyDecorator(LookupElement element, AutoCompletionPolicy policy) { diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElement.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElement.java index 10ad5a4984c0..af5581c3e8ff 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElement.java +++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElement.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.lookup; import com.intellij.codeInsight.completion.InsertionContext; import com.intellij.codeInsight.completion.PrefixMatcher; +import com.intellij.openapi.util.ClassConditionKey; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; @@ -82,10 +83,18 @@ public abstract class LookupElement extends UserDataHolderBase { presentation.setItemText(getLookupString()); } + /** + * use {@link #as(com.intellij.openapi.util.ClassConditionKey)} instead + */ + @Deprecated @Nullable - public T as(Class aClass) { - //noinspection unchecked - return aClass.isInstance(this) ? (T) this : null; + public final T as(Class aClass) { + return as(ClassConditionKey.create(aClass)); + } + + @Nullable + public T as(ClassConditionKey conditionKey) { + return conditionKey.isInstance(this) ? (T) this : null; } public boolean isCaseSensitive() { diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementDecorator.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementDecorator.java index 1aab873ff062..3584b38fb685 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementDecorator.java +++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementDecorator.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.completion.CompletionService; import com.intellij.codeInsight.completion.InsertHandler; import com.intellij.codeInsight.completion.InsertionContext; import com.intellij.codeInsight.completion.PrefixMatcher; +import com.intellij.openapi.util.ClassConditionKey; import org.jetbrains.annotations.NotNull; import java.util.Set; @@ -108,9 +109,9 @@ public abstract class LookupElementDecorator extends Lo } @Override - public T as(Class aClass) { - final T t = super.as(aClass); - return t == null ? myDelegate.as(aClass) : t; + public T as(ClassConditionKey conditionKey) { + final T t = super.as(conditionKey); + return t == null ? myDelegate.as(conditionKey) : t; } public boolean isCaseSensitive() { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 9035ea961bb7..af8c10fd19a6 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -452,7 +452,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { return policy; } - final LookupItem item = element.as(LookupItem.class); + final LookupItem item = element.as(LookupItem.CLASS_CONDITION_KEY); if (item != null) { return item.getAutoCompletionPolicy(); } @@ -505,8 +505,8 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { protected void run(Result result) throws Throwable { String uniqueText = _uniqueText; - if (item.getObject() instanceof DeferredUserLookupValue && item.as(LookupItem.class) != null) { - if (!((DeferredUserLookupValue)item.getObject()).handleUserSelection(item.as(LookupItem.class), context.getProject())) { + if (item.getObject() instanceof DeferredUserLookupValue && item.as(LookupItem.CLASS_CONDITION_KEY) != null) { + if (!((DeferredUserLookupValue)item.getObject()).handleUserSelection(item.as(LookupItem.CLASS_CONDITION_KEY), context.getProject())) { return; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/GroupingWeigher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/GroupingWeigher.java index 10d7fda3fd4b..a452c63ec561 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/GroupingWeigher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/GroupingWeigher.java @@ -18,7 +18,6 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.lookup.LookupElement; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author peter @@ -26,10 +25,7 @@ import org.jetbrains.annotations.Nullable; public class GroupingWeigher extends CompletionWeigher { @Override public Integer weigh(@NotNull LookupElement element, @NotNull CompletionLocation location) { - if (location == null) { - return null; - } - final PrioritizedLookupElement prioritized = element.as(PrioritizedLookupElement.class); + final PrioritizedLookupElement prioritized = element.as(PrioritizedLookupElement.CLASS_CONDITION_KEY); if (prioritized != null) { return -prioritized.getGrouping(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java index 13dd3f790f53..113fc37dd4f2 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java @@ -25,6 +25,7 @@ import com.intellij.codeInsight.completion.InsertionContext; import com.intellij.codeInsight.lookup.impl.ElementLookupRenderer; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.util.ClassConditionKey; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.util.containers.ContainerUtil; @@ -42,6 +43,8 @@ import java.util.Set; * This class represents an item of a lookup list. */ public class LookupItem extends MutableLookupElement implements Comparable { + public static final ClassConditionKey CLASS_CONDITION_KEY = ClassConditionKey.create(LookupItem.class); + public static final Object HIGHLIGHTED_ATTR = Key.create("highlighted"); public static final Object ICON_ATTR = Key.create("icon"); public static final Object TYPE_TEXT_ATTR = Key.create("typeText"); @@ -358,14 +361,6 @@ public class LookupItem extends MutableLookupElement implements Comparable return myAllLookupStrings; } - public void copyAttributes(final LookupItem item) { - if (myAttributes == null) { - if (item.myAttributes == null) return; - myAttributes = new HashMap(5); - } - myAttributes.putAll(item.myAttributes); - } - @Override public boolean isCaseSensitive() { return !Boolean.TRUE.equals(getAttribute(CASE_INSENSITIVE)); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/TailTypeDecorator.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/TailTypeDecorator.java index 264afef7d421..f5c649b16ee1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/TailTypeDecorator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/TailTypeDecorator.java @@ -46,7 +46,7 @@ public abstract class TailTypeDecorator extends LookupE final LookupElement delegate = getDelegate(); final TailType tailType = computeTailType(context); - final LookupItem lookupItem = delegate.as(LookupItem.class); + final LookupItem lookupItem = delegate.as(LookupItem.CLASS_CONDITION_KEY); if (lookupItem != null && tailType != null) { lookupItem.setTailType(TailType.UNKNOWN); } 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 bec42fbd1224..7b334b63176a 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 @@ -593,8 +593,8 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { if (item == null || item instanceof EmptyLookupItem || item.getObject() instanceof DeferredUserLookupValue && - item.as(LookupItem.class) != null && - !((DeferredUserLookupValue)item.getObject()).handleUserSelection(item.as(LookupItem.class), myProject)) { + item.as(LookupItem.CLASS_CONDITION_KEY) != null && + !((DeferredUserLookupValue)item.getObject()).handleUserSelection(item.as(LookupItem.CLASS_CONDITION_KEY), myProject)) { fireItemSelected(null, completionChar); return; } diff --git a/platform/platform-api/src/com/intellij/openapi/util/ClassConditionKey.java b/platform/platform-api/src/com/intellij/openapi/util/ClassConditionKey.java new file mode 100644 index 000000000000..fb47b5f635e3 --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/util/ClassConditionKey.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.util; + +import com.intellij.util.InstanceofCheckerGenerator; + +/** + * @author peter + */ +public class ClassConditionKey { + private final Condition myCondition; + private final Class myConditionClass; + + private ClassConditionKey(Class aClass) { + myCondition = InstanceofCheckerGenerator.getInstance().getInstanceofChecker(aClass); + myConditionClass = aClass; + } + + public static ClassConditionKey create(Class aClass) { + return new ClassConditionKey(aClass); + } + + public boolean isInstance(Object o) { + return myCondition.value(o); + } + + @Override + public String toString() { + return myConditionClass.getName(); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodMergingContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodMergingContributor.java index 9af0d1b949b3..08bc54b2eccc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodMergingContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodMergingContributor.java @@ -57,7 +57,7 @@ public class GrMethodMergingContributor extends CompletionContributor { } final PsiMethod method = (PsiMethod)o; - final JavaChainLookupElement chain = item.as(JavaChainLookupElement.class); + final JavaChainLookupElement chain = item.as(JavaChainLookupElement.CLASS_CONDITION_KEY); final String name = method.getName() + "#" + (chain == null ? "" : chain.getQualifier().getLookupString()); if (commonName != null && !commonName.equals(name)) { From cb3a2d6e35933403475ecdf22b32cee3f07f6c19 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 20:44:13 +0100 Subject: [PATCH 88/94] use LookupElement.as instead of ad hoc inlining everywhere --- .../CastingLookupElementDecorator.java | 10 ------- .../completion/JavaChainLookupElement.java | 2 +- .../JavaCompletionStatistician.java | 3 +- .../completion/JavaCompletionUtil.java | 29 +++++++------------ .../JavaSmartCompletionContributor.java | 2 +- .../completion/PreferSimpleWeigher.java | 8 ++--- .../codeInsight/lookup/PsiTypeLookupItem.java | 14 ++------- .../codeInsight/lookup/TypedLookupItem.java | 3 ++ .../completion/PrioritizedLookupElement.java | 11 ++----- .../completion/PriorityWeigher.java | 8 ++--- .../codeInsight/lookup/LookupItem.java | 8 ----- 11 files changed, 25 insertions(+), 73 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/CastingLookupElementDecorator.java b/java/java-impl/src/com/intellij/codeInsight/completion/CastingLookupElementDecorator.java index 9b97a9451a2b..00b8538dcc66 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/CastingLookupElementDecorator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/CastingLookupElementDecorator.java @@ -81,14 +81,4 @@ public class CastingLookupElementDecorator extends LookupElementDecorator>() { - @Override - public void renderElement(LookupElementDecorator element, LookupElementPresentation presentation) { - element.getDelegate().renderElement(presentation); - presentation.setItemTextBold(true); - } - }), 1); + return PrioritizedLookupElement.withGrouping( + LookupElementDecorator.withRenderer(decorator, new LookupElementRenderer>() { + @Override + public void renderElement(LookupElementDecorator element, LookupElementPresentation presentation) { + element.getDelegate().renderElement(presentation); + presentation.setItemTextBold(true); + } + }), 1); } private static LookupItem createLookupElement(CompletionElement completionElement, PsiType qualifierType) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index 180ef6f374a8..57b98d2a4cc6 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -200,7 +200,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor { final CompletionService service = CompletionService.getCompletionService(); new BasicExpressionCompletionContributor().fillCompletionVariants(parameters, service.createResultSet(parameters, new Consumer() { public void consume(final LookupElement lookupElement) { - final TypedLookupItem typed = JavaCompletionUtil.typedFrom(lookupElement); + final TypedLookupItem typed = lookupElement.as(TypedLookupItem.CLASS_CONDITION_KEY); if (typed != null) { final PsiType psiType = typed.getType(); if (psiType != null && type.isAssignableFrom(psiType)) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferSimpleWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferSimpleWeigher.java index 97339f0b33c7..c7361df1f7af 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferSimpleWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferSimpleWeigher.java @@ -18,7 +18,6 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.PsiTypeLookupItem; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author peter @@ -26,14 +25,11 @@ import org.jetbrains.annotations.Nullable; public class PreferSimpleWeigher extends CompletionWeigher { public Comparable weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) { - if (location == null) { - return null; - } - final PsiTypeLookupItem lookupItem = PsiTypeLookupItem.from(item); + final PsiTypeLookupItem lookupItem = item.as(PsiTypeLookupItem.CLASS_CONDITION_KEY); if (lookupItem != null) { return -lookupItem.getBracketsCount(); } - if (CastingLookupElementDecorator.from(item) != null) { + if (item.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null) { return -239; } return 0; diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java index a268b4339513..48d521bc9856 100644 --- a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java +++ b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java @@ -18,9 +18,9 @@ package com.intellij.codeInsight.lookup; import com.intellij.codeInsight.completion.DefaultInsertHandler; import com.intellij.codeInsight.completion.InsertionContext; import com.intellij.codeInsight.completion.JavaPsiClassReferenceElement; +import com.intellij.openapi.util.ClassConditionKey; import com.intellij.psi.*; import com.intellij.psi.impl.source.PsiClassReferenceType; -import com.intellij.psi.util.TypeConversionUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,6 +29,8 @@ import org.jetbrains.annotations.Nullable; * @author peter */ public class PsiTypeLookupItem extends LookupItem { + public static final ClassConditionKey CLASS_CONDITION_KEY = ClassConditionKey.create(PsiTypeLookupItem.class); + public PsiTypeLookupItem(Object o, @NotNull @NonNls String lookupString) { super(o, lookupString); } @@ -130,16 +132,6 @@ public class PsiTypeLookupItem extends LookupItem { } return new LookupItem(type, type.getPresentableText()); } - - public static @Nullable PsiTypeLookupItem from(LookupElement element) { - if (element instanceof PsiTypeLookupItem) return (PsiTypeLookupItem)element; - else if (element instanceof LookupElementDecorator) { - element = ((LookupElementDecorator)element).getDelegate(); - if (element instanceof PsiTypeLookupItem) return (PsiTypeLookupItem)element; - } - - return null; - } @Override public void renderElement(LookupElementPresentation presentation) { diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/TypedLookupItem.java b/java/java-impl/src/com/intellij/codeInsight/lookup/TypedLookupItem.java index e2bfb8945e78..34415abc0f16 100644 --- a/java/java-impl/src/com/intellij/codeInsight/lookup/TypedLookupItem.java +++ b/java/java-impl/src/com/intellij/codeInsight/lookup/TypedLookupItem.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.lookup; +import com.intellij.openapi.util.ClassConditionKey; import com.intellij.psi.PsiType; import org.jetbrains.annotations.Nullable; @@ -22,6 +23,8 @@ import org.jetbrains.annotations.Nullable; * @author peter */ public interface TypedLookupItem { + ClassConditionKey CLASS_CONDITION_KEY = ClassConditionKey.create(TypedLookupItem.class); + @Nullable PsiType getType(); } diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/PrioritizedLookupElement.java b/platform/lang-api/src/com/intellij/codeInsight/completion/PrioritizedLookupElement.java index 07718c7181fd..3a801015849c 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/PrioritizedLookupElement.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/PrioritizedLookupElement.java @@ -19,7 +19,6 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementDecorator; import com.intellij.openapi.util.ClassConditionKey; -import org.jetbrains.annotations.Nullable; /** * Use only when you want to control lookup sorting & preference in simple cases when you have control over ALL the items in lookup. @@ -48,18 +47,12 @@ public class PrioritizedLookupElement extends LookupEle } public static LookupElement withPriority(LookupElement element, double priority) { - final PrioritizedLookupElement prioritized = PrioritizedLookupElement.from(element); + final PrioritizedLookupElement prioritized = element.as(CLASS_CONDITION_KEY); return new PrioritizedLookupElement(element, priority, prioritized == null ? 0 : prioritized.getGrouping()); } public static LookupElement withGrouping(LookupElement element, int grouping) { - final PrioritizedLookupElement prioritized = PrioritizedLookupElement.from(element); + final PrioritizedLookupElement prioritized = element.as(CLASS_CONDITION_KEY); return new PrioritizedLookupElement(element, prioritized == null ? 0 : prioritized.getPriority(), grouping); } - - public static @Nullable PrioritizedLookupElement from(LookupElement element) { - if (element instanceof PrioritizedLookupElement) return (PrioritizedLookupElement)element; - if (element instanceof LookupElementDecorator) return from (((LookupElementDecorator)element).getDelegate()); - return null; - } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/PriorityWeigher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/PriorityWeigher.java index b4eabfb4cc1b..196f443e8c07 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/PriorityWeigher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/PriorityWeigher.java @@ -19,7 +19,6 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupItem; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author peter @@ -27,15 +26,12 @@ import org.jetbrains.annotations.Nullable; public class PriorityWeigher extends CompletionWeigher { @Override public Double weigh(@NotNull LookupElement element, @NotNull CompletionLocation location) { - if (location == null) { - return null; - } - final PrioritizedLookupElement prioritized = PrioritizedLookupElement.from(element); + final PrioritizedLookupElement prioritized = element.as(PrioritizedLookupElement.CLASS_CONDITION_KEY); if (prioritized != null) { return -prioritized.getPriority(); } - final LookupItem item = LookupItem.from(element); + final LookupItem item = element.as(LookupItem.CLASS_CONDITION_KEY); if (item != null) { return -item.getPriority(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java index 113fc37dd4f2..4ba771b58efb 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java @@ -365,12 +365,4 @@ public class LookupItem extends MutableLookupElement implements Comparable public boolean isCaseSensitive() { return !Boolean.TRUE.equals(getAttribute(CASE_INSENSITIVE)); } - - public static @Nullable LookupItem from(LookupElement lookupElement) { - while (lookupElement instanceof LookupElementDecorator) { - lookupElement = ((LookupElementDecorator)lookupElement).getDelegate(); - } - if (lookupElement instanceof LookupItem) return (LookupItem)lookupElement; - return null; - } } From 7e5f15905cfce1b6eef8a0710766f75c6200f266 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 21:00:58 +0100 Subject: [PATCH 89/94] extract MapArgumentCompletionProvider --- .../GroovyCompletionContributor.java | 144 +------------- .../MapArgumentCompletionProvider.java | 177 ++++++++++++++++++ 2 files changed, 179 insertions(+), 142 deletions(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index d1d663dbf9fa..29eb4bddd0c1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -36,13 +36,8 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Consumer; import com.intellij.util.PairConsumer; import com.intellij.util.ProcessingContext; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.hash.HashMap; -import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.GroovyBundle; -import org.jetbrains.plugins.groovy.GroovyIcons; -import org.jetbrains.plugins.groovy.lang.completion.handlers.NamedArgumentInsertHandler; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; @@ -56,29 +51,23 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgument import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrConstructorCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; -import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; import org.jetbrains.plugins.groovy.lang.resolve.processors.CompletionProcessor; import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor; -import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Set; import static com.intellij.patterns.PlatformPatterns.psiElement; import static com.intellij.patterns.PsiJavaPatterns.elementType; @@ -170,78 +159,6 @@ public class GroovyCompletionContributor extends CompletionContributor { } }; - private static final CompletionProvider MAP_ARGUMENT_COMPLETION_PROVIDER = - new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet result) { - final GrArgumentList argumentList; - - PsiElement parent = parameters.getPosition().getParent(); - if (parent instanceof GrReferenceExpression) { - if (((GrReferenceExpression)parent).getQualifier() != null) return; - argumentList = (GrArgumentList)parent.getParent(); - } - else { - argumentList = (GrArgumentList)parent.getParent().getParent(); - } - - final GrCall call = (GrCall)argumentList.getParent(); - List results = new ArrayList(); - //constructor call - if (call instanceof GrConstructorCall) { - GrConstructorCall constructorCall = (GrConstructorCall)call; - ContainerUtil.addAll(results, constructorCall.multiResolveConstructor()); - ContainerUtil.addAll(results, constructorCall.multiResolveClass()); - } - else if (call instanceof GrCallExpression) { - GrCallExpression constructorCall = (GrCallExpression)call; - ContainerUtil.addAll(results, constructorCall.getCallVariants(null)); - final PsiType type = ((GrCallExpression)call).getType(); - if (type instanceof PsiClassType) { - final PsiClass psiClass = ((PsiClassType)type).resolve(); - results.add(new GroovyResolveResultImpl(psiClass, true)); - } - } - - Set usedClasses = new HashSet(); - Set usedNames = new HashSet(); - for (GrNamedArgument argument : argumentList.getNamedArguments()) { - final GrArgumentLabel label = argument.getLabel(); - if (label != null) { - final String name = label.getName(); - if (name != null) { - usedNames.add(name); - } - } - } - - for (GroovyResolveResult resolveResult : results) { - PsiElement element = resolveResult.getElement(); - if (element instanceof PsiMethod) { - final PsiMethod method = (PsiMethod)element; - final PsiClass containingClass = method.getContainingClass(); - if (containingClass != null) { - addPropertiesForClass(result, usedClasses, usedNames, containingClass, call); - } - if (method instanceof GrMethod) { - for (String parameter : ((GrMethod)method).getNamedParametersArray()) { - if (!usedNames.contains(parameter)) { - final LookupElementBuilder lookup = - LookupElementBuilder.create(parameter).setIcon(GroovyIcons.DYNAMIC).setInsertHandler(NamedArgumentInsertHandler.INSTANCE); - result.addElement(lookup); - } - } - } - } - else if (element instanceof PsiClass) { - addPropertiesForClass(result, usedClasses, usedNames, (PsiClass)element, call); - } - } - } - }; - private static final PsiElementPattern.Capture STATEMENT_START = psiElement(GroovyElementTypes.mIDENT).andOr( psiElement().afterLeaf(StandardPatterns.or( @@ -374,8 +291,8 @@ public class GroovyCompletionContributor extends CompletionContributor { } }); - extend(CompletionType.BASIC, IN_ARGUMENT_LIST_OF_CALL, MAP_ARGUMENT_COMPLETION_PROVIDER); - extend(CompletionType.BASIC, IN_MAP_KEY_ARGUMENT_LIST_OF_CALL, MAP_ARGUMENT_COMPLETION_PROVIDER); + extend(CompletionType.BASIC, IN_ARGUMENT_LIST_OF_CALL, new MapArgumentCompletionProvider()); + extend(CompletionType.BASIC, IN_MAP_KEY_ARGUMENT_LIST_OF_CALL, new MapArgumentCompletionProvider()); // class name stuff @@ -616,62 +533,6 @@ public class GroovyCompletionContributor extends CompletionContributor { return processor; } - private static void addPropertiesForClass(CompletionResultSet result, - Set usedClasses, - Set usedNames, - PsiClass containingClass, - GrCall call) { - if (usedClasses.contains(containingClass)) return; - usedClasses.add(containingClass); - final PsiClass eventListener = - JavaPsiFacade.getInstance(call.getProject()).findClass("java.util.EventListener", call.getResolveScope()); - Map writableProperties = new HashMap(); - for (PsiMethod method : containingClass.getAllMethods()) { - if (GroovyPropertyUtils.isSimplePropertySetter(method)) { - if (PsiUtil.isStaticsOK(method, call)) { - final String name = GroovyPropertyUtils.getPropertyNameBySetter(method); - if (name != null && !writableProperties.containsKey(name)) { - writableProperties.put(name, method); - } - } - } - else if (eventListener != null) { - consumeListenerProperties(result, usedNames, method, eventListener); - } - } - - for (String name : writableProperties.keySet()) { - if (usedNames.contains(name)) continue; - usedNames.add(name); - final LookupElementBuilder builder = - LookupElementBuilder.create(writableProperties.get(name), name).setIcon(GroovyIcons.PROPERTY) - .setInsertHandler(NamedArgumentInsertHandler.INSTANCE); - result.addElement(builder); - } - } - - private static void consumeListenerProperties(CompletionResultSet result, - Set usedNames, PsiMethod method, PsiClass eventListenerClass) { - if (method.getName().startsWith("add") && method.getParameterList().getParametersCount() == 1) { - final PsiParameter parameter = method.getParameterList().getParameters()[0]; - final PsiType type = parameter.getType(); - if (type instanceof PsiClassType) { - final PsiClassType classType = (PsiClassType)type; - final PsiClass listenerClass = classType.resolve(); - if (listenerClass != null) { - final PsiMethod[] listenerMethods = listenerClass.getMethods(); - if (InheritanceUtil.isInheritorOrSelf(listenerClass, eventListenerClass, true)) { - for (PsiMethod listenerMethod : listenerMethods) { - final String name = listenerMethod.getName(); - usedNames.add(name); - result.addElement(LookupElementBuilder.create(name).setIcon(GroovyIcons.PROPERTY).setInsertHandler(NamedArgumentInsertHandler.INSTANCE)); - } - } - } - } - } - } - public void beforeCompletion(@NotNull final CompletionInitializationContext context) { if (context.getCompletionType() == CompletionType.BASIC && context.getFile() instanceof GroovyFile) { if (semicolonNeeded(context)) { @@ -729,5 +590,4 @@ public class GroovyCompletionContributor extends CompletionContributor { } return true; } - } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java new file mode 100644 index 000000000000..b804471b5b2a --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java @@ -0,0 +1,177 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.lang.completion; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.util.ProcessingContext; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.hash.HashMap; +import com.intellij.util.containers.hash.HashSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.GroovyIcons; +import org.jetbrains.plugins.groovy.lang.completion.handlers.NamedArgumentInsertHandler; +import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrConstructorCall; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; +import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** +* @author peter +*/ +class MapArgumentCompletionProvider extends CompletionProvider { + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + final GrArgumentList argumentList; + + PsiElement parent = parameters.getPosition().getParent(); + if (parent instanceof GrReferenceExpression) { + if (((GrReferenceExpression)parent).getQualifier() != null) return; + argumentList = (GrArgumentList)parent.getParent(); + } + else { + argumentList = (GrArgumentList)parent.getParent().getParent(); + } + + final GrCall call = (GrCall)argumentList.getParent(); + List results = new ArrayList(); + //constructor call + if (call instanceof GrConstructorCall) { + GrConstructorCall constructorCall = (GrConstructorCall)call; + ContainerUtil.addAll(results, constructorCall.multiResolveConstructor()); + ContainerUtil.addAll(results, constructorCall.multiResolveClass()); + } + else if (call instanceof GrCallExpression) { + GrCallExpression constructorCall = (GrCallExpression)call; + ContainerUtil.addAll(results, constructorCall.getCallVariants(null)); + final PsiType type = ((GrCallExpression)call).getType(); + if (type instanceof PsiClassType) { + final PsiClass psiClass = ((PsiClassType)type).resolve(); + results.add(new GroovyResolveResultImpl(psiClass, true)); + } + } + + Set usedClasses = new HashSet(); + Set usedNames = new HashSet(); + for (GrNamedArgument argument : argumentList.getNamedArguments()) { + final GrArgumentLabel label = argument.getLabel(); + if (label != null) { + final String name = label.getName(); + if (name != null) { + usedNames.add(name); + } + } + } + + for (GroovyResolveResult resolveResult : results) { + PsiElement element = resolveResult.getElement(); + if (element instanceof PsiMethod) { + final PsiMethod method = (PsiMethod)element; + final PsiClass containingClass = method.getContainingClass(); + if (containingClass != null) { + addPropertiesForClass(result, usedClasses, usedNames, containingClass, call); + } + if (method instanceof GrMethod) { + for (String parameter : ((GrMethod)method).getNamedParametersArray()) { + if (!usedNames.contains(parameter)) { + final LookupElementBuilder lookup = + LookupElementBuilder.create(parameter).setIcon(GroovyIcons.DYNAMIC).setInsertHandler(NamedArgumentInsertHandler.INSTANCE); + result.addElement(lookup); + } + } + } + } + else if (element instanceof PsiClass) { + addPropertiesForClass(result, usedClasses, usedNames, (PsiClass)element, call); + } + } + } + + private static void addPropertiesForClass(CompletionResultSet result, + Set usedClasses, + Set usedNames, + PsiClass containingClass, + GrCall call) { + if (usedClasses.contains(containingClass)) return; + usedClasses.add(containingClass); + final PsiClass eventListener = + JavaPsiFacade.getInstance(call.getProject()).findClass("java.util.EventListener", call.getResolveScope()); + Map writableProperties = new HashMap(); + for (PsiMethod method : containingClass.getAllMethods()) { + if (GroovyPropertyUtils.isSimplePropertySetter(method)) { + if (PsiUtil.isStaticsOK(method, call)) { + final String name = GroovyPropertyUtils.getPropertyNameBySetter(method); + if (name != null && !writableProperties.containsKey(name)) { + writableProperties.put(name, method); + } + } + } + else if (eventListener != null) { + consumeListenerProperties(result, usedNames, method, eventListener); + } + } + + for (String name : writableProperties.keySet()) { + if (usedNames.contains(name)) continue; + usedNames.add(name); + final LookupElementBuilder builder = + LookupElementBuilder.create(writableProperties.get(name), name).setIcon(GroovyIcons.PROPERTY) + .setInsertHandler(NamedArgumentInsertHandler.INSTANCE); + result.addElement(builder); + } + } + + private static void consumeListenerProperties(CompletionResultSet result, + Set usedNames, PsiMethod method, PsiClass eventListenerClass) { + if (method.getName().startsWith("add") && method.getParameterList().getParametersCount() == 1) { + final PsiParameter parameter = method.getParameterList().getParameters()[0]; + final PsiType type = parameter.getType(); + if (type instanceof PsiClassType) { + final PsiClassType classType = (PsiClassType)type; + final PsiClass listenerClass = classType.resolve(); + if (listenerClass != null) { + final PsiMethod[] listenerMethods = listenerClass.getMethods(); + if (InheritanceUtil.isInheritorOrSelf(listenerClass, eventListenerClass, true)) { + for (PsiMethod listenerMethod : listenerMethods) { + final String name = listenerMethod.getName(); + usedNames.add(name); + result.addElement(LookupElementBuilder.create(name).setIcon(GroovyIcons.PROPERTY).setInsertHandler(NamedArgumentInsertHandler.INSTANCE)); + } + } + } + } + } + } +} From f5530cba105a389b62ce12c29fcce6162b734e6e Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 21:24:05 +0100 Subject: [PATCH 90/94] highlight and prefer members declared in the qualifier type in groovy as well --- .../completion/JavaCompletionUtil.java | 16 +++--- .../GroovyCompletionContributor.java | 10 +--- .../GrCompletionTestWithLibrary.groovy | 53 +++++++++++++++++++ 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java index 6231b25da1ea..8969ae0704a5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -595,7 +595,7 @@ public class JavaCompletionUtil { if (o instanceof PsiMember) { mentioned.add((PsiMember)o); } - set.add(mayHighlight ? highlightIfNeeded(qualifierType, item) : item); + set.add(mayHighlight ? highlightIfNeeded(qualifierType, item, o) : item); } } @@ -658,7 +658,8 @@ public class JavaCompletionUtil { for (CompletionElement completionElement : processor.getResults()) { final LookupElement item = createLookupElement(completionElement, castTo); if (item != null) { - set.add(highlightIfNeeded(castTo, castQualifier(project, item, castItem))); + LookupElement item1 = castQualifier(project, item, castItem); + set.add(highlightIfNeeded(castTo, item1, item1.getObject())); } } return castTo; @@ -696,11 +697,10 @@ public class JavaCompletionUtil { }); } - private static LookupElement highlightIfNeeded(@NotNull PsiType qualifierType, @NotNull LookupElement item) { - Object o = item.getObject(); + public static LookupElement highlightIfNeeded(PsiType qualifierType, LookupElement item, Object object) { if (qualifierType instanceof PsiArrayType) { - if (o instanceof PsiField || o instanceof PsiMethod) { //length and clone() - PsiElement parent = ((PsiElement)o).getParent(); + if (object instanceof PsiField || object instanceof PsiMethod) { //length and clone() + PsiElement parent = ((PsiElement)object).getParent(); if (parent instanceof PsiClass && parent.getContainingFile().getVirtualFile() == null) { //yes, they're a bit dummy return highlight(item); } @@ -708,8 +708,8 @@ public class JavaCompletionUtil { } else if (qualifierType instanceof PsiClassType) { PsiClass qualifierClass = ((PsiClassType)qualifierType).resolve(); - if (o instanceof PsiField || o instanceof PsiMethod || o instanceof PsiClass) { - PsiElement parent = ((PsiElement)o).getParent(); + if (object instanceof PsiField || object instanceof PsiMethod || object instanceof PsiClass) { + PsiClass parent = ((PsiMember)object).getContainingClass(); if (parent != null && parent.equals(qualifierClass)) { return highlight(item); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index 29eb4bddd0c1..23c74940a745 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -368,13 +368,7 @@ public class GroovyCompletionContributor extends CompletionContributor { result.restartCompletionOnPrefixChange(IS_PREFIX); final Map staticMembers = hashMap(); final PsiElement qualifier = reference.getQualifier(); - final PsiType qualifierType; - if (qualifier instanceof GrExpression) { - qualifierType = ((GrExpression)qualifier).getType(); - } - else { - qualifierType = null; - } + final PsiType qualifierType = qualifier instanceof GrExpression ? ((GrExpression)qualifier).getType() : null; final ElementFilter classFilter = getClassFilter(position); @@ -448,7 +442,7 @@ public class GroovyCompletionContributor extends CompletionContributor { if (object instanceof PsiClass && !classFilter.isAcceptable(object, position)) { return; } - result.addElement(lookupElement); + result.addElement(JavaCompletionUtil.highlightIfNeeded(qualifierType, lookupElement, object)); } }); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GrCompletionTestWithLibrary.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GrCompletionTestWithLibrary.groovy index 7ccd12a9a202..cf5bb0c9d232 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GrCompletionTestWithLibrary.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GrCompletionTestWithLibrary.groovy @@ -110,4 +110,57 @@ for (def ch: "abc".toCharArray()) { print ch.toUpperCase() }""" } + + public void testDeclaredMembersGoFirst() { + myFixture.configureByText "a.groovy", """ + class Foo { + def superProp + void fromSuper() {} + void fromSuper2() {} + void overridden() {} + } + + class FooImpl extends Foo { + def thisProp + void overridden() {} + void fromThis() {} + void fromThis2() {} + void fromThis3() {} + void fromThis4() {} + void fromThis5() {} + } + + new FooImpl(). + """ + myFixture.completeBasic() + assertOrderedEquals myFixture.lookupElementStrings,"""\ +fromThis +fromThis2 +fromThis3 +fromThis4 +fromThis5 +overridden +thisProp +class +equals +fromSuper +fromSuper2 +getProperty +hashCode +invokeMethod +metaClass +metaPropertyValues +notify +notifyAll +properties +setProperty +superProp +toString +wait +wait +wait +with\ +""".split('\n') + } + } From a92e8b744af3b69fa1f1edf4f8da7942b4422f6f Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 4 Feb 2011 21:40:26 +0100 Subject: [PATCH 91/94] autopopup after . is also an autopopup and should track editor events --- .../completion/JavaAutoPopupTest.groovy | 17 ++++++ .../codeInsight/AutoPopupController.java | 4 +- .../CompletionAutoPopupHandler.java | 54 ++++++++++--------- 3 files changed, 47 insertions(+), 28 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 afd34e187649..91358a78ea48 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -444,4 +444,21 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { assert !lookup } + public void testResumeAfterBackspace() { + myFixture.configureByText("a.java", """ + class A { + Object foo() { this } + } + """) + type '.' + assert lookup + type 'a' + assert !lookup + type '\b' + assert !lookup + type 'c' + assert lookup + } + + } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java b/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java index d058ddc4c223..e1cf188cc940 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java @@ -16,9 +16,7 @@ package com.intellij.codeInsight; -import com.intellij.codeInsight.completion.CodeCompletionHandlerBase; import com.intellij.codeInsight.completion.CompletionProgressIndicator; -import com.intellij.codeInsight.completion.CompletionType; import com.intellij.codeInsight.completion.impl.CompletionServiceImpl; import com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler; import com.intellij.codeInsight.hint.ShowParameterInfoHandler; @@ -101,7 +99,7 @@ public class AutoPopupController implements Disposable { if (!file.isValid()) return; if (condition != null && !condition.value(file)) return; - new CodeCompletionHandlerBase(CompletionType.BASIC, false, true).invoke(myProject, editor, file); + CompletionAutoPopupHandler.invokeAutoPopupCompletion(myProject, editor); } }; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java index 5c4b2a9c575e..1cf7cfa90d96 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java @@ -112,37 +112,41 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { if (ApplicationManager.getApplication().isWriteAccessAllowed()) return; //it will fail anyway if (DumbService.getInstance(project).isDumb()) return; - new CodeCompletionHandlerBase(CompletionType.BASIC, false, true).invoke(project, editor); - - final AutoPopupState state = new AutoPopupState(project, editor); - editor.putUserData(STATE_KEY, state); - - final Lookup lookup = LookupManager.getActiveLookup(editor); - if (lookup != null) { - lookup.addLookupListener(new LookupAdapter() { - @Override - public void itemSelected(LookupEvent event) { - final AutoPopupState state = getAutoPopupState(editor); - if (state != null) { - state.stopAutoPopup(); - } - } - - @Override - public void lookupCanceled(LookupEvent event) { - final AutoPopupState state = getAutoPopupState(editor); - if (event.isCanceledExplicitly() && state != null) { - state.stopAutoPopup(); - } - } - }); - } + invokeAutoPopupCompletion(project, editor); } }; AutoPopupController.getInstance(project).invokeAutoPopupRunnable(request, CodeInsightSettings.getInstance().AUTO_LOOKUP_DELAY); return Result.STOP; } + public static void invokeAutoPopupCompletion(Project project, final Editor editor) { + new CodeCompletionHandlerBase(CompletionType.BASIC, false, true).invoke(project, editor); + + final AutoPopupState state = new AutoPopupState(project, editor); + editor.putUserData(STATE_KEY, state); + + final Lookup lookup = LookupManager.getActiveLookup(editor); + if (lookup != null) { + lookup.addLookupListener(new LookupAdapter() { + @Override + public void itemSelected(LookupEvent event) { + final AutoPopupState state = getAutoPopupState(editor); + if (state != null) { + state.stopAutoPopup(); + } + } + + @Override + public void lookupCanceled(LookupEvent event) { + final AutoPopupState state = getAutoPopupState(editor); + if (event.isCanceledExplicitly() && state != null) { + state.stopAutoPopup(); + } + } + }); + } + } + @Nullable private static AutoPopupState getAutoPopupState(Editor editor) { return editor.getUserData(STATE_KEY); From 2f90c39631ad39f33aec0f0487a281184a43a7f6 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 7 Feb 2011 12:48:45 +0100 Subject: [PATCH 92/94] autopopup sometimes showed no suggestions --- .../completion/JavaAutoPopupTest.groovy | 16 ++++++++++++++++ .../lookup/impl/BackspaceHandler.java | 11 +++++------ .../codeInsight/lookup/impl/LookupImpl.java | 6 ++++-- 3 files changed, 25 insertions(+), 8 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 91358a78ea48..658c03401b20 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -460,5 +460,21 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { assert lookup } + public void testHideOnInvalidSymbolAfterBackspace() { + myFixture.configureByText("a.java", """ + class A { + Object foo() { this } + } + """) + type '.' + assert lookup + type 'c' + assert lookup + type '\b' + assert lookup + type 'x' + assert !lookup + } + } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/BackspaceHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/BackspaceHandler.java index fb95e19ed5b9..9b77ae0ddd89 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/BackspaceHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/BackspaceHandler.java @@ -16,9 +16,8 @@ package com.intellij.codeInsight.lookup.impl; -import com.intellij.codeInsight.completion.CompletionProcess; import com.intellij.codeInsight.completion.CompletionProgressIndicator; -import com.intellij.codeInsight.completion.CompletionService; +import com.intellij.codeInsight.completion.impl.CompletionServiceImpl; import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.editor.Editor; @@ -45,14 +44,14 @@ public class BackspaceHandler extends EditorActionHandler { } }); - if (lookup.truncatePrefix()) { + final CompletionProgressIndicator process = CompletionServiceImpl.getCompletionService().getCurrentCompletion(); + if (lookup.truncatePrefix(process == null || !process.isAutopopupCompletion())) { return; } if (lookup.getLookupStart() < editor.getCaretModel().getOffset()) { - final CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion(); - if (process instanceof CompletionProgressIndicator) { - ((CompletionProgressIndicator)process).scheduleRestart(); + if (process != null) { + process.scheduleRestart(); return; } } 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 7b334b63176a..a6f963b4775a 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 @@ -317,11 +317,13 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { ListScrollingUtil.ensureIndexIsVisible(myList, myList.getSelectedIndex(), 1); } - public boolean truncatePrefix() { + public boolean truncatePrefix(boolean preserveSelection) { final int len = myAdditionalPrefix.length(); if (len == 0) return false; - markSelectionTouched(); + if (preserveSelection) { + markSelectionTouched(); + } myAdditionalPrefix = myAdditionalPrefix.substring(0, len - 1); myInitialPrefix = null; From f8c6b5d24191e9cd33d3e916e660de7dc530c320 Mon Sep 17 00:00:00 2001 From: "Rustam.Vishnyakov" Date: Mon, 7 Feb 2011 14:51:24 +0300 Subject: [PATCH 93/94] Raw Api Doc support for jQuery (initial download implementation) --- .../LangScriptingContextProvider.java | 8 ++++ .../ui/EditLibraryDialog.form | 18 +++++--- .../ui/EditLibraryDialog.java | 45 +++++++++++++++++-- 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextProvider.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextProvider.java index 33a6324db490..443e67eaf6cb 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextProvider.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextProvider.java @@ -23,6 +23,8 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; + /** * @author Rustam Vishnyakov */ @@ -44,5 +46,11 @@ public abstract class LangScriptingContextProvider { @Nullable public abstract String getDefaultDocUrl(VirtualFile file); + + @Nullable + public abstract String getOfflineDocUrl(String defaultDocUrl); + + @Nullable + public abstract String downloadOfflineDoc(Project project, String offlineDocUrl, JComponent parent); } diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.form b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.form index e547839fa495..413d843568fc 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.form +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.form @@ -91,7 +91,7 @@ - + @@ -109,7 +109,7 @@ - + @@ -117,7 +117,7 @@ - + @@ -136,14 +136,22 @@ - + - + + + + + + + + + diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java index 17cb54b3e73a..baf05e820c89 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java @@ -65,6 +65,7 @@ public class EditLibraryDialog extends DialogWrapper { private JButton myAddDocUrlButton; private JButton myRemoveDocUrlButton; private JBList myDocUrlList; + private JButton myDownloadButton; private Project myProject; private FileTableModel myFileTableModel; private VirtualFile mySelectedFile; @@ -110,6 +111,7 @@ public class EditLibraryDialog extends DialogWrapper { @Override public void intervalAdded(ListDataEvent e) { myRemoveDocUrlButton.setEnabled(true); + checkDownloadOfflineDocEnabled(); } @Override @@ -117,6 +119,7 @@ public class EditLibraryDialog extends DialogWrapper { Object source = e.getSource(); if (source instanceof MyDocUrlListModel && ((MyDocUrlListModel)source).getDocUrls().length == 0) { myRemoveDocUrlButton.setEnabled(false); + checkDownloadOfflineDocEnabled(); } } @@ -133,6 +136,14 @@ public class EditLibraryDialog extends DialogWrapper { } }); + myDownloadButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + downloadDocumentation(); + } + }); + myDownloadButton.setVisible(false); //TODO Remove + myRemoveDocUrlButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -161,6 +172,28 @@ public class EditLibraryDialog extends DialogWrapper { if (docUrls.length > 0) { myRemoveDocUrlButton.setEnabled(true); } + checkDownloadOfflineDocEnabled(); + } + + private void checkDownloadOfflineDocEnabled() { + for (String url : getDocUrls()) { + if (myProvider.getOfflineDocUrl(url) != null) { + myDownloadButton.setEnabled(true); + return; + } + } + myDownloadButton.setEnabled(false); + } + + private void downloadDocumentation() { + for (String url : getDocUrls()) { + String offlineDocUrl = myProvider.getOfflineDocUrl(url); + if (offlineDocUrl != null) { + String targetFile = myProvider.downloadOfflineDoc(myProject, offlineDocUrl, getRootPane()); + myDocUrlListModel.addUrl(targetFile); + return; + } + } } private class MyTableCellRenderer extends DefaultTableCellRenderer { @@ -454,10 +487,13 @@ public class EditLibraryDialog extends DialogWrapper { } public int addUrl(String url) { - myDocUrls.add(url); - int newIndex = myDocUrls.indexOf(url); - fireIntervalAdded(this, newIndex, newIndex); - return newIndex; + if (!myDocUrls.contains(url)) { + myDocUrls.add(url); + int newIndex = myDocUrls.indexOf(url); + fireIntervalAdded(this, newIndex, newIndex); + return newIndex; + } + return myDocUrls.indexOf(url); } public int indexOf(String url) { @@ -491,6 +527,7 @@ public class EditLibraryDialog extends DialogWrapper { int index = myDocUrlListModel.addUrl(url); myDocUrlList.ensureIndexIsVisible(index); myDocUrlList.setSelectedIndex(index); + checkDownloadOfflineDocEnabled(); } } From bdebe3992a71b4c026668eea25b077fc1382aec1 Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 7 Feb 2011 15:00:35 +0300 Subject: [PATCH 94/94] JPS library restored --- .idea/libraries/JPS.xml | 11 +++++++++++ build/build.iml | 1 + 2 files changed, 12 insertions(+) create mode 100644 .idea/libraries/JPS.xml diff --git a/.idea/libraries/JPS.xml b/.idea/libraries/JPS.xml new file mode 100644 index 000000000000..b9dae8260f0d --- /dev/null +++ b/.idea/libraries/JPS.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/build/build.iml b/build/build.iml index 677960ccfaf4..00662eab0dae 100644 --- a/build/build.iml +++ b/build/build.iml @@ -7,6 +7,7 @@ +