From 553147e8bfa37c96e3c426db5674153338a56266 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Wed, 13 Apr 2011 12:10:57 +0400 Subject: [PATCH 001/100] updateGroovyCopyright exception fix --- .../psi/UpdateJavaFileCopyright.java | 7 ++++-- .../UpdateGroovyCopyrightsProvider.java | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/psi/UpdateJavaFileCopyright.java b/plugins/copyright/src/com/maddyhome/idea/copyright/psi/UpdateJavaFileCopyright.java index 211eb5509f21..7a7ec803f769 100644 --- a/plugins/copyright/src/com/maddyhome/idea/copyright/psi/UpdateJavaFileCopyright.java +++ b/plugins/copyright/src/com/maddyhome/idea/copyright/psi/UpdateJavaFileCopyright.java @@ -24,7 +24,6 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.maddyhome.idea.copyright.CopyrightProfile; import com.maddyhome.idea.copyright.options.JavaOptions; -import com.maddyhome.idea.copyright.options.LanguageOptions; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -84,7 +83,7 @@ public class UpdateJavaFileCopyright extends UpdatePsiFileCopyright final List comments = new ArrayList(); collectComments(first, topclass, comments); collectComments(topclass.getFirstChild(), topclass.getModifierList(), comments); - checkComments(topclass.getModifierList(), location == JavaOptions.LOCATION_BEFORE_CLASS, comments); + checkCommentsForTopClass(topclass, location, comments); } else if (location == JavaOptions.LOCATION_BEFORE_CLASS) { @@ -92,6 +91,10 @@ public class UpdateJavaFileCopyright extends UpdatePsiFileCopyright } } + protected void checkCommentsForTopClass(PsiClass topclass, int location, List comments) { + checkComments(topclass.getModifierList(), location == JavaOptions.LOCATION_BEFORE_CLASS, comments); + } + @Nullable protected PsiElement[] getImportsList() { final PsiJavaFile javaFile = (PsiJavaFile)getFile(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/copyright/UpdateGroovyCopyrightsProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/copyright/UpdateGroovyCopyrightsProvider.java index af2d7df463a3..8ae953644721 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/copyright/UpdateGroovyCopyrightsProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/copyright/UpdateGroovyCopyrightsProvider.java @@ -24,12 +24,19 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; import com.maddyhome.idea.copyright.CopyrightProfile; +import com.maddyhome.idea.copyright.options.JavaOptions; import com.maddyhome.idea.copyright.psi.UpdateCopyright; import com.maddyhome.idea.copyright.psi.UpdateCopyrightsProvider; import com.maddyhome.idea.copyright.psi.UpdateJavaFileCopyright; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass; + +import java.util.List; public class UpdateGroovyCopyrightsProvider extends UpdateCopyrightsProvider { public UpdateCopyright createInstance(Project project, Module module, VirtualFile file, FileType base, CopyrightProfile options) { @@ -47,6 +54,21 @@ public class UpdateGroovyCopyrightsProvider extends UpdateCopyrightsProvider { protected PsiElement getPackageStatement() { return ((GroovyFile)getFile()).getPackageDefinition(); } + + @Override + protected void checkCommentsForTopClass(PsiClass topclass, int location, List comments) { + if (!(topclass instanceof GroovyScriptClass)) { + super.checkCommentsForTopClass(topclass, location, comments); + return; + } + final GroovyFile containingFile = (GroovyFile)topclass.getContainingFile(); + + PsiElement last = containingFile.getFirstChild(); + while (last != null && !(last instanceof GrStatement)) { + last = last.getNextSibling(); + } + checkComments(last, location == JavaOptions.LOCATION_BEFORE_CLASS, comments); + } }; } } \ No newline at end of file From 7a8589058483c9b7593538d383ad6c778a4ed8e6 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Wed, 13 Apr 2011 15:17:46 +0400 Subject: [PATCH 002/100] native Groovy lists have ArrayList type --- .../jetbrains/plugins/groovy/lang/psi/impl/GrTupleType.java | 4 ++-- .../plugins/groovy/lang/GroovyMapAttributeTest.groovy | 2 +- .../plugins/groovy/lang/resolve/TypeInferenceTest.java | 2 +- .../groovy/refactoring/extractMethod/implicitReturn.test | 2 +- .../groovy/testdata/highlighting/TupleTypeAssignments.groovy | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrTupleType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrTupleType.java index e2b020587fd8..35ff1dd03080 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrTupleType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrTupleType.java @@ -43,11 +43,11 @@ public class GrTupleType extends GrLiteralClassType { @Override protected String getJavaClassName() { - return CommonClassNames.JAVA_UTIL_LIST; + return CommonClassNames.JAVA_UTIL_ARRAY_LIST; } public String getClassName() { - return "List"; + return "ArrayList"; } @NotNull diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyMapAttributeTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyMapAttributeTest.groovy index 4419d7e2d5d8..5504d04a1c1d 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyMapAttributeTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyMapAttributeTest.groovy @@ -434,7 +434,7 @@ class CccList extends Ccc {} println(new CccMap(foo: [:])) println(new CccList(foo: [])) -println(new CccMap(foo: [])) +println(new CccMap(foo: [])) println(new CccList(foo: [:])) """ } 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 ac8e9b5c568f..c8f43ef182d1 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 @@ -171,7 +171,7 @@ public class TypeInferenceTest extends GroovyResolveTestCase { } public void testTupleWithNullInIt() { - assertTypeEquals("java.util.List", "A.groovy"); + assertTypeEquals("java.util.ArrayList", "A.groovy"); } public void testImplicitlyReturnedMethodCall() { diff --git a/plugins/groovy/testdata/groovy/refactoring/extractMethod/implicitReturn.test b/plugins/groovy/testdata/groovy/refactoring/extractMethod/implicitReturn.test index 5888230be0f0..0e1d7f2e8f48 100644 --- a/plugins/groovy/testdata/groovy/refactoring/extractMethod/implicitReturn.test +++ b/plugins/groovy/testdata/groovy/refactoring/extractMethod/implicitReturn.test @@ -10,7 +10,7 @@ def List getMethodArguments(def methodCall) { return testMethod(methodCall) } -private List testMethod(methodCall) { +private ArrayList testMethod(methodCall) { def argumentsExpression = methodCall.arguments if (respondsTo(argumentsExpression, 'getExpressions')) { return [1, 2, 3] diff --git a/plugins/groovy/testdata/highlighting/TupleTypeAssignments.groovy b/plugins/groovy/testdata/highlighting/TupleTypeAssignments.groovy index 3ff59e526b1c..86688399c05c 100644 --- a/plugins/groovy/testdata/highlighting/TupleTypeAssignments.groovy +++ b/plugins/groovy/testdata/highlighting/TupleTypeAssignments.groovy @@ -1,5 +1,5 @@ def foo = [1, 2, 3] -Double d = [1, 2, 3] -List list = ["1", "2"] +Double d = [1, 2, 3] +List list = ["1", "2"] List doubleList = [1, 2] List secondDoubleList = [1.2, 2.5] \ No newline at end of file From b7f5f0d87dcee88e16f8512f81370c0267f2c7ef Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Wed, 13 Apr 2011 15:27:25 +0400 Subject: [PATCH 003/100] ArrayList in CommonClassNames --- java/openapi/src/com/intellij/psi/CommonClassNames.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/openapi/src/com/intellij/psi/CommonClassNames.java b/java/openapi/src/com/intellij/psi/CommonClassNames.java index da485d201129..664976bb0cb0 100644 --- a/java/openapi/src/com/intellij/psi/CommonClassNames.java +++ b/java/openapi/src/com/intellij/psi/CommonClassNames.java @@ -79,4 +79,5 @@ public interface CommonClassNames { @NonNls String CLASS_FILE_EXTENSION = ".class"; @NonNls String JAVA_UTIL_CONCURRENT_FUTURE = "java.util.concurrent.Future"; + @NonNls String JAVA_UTIL_ARRAY_LIST = "java.util.ArrayList"; } From 0fe604b59e1ed0fa3a95014f068da38a13c210a7 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Wed, 13 Apr 2011 20:54:30 +0200 Subject: [PATCH 004/100] XDebugger: auto-focusing Console/Frames tabs when necessary (like in Java-debugger) --- .../debugger/ui/DebuggerSessionTab.java | 11 ++- .../actions/FocusOnBreakpointAction.java | 4 +- .../ui/layout/LayoutViewOptions.java | 2 + .../src/messages/XDebuggerBundle.properties | 3 + .../com/intellij/xdebugger/XDebugSession.java | 3 + .../xdebugger/impl/XDebugSessionImpl.java | 14 ++++ .../xdebugger/impl/ui/XDebugSessionTab.java | 72 ++----------------- .../src/messages/DebuggerBundle.properties | 1 - 8 files changed, 35 insertions(+), 75 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java index a95baf60fdf6..16775fddc8f3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java @@ -94,7 +94,6 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos private ExecutionEnvironment myEnvironment; private RunProfile myConfiguration; - public static final String BREAKPOINT_CONDITION = "breakpoint"; private final ThreadsPanel myThreadsPanel; private static final String THREAD_DUMP_CONTENT_PREFIX = "Dump"; private final Icon myIcon; @@ -104,10 +103,10 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos myIcon = icon; - myUi = RunnerLayoutUi.Factory.getInstance(project).create("JavaDebugger", DebuggerBundle.message("title.generic.debug.dialog"), sessionName, this); + myUi = RunnerLayoutUi.Factory.getInstance(project).create("JavaDebugger", XDebuggerBundle.message("xdebugger.default.content.title"), sessionName, this); - myUi.getDefaults().initTabDefaults(0, "Debugger", null). - initFocusContent(DebuggerContentInfo.FRAME_CONTENT, BREAKPOINT_CONDITION). + myUi.getDefaults().initTabDefaults(0, XDebuggerBundle.message("xdebugger.debugger.tab.title"), null). + initFocusContent(DebuggerContentInfo.FRAME_CONTENT, LayoutViewOptions.BREAKPOINT_CONDITION). initFocusContent(DebuggerContentInfo.CONSOLE_CONTENT, LayoutViewOptions.STARTUP, new LayoutAttractionPolicy.FocusOnce(false)); final DefaultActionGroup focus = new DefaultActionGroup(); @@ -479,9 +478,9 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos private void attractFramesOnPause(final int event) { if (DebuggerSession.EVENT_PAUSE == event) { - myUi.attractBy(BREAKPOINT_CONDITION); + myUi.attractBy(LayoutViewOptions.BREAKPOINT_CONDITION); } else if (DebuggerSession.EVENT_RESUME == event) { - myUi.clearAttractionBy(BREAKPOINT_CONDITION); + myUi.clearAttractionBy(LayoutViewOptions.BREAKPOINT_CONDITION); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/actions/FocusOnBreakpointAction.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/actions/FocusOnBreakpointAction.java index 74c2b60220ed..d248c4a0db9e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/actions/FocusOnBreakpointAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/actions/FocusOnBreakpointAction.java @@ -16,10 +16,10 @@ package com.intellij.debugger.ui.breakpoints.actions; import com.intellij.execution.ui.actions.AbstractFocusOnAction; -import com.intellij.debugger.ui.DebuggerSessionTab; +import com.intellij.execution.ui.layout.LayoutViewOptions; public class FocusOnBreakpointAction extends AbstractFocusOnAction { public FocusOnBreakpointAction() { - super(DebuggerSessionTab.BREAKPOINT_CONDITION); + super(LayoutViewOptions.BREAKPOINT_CONDITION); } } \ No newline at end of file diff --git a/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutViewOptions.java b/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutViewOptions.java index d312a3186ab4..a71581ba1170 100644 --- a/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutViewOptions.java +++ b/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutViewOptions.java @@ -16,6 +16,7 @@ package com.intellij.execution.ui.layout; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import com.intellij.openapi.actionSystem.ActionGroup; @@ -25,6 +26,7 @@ import com.intellij.ui.content.Content; public interface LayoutViewOptions { String STARTUP = "startup"; + String BREAKPOINT_CONDITION = "breakpoint"; @NotNull LayoutViewOptions setTopToolbar(@NotNull ActionGroup actions, @NotNull String place); diff --git a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties index 1a348fb16065..3d8a4ddef3a1 100644 --- a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties +++ b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties @@ -2,6 +2,9 @@ xdebugger.colors.page.name=Debugger debugger.configurable.display.name=Debugger +xdebugger.default.content.title=Debug +xdebugger.debugger.tab.title=Debugger + xdebugger.remove.line.breakpoint.action.text=Remove xdebugger.disable.breakpoint.action.text=Disable xdebugger.enable.breakpoint.action.text=Enable diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java index 86453dbf60be..00b5143ce45a 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java @@ -19,6 +19,7 @@ package com.intellij.xdebugger; import com.intellij.execution.configurations.RunProfile; import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.execution.ui.RunnerLayoutUi; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.xdebugger.breakpoints.XBreakpoint; @@ -135,4 +136,6 @@ public interface XDebugSession extends AbstractDebuggerSession { void updateExecutionPosition(); ConsoleView getConsoleView(); + + RunnerLayoutUi getUI(); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index 14da42c4b621..c4f81befec53 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -28,6 +28,8 @@ import com.intellij.execution.runners.ProgramRunner; import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.execution.ui.RunnerLayoutUi; +import com.intellij.execution.ui.layout.LayoutViewOptions; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.application.Result; import com.intellij.openapi.diagnostic.Logger; @@ -217,6 +219,11 @@ public class XDebugSessionImpl implements XDebugSession { return mySessionTab; } + @Override + public RunnerLayoutUi getUI() { + return mySessionTab.getUi(); + } + private void initSessionTab() { mySessionTab = new XDebugSessionTab(myProject, mySessionName); if (myEnvironment != null) { @@ -408,6 +415,12 @@ public class XDebugSessionImpl implements XDebugSession { myCurrentStackFrame = null; myCurrentPosition = null; myPaused = false; + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + mySessionTab.getUi().clearAttractionBy(LayoutViewOptions.BREAKPOINT_CONDITION); + } + }); myDispatcher.getMulticaster().sessionResumed(); } @@ -574,6 +587,7 @@ public class XDebugSessionImpl implements XDebugSession { showSessionTab(); } mySessionTab.toFront(); + mySessionTab.getUi().attractBy(LayoutViewOptions.BREAKPOINT_CONDITION); } }); myDispatcher.getMulticaster().sessionPaused(); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java index 3f2b06d4a977..d29928bca354 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java @@ -29,6 +29,8 @@ import com.intellij.execution.ui.ExecutionConsole; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.ui.RunnerLayoutUi; import com.intellij.execution.ui.actions.CloseAction; +import com.intellij.execution.ui.layout.LayoutAttractionPolicy; +import com.intellij.execution.ui.layout.LayoutViewOptions; import com.intellij.execution.ui.layout.PlaceInGrid; import com.intellij.ide.CommonActionsManager; import com.intellij.ide.actions.ContextHelpAction; @@ -68,7 +70,10 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { mySessionName = sessionName; myUi = RunnerLayoutUi.Factory.getInstance(project).create("Debug", "unknown!", sessionName, this); - myUi.getDefaults().initTabDefaults(0, "Debug", null); + myUi.getDefaults() + .initTabDefaults(0, XDebuggerBundle.message("xdebugger.debugger.tab.title"), null) + .initFocusContent(DebuggerContentInfo.FRAME_CONTENT, LayoutViewOptions.BREAKPOINT_CONDITION) + .initFocusContent(DebuggerContentInfo.CONSOLE_CONTENT, LayoutViewOptions.STARTUP, new LayoutAttractionPolicy.FocusOnce(false)); } private static ActionGroup getActionGroup(final String id) { @@ -201,71 +206,6 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { return myRunContentDescriptor; } - private RunContentDescriptor initUI(final @NotNull XDebugSession session, final @NotNull XDebugSessionData sessionData, - final @Nullable ExecutionEnvironment environment, - final @Nullable ProgramRunner runner, - ConsoleView consoleView) { - final XDebugProcess debugProcess = session.getDebugProcess(); - ProcessHandler processHandler = debugProcess.getProcessHandler(); - myConsole = consoleView; - myRunContentDescriptor = new RunContentDescriptor(myConsole, processHandler, myUi.getComponent(), mySessionName); - - myUi.addContent(createFramesContent(session), 0, PlaceInGrid.left, false); - myUi.addContent(createVariablesContent(session), 0, PlaceInGrid.center, false); - myUi.addContent(createWatchesContent(session, sessionData), 0, PlaceInGrid.right, false); - final Content consoleContent = createConsoleContent(); - myUi.addContent(consoleContent, 1, PlaceInGrid.bottom, false); - attachNotificationTo(consoleContent); - - session.getDebugProcess().registerAdditionalContent(myUi); - RunContentBuilder.addAdditionalConsoleEditorActions(myConsole, consoleContent); - myUi.addContent(consoleContent, 0, PlaceInGrid.bottom, false); - - if (ApplicationManager.getApplication().isUnitTestMode()) { - return myRunContentDescriptor; - } - - DefaultActionGroup leftToolbar = new DefaultActionGroup(); - final Executor executor = DefaultDebugExecutor.getDebugExecutorInstance(); - if (runner != null && environment != null) { - RestartAction restartAction = new RestartAction(executor, runner, myRunContentDescriptor.getProcessHandler(), XDebuggerUIConstants.DEBUG_AGAIN_ICON, - myRunContentDescriptor, environment); - leftToolbar.add(restartAction); - restartAction.registerShortcut(myUi.getComponent()); - } - - leftToolbar.addAll(getActionGroup(XDebuggerActions.TOOL_WINDOW_LEFT_TOOLBAR_GROUP)); - - //group.addSeparator(); - //addAction(group, DebuggerActions.EXPORT_THREADS); - leftToolbar.addSeparator(); - - leftToolbar.add(myUi.getOptions().getLayoutActions()); - - leftToolbar.addSeparator(); - - leftToolbar.add(PinToolwindowTabAction.getPinAction()); - leftToolbar.add(new CloseAction(executor, myRunContentDescriptor, getProject())); - leftToolbar.add(new ContextHelpAction(executor.getHelpId())); - - DefaultActionGroup topToolbar = new DefaultActionGroup(); - topToolbar.addAll(getActionGroup(XDebuggerActions.TOOL_WINDOW_TOP_TOOLBAR_GROUP)); - - session.getDebugProcess().registerAdditionalActions(leftToolbar, topToolbar); - myUi.getOptions().setLeftToolbar(leftToolbar, ActionPlaces.DEBUGGER_TOOLBAR); - myUi.getOptions().setTopToolbar(topToolbar, ActionPlaces.DEBUGGER_TOOLBAR); - - if (environment != null) { - final RunProfile runConfiguration = environment.getRunProfile(); - registerFileMatcher(runConfiguration); - initLogConsoles(runConfiguration, myRunContentDescriptor.getProcessHandler()); - } - - rebuildViews(); - - return myRunContentDescriptor; - } - public RunnerLayoutUi getUi() { return myUi; } diff --git a/resources-en/src/messages/DebuggerBundle.properties b/resources-en/src/messages/DebuggerBundle.properties index 9239dd87a967..d0acc93f0c4c 100644 --- a/resources-en/src/messages/DebuggerBundle.properties +++ b/resources-en/src/messages/DebuggerBundle.properties @@ -69,7 +69,6 @@ error.vm.disconnected=VM disconnected. Target virtual machine closed connection error.unknown.host=Cannot connect to remote process, host is unknown error.cannot.open.debugger.port=Unable to open debugger port error.exception.while.connecting=Error connecting to remote process.\nException occurred: {0}\nException message: {1} -title.generic.debug.dialog=Debug status.waiting.attach=Debugger is waiting for application to start; debug address: ''{0}''; transport: ''{1}'' status.listening=Listening to the connection, address: ''{0}'', transport: ''{1}'' status.connecting=Connecting to the target VM, address: ''{0}'', transport: ''{1}'' From 5e1e51ed21470ee0e87b35f87bca4dbd41536fba Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Wed, 13 Apr 2011 23:05:04 +0400 Subject: [PATCH 005/100] IDEA-68051 Database support: encoding of .ids files is system default --- .../intellij/execution/console/ConsoleHistoryController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java index 94c2086dd306..ca98abdf0048 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java +++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java @@ -285,7 +285,7 @@ public class ConsoleHistoryController { } private void saveHistory(final XmlSerializer out) throws IOException { - out.startDocument(System.getProperty(CharsetToolkit.FILE_ENCODING_PROPERTY), null); + out.startDocument("UTF8", null); out.startTag(null, "console-history"); out.attribute(null, "id", myId); for (String s : myModel.getHistory()) { From 4cfe2bf18a3a02c0f8e8b35d6d86920f56b61ba9 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 12 Apr 2011 20:02:25 +0200 Subject: [PATCH 006/100] use QueryExecutorBase --- .../psi/search/SingleTargetRequestResultProcessor.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/lang-api/src/com/intellij/psi/search/SingleTargetRequestResultProcessor.java b/platform/lang-api/src/com/intellij/psi/search/SingleTargetRequestResultProcessor.java index 9c9628ec91da..edd55f417dfe 100644 --- a/platform/lang-api/src/com/intellij/psi/search/SingleTargetRequestResultProcessor.java +++ b/platform/lang-api/src/com/intellij/psi/search/SingleTargetRequestResultProcessor.java @@ -7,6 +7,8 @@ import com.intellij.psi.ReferenceRange; import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; +import java.util.List; + /** * @author peter */ @@ -20,7 +22,9 @@ public final class SingleTargetRequestResultProcessor extends RequestResultProce } public boolean processTextOccurrence(PsiElement element, int offsetInElement, final Processor consumer) { - for (PsiReference ref : ourReferenceService.getReferences(element, new PsiReferenceService.Hints(myTarget, offsetInElement))) { + final List references = ourReferenceService.getReferences(element, + new PsiReferenceService.Hints(myTarget, offsetInElement)); + for (PsiReference ref : references) { if (ReferenceRange.containsOffsetInElement(ref, offsetInElement)) { if (ref.isReferenceTo(myTarget)) { if (!consumer.process(ref)) { From b7c703783692b260130d9223d7fb0e18d71d43ed Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 13 Apr 2011 13:29:02 +0200 Subject: [PATCH 007/100] exception tolerance (PY-3334 & friends) --- .../intellij/openapi/application/impl/ApplicationImpl.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index a878e19483cc..d679cecbe8db 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -486,7 +486,12 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application ExtensionPoint point = Extensions.getRootArea().getExtensionPoint("com.intellij.ApplicationLoadListener"); final ApplicationLoadListener[] objects = point.getExtensions(); for (ApplicationLoadListener object : objects) { - object.beforeApplicationLoaded(this); + try { + object.beforeApplicationLoaded(this); + } + catch(Exception e) { + LOG.error(e); + } } } From 5eb3e4d48852dd27f08583d922e0803ee6e5f259 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 13 Apr 2011 17:14:02 +0200 Subject: [PATCH 008/100] IDEA-41363 --- .../src/com/intellij/uiDesigner/editor/UIFormEditor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/editor/UIFormEditor.java b/plugins/ui-designer/src/com/intellij/uiDesigner/editor/UIFormEditor.java index 39dd6b9c1e23..23993b22377f 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/editor/UIFormEditor.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/editor/UIFormEditor.java @@ -80,7 +80,7 @@ public final class UIFormEditor extends UserDataHolderBase implements /*Navigata } public boolean isModified(){ - return FileDocumentManager.getInstance().isFileModified(myFile); + return false; } public boolean isValid(){ From 9a915100d3732b5e05cac5d77d8d37517c4b4d2d Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 13 Apr 2011 17:12:13 +0200 Subject: [PATCH 009/100] @Nullable --- .../psi/impl/PsiJavaParserFacadeImpl.java | 46 ++++++++++--------- .../com/intellij/psi/PsiJavaParserFacade.java | 46 +++++++++---------- 2 files changed, 47 insertions(+), 45 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java b/java/java-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java index 42dd27340cf9..5dc7bdf197ce 100644 --- a/java/java-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java @@ -170,7 +170,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiAnnotation createAnnotationFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiAnnotation createAnnotationFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, ANNOTATION, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiAnnotation)) { @@ -187,7 +187,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiDocTag createDocTagFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiDocTag createDocTagFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { return createDocTagFromText(text); } @@ -202,13 +202,13 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiDocComment createDocCommentFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiDocComment createDocCommentFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { return createDocCommentFromText(text); } @NotNull @Override - public PsiClass createClassFromText(@NotNull final String body, final PsiElement context) throws IncorrectOperationException { + public PsiClass createClassFromText(@NotNull final String body, @Nullable final PsiElement context) throws IncorrectOperationException { final PsiJavaFile aFile = createDummyJavaFile(StringUtil.join("class _Dummy_ { ", body, " }")); final PsiClass[] classes = aFile.getClasses(); if (classes.length != 1) { @@ -219,7 +219,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiField createFieldFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiField createFieldFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, DECLARATION, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiField)) { @@ -230,7 +230,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiMethod createMethodFromText(@NotNull final String text, final PsiElement context, final LanguageLevel level) throws IncorrectOperationException { + public PsiMethod createMethodFromText(@NotNull final String text, @Nullable final PsiElement context, final LanguageLevel level) throws IncorrectOperationException { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, DECLARATION, level), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiMethod)) { @@ -241,14 +241,14 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public final PsiMethod createMethodFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public final PsiMethod createMethodFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { final LanguageLevel level = LanguageLevelProjectExtension.getInstance(myManager.getProject()).getLanguageLevel(); return createMethodFromText(text, context, level); } @NotNull @Override - public PsiParameter createParameterFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiParameter createParameterFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, PARAMETER, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiParameter)) { @@ -259,7 +259,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiResourceVariable createResourceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiResourceVariable createResourceFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, RESOURCE, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiResourceVariable)) { @@ -270,13 +270,13 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiType createTypeFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiType createTypeFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { return createTypeInner(text, context, false); } @NotNull @Override - public PsiTypeElement createTypeElementFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiTypeElement createTypeElementFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, TYPE, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiTypeElement)) { @@ -285,7 +285,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ return (PsiTypeElement)element; } - protected PsiType createTypeInner(final String text, final PsiElement context, final boolean markAsCopy) throws IncorrectOperationException { + protected PsiType createTypeInner(final String text, @Nullable final PsiElement context, final boolean markAsCopy) throws IncorrectOperationException { final PsiPrimitiveType primitiveType = PRIMITIVE_TYPES.get(text); if (primitiveType != null) return primitiveType; @@ -298,7 +298,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiJavaCodeReferenceElement createReferenceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiJavaCodeReferenceElement createReferenceFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { final boolean isStaticImport = context instanceof PsiImportStaticStatement && !((PsiImportStaticStatement)context).isOnDemand(); final boolean mayHaveDiamonds = context instanceof PsiNewExpression && @@ -314,7 +314,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiCodeBlock createCodeBlockFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiCodeBlock createCodeBlockFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, CODE_BLOCK, level(context), true), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiCodeBlock)) { @@ -325,7 +325,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiStatement createStatementFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiStatement createStatementFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, STATEMENT, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiStatement)) { @@ -336,7 +336,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiExpression createExpressionFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiExpression createExpressionFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, EXPRESSION, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiExpression)) { @@ -353,7 +353,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiTypeParameter createTypeParameterFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiTypeParameter createTypeParameterFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, TYPE_PARAMETER, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiTypeParameter)) { @@ -364,7 +364,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiComment createCommentFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiComment createCommentFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { final PsiJavaFile aFile = createDummyJavaFile(text); for (PsiElement aChildren : aFile.getChildren()) { if (aChildren instanceof PsiComment) { @@ -382,7 +382,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiEnumConstant createEnumConstantFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { + public PsiEnumConstant createEnumConstantFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, ENUM_CONSTANT, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiEnumConstant)) { @@ -393,8 +393,9 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override - public PsiCatchSection createCatchSection(@NotNull final PsiClassType exceptionType, @NotNull final String exceptionName, - final PsiElement context) throws IncorrectOperationException { + public PsiCatchSection createCatchSection(@NotNull final PsiClassType exceptionType, + @NotNull final String exceptionName, + @Nullable final PsiElement context) throws IncorrectOperationException { final String text = StringUtil .join("catch (", exceptionType.getCanonicalText(), " ", exceptionName, ") {}"); final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, CATCH_SECTION, level(context)), context); @@ -406,7 +407,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ return (PsiCatchSection)myManager.getCodeStyleManager().reformat(element); } - private void setupCatchBlock(final String exceptionName, final PsiElement context, final PsiCatchSection psiCatchSection) + private void setupCatchBlock(final String exceptionName, @Nullable final PsiElement context, final PsiCatchSection psiCatchSection) throws IncorrectOperationException { final FileTemplate catchBodyTemplate = FileTemplateManager.getInstance().getCodeTemplate(JavaTemplateUtil.TEMPLATE_CATCH_BODY); LOG.assertTrue(catchBodyTemplate != null); @@ -433,6 +434,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ psiCatchSection.getCatchBlock().replace(codeBlockFromText); } + @NotNull @Override public PsiType createPrimitiveType(@NotNull final String text, @NotNull final PsiAnnotation[] annotations) throws IncorrectOperationException { final PsiPrimitiveType primitiveType = getPrimitiveType(text); diff --git a/java/openapi/src/com/intellij/psi/PsiJavaParserFacade.java b/java/openapi/src/com/intellij/psi/PsiJavaParserFacade.java index 332f2f2928f2..7029a6ff4a60 100644 --- a/java/openapi/src/com/intellij/psi/PsiJavaParserFacade.java +++ b/java/openapi/src/com/intellij/psi/PsiJavaParserFacade.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.psi; import com.intellij.pom.java.LanguageLevel; @@ -22,8 +21,9 @@ import com.intellij.psi.javadoc.PsiDocTag; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -/* +/** * @author max */ public interface PsiJavaParserFacade extends PsiParserFacade { @@ -41,7 +41,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @deprecated use {@link #createDocTagFromText(String)} (to remove in IDEA 11) */ @NotNull - PsiDocTag createDocTagFromText(@NotNull String docTagText, PsiElement context) throws IncorrectOperationException; + PsiDocTag createDocTagFromText(@NotNull String docTagText, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a JavaDoc comment from the specified text. @@ -57,7 +57,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @deprecated use {@link #createDocCommentFromText(String)} (to remove in IDEA 11) */ @NotNull - PsiDocComment createDocCommentFromText(@NotNull String docCommentText, PsiElement context) throws IncorrectOperationException; + PsiDocComment createDocCommentFromText(@NotNull String docCommentText, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a Java class from the specified text. @@ -69,7 +69,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text is not a valid class body. */ @NotNull - PsiClass createClassFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException; + PsiClass createClassFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a Java field from the specified text. @@ -80,7 +80,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text is not a valid field body. */ @NotNull - PsiField createFieldFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException; + PsiField createFieldFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a Java method from the specified text with the specified language level. @@ -92,7 +92,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text is not a valid method body. */ @NotNull - PsiMethod createMethodFromText(@NotNull @NonNls String text, PsiElement context, LanguageLevel languageLevel) throws IncorrectOperationException; + PsiMethod createMethodFromText(@NotNull @NonNls String text, @Nullable PsiElement context, LanguageLevel languageLevel) throws IncorrectOperationException; /** * Creates a Java method from the specified text. @@ -103,7 +103,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text is not a valid method body. */ @NotNull - PsiMethod createMethodFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException; + PsiMethod createMethodFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a Java parameter from the specified text. @@ -114,7 +114,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text is not a valid parameter body. */ @NotNull - PsiParameter createParameterFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException; + PsiParameter createParameterFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a Java try-resource from the specified text. @@ -125,7 +125,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text is not a valid resource definition. */ @NotNull - PsiResourceVariable createResourceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException; + PsiResourceVariable createResourceFromText(@NotNull String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a Java type from the specified text. @@ -137,7 +137,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid type. */ @NotNull - PsiType createTypeFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException; + PsiType createTypeFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a Java type element from the specified text. @@ -149,7 +149,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid type. */ @NotNull - PsiTypeElement createTypeElementFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException; + PsiTypeElement createTypeElementFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a Java code reference from the specified text. @@ -161,7 +161,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid type. */ @NotNull - PsiJavaCodeReferenceElement createReferenceFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException; + PsiJavaCodeReferenceElement createReferenceFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a Java code block from the specified text. @@ -172,7 +172,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid code block. */ @NotNull - PsiCodeBlock createCodeBlockFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException; + PsiCodeBlock createCodeBlockFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a Java statement from the specified text. @@ -183,7 +183,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid statement. */ @NotNull - PsiStatement createStatementFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException; + PsiStatement createStatementFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a Java expression from the specified text. @@ -194,7 +194,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid expression. */ @NotNull - PsiExpression createExpressionFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException; + PsiExpression createExpressionFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a Java comment from the specified text. @@ -205,7 +205,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid comment. */ @NotNull - PsiComment createCommentFromText(@NotNull String text, PsiElement context) throws IncorrectOperationException; + PsiComment createCommentFromText(@NotNull String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a type parameter from the specified text. @@ -216,7 +216,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid type parameter. */ @NotNull - PsiTypeParameter createTypeParameterFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException; + PsiTypeParameter createTypeParameterFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates an annotation from the specified text. @@ -227,11 +227,10 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid annotation. */ @NotNull - PsiAnnotation createAnnotationFromText(@NotNull @NonNls String annotationText, PsiElement context) throws IncorrectOperationException; + PsiAnnotation createAnnotationFromText(@NotNull @NonNls String annotationText, @Nullable PsiElement context) throws IncorrectOperationException; @NotNull - PsiEnumConstant createEnumConstantFromText(@NotNull String text, PsiElement context) throws IncorrectOperationException; - + PsiEnumConstant createEnumConstantFromText(@NotNull String text, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a catch section for catching an exception of the specified @@ -243,8 +242,8 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @return the created catch section instance. * @throws IncorrectOperationException if some of the parameters are not valid. */ - @NotNull PsiCatchSection createCatchSection(@NotNull PsiClassType exceptionType, @NotNull String exceptionName, PsiElement context) - throws IncorrectOperationException; + @NotNull + PsiCatchSection createCatchSection(@NotNull PsiClassType exceptionType, @NotNull String exceptionName, @Nullable PsiElement context) throws IncorrectOperationException; /** * Creates a Java type from the specified text. @@ -254,5 +253,6 @@ public interface PsiJavaParserFacade extends PsiParserFacade { * @return the created type instance. * @throws IncorrectOperationException if some of the parameters are not valid. */ + @NotNull PsiType createPrimitiveType(@NotNull String text, @NotNull PsiAnnotation[] annotations) throws IncorrectOperationException; } From 17c21afadfc4c686a2953f6c938902dcb0370d69 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 13 Apr 2011 18:13:44 +0200 Subject: [PATCH 010/100] Little fix in Java parser facade (correctly create class members with comments) --- .../src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java b/java/java-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java index 5dc7bdf197ce..827ae506379a 100644 --- a/java/java-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java @@ -209,7 +209,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override public PsiClass createClassFromText(@NotNull final String body, @Nullable final PsiElement context) throws IncorrectOperationException { - final PsiJavaFile aFile = createDummyJavaFile(StringUtil.join("class _Dummy_ { ", body, " }")); + final PsiJavaFile aFile = createDummyJavaFile(StringUtil.join("class _Dummy_ {\n", body, "\n}")); final PsiClass[] classes = aFile.getClasses(); if (classes.length != 1) { throw new IncorrectOperationException("Incorrect class \"" + body + "\"."); From cc68adee4ecfe59a5c90d9770ffa87891b9cf28b Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 13 Apr 2011 19:32:43 +0200 Subject: [PATCH 011/100] Cleanup --- .../move/moveMembers/MockMoveMembersOptions.java | 4 ++-- .../intellij/refactoring/BaseRefactoringProcessor.java | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/java/testFramework/src/com/intellij/refactoring/move/moveMembers/MockMoveMembersOptions.java b/java/testFramework/src/com/intellij/refactoring/move/moveMembers/MockMoveMembersOptions.java index b10bc2e57495..bc6b7473ad2b 100644 --- a/java/testFramework/src/com/intellij/refactoring/move/moveMembers/MockMoveMembersOptions.java +++ b/java/testFramework/src/com/intellij/refactoring/move/moveMembers/MockMoveMembersOptions.java @@ -17,6 +17,7 @@ package com.intellij.refactoring.move.moveMembers; import com.intellij.psi.PsiMember; import com.intellij.psi.PsiModifier; +import org.jetbrains.annotations.Nullable; import java.util.Collection; @@ -47,7 +48,7 @@ public class MockMoveMembersOptions implements MoveMembersOptions { return true; } - public void setMemberVisibility(String visibility) { + public void setMemberVisibility(@Nullable String visibility) { myMemberVisibility = visibility; } @@ -60,5 +61,4 @@ public class MockMoveMembersOptions implements MoveMembersOptions { public String getTargetClassName() { return myTargetClassName; } - } diff --git a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java index a5670b2e26b8..d8c4d996c419 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java +++ b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java @@ -149,7 +149,7 @@ public abstract class BaseRefactoringProcessor { final Ref refUsages = new Ref(); final Ref refErrorLanguage = new Ref(); final Ref refProcessCanceled = new Ref(); - final Ref dumbModeOccured = new Ref(); + final Ref dumbModeOccurred = new Ref(); final Runnable findUsagesRunnable = new Runnable() { public void run() { @@ -163,7 +163,7 @@ public abstract class BaseRefactoringProcessor { refProcessCanceled.set(Boolean.TRUE); } catch (IndexNotReadyException e) { - dumbModeOccured.set(Boolean.TRUE); + dumbModeOccurred.set(Boolean.TRUE); } } }; @@ -176,13 +176,12 @@ public abstract class BaseRefactoringProcessor { Messages.showErrorDialog(myProject, RefactoringBundle.message("unsupported.refs.found", refErrorLanguage.get().getDisplayName()), RefactoringBundle.message("error.title")); return; } - if (!dumbModeOccured.isNull()) { + if (!dumbModeOccurred.isNull()) { DumbService.getInstance(myProject).showDumbModeNotification("Usage search is not available until indices are ready"); return; } if (!refProcessCanceled.isNull()) { - Messages.showErrorDialog(myProject, "Index corruption detected. Please retry the refactoring - indexes will be rebuilt automatically", - RefactoringBundle.message("error.title")); + Messages.showErrorDialog(myProject, "Index corruption detected. Please retry the refactoring - indexes will be rebuilt automatically", RefactoringBundle.message("error.title")); return; } From c5adb0d74ec4bfecd6a1ece0f7dfee521945358d Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Apr 2011 00:30:19 +0200 Subject: [PATCH 012/100] some logging for mysteriously failing tests --- .../util/xml/impl/FileDescriptionCachedValueProvider.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/FileDescriptionCachedValueProvider.java b/xml/dom-impl/src/com/intellij/util/xml/impl/FileDescriptionCachedValueProvider.java index 8a1f6cf54cf2..bc6b082c39be 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/FileDescriptionCachedValueProvider.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/FileDescriptionCachedValueProvider.java @@ -15,6 +15,7 @@ */ package com.intellij.util.xml.impl; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Key; @@ -68,7 +69,11 @@ class FileDescriptionCachedValueProvider implements SemEle public final DomFileElementImpl getFileElement() { if (myComputed) return myLastResult; - DomFileElementImpl result = _computeFileElement(false, getRootTag(), null); + final StringBuilder log = ApplicationManager.getApplication().isUnitTestMode() ? new StringBuilder() : null; + DomFileElementImpl result = _computeFileElement(false, getRootTag(), log); + if (log != null && result == null) { + System.out.println(log); + } synchronized (myCondition) { if (myComputed) return myLastResult; From da3c058a190f183066840ca55c0a74645c128310 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 14 Apr 2011 10:28:25 +0400 Subject: [PATCH 013/100] show warning when unable to modify --- .../lang-impl/src/com/intellij/ide/util/DeleteHandler.java | 7 ++++--- .../intellij/refactoring/inline/GenericInlineHandler.java | 2 +- .../intellij/refactoring/safeDelete/SafeDeleteHandler.java | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java b/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java index a458b57396e3..99c6273904e2 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java +++ b/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java @@ -31,6 +31,7 @@ import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.ex.MessagesEx; import com.intellij.openapi.vfs.VirtualFile; @@ -112,10 +113,10 @@ public class DeleteHandler { if (safeDeleteApplicable && !dumb) { DeleteDialog dialog = new DeleteDialog(project, elements, new DeleteDialog.Callback() { public void run(final DeleteDialog dialog) { - if (!CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, Arrays.asList(elements))) return; + if (!CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, Arrays.asList(elements), true)) return; SafeDeleteProcessor.createInstance(project, new Runnable() { public void run() { - dialog.close(DeleteDialog.CANCEL_EXIT_CODE); + dialog.close(DialogWrapper.CANCEL_EXIT_CODE); } }, elements, dialog.isSearchInComments(), dialog.isSearchInNonJava(), true).run(); } @@ -174,7 +175,7 @@ public class DeleteHandler { ArrayList readOnlyFiles = new ArrayList(); getReadOnlyVirtualFiles(virtualFile, readOnlyFiles, ftManager); - if (readOnlyFiles.size() > 0) { + if (!readOnlyFiles.isEmpty()) { int _result = Messages.showYesNoDialog(project, IdeBundle.message("prompt.directory.contains.read.only.files", virtualFile.getPresentableUrl()), IdeBundle.message("title.delete"), Messages.getQuestionIcon()); diff --git a/platform/lang-impl/src/com/intellij/refactoring/inline/GenericInlineHandler.java b/platform/lang-impl/src/com/intellij/refactoring/inline/GenericInlineHandler.java index 875bee27ff72..207d28df1ae1 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/inline/GenericInlineHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/inline/GenericInlineHandler.java @@ -119,7 +119,7 @@ public class GenericInlineHandler { elements.add(element); } - if (!CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, elements)) { + if (!CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, elements, true)) { return true; } ApplicationManager.getApplication().runWriteAction(new Runnable() { diff --git a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java index 190ba8e8c501..2f3f3db0ff6c 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java @@ -96,7 +96,7 @@ public class SafeDeleteHandler implements RefactoringActionHandler { ContainerUtil.addAll(fullElementsSet, temptoDelete); } - if (!CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, fullElementsSet)) return; + if (!CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, fullElementsSet, true)) return; final PsiElement[] elementsToDelete = PsiUtilBase.toPsiElementArray(fullElementsSet); From 636f5cf38c859fb079da854f27cfe4ca553b2de7 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 13 Apr 2011 19:31:27 +0400 Subject: [PATCH 014/100] IDEA-67921 IDEA-65888 Mercurial installed via easy_install/pip on Windows. Root cause: the pipe symbol (|) used in changesets templates (--template) is interpreted by system in the case of such configuration and running via hg.bat). If Windows, surround the template by double-quotes. It breaks UNIX version, however, so don't do it for UNIX. Refactored all usages of --template to go through HgChangesetUtil.makeTemplate() using common separators and quoting if needed. --- .../hg4idea/command/HgChangesetsCommand.java | 9 ++-- .../hg4idea/command/HgRevisionsCommand.java | 17 ++++--- ...TrackFileNamesAccrossRevisionsCommand.java | 13 +++-- .../HgWorkingCopyRevisionsCommand.java | 7 +-- .../zmlx/hg4idea/util/HgChangesetUtil.java | 48 +++++++++++++++++++ 5 files changed, 70 insertions(+), 24 deletions(-) create mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/util/HgChangesetUtil.java diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgChangesetsCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgChangesetsCommand.java index 261fdda52a77..c8f1ad54d7e8 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgChangesetsCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgChangesetsCommand.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.HgRevisionNumber; import org.zmlx.hg4idea.execution.HgCommandExecutor; import org.zmlx.hg4idea.execution.HgCommandResult; +import org.zmlx.hg4idea.util.HgChangesetUtil; import java.util.ArrayList; import java.util.Arrays; @@ -33,8 +34,6 @@ public abstract class HgChangesetsCommand { private static final Logger LOG = Logger.getInstance(HgChangesetsCommand.class.getName()); - private static final String SEPARATOR_STRING = "\u0017"; //ascii: end of transmission block - protected final Project project; protected final String command; @@ -50,7 +49,7 @@ public abstract class HgChangesetsCommand { protected List getRevisions(VirtualFile repo) { List args = new ArrayList(Arrays.asList( "--template", - "{rev}|{node|short}|{author}|{desc|firstline}" + SEPARATOR_STRING, + HgChangesetUtil.makeTemplate("{rev}", "{node|short}", "{author}", "{desc|firstline}"), "--quiet" )); @@ -67,11 +66,11 @@ public abstract class HgChangesetsCommand { return Collections.emptyList(); } - String[] changesets = output.split(SEPARATOR_STRING); + String[] changesets = output.split(HgChangesetUtil.CHANGESET_SEPARATOR); List revisions = new ArrayList(changesets.length); for(String changeset: changesets) { - String[] parts = StringUtils.split(changeset, "|", 4); + String[] parts = StringUtils.split(changeset, HgChangesetUtil.ITEM_SEPARATOR, 4); if (parts.length == 4) { revisions.add(HgRevisionNumber.getInstance(parts[0], parts[1], parts[2], parts[3])); } else { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRevisionsCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRevisionsCommand.java index 3e5ee5319ce6..ce13c6e053fa 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRevisionsCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRevisionsCommand.java @@ -23,6 +23,7 @@ import org.zmlx.hg4idea.HgFile; import org.zmlx.hg4idea.HgFileRevision; import org.zmlx.hg4idea.HgRevisionNumber; import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.util.HgChangesetUtil; import org.zmlx.hg4idea.execution.HgCommandResult; import org.zmlx.hg4idea.execution.HgCommandExecutor; @@ -33,12 +34,10 @@ import java.util.*; abstract class HgRevisionsCommand { private static final Logger LOG = Logger.getInstance(HgRevisionsCommand.class.getName()); - private static final String SEPARATOR_STRING = "\u0017"; //ascii: end of transmission block - private static final String SHORT_TEMPLATE = "{rev}|{node|short}|{parents}|{date|isodatesec}|{author}|{branches}|{desc}" + SEPARATOR_STRING; - private static final int SHORT_ITEM_COUNT = 7; - private static final String LONG_TEMPLATE = "{rev}|{node|short}|{parents}|{date|isodatesec}|{author}|{branches}|{desc}|{file_adds}|{file_mods}|{file_dels}|{file_copies}" + SEPARATOR_STRING; - private static final int LONG_ITEM_COUNT = 11; + private static final String[] SHORT_TEMPLATE_ITEMS = { "{rev}","{node|short}", "{parents}", "{date|isodatesec}", "{author}", "{branches}", "{desc}" }; + private static final String[] LONG_TEMPLATE_ITEMS = + { "{rev}", "{node|short}", "{parents}", "{date|isodatesec}", "{author}", "{branches}", "{desc}", "{file_adds}", "{file_mods}", "{file_dels}", "{file_copies}" }; private static final int REVISION_INDEX = 0; private static final int CHANGESET_INDEX = 1; @@ -73,8 +72,8 @@ abstract class HgRevisionsCommand { HgCommandExecutor hgCommandExecutor = new HgCommandExecutor(project); - String template = includeFiles ? LONG_TEMPLATE : SHORT_TEMPLATE; - int itemCount = includeFiles ? LONG_ITEM_COUNT : SHORT_ITEM_COUNT; + String template = HgChangesetUtil.makeTemplate(includeFiles ? LONG_TEMPLATE_ITEMS : SHORT_TEMPLATE_ITEMS); + int itemCount = includeFiles ? LONG_TEMPLATE_ITEMS.length : SHORT_TEMPLATE_ITEMS.length; FilePath originalFileName = HgUtil.getOriginalFileName(hgFile.toFilePath(), ChangeListManager.getInstance(project)); HgFile originalHgFile = new HgFile(hgFile.getRepo(), originalFileName); @@ -84,10 +83,10 @@ abstract class HgRevisionsCommand { List revisions = new LinkedList(); String output = result.getRawOutput(); - String[] changeSets = output.split(SEPARATOR_STRING); + String[] changeSets = output.split(HgChangesetUtil.CHANGESET_SEPARATOR); for (String line : changeSets) { try { - String[] attributes = StringUtils.splitPreserveAllTokens(line, '|'); + String[] attributes = line.split(HgChangesetUtil.ITEM_SEPARATOR); if (attributes.length != itemCount) { LOG.debug("Wrong format. Skipping line " + line); continue; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTrackFileNamesAccrossRevisionsCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTrackFileNamesAccrossRevisionsCommand.java index ee141ca08e9a..49e171540ebf 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTrackFileNamesAccrossRevisionsCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTrackFileNamesAccrossRevisionsCommand.java @@ -19,16 +19,15 @@ import org.apache.commons.lang.StringUtils; import org.zmlx.hg4idea.HgFile; import org.zmlx.hg4idea.execution.HgCommandExecutor; import org.zmlx.hg4idea.execution.HgCommandResult; +import org.zmlx.hg4idea.util.HgChangesetUtil; import java.util.*; class HgTrackFileNamesAccrossRevisionsCommand { private static final Logger LOG = Logger.getInstance(HgTrackFileNamesAccrossRevisionsCommand.class.getName()); - private static final String SEPARATOR_STRING = "\u0027"; //ascii: end of transmission block - private static final String TEMPLATE = "{rev}|{file_dels}|{file_copies}" + SEPARATOR_STRING; - private static final int ITEM_COUNT = 3; + private static final String[] TEMPLATE_ITEMS = { "{rev}", "{file_dels}", "{file_copies}" }; private static final int REVISION_INDEX = 0; private static final int FILES_DELETED_INDEX = 1; @@ -48,7 +47,7 @@ class HgTrackFileNamesAccrossRevisionsCommand { arguments.add("--follow"); arguments.add("--template"); - arguments.add(TEMPLATE); + arguments.add(HgChangesetUtil.makeTemplate(TEMPLATE_ITEMS)); if (limit != -1) { arguments.add("--limit"); @@ -69,15 +68,15 @@ class HgTrackFileNamesAccrossRevisionsCommand { HgCommandResult result = execute(hgCommandExecutor, hgFile.getRepo(), limit, hgFile, currentRevision, givenRevision); String output = result.getRawOutput(); - String[] changeSets = output.split(SEPARATOR_STRING); + String[] changeSets = output.split(HgChangesetUtil.CHANGESET_SEPARATOR); String currentFileName = hgFile.getRelativePath(); // needed on windows machines currentFileName = currentFileName.replaceAll("\\\\", "/"); for (String line : changeSets) { try { - String[] attributes = StringUtils.splitPreserveAllTokens(line, '|'); - if (attributes.length != ITEM_COUNT) { + String[] attributes = line.split(HgChangesetUtil.ITEM_SEPARATOR); + if (attributes.length != TEMPLATE_ITEMS.length) { LOG.debug("Wrong format. Skipping line " + line); continue; } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java index db4e5de1ab98..689ceb481b7d 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java @@ -25,6 +25,7 @@ import org.zmlx.hg4idea.HgRevisionNumber; import org.zmlx.hg4idea.HgUtil; import org.zmlx.hg4idea.execution.HgCommandResult; import org.zmlx.hg4idea.execution.HgCommandExecutor; +import org.zmlx.hg4idea.util.HgChangesetUtil; import java.util.ArrayList; import java.util.Arrays; @@ -165,7 +166,7 @@ public class HgWorkingCopyRevisionsCommand { boolean silent) { final List args = new LinkedList(); args.add("--template"); - args.add("{rev}|{node|short}\\n"); + args.add(HgChangesetUtil.makeTemplate("{rev}", "{node|short}")); if (revision != null) { args.add("-r"); args.add(revision.getChangeset()); @@ -180,10 +181,10 @@ public class HgWorkingCopyRevisionsCommand { if (result == null) { return new ArrayList(0); } - final List lines = result.getOutputLines(); + final List lines = Arrays.asList(result.getRawOutput().split(HgChangesetUtil.CHANGESET_SEPARATOR)); final List revisions = new ArrayList(lines.size()); for(String line: lines) { - final String[] parts = StringUtils.split(line, '|'); + final String[] parts = StringUtils.split(line, HgChangesetUtil.ITEM_SEPARATOR); revisions.add(HgRevisionNumber.getInstance(parts[0], parts[1])); } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgChangesetUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgChangesetUtil.java new file mode 100644 index 000000000000..9118dc217fb9 --- /dev/null +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgChangesetUtil.java @@ -0,0 +1,48 @@ +/* + * 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.zmlx.hg4idea.util; + +import com.intellij.openapi.util.SystemInfo; + +/** + * Utilities for operations involving working with a number of changesets: log, incoming, outgoing, parents, etc. + * @author Kirill Likhodedov + */ +public class HgChangesetUtil { + + public static final String CHANGESET_SEPARATOR = "\u0003"; + public static final String ITEM_SEPARATOR = "\u0017"; + + /** + * Common method for hg commands which receive templates via --template option. + * @param templateItems template items like
{rev}
,
{node}
. + * @return items joined by ITEM_SEPARATOR, ended by CHANGESET_SEPARATOR, and, if needed (for Windows), surrounded with double-quotes. + */ + public static String makeTemplate(String... templateItems) { + StringBuilder template = new StringBuilder(); + + for (String item : templateItems) { + template.append(item).append(ITEM_SEPARATOR); + } + + template.append(CHANGESET_SEPARATOR); + if (SystemInfo.isWindows) { + return "\"" + template + "\""; + } + return template.toString(); + } + +} From 5058298f241a5c526750e03383162285ed52613f Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 13 Apr 2011 19:32:37 +0400 Subject: [PATCH 015/100] [hg] move HgUtil and HgErrorUtil to the util subpackage. --- plugins/hg4idea/src/org/zmlx/hg4idea/HgContentRevision.java | 1 + plugins/hg4idea/src/org/zmlx/hg4idea/HgFileRevision.java | 1 + plugins/hg4idea/src/org/zmlx/hg4idea/HgPusher.java | 2 ++ plugins/hg4idea/src/org/zmlx/hg4idea/HgRootsHandler.java | 1 + plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java | 1 + plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java | 1 + .../src/org/zmlx/hg4idea/action/HgAbstractFilesAction.java | 2 +- .../src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java | 4 ++-- .../src/org/zmlx/hg4idea/action/HgCommandResultNotifier.java | 2 +- plugins/hg4idea/src/org/zmlx/hg4idea/action/HgInit.java | 2 +- .../hg4idea/src/org/zmlx/hg4idea/command/HgAddCommand.java | 2 +- .../hg4idea/src/org/zmlx/hg4idea/command/HgInitCommand.java | 2 +- .../hg4idea/src/org/zmlx/hg4idea/command/HgRemoveCommand.java | 2 +- .../src/org/zmlx/hg4idea/command/HgRevisionsCommand.java | 2 +- .../zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java | 2 +- .../src/org/zmlx/hg4idea/execution/HgCommandExecutor.java | 1 + .../src/org/zmlx/hg4idea/provider/HgHistoryProvider.java | 2 +- .../src/org/zmlx/hg4idea/provider/HgMergeProvider.java | 2 +- .../src/org/zmlx/hg4idea/provider/update/HgHeadMerger.java | 2 +- plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.java | 2 +- .../hg4idea/src/org/zmlx/hg4idea/{ => util}/HgErrorUtil.java | 2 +- plugins/hg4idea/src/org/zmlx/hg4idea/{ => util}/HgUtil.java | 3 ++- 22 files changed, 25 insertions(+), 16 deletions(-) rename plugins/hg4idea/src/org/zmlx/hg4idea/{ => util}/HgErrorUtil.java (98%) rename plugins/hg4idea/src/org/zmlx/hg4idea/{ => util}/HgUtil.java (99%) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgContentRevision.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgContentRevision.java index 41d1d3dfe930..d213e5703b51 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgContentRevision.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgContentRevision.java @@ -24,6 +24,7 @@ import org.apache.commons.lang.builder.HashCodeBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.command.HgCatCommand; +import org.zmlx.hg4idea.util.HgUtil; import java.io.UnsupportedEncodingException; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgFileRevision.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgFileRevision.java index 070190b7ae33..240febc364e3 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgFileRevision.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgFileRevision.java @@ -18,6 +18,7 @@ import com.intellij.openapi.vcs.history.VcsFileRevision; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.zmlx.hg4idea.command.HgCatCommand; +import org.zmlx.hg4idea.util.HgUtil; import java.io.IOException; import java.io.UnsupportedEncodingException; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgPusher.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgPusher.java index 6d9932321be5..399290077632 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgPusher.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgPusher.java @@ -25,6 +25,8 @@ import org.zmlx.hg4idea.command.HgPushCommand; import org.zmlx.hg4idea.execution.HgCommandResult; import org.zmlx.hg4idea.execution.HgCommandResultHandler; import org.zmlx.hg4idea.ui.HgPushDialog; +import org.zmlx.hg4idea.util.HgErrorUtil; +import org.zmlx.hg4idea.util.HgUtil; import java.util.List; import java.util.regex.Matcher; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgRootsHandler.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgRootsHandler.java index 5da62435f18a..4aef2c466071 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgRootsHandler.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgRootsHandler.java @@ -23,6 +23,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.vcsUtil.VcsUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.Nullable; +import org.zmlx.hg4idea.util.HgUtil; import java.util.ArrayList; import java.util.List; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java index 0f98a89c5eca..10c8dbac9970 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java @@ -27,6 +27,7 @@ import com.intellij.util.ui.VcsBackgroundTask; import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.NotNull; import org.zmlx.hg4idea.command.*; +import org.zmlx.hg4idea.util.HgUtil; import java.util.*; import java.util.concurrent.atomic.AtomicReference; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java index a58acb43336b..0afbaf0ec6b4 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java @@ -59,6 +59,7 @@ import org.zmlx.hg4idea.provider.update.HgIntegrateEnvironment; import org.zmlx.hg4idea.provider.update.HgUpdateEnvironment; import org.zmlx.hg4idea.ui.HgChangesetStatus; import org.zmlx.hg4idea.ui.HgCurrentBranchStatus; +import org.zmlx.hg4idea.util.HgUtil; import javax.swing.*; import java.io.File; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractFilesAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractFilesAction.java index 2efb5e73116a..82e8489074a9 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractFilesAction.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractFilesAction.java @@ -21,7 +21,7 @@ import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.TransactionRunnable; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; -import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.util.HgUtil; import org.zmlx.hg4idea.HgVcs; import java.lang.reflect.InvocationTargetException; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java index e752629af847..1c4e1ea0c350 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java @@ -18,7 +18,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.Nullable; -import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.util.HgUtil; import org.zmlx.hg4idea.execution.HgCommandException; import java.lang.reflect.InvocationTargetException; @@ -42,7 +42,7 @@ abstract class HgAbstractGlobalAction extends AnAction { } try { command.execute(); - HgUtil.markDirectoryDirty(project,command.getRepo()); + HgUtil.markDirectoryDirty(project, command.getRepo()); } catch (HgCommandException e) { handleException(project, e); } catch (InvocationTargetException e) { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommandResultNotifier.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommandResultNotifier.java index 7b2aba879952..5eaa0f5bed54 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommandResultNotifier.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommandResultNotifier.java @@ -19,7 +19,7 @@ import com.intellij.openapi.project.Project; import com.intellij.vcsUtil.VcsUtil; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.Nullable; -import org.zmlx.hg4idea.HgErrorUtil; +import org.zmlx.hg4idea.util.HgErrorUtil; import org.zmlx.hg4idea.HgVcs; import org.zmlx.hg4idea.execution.HgCommandResult; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgInit.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgInit.java index e745a7b0085e..8ab3aaa6c7e1 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgInit.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgInit.java @@ -13,7 +13,7 @@ import com.intellij.openapi.vcs.VcsDirectoryMapping; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; -import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.util.HgUtil; import org.zmlx.hg4idea.HgVcs; import org.zmlx.hg4idea.HgVcsMessages; import org.zmlx.hg4idea.command.HgInitCommand; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgAddCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgAddCommand.java index 7025c7f68227..fb2445f56450 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgAddCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgAddCommand.java @@ -16,7 +16,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.zmlx.hg4idea.HgFile; -import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.util.HgUtil; import org.zmlx.hg4idea.execution.HgCommandExecutor; import java.util.Arrays; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgInitCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgInitCommand.java index 9043571410b0..805becdf15b2 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgInitCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgInitCommand.java @@ -5,7 +5,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.zmlx.hg4idea.HgErrorUtil; +import org.zmlx.hg4idea.util.HgErrorUtil; import org.zmlx.hg4idea.execution.HgCommandExecutor; import org.zmlx.hg4idea.execution.HgCommandResult; import org.zmlx.hg4idea.execution.HgCommandResultHandler; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRemoveCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRemoveCommand.java index 6f21cff6bcbb..802e8b88fc69 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRemoveCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRemoveCommand.java @@ -16,7 +16,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.zmlx.hg4idea.HgFile; -import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.util.HgUtil; import org.zmlx.hg4idea.execution.HgCommandExecutor; import java.util.Arrays; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRevisionsCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRevisionsCommand.java index ce13c6e053fa..eaa89a78c6c0 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRevisionsCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRevisionsCommand.java @@ -22,7 +22,7 @@ import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.HgFile; import org.zmlx.hg4idea.HgFileRevision; import org.zmlx.hg4idea.HgRevisionNumber; -import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.util.HgUtil; import org.zmlx.hg4idea.util.HgChangesetUtil; import org.zmlx.hg4idea.execution.HgCommandResult; import org.zmlx.hg4idea.execution.HgCommandExecutor; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java index 689ceb481b7d..263abab6aa40 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java @@ -22,7 +22,7 @@ import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.HgRevisionNumber; -import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.util.HgUtil; import org.zmlx.hg4idea.execution.HgCommandResult; import org.zmlx.hg4idea.execution.HgCommandExecutor; import org.zmlx.hg4idea.util.HgChangesetUtil; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java index 385e390e8b77..0b974bfa4c74 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java @@ -21,6 +21,7 @@ import com.intellij.vcsUtil.VcsUtil; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.*; +import org.zmlx.hg4idea.util.HgErrorUtil; import javax.swing.*; import java.awt.*; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgHistoryProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgHistoryProvider.java index a6690f64f6de..f19a2429102a 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgHistoryProvider.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgHistoryProvider.java @@ -23,7 +23,7 @@ import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.HgFile; import org.zmlx.hg4idea.HgFileRevision; -import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.util.HgUtil; import org.zmlx.hg4idea.command.HgLogCommand; import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgMergeProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgMergeProvider.java index 1d31179d512a..a21515c79577 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgMergeProvider.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgMergeProvider.java @@ -29,7 +29,7 @@ import org.jetbrains.annotations.NotNull; import org.zmlx.hg4idea.HgContentRevision; import org.zmlx.hg4idea.HgFile; import org.zmlx.hg4idea.HgRevisionNumber; -import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.util.HgUtil; import org.zmlx.hg4idea.command.HgResolveCommand; import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgHeadMerger.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgHeadMerger.java index 7120af385c8d..8e710804ac44 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgHeadMerger.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgHeadMerger.java @@ -22,7 +22,7 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.zmlx.hg4idea.HgChange; import org.zmlx.hg4idea.HgFile; -import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.util.HgUtil; import org.zmlx.hg4idea.HgVcs; import org.zmlx.hg4idea.execution.HgCommandResult; import org.zmlx.hg4idea.command.HgMergeCommand; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.java index 936d99151478..281c9b860a21 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgInitDialog.java @@ -24,7 +24,7 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.Nullable; -import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.util.HgUtil; import org.zmlx.hg4idea.HgVcsMessages; import javax.swing.*; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgErrorUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java similarity index 98% rename from plugins/hg4idea/src/org/zmlx/hg4idea/HgErrorUtil.java rename to plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java index a9c087df5035..6f328d14f6fe 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgErrorUtil.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java @@ -10,7 +10,7 @@ // 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.zmlx.hg4idea; +package org.zmlx.hg4idea.util; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.Nullable; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java similarity index 99% rename from plugins/hg4idea/src/org/zmlx/hg4idea/HgUtil.java rename to plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java index 9a8c4b6fc989..2545612e5831 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgUtil.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java @@ -10,7 +10,7 @@ // 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.zmlx.hg4idea; +package org.zmlx.hg4idea.util; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; @@ -31,6 +31,7 @@ import com.intellij.util.containers.HashMap; import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.zmlx.hg4idea.*; import org.zmlx.hg4idea.command.HgRemoveCommand; import org.zmlx.hg4idea.command.HgStatusCommand; import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand; From c1527ea9465233bace7da35187667c3d8cb116b9 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 13 Apr 2011 19:47:05 +0400 Subject: [PATCH 016/100] [hg] don't check for incoming/outgoing changes if there is no default repository. For outgoing changes check default-push instead of default (if exists). --- .../zmlx/hg4idea/command/HgOutgoingCommand.java | 5 +++++ .../hg4idea/command/HgRemoteChangesetsCommand.java | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgOutgoingCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgOutgoingCommand.java index a14eb43e2cac..cc045d2affd7 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgOutgoingCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgOutgoingCommand.java @@ -13,6 +13,7 @@ package org.zmlx.hg4idea.command; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; public class HgOutgoingCommand extends HgRemoteChangesetsCommand { @@ -20,4 +21,8 @@ public class HgOutgoingCommand extends HgRemoteChangesetsCommand { super(project, "outgoing"); } + protected String getRepositoryUrl(VirtualFile repo) { + return new HgShowConfigCommand(project).getDefaultPushPath(repo); + } + } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRemoteChangesetsCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRemoteChangesetsCommand.java index 2dedb57a86cb..702e419c1ca3 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRemoteChangesetsCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRemoteChangesetsCommand.java @@ -19,6 +19,7 @@ import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; @@ -36,6 +37,9 @@ import java.util.List; * @author Kirill Likhodedov */ public abstract class HgRemoteChangesetsCommand extends HgChangesetsCommand { + + private static final Logger LOG = Logger.getInstance(HgRemoteChangesetsCommand.class); + public HgRemoteChangesetsCommand(Project project, String command) { super(project, command); } @@ -50,9 +54,17 @@ public abstract class HgRemoteChangesetsCommand extends HgChangesetsCommand { return true; } + protected String getRepositoryUrl(VirtualFile repo) { + return new HgShowConfigCommand(project).getDefaultPath(repo); + } + @Override protected HgCommandResult executeCommand(VirtualFile repo, List args) { - String repositoryURL = new HgShowConfigCommand(project).getDefaultPath(repo); + String repositoryURL = getRepositoryUrl(repo); + if (repositoryURL == null) { + LOG.info("executeCommand no default path configured"); + return null; + } HgCommandResult result = new HgCommandExecutor(project).executeInCurrentThread(repo, command, args); if (result == HgCommandResult.CANCELLED) { final HgVcs vcs = HgVcs.getInstance(project); From f9a9d3af22e89bfd5f6e2d921980f665c6fbc74f Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 13 Apr 2011 20:16:21 +0400 Subject: [PATCH 017/100] GitUIUtil change \n by
when displaying exception message --- plugins/git4idea/src/git4idea/ui/GitUIUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/git4idea/src/git4idea/ui/GitUIUtil.java b/plugins/git4idea/src/git4idea/ui/GitUIUtil.java index 52a7ad517847..6f6c19331a20 100644 --- a/plugins/git4idea/src/git4idea/ui/GitUIUtil.java +++ b/plugins/git4idea/src/git4idea/ui/GitUIUtil.java @@ -72,7 +72,9 @@ public class GitUIUtil { } else { errorMessages = new HashSet(errors.size()); for (VcsException error : errors) { - errorMessages.addAll(Arrays.asList(error.getMessages())); + for (String message : error.getMessages()) { + errorMessages.add(message.replace("\n", "
")); + } } } notifyMessages(project, title, description, type, important, errorMessages); From eb7d6c5e3b91e603c52df8f193daed1a4af10b25 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 14 Apr 2011 10:48:36 +0400 Subject: [PATCH 018/100] [hg] Show actual executable in the command line (not hg.exe for hg.bat, for instance). --- .../src/org/zmlx/hg4idea/execution/HgCommandExecutor.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java index 0b974bfa4c74..b7f9cbc9cf0f 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java @@ -181,7 +181,11 @@ public final class HgCommandExecutor { // logging to the Version Control console (without extensions and configs) private void log(String operation, List arguments, HgCommandResult result) { - final String executable = mySettings.isRunViaBash() ? "bash -c " + HgVcs.HG_EXECUTABLE_FILE_NAME : HgVcs.HG_EXECUTABLE_FILE_NAME; + String exeName; + final int lastSlashIndex = mySettings.getHgExecutable().lastIndexOf("/"); + exeName = mySettings.getHgExecutable().substring(lastSlashIndex + 1); + + final String executable = mySettings.isRunViaBash() ? "bash -c " + exeName : exeName; final String cmdString = String.format("%s %s %s", executable, operation, StringUtils.join(arguments, " ")); // log command From 60902439a0792d81c6887a230e2c506bd7ce9fbe Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Thu, 14 Apr 2011 11:39:58 +0400 Subject: [PATCH 019/100] separate element types for left and right shifts --- .../plugins/groovy/lang/lexer/TokenSets.java | 49 +++++++++++++++++-- .../lang/parser/GroovyElementTypes.java | 5 +- .../groovy/lang/parser/GroovyPsiCreator.java | 3 +- .../expressions/AssignmentExpression.java | 20 +------- .../arithmetic/ShiftExpression.java | 20 ++++++-- .../relational/RelationalExpression.java | 2 +- .../groovy/lang/psi/impl/PsiImplUtil.java | 7 ++- 7 files changed, 71 insertions(+), 35 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java index 3ef85844537b..b69e99d0bf0b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java @@ -17,15 +17,20 @@ package org.jetbrains.plugins.groovy.lang.lexer; import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; -import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; +import com.intellij.util.containers.hash.HashMap; + +import static org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes.*; + +import java.util.Map; /** * Utility classdef, tha contains various useful TokenSets * * @author ilyas */ -public abstract class TokenSets implements GroovyTokenTypes, GroovyElementTypes { +public abstract class TokenSets { public static TokenSet COMMENTS_TOKEN_SET = TokenSet.create( mSL_COMMENT, @@ -150,11 +155,45 @@ public abstract class TokenSets implements GroovyTokenTypes, GroovyElementTypes public static final TokenSet POSTFIX_UNARY_OP_SET = TokenSet.create(mDEC, mINC); - public static final TokenSet BINARY_OP_SET = TokenSet.create(mBAND, mBOR, mBXOR, mDIV, mEQUAL, mGE, mGT, mLAND, mLOR, mLT, mLE, mMINUS, - mMOD, mPLUS, mSTAR, mSTAR_STAR, mNOT_EQUAL, mCOMPARE_TO, - COMPOSITE_SHIFT_SIGN, kIN, kINSTANCEOF, kAS); + public static final TokenSet BINARY_OP_SET = TokenSet.create(mBAND, mBOR, mBXOR, mDIV, mEQUAL, mGE, mGT, mLOR, mLT, mLE, mMINUS, kAS, kIN, + mMOD, mPLUS, mSTAR, mSTAR_STAR, mNOT_EQUAL, mCOMPARE_TO, mLAND, kINSTANCEOF, + COMPOSITE_LSHIFT_SIGN, COMPOSITE_RSHIFT_SIGN, COMPOSITE_TRIPLE_SHIFT_SIGN); public static final TokenSet DOTS = TokenSet.create(mSPREAD_DOT, mOPTIONAL_DOT, mMEMBER_POINTER, mDOT); public static final TokenSet WHITE_SPACES_OR_COMMENTS = TokenSet.orSet(WHITE_SPACES_SET, COMMENT_SET); + + public static final Map ASSIGNMENTS_TO_OPERATORS = new HashMap(); + static { + ASSIGNMENTS_TO_OPERATORS.put(mMINUS_ASSIGN, mMINUS); + ASSIGNMENTS_TO_OPERATORS.put(mPLUS_ASSIGN, mPLUS); + ASSIGNMENTS_TO_OPERATORS.put(mDIV_ASSIGN, mDIV); + ASSIGNMENTS_TO_OPERATORS.put(mSTAR_ASSIGN, mSTAR); + ASSIGNMENTS_TO_OPERATORS.put(mMOD_ASSIGN, mMOD); + ASSIGNMENTS_TO_OPERATORS.put(mSL_ASSIGN, COMPOSITE_LSHIFT_SIGN); + ASSIGNMENTS_TO_OPERATORS.put(mSR_ASSIGN, COMPOSITE_RSHIFT_SIGN); + ASSIGNMENTS_TO_OPERATORS.put(mBSR_ASSIGN, COMPOSITE_TRIPLE_SHIFT_SIGN); + ASSIGNMENTS_TO_OPERATORS.put(mBAND_ASSIGN, mBAND); + ASSIGNMENTS_TO_OPERATORS.put(mBOR_ASSIGN, mBOR); + ASSIGNMENTS_TO_OPERATORS.put(mBXOR_ASSIGN, mBXOR); + ASSIGNMENTS_TO_OPERATORS.put(mSTAR_STAR_ASSIGN, mSTAR_STAR); + } + + public static final TokenSet ASSIGNMENTS = TokenSet.create( + mASSIGN, + mPLUS_ASSIGN, + mMINUS_ASSIGN, + mSTAR_ASSIGN, + mDIV_ASSIGN, + mMOD_ASSIGN, + mSL_ASSIGN, + mSR_ASSIGN, + mBSR_ASSIGN, + mBAND_ASSIGN, + mBOR_ASSIGN, + mBXOR_ASSIGN, + mSTAR_STAR_ASSIGN + ); + + public static final TokenSet SHIFT_SIGNS = TokenSet.create(COMPOSITE_LSHIFT_SIGN, COMPOSITE_RSHIFT_SIGN, COMPOSITE_TRIPLE_SHIFT_SIGN); } 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 4e9463950056..01a5c6797389 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 @@ -196,7 +196,10 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy GroovyElementType RELATIONAL_EXPRESSION = new GroovyElementType("Relational expression"); GroovyElementType SHIFT_EXPRESSION = new GroovyElementType("Shift expression"); GroovyElementType RANGE_EXPRESSION = new GroovyElementType("Range expression"); - GroovyElementType COMPOSITE_SHIFT_SIGN = new GroovyElementType("Composite shift sign"); + GroovyElementType COMPOSITE_LSHIFT_SIGN = new GroovyElementType("Composite shift sign <<"); + GroovyElementType COMPOSITE_RSHIFT_SIGN = new GroovyElementType("Composite shift sign >>"); + GroovyElementType COMPOSITE_TRIPLE_SHIFT_SIGN = new GroovyElementType("Composite shift sign >>>"); + GroovyElementType MORE_OR_EQUALS_SIGN = new GroovyElementType(">="); GroovyElementType ADDITIVE_EXPRESSION = new GroovyElementType("Additive expression"); GroovyElementType MULTIPLICATIVE_EXPRESSION = new GroovyElementType("Multiplicative expression"); GroovyElementType POWER_EXPRESSION = new GroovyElementType("Power expression"); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java index 919782117ea8..6e487818ca46 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java @@ -23,6 +23,7 @@ import com.intellij.psi.tree.IElementType; import org.jetbrains.plugins.groovy.lang.groovydoc.lexer.IGroovyDocElementType; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.GroovyDocPsiCreator; import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType; +import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiElementImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.GrLabelImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.GrListOrMapImpl; @@ -212,7 +213,7 @@ public class GroovyPsiCreator implements GroovyElementTypes { if (elem.equals(RELATIONAL_EXPRESSION)) return new GrRelationalExpressionImpl(node); if (elem.equals(SHIFT_EXPRESSION)) return new GrShiftExpressionImpl(node); if (elem.equals(RANGE_EXPRESSION)) return new GrRangeExpressionImpl(node); - if (elem.equals(COMPOSITE_SHIFT_SIGN)) return new GrOperationSignImpl(node); + if (TokenSets.SHIFT_SIGNS.contains(elem)) return new GrOperationSignImpl(node); if (elem.equals(ADDITIVE_EXPRESSION)) return new GrAdditiveExpressionImpl(node); if (elem.equals(MULTIPLICATIVE_EXPRESSION)) return new GrMultiplicativeExpressionImpl(node); if (elem.equals(POWER_EXPRESSION)) return new GrPowerExpressionImpl(node); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/AssignmentExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/AssignmentExpression.java index ee983d7bcba7..479ad8ba3b28 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/AssignmentExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/AssignmentExpression.java @@ -18,8 +18,8 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions; import com.intellij.lang.PsiBuilder; import com.intellij.lang.PsiBuilder.Marker; -import com.intellij.psi.tree.TokenSet; import org.jetbrains.plugins.groovy.GroovyBundle; +import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.parser.GroovyParser; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.TupleParse; @@ -31,22 +31,6 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; */ public class AssignmentExpression implements GroovyElementTypes { - private static final TokenSet ASSIGNMENTS = TokenSet.create( - mASSIGN, - mPLUS_ASSIGN, - mMINUS_ASSIGN, - mSTAR_ASSIGN, - mDIV_ASSIGN, - mMOD_ASSIGN, - mSL_ASSIGN, - mBAND_ASSIGN, - mBOR_ASSIGN, - mBXOR_ASSIGN, - mSTAR_STAR_ASSIGN, - mSR_ASSIGN, - mBSR_ASSIGN - ); - public static boolean parse(PsiBuilder builder, GroovyParser parser) { return parse(builder, parser, false); } @@ -55,7 +39,7 @@ public class AssignmentExpression implements GroovyElementTypes { Marker marker = builder.mark(); final boolean isTuple = ParserUtils.lookAhead(builder, mLPAREN, mIDENT, mCOMMA); if (parseSide(builder, parser, isTuple,comExprAllowed)) { - if (ParserUtils.getToken(builder, ASSIGNMENTS)) { + if (ParserUtils.getToken(builder, TokenSets.ASSIGNMENTS)) { ParserUtils.getToken(builder, mNLS); if (!parse(builder, parser, comExprAllowed)) { builder.error(GroovyBundle.message("expression.expected")); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/ShiftExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/ShiftExpression.java index 5085aef545d9..a924467343e9 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/ShiftExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/ShiftExpression.java @@ -80,18 +80,28 @@ public class ShiftExpression implements GroovyElementTypes { builder.getTokenText(); //todo[peter] remove look-ahead assertion builder.advanceLexer(); } - marker.done(COMPOSITE_SHIFT_SIGN); + marker.done(COMPOSITE_TRIPLE_SHIFT_SIGN); return true; - } else if (ParserUtils.lookAhead(builder, mLT, mLT) || - ParserUtils.lookAhead(builder, mGT, mGT)) { + } + else if (ParserUtils.lookAhead(builder, mLT, mLT)) { PsiBuilder.Marker marker = builder.mark(); for (int i = 0; i < 2; i++) { builder.getTokenText(); //todo[peter] remove look-ahead assertion builder.advanceLexer(); } - marker.done(COMPOSITE_SHIFT_SIGN); + marker.done(COMPOSITE_LSHIFT_SIGN); return true; - } else { + } + else if (ParserUtils.lookAhead(builder, mGT, mGT)) { + PsiBuilder.Marker marker = builder.mark(); + for (int i = 0; i < 2; i++) { + builder.getTokenText(); //todo[peter] remove look-ahead assertion + builder.advanceLexer(); + } + marker.done(COMPOSITE_RSHIFT_SIGN); + return true; + } + else { return false; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/relational/RelationalExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/relational/RelationalExpression.java index e00b0bfd7895..3b349a84a28f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/relational/RelationalExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/relational/RelationalExpression.java @@ -82,7 +82,7 @@ public class RelationalExpression implements GroovyElementTypes { for (int i = 0; i < 2; i++) { builder.advanceLexer(); } - marker.done(COMPOSITE_SHIFT_SIGN); + marker.done(MORE_OR_EQUALS_SIGN); return true; } else { return false; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java index 01aba2e4633c..7cc62356f405 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java @@ -62,8 +62,7 @@ import java.util.List; import static com.intellij.psi.impl.source.tree.Factory.createSingleLeafElement; import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*; -import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.RELATIONS; -import static org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes.COMPOSITE_SHIFT_SIGN; +import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.*; /** * @@ -176,7 +175,7 @@ public class PsiImplUtil { } return RELATIONS.contains(opToken) || opToken == mCOMPARE_TO || opToken == mREGEX_FIND || opToken == mREGEX_MATCH - || opToken == COMPOSITE_SHIFT_SIGN + || SHIFT_SIGNS.contains(opToken) || opToken==mSTAR; } @@ -263,7 +262,7 @@ public class PsiImplUtil { if (opToken == mSTAR_STAR) priority = 7; else if (opToken == mSTAR || opToken == mDIV) priority = 8; else if (opToken == mPLUS || opToken == mMINUS) priority = 9; - else if (opToken == COMPOSITE_SHIFT_SIGN) priority = 10; + else if (SHIFT_SIGNS.contains(opToken)) priority = 10; else if (RELATIONS.contains(opToken)) priority = 12; else if (opToken == mEQUAL || opToken == mNOT_EQUAL || opToken == mCOMPARE_TO) priority = 13; else if (opToken == mREGEX_FIND || opToken == mREGEX_MATCH) priority = 14; From bf271b1a9496881c43511040db4f75d126261fae Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 14 Apr 2011 12:48:00 +0400 Subject: [PATCH 020/100] Git: split clone into atomic operations. Split clone to mkdir, init, add remote, fetch and checkout. Add notifications in the case of error. Reason: extract the remote FETCH operation, which will be handled by JGit for HTTP in futher changes. --- plugins/git4idea/src/git4idea/Git.java | 44 +++++ .../src/git4idea/actions/GitInit.java | 16 +- .../checkout/GitCheckoutProvider.java | 166 ++++++++++++------ .../src/git4idea/commands/GitHandlerUtil.java | 2 +- .../github/GithubCheckoutProvider.java | 2 +- 5 files changed, 164 insertions(+), 66 deletions(-) create mode 100644 plugins/git4idea/src/git4idea/Git.java diff --git a/plugins/git4idea/src/git4idea/Git.java b/plugins/git4idea/src/git4idea/Git.java new file mode 100644 index 000000000000..9d1c50133508 --- /dev/null +++ b/plugins/git4idea/src/git4idea/Git.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 git4idea; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vfs.VirtualFile; +import git4idea.commands.GitCommand; +import git4idea.commands.GitHandlerUtil; +import git4idea.commands.GitLineHandler; + +/** + * Low level layer of Git commands. + * + * @author Kirill Likhodedov + */ +public class Git { + + /** + * Calls 'git init' on the specified directory. + */ + public static void init(Project project, VirtualFile root) throws VcsException { + GitLineHandler h = new GitLineHandler(project, root, GitCommand.INIT); + h.setNoSSH(true); + GitHandlerUtil.runInCurrentThread(h, null); + if (!h.errors().isEmpty()) { + throw h.errors().get(0); + } + } + +} diff --git a/plugins/git4idea/src/git4idea/actions/GitInit.java b/plugins/git4idea/src/git4idea/actions/GitInit.java index b234fb22d740..ae31838a3d88 100644 --- a/plugins/git4idea/src/git4idea/actions/GitInit.java +++ b/plugins/git4idea/src/git4idea/actions/GitInit.java @@ -28,12 +28,11 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsDirectoryMapping; +import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; +import git4idea.Git; import git4idea.GitUtil; import git4idea.GitVcs; -import git4idea.commands.GitCommand; -import git4idea.commands.GitHandlerUtil; -import git4idea.commands.GitLineHandler; import git4idea.i18n.GitBundle; import git4idea.ui.GitUIUtil; import org.jetbrains.annotations.NotNull; @@ -73,13 +72,14 @@ public class GitInit extends DumbAwareAction { return; } } - GitLineHandler h = new GitLineHandler(project, root, GitCommand.INIT); - h.setNoSSH(true); - GitHandlerUtil.doSynchronously(h, GitBundle.getString("initializing.title"), h.printableCommandLine()); - if (!h.errors().isEmpty()) { - GitUIUtil.showOperationErrors(project, h.errors(), "git init"); + + try { + Git.init(project, root); + } catch (VcsException ex) { + GitUIUtil.showOperationErrors(project, Collections.singleton(ex), "git init"); return; } + if (project.isDefault()) return; int rc = Messages.showYesNoDialog(project, GitBundle.getString("init.add.root.message"), GitBundle.getString("init.add.root.title"), Messages.getQuestionIcon()); diff --git a/plugins/git4idea/src/git4idea/checkout/GitCheckoutProvider.java b/plugins/git4idea/src/git4idea/checkout/GitCheckoutProvider.java index ee5fe42d0217..269e0c843a62 100644 --- a/plugins/git4idea/src/git4idea/checkout/GitCheckoutProvider.java +++ b/plugins/git4idea/src/git4idea/checkout/GitCheckoutProvider.java @@ -15,31 +15,39 @@ */ package git4idea.checkout; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.CheckoutProvider; +import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import git4idea.GitVcs; +import com.intellij.vcsUtil.VcsUtil; +import git4idea.Git; import git4idea.actions.BasicAction; -import git4idea.commands.*; -import git4idea.config.GitVersion; +import git4idea.commands.GitCommand; +import git4idea.commands.GitSimpleHandler; import git4idea.i18n.GitBundle; import git4idea.ui.GitUIUtil; +import git4idea.update.GitFetcher; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; +import java.util.concurrent.atomic.AtomicBoolean; /** * Checkout provider for the Git */ public class GitCheckoutProvider implements CheckoutProvider { - /** - * The version number since which "-v" options is supported. - */ - // TODO check if they will actually support the switch in the released 1.6.0.5 - private static final GitVersion VERBOSE_CLONE_SUPPORTED = new GitVersion(1, 6, 0, 5); + + private static final Logger LOG = Logger.getInstance(GitCheckoutProvider.class); + + public String getVcsName() { + return "_Git"; + } public void doCheckout(@NotNull final Project project, @Nullable final Listener listener) { BasicAction.saveAll(); @@ -56,64 +64,110 @@ public class GitCheckoutProvider implements CheckoutProvider { final String sourceRepositoryURL = dialog.getSourceRepositoryURL(); final String directoryName = dialog.getDirectoryName(); final String parentDirectory = dialog.getParentDirectory(); - checkout(project, listener, destinationParent, sourceRepositoryURL, directoryName, parentDirectory); + clone(project, listener, destinationParent, sourceRepositoryURL, directoryName, parentDirectory); } - public static void checkout(final Project project, - final Listener listener, - final VirtualFile destinationParent, - final String sourceRepositoryURL, - final String directoryName, - final String parentDirectory) { - final GitLineHandler handler = getCloneHandler(project, sourceRepositoryURL, new File(parentDirectory), directoryName); - GitTask task = new GitTask(project, handler, GitBundle.message("cloning.repository", sourceRepositoryURL)); - task.setProgressAnalyzer(new GitStandardProgressAnalyzer()); - task.executeAsync(new GitTaskResultHandlerAdapter() { + public static void clone(final Project project, + final Listener listener, + final VirtualFile destinationParent, + final String sourceRepositoryURL, + final String directoryName, + final String parentDirectory) { + + final AtomicBoolean cloneResult = new AtomicBoolean(); + new Task.Backgroundable(project, GitBundle.message("cloning.repository", sourceRepositoryURL)) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + cloneResult.set(doClone(indicator, project, directoryName, parentDirectory, sourceRepositoryURL)); + } + @Override public void onSuccess() { - destinationParent.refresh(true, true, new Runnable() { - public void run() { - if (project.isOpen() && (!project.isDisposed()) && (!project.isDefault())) { - final VcsDirtyScopeManager mgr = VcsDirtyScopeManager.getInstance(project); - mgr.fileDirty(destinationParent); - } + if (!cloneResult.get()) { + return; + } + + destinationParent.refresh(true, true, new Runnable() { + public void run() { + if (project.isOpen() && (!project.isDisposed()) && (!project.isDefault())) { + final VcsDirtyScopeManager mgr = VcsDirtyScopeManager.getInstance(project); + mgr.fileDirty(destinationParent); } - }); - listener.directoryCheckedOut(new File(parentDirectory, directoryName)); - listener.checkoutCompleted(); + } + }); + listener.directoryCheckedOut(new File(parentDirectory, directoryName)); + listener.checkoutCompleted(); } - - @Override - protected void onFailure() { - GitUIUtil.notifyGitErrors(project, "Couldn't clone", "Couldn't clone from " + sourceRepositoryURL, handler.errors()); - } - }); + }.queue(); } - /** - * {@inheritDoc} - */ - public String getVcsName() { - return "_Git"; + private static boolean doClone(ProgressIndicator indicator, Project project, String directoryName, String parentDirectory, String sourceRepositoryURL) { + final VirtualFile root = mkdir(project, directoryName, parentDirectory); + if (root == null) { return false; } + if (!init(project, root)) { return false; } + if (!addRemote(project, root, sourceRepositoryURL)) { return false; } + if (!fetch(project, root, indicator)) { return false; } + return checkout(project, root); } - /** - * Prepare clone handler - * - * @param project a project - * @param url an url - * @param directory a base directory - * @param name a name to checkout - * @param originName origin name (ignored if null or empty string) - * @return a handler for clone operation - */ - public static GitLineHandler getCloneHandler(Project project, final String url, final File directory, final String name) { - GitLineHandler handler = new GitLineHandler(project, directory, GitCommand.CLONE); - if (VERBOSE_CLONE_SUPPORTED.isOlderOrEqual(GitVcs.getInstance(project).getVersion())) { - handler.addParameters("-v"); + private static @Nullable VirtualFile mkdir(Project project, String directoryName, String parentDirectory) { + final File dir = new File(parentDirectory, directoryName); + if (dir.exists()) { + GitUIUtil.notifyError(project, "Couldn't clone", "Directory " + dir + " already exists."); + return null; } - handler.addParameters(url, name); - handler.addProgressParameter(); - return handler; + if (!dir.mkdir()) { + GitUIUtil.notifyError(project, "Couldn't clone", "Can't create directory " + dir + ""); + return null; + } + + return VcsUtil.getVirtualFileWithRefresh(dir); } + + private static boolean init(Project project, VirtualFile root) { + try { + Git.init(project, root); + } catch (VcsException e) { + LOG.info("init ", e); + GitUIUtil.notifyError(project, "Couldn't clone", "Couldn't git init in " + root.getPresentableUrl() + "", true, e); + return false; + } + return true; + } + + private static boolean addRemote(Project project, VirtualFile root, String remoteUrl) { + final GitSimpleHandler addRemoteHandler = new GitSimpleHandler(project, root, GitCommand.REMOTE); + addRemoteHandler.setNoSSH(true); + addRemoteHandler.addParameters("add", "origin", remoteUrl); + try { + addRemoteHandler.run(); + return true; + } + catch (VcsException e) { + LOG.info("addRemote ", e); + GitUIUtil.notifyError(project, "Couldn't clone", "Couldn't add remote " + remoteUrl + "", true, e); + return false; + } + } + + private static boolean fetch(Project project, VirtualFile root, ProgressIndicator indicator) { + return new GitFetcher(project, indicator).fetch(root); + } + + private static boolean checkout(Project project, VirtualFile root) { + GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.CHECKOUT); + h.setNoSSH(true); + h.addParameters("-b", "master", "origin/master"); + try { + h.run(); + return true; + } + catch (VcsException e) { + LOG.info("checkout ", e); + GitUIUtil.notifyError(project, "Clone not completed", + "Couldn't checkout master branch.
All changes were fetched to " + root + ".", true, e); + return false; + } + } + } diff --git a/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java b/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java index 5b16c138a697..3e9acd911347 100644 --- a/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java +++ b/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java @@ -181,7 +181,7 @@ public class GitHandlerUtil { * @param handler a handler to run * @param postStartAction an action that is executed */ - static void runInCurrentThread(final GitHandler handler, @Nullable final Runnable postStartAction) { + public static void runInCurrentThread(final GitHandler handler, @Nullable final Runnable postStartAction) { handler.runInCurrentThread(postStartAction); } diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java index 4efad1a01bfd..8ec8f7b1edc4 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java @@ -109,7 +109,7 @@ public class GithubCheckoutProvider implements CheckoutProvider { final String repositoryName = name; final String repositoryOwner = owner; final String checkoutUrl = host + repositoryOwner + "/" + repositoryName + ".git"; - GitCheckoutProvider.checkout(project, listener, selectedPathFile, checkoutUrl, projectName, selectedPath); + GitCheckoutProvider.clone(project, listener, selectedPathFile, checkoutUrl, projectName, selectedPath); } @Override From 040fcbbc7b55e45eb205fa38134db4ea028ab0e8 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 14 Apr 2011 12:57:57 +0400 Subject: [PATCH 021/100] move --- .../src/com/intellij/debugger/ui/DebuggerSessionTab.java | 6 +++--- .../ui/breakpoints/actions/FocusOnBreakpointAction.java | 4 ++-- .../intellij/execution/ui/layout/LayoutViewOptions.java | 6 ++---- .../src/com/intellij/xdebugger/impl/XDebugSessionImpl.java | 7 +++---- .../com/intellij/xdebugger/impl/ui/XDebugSessionTab.java | 2 +- .../intellij/xdebugger/impl/ui/XDebuggerUIConstants.java | 1 + 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java index 16775fddc8f3..a024d125154f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java @@ -106,7 +106,7 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos myUi = RunnerLayoutUi.Factory.getInstance(project).create("JavaDebugger", XDebuggerBundle.message("xdebugger.default.content.title"), sessionName, this); myUi.getDefaults().initTabDefaults(0, XDebuggerBundle.message("xdebugger.debugger.tab.title"), null). - initFocusContent(DebuggerContentInfo.FRAME_CONTENT, LayoutViewOptions.BREAKPOINT_CONDITION). + initFocusContent(DebuggerContentInfo.FRAME_CONTENT, XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION). initFocusContent(DebuggerContentInfo.CONSOLE_CONTENT, LayoutViewOptions.STARTUP, new LayoutAttractionPolicy.FocusOnce(false)); final DefaultActionGroup focus = new DefaultActionGroup(); @@ -478,9 +478,9 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos private void attractFramesOnPause(final int event) { if (DebuggerSession.EVENT_PAUSE == event) { - myUi.attractBy(LayoutViewOptions.BREAKPOINT_CONDITION); + myUi.attractBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION); } else if (DebuggerSession.EVENT_RESUME == event) { - myUi.clearAttractionBy(LayoutViewOptions.BREAKPOINT_CONDITION); + myUi.clearAttractionBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/actions/FocusOnBreakpointAction.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/actions/FocusOnBreakpointAction.java index d248c4a0db9e..91b223c613c9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/actions/FocusOnBreakpointAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/actions/FocusOnBreakpointAction.java @@ -16,10 +16,10 @@ package com.intellij.debugger.ui.breakpoints.actions; import com.intellij.execution.ui.actions.AbstractFocusOnAction; -import com.intellij.execution.ui.layout.LayoutViewOptions; +import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; public class FocusOnBreakpointAction extends AbstractFocusOnAction { public FocusOnBreakpointAction() { - super(LayoutViewOptions.BREAKPOINT_CONDITION); + super(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION); } } \ No newline at end of file diff --git a/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutViewOptions.java b/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutViewOptions.java index a71581ba1170..900d4b929a93 100644 --- a/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutViewOptions.java +++ b/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutViewOptions.java @@ -16,17 +16,15 @@ package com.intellij.execution.ui.layout; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.ui.content.Content; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public interface LayoutViewOptions { String STARTUP = "startup"; - String BREAKPOINT_CONDITION = "breakpoint"; @NotNull LayoutViewOptions setTopToolbar(@NotNull ActionGroup actions, @NotNull String place); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index c4f81befec53..ea8d0cfa129f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -29,14 +29,12 @@ import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.ui.RunnerLayoutUi; -import com.intellij.execution.ui.layout.LayoutViewOptions; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.application.Result; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; @@ -53,6 +51,7 @@ import com.intellij.xdebugger.impl.evaluate.quick.common.ValueLookupManager; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import com.intellij.xdebugger.impl.ui.XDebugSessionData; import com.intellij.xdebugger.impl.ui.XDebugSessionTab; +import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; import com.intellij.xdebugger.stepping.XSmartStepIntoHandler; import com.intellij.xdebugger.stepping.XSmartStepIntoVariant; import org.jetbrains.annotations.NotNull; @@ -418,7 +417,7 @@ public class XDebugSessionImpl implements XDebugSession { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { - mySessionTab.getUi().clearAttractionBy(LayoutViewOptions.BREAKPOINT_CONDITION); + mySessionTab.getUi().clearAttractionBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION); } }); myDispatcher.getMulticaster().sessionResumed(); @@ -587,7 +586,7 @@ public class XDebugSessionImpl implements XDebugSession { showSessionTab(); } mySessionTab.toFront(); - mySessionTab.getUi().attractBy(LayoutViewOptions.BREAKPOINT_CONDITION); + mySessionTab.getUi().attractBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION); } }); myDispatcher.getMulticaster().sessionPaused(); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java index d29928bca354..d96830595c0b 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java @@ -72,7 +72,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { myUi = RunnerLayoutUi.Factory.getInstance(project).create("Debug", "unknown!", sessionName, this); myUi.getDefaults() .initTabDefaults(0, XDebuggerBundle.message("xdebugger.debugger.tab.title"), null) - .initFocusContent(DebuggerContentInfo.FRAME_CONTENT, LayoutViewOptions.BREAKPOINT_CONDITION) + .initFocusContent(DebuggerContentInfo.FRAME_CONTENT, XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION) .initFocusContent(DebuggerContentInfo.CONSOLE_CONTENT, LayoutViewOptions.STARTUP, new LayoutAttractionPolicy.FocusOnce(false)); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerUIConstants.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerUIConstants.java index cdafa528aeea..d467eac7bea4 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerUIConstants.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerUIConstants.java @@ -50,6 +50,7 @@ public class XDebuggerUIConstants { public static final Icon WATCHES_TAB_ICON = IconLoader.getIcon("/debugger/watches.png"); public static final Icon CONSOLE_TAB_ICON = IconLoader.getIcon("/debugger/console.png"); public static final SimpleTextAttributes TYPE_ATTRIBUTES = SimpleTextAttributes.GRAY_ATTRIBUTES; + public static final String LAYOUT_VIEW_BREAKPOINT_CONDITION = "breakpoint"; private XDebuggerUIConstants() { } From 8d159571c7f3c0afc4d520e839256f1a36635a12 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Thu, 14 Apr 2011 13:11:11 +0400 Subject: [PATCH 022/100] resolve & type inference for assignments (+=, -= etc) --- .../expressions/GrAssignmentExpression.java | 14 +- .../psi/dataFlow/types/TypeDfaInstance.java | 16 +-- .../GrAssignmentExpressionImpl.java | 132 +++++++++++++++++- .../lang/resolve/ResolveMethodTest.groovy | 6 + .../lang/resolve/TypeInferenceTest.java | 12 ++ .../resolve/inference/plusEquals1/A.groovy | 9 ++ .../resolve/inference/plusEquals2/A.groovy | 9 ++ .../resolve/inference/plusEquals3/A.groovy | 9 ++ .../resolve/method/plusAssignment/A.groovy | 7 + 9 files changed, 195 insertions(+), 19 deletions(-) create mode 100644 plugins/groovy/testdata/resolve/inference/plusEquals1/A.groovy create mode 100644 plugins/groovy/testdata/resolve/inference/plusEquals2/A.groovy create mode 100644 plugins/groovy/testdata/resolve/inference/plusEquals3/A.groovy create mode 100644 plugins/groovy/testdata/resolve/method/plusAssignment/A.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrAssignmentExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrAssignmentExpression.java index 2f78a6d2e02b..78fba067f194 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrAssignmentExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrAssignmentExpression.java @@ -16,22 +16,30 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiPolyVariantReference; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; /** * @author ilyas */ -public interface GrAssignmentExpression extends GrExpression { +public interface GrAssignmentExpression extends GrExpression, PsiPolyVariantReference { boolean isTupleAssignment(); @NotNull - public GrExpression getLValue(); + GrExpression getLValue(); @Nullable - public GrExpression getRValue(); + GrExpression getRValue(); IElementType getOperationToken(); + + @NotNull + GroovyResolveResult[] multiResolve(boolean incompleteCode); + + PsiElement getOpToken(); } 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 c32de5b6689c..b7e765dd5672 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 @@ -72,16 +72,12 @@ public class TypeDfaInstance implements DfaInstance> { if (element instanceof GrReferenceExpression && ((GrReferenceExpression) element).getQualifierExpression() == null) { final PsiElement parent = element.getParent(); if (parent instanceof GrAssignmentExpression) { - final GrExpression initializer = ((GrAssignmentExpression)parent).getRValue(); - if (initializer != null) { - return new Computable() { - @Nullable - public PsiType compute() { - return initializer.getType(); - } - }; - } - return null; + return new Computable() { + @Nullable + public PsiType compute() { + return ((GrAssignmentExpression)parent).getType(); + } + }; } if (parent instanceof GrTupleExpression) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrAssignmentExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrAssignmentExpressionImpl.java index ac62d6074384..bcdbae331cce 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrAssignmentExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrAssignmentExpressionImpl.java @@ -17,21 +17,29 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions; import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiType; -import com.intellij.psi.PsiVariable; -import com.intellij.psi.ResolveState; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.resolve.ResolveCache; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.tree.IElementType; +import com.intellij.util.ArrayUtil; +import com.intellij.util.Function; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.NullableFunction; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; +import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrTupleDeclaration; 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.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; +import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; +import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor; /** @@ -39,6 +47,31 @@ import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor; */ public class GrAssignmentExpressionImpl extends GrExpressionImpl implements GrAssignmentExpression { + private static final Function TYPE_CALCULATOR = + new NullableFunction() { + @Override + public PsiType fun(GrAssignmentExpressionImpl assignment) { + final GroovyResolveResult[] results = assignment.multiResolve(false); + + if (results.length == 0) { + final GrExpression rValue = assignment.getRValue(); + return rValue == null ? null : rValue.getType(); + } + + + PsiType returnType = null; + final PsiManager manager = assignment.getManager(); + for (GroovyResolveResult result : results) { + final PsiElement element = result.getElement(); + if (element instanceof PsiMethod) { + final PsiType substituted = result.getSubstitutor().substitute(PsiUtil.getSmartReturnType((PsiMethod)element)); + returnType = TypesUtil.getLeastUpperBoundNullable(returnType, substituted, manager); + } + } + return returnType; + } + }; + public GrAssignmentExpressionImpl(@NotNull ASTNode node) { super(node); } @@ -66,11 +99,15 @@ public class GrAssignmentExpressionImpl extends GrExpressionImpl implements GrAs } public IElementType getOperationToken() { - return findNotNullChildByType(TokenSets.ASSIGN_OP_SET).getNode().getElementType(); + return getOpToken().getNode().getElementType(); + } + + public PsiElement getOpToken() { + return findNotNullChildByType(TokenSets.ASSIGN_OP_SET); } public PsiType getType() { - return getLValue().getType(); + return GroovyPsiManager.getInstance(getProject()).getType(this, TYPE_CALCULATOR); } public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place) { @@ -102,4 +139,87 @@ public class GrAssignmentExpressionImpl extends GrExpressionImpl implements GrAs public void accept(GroovyElementVisitor visitor) { visitor.visitAssignmentExpression(this); } + + @NotNull + @Override + public GroovyResolveResult[] multiResolve(boolean incompleteCode) { + return (GroovyResolveResult[])getManager().getResolveCache().resolveWithCaching(this, RESOLVER, false, incompleteCode); + } + + @Override + public PsiElement getElement() { + return this; + } + + @Override + public TextRange getRangeInElement() { + final PsiElement token = getOpToken(); + assert token != null; + final int offset = token.getStartOffsetInParent(); + return new TextRange(offset, offset + token.getTextLength()); + } + + @Override + public PsiElement resolve() { + return PsiImplUtil.extractUniqueElement(multiResolve(false)); + } + + @NotNull + @Override + public String getCanonicalText() { + return getText(); + } + + @Override + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + throw new IncorrectOperationException("assignment expression cannot be renamed"); + } + + @Override + public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException("assignment expression cannot be bound to anything"); + } + + @Override + public boolean isReferenceTo(PsiElement element) { + return getManager().areElementsEquivalent(resolve(), element); + } + + @NotNull + @Override + public Object[] getVariants() { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + @Override + public boolean isSoft() { + return false; + } + + @Override + public PsiReference getReference() { + final IElementType operationToken = getOperationToken(); + if (operationToken == GroovyTokenTypes.mASSIGN) return null; + + return this; + } + + private static final ResolveCache.PolyVariantResolver RESOLVER = + new ResolveCache.PolyVariantResolver() { + @Override + public GroovyResolveResult[] resolve(GrAssignmentExpressionImpl assignmentExpression, boolean incompleteCode) { + final IElementType opType = assignmentExpression.getOperationToken(); + if (opType == null || opType == GroovyTokenTypes.mASSIGN) return GroovyResolveResult.EMPTY_ARRAY; + + final PsiType lType = assignmentExpression.getLValue().getType(); + if (lType == null) return GroovyResolveResult.EMPTY_ARRAY; + + final GrExpression rightOperand = assignmentExpression.getRValue(); + PsiType rType = rightOperand == null ? null : rightOperand.getType(); + + final IElementType operatorToken = TokenSets.ASSIGNMENTS_TO_OPERATORS.get(opType); + return TypesUtil.getOverloadedOperatorCandidates(lType, operatorToken, assignmentExpression, new PsiType[]{rType}); + } + }; + } 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 7ed7a1038c4e..ca9937dc803d 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 @@ -648,4 +648,10 @@ class Zoo { public void resoleAsType() { assertInstanceOf resolve("A.groovy"), GrMethod } + + public void testPlusAssignment() { + final PsiElement resolved = resolve("A.groovy") + assertInstanceOf resolved, GrMethod + assertEquals("plus", resolved.name) + } } 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 c8f43ef182d1..ba42e15a4032 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 @@ -181,4 +181,16 @@ public class TypeInferenceTest extends GroovyResolveTestCase { public void testInferWithClosureType() { assertTypeEquals("java.util.Date", "A.groovy"); } + + public void testPlusEquals1() { + assertTypeEquals("Test", "A.groovy"); + } + + public void testPlusEquals2() { + assertTypeEquals("java.lang.String", "A.groovy"); + } + + public void testPlusEquals3() { + assertTypeEquals("java.lang.String", "A.groovy"); + } } diff --git a/plugins/groovy/testdata/resolve/inference/plusEquals1/A.groovy b/plugins/groovy/testdata/resolve/inference/plusEquals1/A.groovy new file mode 100644 index 000000000000..3e80f23377fb --- /dev/null +++ b/plugins/groovy/testdata/resolve/inference/plusEquals1/A.groovy @@ -0,0 +1,9 @@ +class Test { + def plus(def a) { + "a" + } +} +def test = new Test() +test += 2 +print test + diff --git a/plugins/groovy/testdata/resolve/inference/plusEquals2/A.groovy b/plugins/groovy/testdata/resolve/inference/plusEquals2/A.groovy new file mode 100644 index 000000000000..29757767b091 --- /dev/null +++ b/plugins/groovy/testdata/resolve/inference/plusEquals2/A.groovy @@ -0,0 +1,9 @@ +class Test { + def plus(def a) { + "a" + } +} +def test = new Test() +test += 2 +print test + diff --git a/plugins/groovy/testdata/resolve/inference/plusEquals3/A.groovy b/plugins/groovy/testdata/resolve/inference/plusEquals3/A.groovy new file mode 100644 index 000000000000..699ebddccdef --- /dev/null +++ b/plugins/groovy/testdata/resolve/inference/plusEquals3/A.groovy @@ -0,0 +1,9 @@ +class Test { + def plus(def a) { + "a" + } +} +def test = new Test() +def aa = test += 2 +print test +print aa diff --git a/plugins/groovy/testdata/resolve/method/plusAssignment/A.groovy b/plugins/groovy/testdata/resolve/method/plusAssignment/A.groovy new file mode 100644 index 000000000000..f0a832c95104 --- /dev/null +++ b/plugins/groovy/testdata/resolve/method/plusAssignment/A.groovy @@ -0,0 +1,7 @@ +class Test { + def plus(def a) { + new Test() + } +} +def test=new Test() +test+=2 \ No newline at end of file From 538db2cfdb8ad4e0ce4af7ad5664e53aded9bb3b Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Thu, 14 Apr 2011 13:14:47 +0400 Subject: [PATCH 023/100] convert switch --- .../daemon/impl/analysis/HighlightUtil.java | 6 +- .../groovy/actions/ConvertToJavaAction.java | 8 +- .../refactoring/GroovyRefactoringUtil.java | 5 +- .../convertToJava/CodeBlockGenerator.java | 254 +++++++++++------- .../convertToJava/ConvertToJavaHandler.java | 2 +- .../convertToJava/ConvertToJavaProcessor.java | 61 +++-- .../convertToJava/ExpressionContext.java | 9 + .../convertToJava/ExpressionGenerator.java | 107 ++++++-- .../convertToJava/GenerationSettings.java | 23 ++ .../convertToJava/GenerationUtil.java | 73 ++++- .../refactoring/convertToJava/Generator.java | 4 +- .../convertToJava/StatementWriter.java | 23 ++ .../SwitchStatementGenerator.java | 195 ++++++++++++++ .../CodeBlockGenerationTest.groovy | 91 +++++++ .../ExpressionGenerationTest.groovy | 79 ++++++ .../codeBlock/switch1.groovy | 15 ++ .../codeBlock/switch1.java | 14 + .../codeBlock/switch2.groovy | 8 + .../codeBlock/switch2.java | 13 + .../codeBlock/switch3.groovy | 11 + .../codeBlock/switch3.java | 10 + .../codeBlock/switch4.groovy | 11 + .../codeBlock/switch4.java | 14 + .../codeBlock/while1.groovy | 2 +- .../convertGroovyToJava/codeBlock/while1.java | 2 +- .../codeBlock/while2.groovy | 2 +- .../convertGroovyToJava/codeBlock/while2.java | 2 +- .../codeBlock/while3.groovy | 2 + .../convertGroovyToJava/codeBlock/while3.java | 8 + 29 files changed, 878 insertions(+), 176 deletions(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationSettings.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StatementWriter.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/SwitchStatementGenerator.java create mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy create mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerationTest.groovy create mode 100644 plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.groovy create mode 100644 plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.java create mode 100644 plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.groovy create mode 100644 plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.java create mode 100644 plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.groovy create mode 100644 plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.java create mode 100644 plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.groovy create mode 100644 plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.java create mode 100644 plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.groovy create mode 100644 plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index f8c016341883..02866d216848 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -990,7 +990,7 @@ public class HighlightUtil { HighlightInfo errorResult = null; if (expression != null && expression.getType() != null) { PsiType type = expression.getType(); - if (!isValidTypeForSwitchSelector(type, expression)) { + if (!isValidTypeForSwitchSelector(type, PsiUtil.isLanguageLevel7OrHigher(expression))) { String message = JavaErrorMessages.message("incompatible.types", JavaErrorMessages.message("valid.switch.selector.types"), formatType(type)); errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, message); @@ -1002,7 +1002,7 @@ public class HighlightUtil { return errorResult; } - private static boolean isValidTypeForSwitchSelector(PsiType type, PsiExpression expression) { + public static boolean isValidTypeForSwitchSelector(PsiType type, final boolean languageLevel7OrHigher) { if (TypeConversionUtil.getTypeRank(type) <= TypeConversionUtil.INT_RANK) return true; if (type instanceof PsiClassType) { PsiClass psiClass = ((PsiClassType)type).resolve(); @@ -1010,7 +1010,7 @@ public class HighlightUtil { if (psiClass.isEnum()) { return true; } - if (PsiUtil.isLanguageLevel7OrHigher(expression)) { + if (languageLevel7OrHigher) { return Comparing.strEqual(psiClass.getQualifiedName(), CommonClassNames.JAVA_LANG_STRING); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java index 93191c92549d..da3520067bcf 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java @@ -24,7 +24,6 @@ import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.actions.BaseRefactoringAction; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.refactoring.convertToJava.ConvertToJavaHandler; /** @@ -49,14 +48,11 @@ public class ConvertToJavaAction extends BaseRefactoringAction { @Override protected boolean isEnabledOnElements(PsiElement[] elements) { + for (PsiElement element : elements) { - if (element instanceof GrTypeDefinition) { final PsiFile containingFile = element.getContainingFile(); - if (containingFile instanceof GroovyFile && ((GroovyFile)containingFile).getClasses().length == 1) continue; + if (containingFile instanceof GroovyFile) continue; return false; - } - if (element instanceof GroovyFile) continue; - return false; } return true; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java index f4d17aa06754..b434373731a2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java @@ -632,7 +632,10 @@ public abstract class GroovyRefactoringUtil { argText.append(argument.getText()).append(", "); argument.delete(); } - argText.replace(argText.length() - 2, argText.length(), "]"); + if (arguments.size() > 0) { + argText.delete(argText.length() - 2, argText.length()); + } + argText.append("]"); if (type instanceof PsiArrayType) { type = substitutor.substitute(type); String typeText = type.getCanonicalText(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java index a7197c918cc3..be909e23cc79 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java @@ -17,10 +17,8 @@ package org.jetbrains.plugins.groovy.refactoring.convertToJava; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; -import com.intellij.psi.CommonClassNames; -import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiType; +import com.intellij.psi.*; +import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrCondition; @@ -31,18 +29,18 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; 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.blocks.GrOpenBlock; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrAssertStatement; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrFlowInterruptingStatement; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrThrowStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForClause; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClause; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrTraditionalForClause; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement; 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.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; +import java.util.Set; + /** * @author Maxim.Medvedev */ @@ -51,28 +49,15 @@ public class CodeBlockGenerator extends Generator { private final StringBuilder builder; private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.refactoring.convertToJava.CodeBlockGenerator"); - private final boolean insertStatementsFromExpr; - private final ExpressionContext context; - public CodeBlockGenerator(StringBuilder builder, Project project) { - this(builder, project, false); - } - - public CodeBlockGenerator(StringBuilder builder, Project project, boolean insertStatementsFromExpr) { - this(builder, insertStatementsFromExpr, new ExpressionContext(project)); - } - - public CodeBlockGenerator(StringBuilder builder, - boolean insertStatementsFromExpr, - ExpressionContext context) { + public CodeBlockGenerator(StringBuilder builder, ExpressionContext context) { this.builder = builder; - this.insertStatementsFromExpr = insertStatementsFromExpr; this.context = context; } - public CodeBlockGenerator(StringBuilder builder, ExpressionContext context) { - this(builder, false, context); + public CodeBlockGenerator(StringBuilder builder, Project project) { + this(builder, new ExpressionContext(project)); } @Override @@ -126,32 +111,10 @@ public class CodeBlockGenerator extends Generator { writeStatement(statementBuilder, statement, null); } - private void writeStatement(StringBuilder statementBuilder, GrStatement statement, @Nullable ExpressionContext context) { - final PsiElement parent = statement.getParent(); - - final boolean addParentheses = - insertStatementsFromExpr && context != null && context.myStatements.size() > 0 && parent instanceof GrControlStatement; - if (addParentheses) { - builder.append("{\n"); - } - - if (insertStatementsFromExpr) { - if (context != null) { - for (String st : context.myStatements) { - builder.append(st).append("\n"); - } - } - } - else { - LOG.assertTrue(context != null); - LOG.assertTrue(context.myStatements.size() == 0); - context.myStatements.addAll(context.myStatements); - } - - builder.append(statementBuilder); - if (addParentheses) { - builder.append("}\n"); - } + private void writeStatement(StringBuilder statementBuilder, + GrStatement statement, + @Nullable ExpressionContext context) { + GenerationUtil.writeStatement(builder, statementBuilder, statement, context); } @Override @@ -191,9 +154,15 @@ public class CodeBlockGenerator extends Generator { final StringBuilder statementBuilder = new StringBuilder(); final ExpressionContext context = new ExpressionContext(this.context.project, this.context.myUsedVarNames); expression.accept(new ExpressionGenerator(statementBuilder, context)); + statementBuilder.append(";"); writeStatement(statementBuilder, expression, context); } + @Override + public void visitApplicationStatement(GrApplicationStatement applicationStatement) { + visitExpression(applicationStatement); + } + @Override public void visitTypeDefinition(GrTypeDefinition typeDefinition) { //todo ??????? @@ -231,7 +200,7 @@ public class CodeBlockGenerator extends Generator { LOG.assertTrue(declaredVariable != null); builder.append("for("); - writeVariableWithoutColon(builder, declaredVariable); + writeVariableWithoutSemicolonAndInitializer(builder, declaredVariable); builder.append(" : "); if (expression != null) { final ExpressionContext context = forContext.copy(); @@ -247,7 +216,7 @@ public class CodeBlockGenerator extends Generator { if (initialization instanceof GrParameter) { StringBuilder partBuilder = new StringBuilder(); - writeVariableWithoutColon(partBuilder, (GrParameter)initialization); + writeVariableWithoutSemicolonAndInitializer(partBuilder, (GrParameter)initialization); final GrExpression initializer = ((GrParameter)initialization).getDefaultInitializer(); if (initializer != null) { final ExpressionContext partContext = forContext.copy(); @@ -293,11 +262,11 @@ public class CodeBlockGenerator extends Generator { builder.append(visitor.getBuilder()); } - private static void writeVariableWithoutColon(StringBuilder builder, GrVariable var) { - if (GenerationUtil.writeModifiers(builder, var.getModifierList(), GenerationUtil.JAVA_MODIFIERS)) { + private static void writeVariableWithoutSemicolonAndInitializer(StringBuilder builder, GrVariable var) { + if (GenerationUtil.writeModifiers(builder, var.getModifierList())) { builder.append(" "); } - GenerationUtil.writeType(builder, var.getDeclaredType()); + GenerationUtil.writeType(builder, getVarType(var)); builder.append(" ").append(var.getName()); } @@ -321,7 +290,10 @@ public class CodeBlockGenerator extends Generator { @Override public void visitSwitchStatement(GrSwitchStatement switchStatement) { - //todo + final StringBuilder builder = new StringBuilder(); + final ExpressionContext copy = context.copy(); + SwitchStatementGenerator.generate(builder, copy, switchStatement); + writeStatement(builder, switchStatement, copy); } @Override @@ -343,7 +315,7 @@ public class CodeBlockGenerator extends Generator { public void visitCatchClause(GrCatchClause catchClause) { final GrParameter parameter = catchClause.getParameter(); builder.append("catch ("); - writeVariableWithoutColon(builder, parameter); + writeVariableWithoutSemicolonAndInitializer(builder, parameter); builder.append(") "); final GrOpenBlock body = catchClause.getBody(); if (body != null) { @@ -379,58 +351,150 @@ public class CodeBlockGenerator extends Generator { @Override public void visitVariableDeclaration(GrVariableDeclaration variableDeclaration) { - final GrModifierList modifierList = variableDeclaration.getModifierList(); - final GrVariable[] variables = variableDeclaration.getVariables(); StringBuilder builder = new StringBuilder(); ExpressionContext expressionContext = context.copy(); - final ExpressionGenerator expressionGenerator = new ExpressionGenerator(builder, expressionContext); if (variableDeclaration.isTuple()) { - final GrTupleDeclaration tuple = variableDeclaration.getTupleDeclaration(); - final GrExpression tupleInitializer = tuple.getInitializerGroovy(); - if (tupleInitializer instanceof GrListOrMap) { - final GrExpression[] initializers = ((GrListOrMap)tupleInitializer).getInitializers(); - for (int i = 0; i < variables.length; i++) { - final GrVariable v = variables[i]; - final PsiType type = v.getDeclaredType(); - GenerationUtil.writeModifiers(builder, modifierList); - GenerationUtil.writeType(builder, type); - builder.append(" ").append(v.getName()); - if (i < initializers.length) { - builder.append(" = "); - initializers[i].accept(expressionGenerator); + writeTupleDeclaration(variableDeclaration, builder, expressionContext); + } + else { + writeSimpleVarDeclaration(variableDeclaration, builder, expressionContext); + } + + writeStatement(builder, variableDeclaration, expressionContext); + } + + private static void writeSimpleVarDeclaration(GrVariableDeclaration variableDeclaration, + StringBuilder builder, + ExpressionContext expressionContext) { + GrVariable[] variables = variableDeclaration.getVariables(); + + final GrTypeElement typeElement = variableDeclaration.getTypeElementGroovy(); + PsiType type = null; + Set types = new HashSet(variables.length); + if (typeElement == null) { + if (variables.length > 1) { + for (GrVariable variable : variables) { + final GrExpression initializer = variable.getInitializerGroovy(); + if (initializer != null) { + final PsiType varType = initializer.getType(); + if (varType != null) { + types.add(getTypeText(varType)); + type = varType; + } } - builder.append(";\n"); + } + if (type == null) { + type = PsiType.getJavaLangObject(variableDeclaration.getManager(), variableDeclaration.getResolveScope()); } } else { - final PsiType iteratorType = - JavaPsiFacade.getElementFactory(context.project).createTypeFromText(CommonClassNames.JAVA_UTIL_ITERATOR, variableDeclaration); - final String iteratorName = GenerationUtil.suggestVarName(iteratorType, variableDeclaration, expressionContext); - builder.append("final ").append(CommonClassNames.JAVA_UTIL_ITERATOR).append(" ").append(iteratorName).append(" = "); - - GenerationUtil.invokeMethodByName(tupleInitializer, "iterator", GrExpression.EMPTY_ARRAY, GrNamedArgument.EMPTY_ARRAY, - GrClosableBlock.EMPTY_ARRAY, expressionGenerator, variableDeclaration); - for (final GrVariable v : variables) { - GenerationUtil.writeModifiers(builder, modifierList); - final PsiType type = v.getDeclaredType(); - GenerationUtil.writeType(builder, type); - builder.append(" ").append(v.getName()); - builder.append(" = ").append(iteratorName).append(".hasNext() ? ").append(iteratorName).append(".next() : null;"); - } + type = getVarType(variables[0]); } } else { - GenerationUtil.writeModifiers(builder, modifierList); - final GrTypeElement typeElement = variableDeclaration.getTypeElementGroovy(); - PsiType type = typeElement == null - ? PsiType.getJavaLangObject(variableDeclaration.getManager(), variableDeclaration.getResolveScope()) - : typeElement.getType(); - GenerationUtil.writeType(builder, type); + type = typeElement.getType(); } - writeStatement(builder, variableDeclaration, expressionContext); + + if (types.size() > 1) { + if (variableDeclaration.getParent() instanceof GrControlStatement) { + expressionContext.setInsertCurlyBrackets(); + } + for (GrVariable variable : variables) { + writeVariableSeparately(variable, builder, expressionContext); + builder.append(";\n"); + } + return; + } + + GenerationUtil.writeType(builder, type); + + builder.append(" "); + for (GrVariable variable : variables) { + writeVariableWithoutType(builder, expressionContext, variable); + builder.append(", "); + } + if (variables.length > 0) { + builder.delete(builder.length() - 2, builder.length()); + } + builder.append(";"); + } + + private static void writeVariableWithoutType(StringBuilder builder, ExpressionContext expressionContext, GrVariable variable) { + builder.append(variable.getName()); + final GrExpression initializer = variable.getInitializerGroovy(); + if (initializer != null) { + builder.append(" = "); + initializer.accept(new ExpressionGenerator(builder, expressionContext)); + } + } + + private static void writeVariableSeparately(GrVariable variable, StringBuilder builder, ExpressionContext expressionContext) { + PsiType type = getVarType(variable); + + if (GenerationUtil.writeModifiers(builder, variable.getModifierList())) { + builder.append(" "); + } + + GenerationUtil.writeType(builder, type); + builder.append(" "); + + writeVariableWithoutType(builder, expressionContext, variable); + } + + private static PsiType getVarType(GrVariable variable) { + PsiType type = variable.getDeclaredType(); + if (type == null) { + type = variable.getTypeGroovy(); + } + if (type == null) { + type = variable.getType(); + } + return type; + } + + private void writeTupleDeclaration(GrVariableDeclaration variableDeclaration, + StringBuilder builder, + ExpressionContext expressionContext) { + GrVariable[] variables = variableDeclaration.getVariables(); + final GrExpression tupleInitializer = variableDeclaration.getTupleDeclaration().getInitializerGroovy(); + if (tupleInitializer instanceof GrListOrMap) { + for (GrVariable variable : variables) { + writeVariableSeparately(variable, builder, expressionContext); + builder.append(";\n"); + } + } + else { + final PsiType iteratorType = + JavaPsiFacade.getElementFactory(context.project).createTypeFromText(CommonClassNames.JAVA_UTIL_ITERATOR, variableDeclaration); + final String iteratorName = GenerationUtil.suggestVarName(iteratorType, variableDeclaration, expressionContext); + builder.append("final ").append(CommonClassNames.JAVA_UTIL_ITERATOR).append(" ").append(iteratorName).append(" = "); + + GenerationUtil.invokeMethodByName(tupleInitializer, "iterator", GrExpression.EMPTY_ARRAY, GrNamedArgument.EMPTY_ARRAY, + GrClosableBlock.EMPTY_ARRAY, new ExpressionGenerator(builder, expressionContext), + variableDeclaration); + final GrModifierList modifierList = variableDeclaration.getModifierList(); + for (final GrVariable v : variables) { + GenerationUtil.writeModifiers(builder, modifierList); + final PsiType type = getVarType(v); + GenerationUtil.writeType(builder, type); + builder.append(" ").append(v.getName()); + builder.append(" = ").append(iteratorName).append(".hasNext() ? ").append(iteratorName).append(".next() : null;"); + } + } + } + + private void writeVariable(GrVariable variable) { + //todo + throw new UnsupportedOperationException(); + } + + private static String getTypeText(PsiType varType) { + final StringBuilder builder = new StringBuilder(); + GenerationUtil.writeType(builder, varType); + return builder.toString(); } @Override diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaHandler.java index 48ab2035e270..cde84e1bedf7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaHandler.java @@ -49,7 +49,7 @@ public class ConvertToJavaHandler implements RefactoringActionHandler { invokeInner(project, elements, editor); } - private void invokeInner(Project project, PsiElement[] elements, Editor editor) { + private static void invokeInner(Project project, PsiElement[] elements, Editor editor) { for (PsiElement element : elements) { if (!(element instanceof GroovyFile)) { if (!ApplicationManager.getApplication().isUnitTestMode()) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaProcessor.java index 8a4dca3074d9..c4eeebae5882 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaProcessor.java @@ -16,13 +16,10 @@ package org.jetbrains.plugins.groovy.refactoring.convertToJava; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiDirectory; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiFileFactory; +import com.intellij.psi.*; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.ui.UsageViewDescriptorAdapter; import com.intellij.usageView.UsageInfo; @@ -30,10 +27,9 @@ import com.intellij.usageView.UsageViewDescriptor; import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.GrTopStatement; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; -import java.util.Collections; -import java.util.Map; import java.util.Set; /** @@ -73,35 +69,44 @@ public class ConvertToJavaProcessor extends BaseRefactoringProcessor { //private static String @Override protected void performRefactoring(UsageInfo[] usages) { - final GroovyToJavaGenerator generator = new GroovyToJavaGenerator(myProject, Collections.emptyList(), true); - final PsiFileFactory fileFactory = PsiFileFactory.getInstance(myProject); +// final GroovyToJavaGenerator generator = new GroovyToJavaGenerator(myProject, Collections.emptyList(), true); - PsiFile fileToOpen = null; for (GroovyFile file : myFiles) { final PsiDirectory dir = file.getContainingDirectory(); LOG.assertTrue(dir != null); - final Map fileMap = generator.generateStubs(file); - for (String fileName : fileMap.keySet()) { - file.delete(); - final PsiFile[] files = dir.getFiles(); - Set fileNames = new HashSet(); - for (PsiFile psiFile : files) { - fileNames.add(psiFile.getName()); - } - int index = 0; - String prefix = FileUtil.getNameWithoutExtension(fileName); - while (fileNames.contains(fileName)) { - fileName = prefix + index + ".java"; - } - - final PsiFile newFile = fileFactory.createFileFromText(fileName, fileMap.get(fileName)); - dir.add(newFile); + final PsiFile[] files = dir.getFiles(); + Set fileNames = new HashSet(); + for (PsiFile psiFile : files) { + fileNames.add(psiFile.getName()); } + String prefix = FileUtil.getNameWithoutExtension(file.getName()); + String fileName = prefix + ".java"; + int index = 1; + while (fileNames.contains(fileName)) { + fileName = prefix + index + ".java"; + } + final Project project = file.getProject(); + + GrTopStatement[] statements = file.getTopStatements(); + final StringBuilder builder = new StringBuilder(); + CodeBlockGenerator generator = new CodeBlockGenerator(builder, new ExpressionContext(project)); + for (GrTopStatement statement : statements) { + statement.accept(generator); + builder.append("\n"); + } + + final PsiFile newFile = (PsiFile)file.setName(fileName); + final Document document = PsiDocumentManager.getInstance(project).getDocument(newFile); + document.setText(builder); + /*final PsiFile created = PsiFileFactory.getInstance(project) + .createFileFromText(file.getScriptClass().getName() + ".java", StdLanguages.JAVA, builder.toString()); + PostprocessReformattingAspect.getInstance(project).doPostponedFormatting(); + file.delete(); + dir.add(created);*/ + //QuickfixUtil.positionCursor(project, created, created.getFirstChild()); } - - } @Override diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionContext.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionContext.java index 01a04fa9b598..a333b55290de 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionContext.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionContext.java @@ -26,6 +26,7 @@ class ExpressionContext { List myStatements = new ArrayList(); Set myUsedVarNames; Project project; + private boolean myShouldInsertCurlyBrackets = false; ExpressionContext(Project project, Set usedVarNames) { this.project = project; @@ -45,4 +46,12 @@ class ExpressionContext { usedVarNames.addAll(myUsedVarNames); return new ExpressionContext(project, usedVarNames); } + + public void setInsertCurlyBrackets() { + myShouldInsertCurlyBrackets = true; + } + + public boolean shouldInsertCurlyBrackets() { + return myShouldInsertCurlyBrackets; + } } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java index 3b249bbde3a3..6d1d61cfe394 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.refactoring.convertToJava; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.tree.IElementType; @@ -24,9 +25,9 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.intentions.conversions.ConvertGStringToStringIntention; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; -import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier; @@ -58,9 +59,6 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; 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.refactoring.GroovyRefactoringUtil; - -import java.util.*; /** * @author Maxim.Medvedev @@ -324,13 +322,55 @@ public class ExpressionGenerator extends Generator { @Override public void visitAssignmentExpression(GrAssignmentExpression expression) { - //todo + final GrExpression lValue = expression.getLValue(); + GrExpression rValue = expression.getRValue(); + final IElementType token = expression.getOperationToken(); + + + if (token == GroovyTokenTypes.mASSIGN) { + lValue.accept(this); + builder.append(" = "); + if (rValue != null) { + rValue.accept(this); + } + return; + } + + final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(expression.multiResolve(false)); + final PsiElement resolved = resolveResult.getElement(); + + if (resolved instanceof PsiMethod) { + lValue.accept(this); + builder.append(" = "); + if (rValue == null) { + rValue = factory.createExpressionFromText("null"); + } + invokeMethodOn( + ((PsiMethod)resolved), + lValue, + new GrExpression[]{rValue}, + GrNamedArgument.EMPTY_ARRAY, + GrClosableBlock.EMPTY_ARRAY, + resolveResult.getSubstitutor(), + expression + ); + } + else { + writeSimpleBinaryExpression(expression.getOpToken(), lValue, rValue); + } } @Override public void visitBinaryExpression(GrBinaryExpression expression) { final GrExpression left = expression.getLeftOperand(); GrExpression right = expression.getRightOperand(); + final PsiType ltype = left.getType(); + if (GenerationSettings.dontReplaceOperatorsWithMethodsForNumbers && + (TypesUtil.isNumericType(ltype) && (right == null || TypesUtil.isNumericType(right.getType())) || + ltype != null && TypesUtil.typeEqualsToText(ltype, CommonClassNames.JAVA_LANG_STRING))) { + writeSimpleBinaryExpression(expression.getOperationToken(), left, right); + return; + } final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(expression.multiResolve(false)); final PsiElement resolved = resolveResult.getElement(); @@ -349,11 +389,17 @@ public class ExpressionGenerator extends Generator { ); } else { - left.accept(this); - builder.append(expression.getOperationToken().getText()); - if (right != null) { - right.accept(this); - } + writeSimpleBinaryExpression(expression.getOperationToken(), left, right); + } + } + + private void writeSimpleBinaryExpression(PsiElement opToken, GrExpression left, GrExpression right) { + left.accept(this); + builder.append(" "); + builder.append(opToken.getText()); + if (right != null) { + builder.append(" "); + right.accept(this); } } @@ -408,8 +454,12 @@ public class ExpressionGenerator extends Generator { else { value = literal.getValue(); } - - //todo + if (value instanceof String) { + builder.append('"').append(StringUtil.escapeQuotes((String)value)).append('"'); + } + else { + builder.append(value); + } } @Override @@ -574,14 +624,13 @@ public class ExpressionGenerator extends Generator { PsiSubstitutor substitutor, GroovyPsiElement context) { if (method instanceof GrGdkMethod && !method.hasModifierProperty(GrModifier.STATIC)) { - LOG.assertTrue(caller != null); - final GrExpression listOrMap = - GroovyRefactoringUtil.generateArgFromMultiArg(PsiSubstitutor.EMPTY, Arrays.asList(namedArgs), null, method.getProject()); - GrExpression[] newArgs = new GrExpression[exprs.length + 2]; - System.arraycopy(exprs, 0, newArgs, 2, exprs.length); + if (caller == null) { + caller = factory.createExpressionFromText("this", context); + } + GrExpression[] newArgs = new GrExpression[exprs.length + 1]; + System.arraycopy(exprs, 0, newArgs, 1, exprs.length); newArgs[0] = caller; - newArgs[1] = listOrMap; - invokeMethodOn(((GrGdkMethod)method).getStaticMethod(), null, newArgs, GrNamedArgument.EMPTY_ARRAY, closures, substitutor, context); + invokeMethodOn(((GrGdkMethod)method).getStaticMethod(), null, newArgs, namedArgs, closures, substitutor, context); return; } @@ -593,9 +642,11 @@ public class ExpressionGenerator extends Generator { } } else { - LOG.assertTrue(caller != null, "instance method call should have caller"); - caller.accept(this); - builder.append("."); + //LOG.assertTrue(caller != null, "instance method call should have caller"); + if (caller != null) { + caller.accept(this); + builder.append("."); + } } builder.append(method.getName()); final GrClosureSignature signature = GrClosureSignatureUtil.createSignature(method, substitutor); @@ -613,6 +664,7 @@ public class ExpressionGenerator extends Generator { String varName = generateListOrMapVariableDeclaration(listOrMap, type); generateListOrMapElementInsertions(listOrMap, varName); + builder.append(varName); } private void generateListOrMapElementInsertions(GrListOrMap listOrMap, String varName) { @@ -647,6 +699,17 @@ public class ExpressionGenerator extends Generator { context.myStatements.add(insertion.toString()); } } + else { + for (GrExpression arg : listOrMap.getInitializers()) { + StringBuilder insertion = new StringBuilder(); + insertion.append(varName).append(".add("); + arg.accept(new ExpressionGenerator(insertion, context)); + + insertion.append(");"); + context.myStatements.add(insertion.toString()); + } + + } //todo for list } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationSettings.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationSettings.java new file mode 100644 index 000000000000..a9ea1a4e43a3 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationSettings.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 org.jetbrains.plugins.groovy.refactoring.convertToJava; + +/** + * @author Maxim.Medvedev + */ +public class GenerationSettings { + public static boolean dontReplaceOperatorsWithMethodsForNumbers = true; +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java index 3cca78c1bb92..901c0c185492 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java @@ -20,7 +20,8 @@ import com.intellij.psi.*; import org.jetbrains.annotations.Nullable; 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.auxiliary.modifiers.GrModifierList; +import org.jetbrains.plugins.groovy.lang.psi.api.formatter.GrControlStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; 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.GrExpression; @@ -41,14 +42,14 @@ import java.util.List; public class GenerationUtil { private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.refactoring.convertToJava.GenerationUtil"); public static final String[] JAVA_MODIFIERS = new String[]{ - PsiModifier.PUBLIC, - PsiModifier.PROTECTED, - PsiModifier.PRIVATE, - PsiModifier.PACKAGE_LOCAL, - PsiModifier.STATIC, - PsiModifier.ABSTRACT, - PsiModifier.FINAL, - PsiModifier.NATIVE, + PsiModifier.PUBLIC, + PsiModifier.PROTECTED, + PsiModifier.PRIVATE, + PsiModifier.PACKAGE_LOCAL, + PsiModifier.STATIC, + PsiModifier.ABSTRACT, + PsiModifier.FINAL, + PsiModifier.NATIVE, }; private GenerationUtil() { @@ -79,9 +80,12 @@ public class GenerationUtil { return varNames[0]; } + public static String validateName(String name, GroovyPsiElement context, ExpressionContext expressionContext) { + return new DefaultGroovyVariableNameValidator(context, expressionContext.myUsedVarNames, true).validateName(name, true); + } + public static void writeCodeReferenceElement(StringBuilder builder, GrCodeReferenceElement referenceElement) { - //todo - throw new UnsupportedOperationException(); + builder.append(referenceElement.getText()); } public static void invokeMethodByName(GrExpression caller, @@ -146,9 +150,9 @@ public class GenerationUtil { } public static void writeClassModifiers(StringBuilder text, - @Nullable PsiModifierList modifierList, - boolean isInterface, - boolean toplevel) { + @Nullable PsiModifierList modifierList, + boolean isInterface, + boolean toplevel) { if (modifierList == null) { text.append("public "); return; @@ -166,4 +170,45 @@ public class GenerationUtil { writeModifiers(text, modifierList, allowedModifiers.toArray(new String[allowedModifiers.size()])); } + + static void writeStatement(final StringBuilder codeBlockBuilder, + StringBuilder statementBuilder, + @Nullable GrStatement statement, + @Nullable ExpressionContext context) { + final PsiElement parent = statement == null ? null : statement.getParent(); + + final boolean addParentheses; + if (statement == null) { + addParentheses = context != null && context.shouldInsertCurlyBrackets(); + } + else { + addParentheses = + context != null && (context.shouldInsertCurlyBrackets() || context.myStatements.size() > 0) && parent instanceof GrControlStatement; + } + + if (addParentheses) { + codeBlockBuilder.append("{\n"); + } + + if (context != null) { + insertStatementFromContextBefore(codeBlockBuilder, context); + } + codeBlockBuilder.append(statementBuilder); + if (addParentheses) { + codeBlockBuilder.append("}\n"); + } + } + + public static void insertStatementFromContextBefore(StringBuilder codeBlockBuilder, ExpressionContext context) { + for (String st : context.myStatements) { + codeBlockBuilder.append(st).append("\n"); + } + } + + public static void writeStatement(final StringBuilder builder, ExpressionContext context, @Nullable GrStatement statement, StatementWriter writer) { + StringBuilder statementBuilder = new StringBuilder(); + ExpressionContext statementContext = context.copy(); + writer.writeStatement(statementBuilder, statementContext); + writeStatement(builder, statementBuilder, statement, statementContext); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/Generator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/Generator.java index 14ece08f12fd..4c9c1e3ea07a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/Generator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/Generator.java @@ -15,12 +15,12 @@ */ package org.jetbrains.plugins.groovy.refactoring.convertToJava; -import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; +import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; /** * @author Maxim.Medvedev */ -public abstract class Generator extends GroovyRecursiveElementVisitor { +public abstract class Generator extends GroovyElementVisitor { public abstract StringBuilder getBuilder(); public abstract ExpressionContext getContext(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StatementWriter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StatementWriter.java new file mode 100644 index 000000000000..b9a28fb426f9 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StatementWriter.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 org.jetbrains.plugins.groovy.refactoring.convertToJava; + +/** + * @author Maxim.Medvedev + */ +public interface StatementWriter { + void writeStatement(StringBuilder builder, ExpressionContext context); +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/SwitchStatementGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/SwitchStatementGenerator.java new file mode 100644 index 000000000000..0a0f3087e4b8 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/SwitchStatementGenerator.java @@ -0,0 +1,195 @@ +/* + * 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.refactoring.convertToJava; + +import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil; +import com.intellij.psi.PsiType; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrSwitchStatement; +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.branch.GrBreakStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection; +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.impl.statements.expressions.TypesUtil; +import org.jetbrains.plugins.groovy.lang.psi.util.GroovyConstantExpressionEvaluator; + +/** + * @author Maxim.Medvedev + */ +public class SwitchStatementGenerator { + + private static final boolean LANGUAGE_LEVEL_7_OR_HIGHER = false; + + private SwitchStatementGenerator() { + } + + public static void generate(StringBuilder builder, ExpressionContext context, GrSwitchStatement switchStatement) { + final GrExpression condition = switchStatement.getCondition(); + final GrCaseSection[] caseSections = switchStatement.getCaseSections(); + + final PsiType type = condition == null ? null : TypesUtil.unboxPrimitiveTypeWrapper(condition.getType()); + if (type == null || HighlightUtil.isValidTypeForSwitchSelector(type, LANGUAGE_LEVEL_7_OR_HIGHER)) { + generateSwitch(builder, context, condition, caseSections); + } + else { + generateIfs(builder, context, condition, caseSections); + } + } + + private static void generateIfs(StringBuilder builder, ExpressionContext context, GrExpression condition, GrCaseSection[] caseSections) { + if (caseSections.length == 1 && caseSections[0].getCaseLabel().isDefault()) { + //todo + } + + final GrExpression ref; + if (condition instanceof GrReferenceExpression) { + ref = condition; + } + else { + final String varName = generateConditionVar(builder, context, condition); + ref = GroovyPsiElementFactory.getInstance(context.project).createExpressionFromText(varName); + } + final GrExpression[] args = {ref}; + generateIfFromCaseSection(builder, context, caseSections, 0, args); + } + + private static void generateIfFromCaseSection(StringBuilder builder, + ExpressionContext context, + final GrCaseSection[] caseSections, + final int i, + final GrExpression[] args) { + + GenerationUtil.writeStatement(builder, context, null, new StatementWriter() { + @Override + public void writeStatement(StringBuilder builder, ExpressionContext context) { + GrCaseSection section = caseSections[i]; + boolean isCase = !section.getCaseLabel().isDefault(); + + if (isCase) { + builder.append("if ("); + GenerationUtil.invokeMethodByName( + section.getCaseLabel().getValue(), + "isCase", + args, + GrNamedArgument.EMPTY_ARRAY, + GrClosableBlock.EMPTY_ARRAY, + new ExpressionGenerator(builder, context), + section + ); + builder.append(") {\n"); + } + final ExpressionContext extended = context.extend(); + CodeBlockGenerator generator = new CodeBlockGenerator(builder, extended); + + Outer: + for (int j = i; j < caseSections.length; j++) { + section = caseSections[j]; + final GrStatement[] statements = section.getStatements(); + for (GrStatement statement : statements) { + if (statement instanceof GrBreakStatement && ((GrBreakStatement)statement).getLabelIdentifier() == null) { + break Outer; + } + statement.accept(generator); + builder.append("\n"); + } + } + + if (isCase && i + 1 < caseSections.length) { + builder.append("}\nelse "); + StringBuilder elseBuilder = new StringBuilder(); + final ExpressionContext elseContext = context.extend(); + + generateIfFromCaseSection(elseBuilder, elseContext, caseSections, i + 1, args); + GenerationUtil.insertStatementFromContextBefore(builder, elseContext); + builder.append(elseBuilder); + } + if (context.myStatements.size() > 0) context.setInsertCurlyBrackets(); + } + }); + } + + private static String generateConditionVar(StringBuilder builder, + ExpressionContext context, + GrExpression condition) { + StringBuilder conditionBuilder = new StringBuilder(); + final PsiType type = condition.getType(); + final String varName = GenerationUtil.validateName("switchArg", condition, context); + conditionBuilder.append("final "); + GenerationUtil.writeType(conditionBuilder, type); + conditionBuilder.append(" ").append(varName).append(" = "); + condition.accept(new ExpressionGenerator(conditionBuilder, context)); + conditionBuilder.append(";\n"); + GenerationUtil.insertStatementFromContextBefore(builder, context); + builder.append(conditionBuilder); + return varName; + } + + private static void generateSwitch(StringBuilder builder, + ExpressionContext context, + GrExpression condition, + GrCaseSection[] caseSections) { + builder.append("switch ("); + if (condition != null) { + condition.accept(new ExpressionGenerator(builder, context)); + } + builder.append(") {\n"); + + final ExpressionContext innerContext = context.extend(); + for (GrCaseSection section : caseSections) { + generateCaseSection(builder, context, innerContext, section); + } + + builder.append("}"); + } + + private static void generateCaseSection(StringBuilder builder, + ExpressionContext context, + ExpressionContext innerContext, + GrCaseSection section) { + if (section.getCaseLabel().isDefault()) { + builder.append("default"); + } + else { + builder.append("case "); + final GrExpression value = section.getCaseLabel().getValue(); + Object evaluated; + try { + evaluated = GroovyConstantExpressionEvaluator.evaluate(value); + } + catch (Throwable e) { + evaluated = null; + } + + if (evaluated != null) { + builder.append(evaluated); + } + else if (value != null) { + value.accept(new ExpressionGenerator(builder, context)); + } + } + + builder.append(":\n"); + final GrStatement[] statements = section.getStatements(); + CodeBlockGenerator generator = new CodeBlockGenerator(builder, innerContext); + for (GrStatement statement : statements) { + statement.accept(generator); + builder.append("\n"); + } + } +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy new file mode 100644 index 000000000000..58a2a302cd16 --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy @@ -0,0 +1,91 @@ +/* + * 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.refactoring.convertToJava; + + +import com.intellij.lang.StdLanguages +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.ContentEntry +import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.roots.libraries.Library +import com.intellij.openapi.vfs.JarFileSystem +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiFile +import com.intellij.psi.impl.source.PostprocessReformattingAspect +import com.intellij.testFramework.LightProjectDescriptor +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.annotations.NotNull +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile +import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.GrTopStatement +import org.jetbrains.plugins.groovy.util.TestUtils + +/** + * @author Maxim.Medvedev + */ +public class CodeBlockGenerationTest extends LightCodeInsightFixtureTestCase { + public static final DefaultLightProjectDescriptor GROOVY_17_PROJECT_DESCRIPTOR = new DefaultLightProjectDescriptor() { + @Override + public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { + final Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary("GROOVY").getModifiableModel(); + final VirtualFile groovyJar = JarFileSystem.getInstance().refreshAndFindFileByPath(TestUtils.getMockGroovy1_7LibraryName() + "!/"); + modifiableModel.addRoot(groovyJar, OrderRootType.CLASSES); + modifiableModel.commit(); + } + }; + + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return GROOVY_17_PROJECT_DESCRIPTOR; + } + + @Override + protected String getBasePath() { + return TestUtils.testDataPath + "/refactoring/convertGroovyToJava/codeBlock"; + } + + private void doTest() { + final String testName = getTestName(false) + final PsiFile file = myFixture.configureByFile(testName + ".groovy"); + assertInstanceOf file, GroovyFile + + GrTopStatement[] statements = file.topStatements + final StringBuilder builder = new StringBuilder() + def generator = new CodeBlockGenerator(builder, new ExpressionContext(project)); + for (def statement: statements) { + statement.accept(generator); + builder.append("\n") + } + + final PsiFile result = createLightFile(testName + ".java", StdLanguages.JAVA, builder.toString()) + PostprocessReformattingAspect.getInstance(project).doPostponedFormatting() + final String text = result.text + final String expected = psiManager.findFile(myFixture.copyFileToProject(testName + ".java")).text + assertEquals expected, text + } + + void testSwitch1() {doTest()} + void testSwitch2() {doTest()} + void testSwitch3() {doTest()} + void testSwitch4() {doTest()} + + void _testWhile1() {doTest()} + void _testWhile2() {doTest()} + void _testWhile3() {doTest()} + +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerationTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerationTest.groovy new file mode 100644 index 000000000000..f82d6cd060b6 --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerationTest.groovy @@ -0,0 +1,79 @@ +/* + * 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.refactoring.convertToJava + +import com.intellij.lang.StdLanguages +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.ContentEntry +import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.roots.libraries.Library +import com.intellij.openapi.vfs.JarFileSystem +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiFile +import com.intellij.psi.impl.source.PostprocessReformattingAspect +import com.intellij.testFramework.LightProjectDescriptor +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.annotations.NotNull +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile +import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.GrTopStatement +import org.jetbrains.plugins.groovy.util.TestUtils + +/** + * @author Maxim.Medvedev + */ +class ExpressionGenerationTest extends LightCodeInsightFixtureTestCase { + public static final DefaultLightProjectDescriptor GROOVY_17_PROJECT_DESCRIPTOR = new DefaultLightProjectDescriptor() { + @Override + public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { + final Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary("GROOVY").getModifiableModel(); + final VirtualFile groovyJar = JarFileSystem.getInstance().refreshAndFindFileByPath(TestUtils.getMockGroovy1_7LibraryName() + "!/"); + modifiableModel.addRoot(groovyJar, OrderRootType.CLASSES); + modifiableModel.commit(); + } + }; + + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return GROOVY_17_PROJECT_DESCRIPTOR; + } + + @Override + protected String getBasePath() { + return TestUtils.testDataPath + "/refactoring/convertGroovyToJava/codeBlock"; + } + + private void doTest() { + final String testName = getTestName(false); + final PsiFile file = myFixture.configureByFile(testName + ".groovy"); + assertInstanceOf file, GroovyFile + + GrTopStatement[] statements = file.topStatements + final StringBuilder builder = new StringBuilder() + statements.last().accept(new ExpressionGenerator(builder, new ExpressionContext(project))) + + final PsiFile result = createLightFile(testName + ".java", StdLanguages.JAVA, builder.toString()) + PostprocessReformattingAspect.getInstance(project).doPostponedFormatting() + final String text = result.text + final String expected = psiManager.findFile(myFixture.copyFileToProject(testName + ".java")).text + assertEquals expected, text + } + + void testAssignment() {//todo + } +} diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.groovy new file mode 100644 index 000000000000..f1227d34d243 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.groovy @@ -0,0 +1,15 @@ +def a = 2 +switch (a) { + case 1: + print a; + case 2: + print a+2 + break + case 3: + print a-1 + break + default: + print "foooo"; +} + +print "wow" diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.java new file mode 100644 index 000000000000..41c1f8e9768b --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.java @@ -0,0 +1,14 @@ +java.lang.Integer a = 2; +switch (a) { +case 1: +print(a); +case 2: +print(a + 2); +break; +case 3: +print(a - 1); +break; +default: +print("foooo"); +} +print("wow"); diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.groovy new file mode 100644 index 000000000000..460c787527ed --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.groovy @@ -0,0 +1,8 @@ +def a = 2; + +switch (a) { + case 2 + [4, 5]: + print a; + case [1, 2]: + print a; +} diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.java new file mode 100644 index 000000000000..b1399d2c654a --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.java @@ -0,0 +1,13 @@ +java.lang.Integer a = 2; +java.util.ArrayList integers = new java.util.ArrayList(2); +integers.add(4); +integers.add(5); +java.util.ArrayList integers1 = new java.util.ArrayList(2); +integers1.add(1); +integers1.add(2); +switch (a) { +case 2 + integers: +print(a); +case integers1: +print(a); +} diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.groovy new file mode 100644 index 000000000000..134f8d552102 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.groovy @@ -0,0 +1,11 @@ +def date = new Date(2011, 04, 09) + +switch (date) { + case new Date(20, 11, 23): + print "aaa" + case new Date(45, 1, 2): + print "bbb" + break + default: + print "ccc" +} diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.java new file mode 100644 index 000000000000..ab6d5cf98598 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.java @@ -0,0 +1,10 @@ +java.util.Date date = new Date(2011, 4, 9); +if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(new Date(20, 11, 23), date)) { +print("aaa"); +print("bbb"); +} +else if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(new Date(45, 1, 2), date)) { +print("bbb"); +} +else print("ccc"); + diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.groovy new file mode 100644 index 000000000000..6975afb5d3de --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.groovy @@ -0,0 +1,11 @@ +def date = new Date(2011, 04, 09) + +switch (date) { + case new Date(20, 11, 23): + print "aaa" + case [1]: + print "bbb" + break + default: + print "ccc" +} diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.java new file mode 100644 index 000000000000..feadc641f3e2 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.java @@ -0,0 +1,14 @@ +java.util.Date date = new Date(2011, 4, 9); +if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(new Date(20, 11, 23), date)) { +print("aaa"); +print("bbb"); +} +else { +java.util.ArrayList integers = new java.util.ArrayList(1); +integers.add(1); +if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(integers, date)) { +print("bbb"); +} +else print("ccc"); +} + diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.groovy index be9f67913ed1..d66a8772c33d 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.groovy +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.groovy @@ -1,2 +1,2 @@ def a = 5; -while (a < 20) a-- +while (a < 20) a=a+2 diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.java index cae661e2816f..095da612376e 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.java @@ -1,2 +1,2 @@ int a = 5; -while (a < 20) a--; \ No newline at end of file +while (a < 20) a=a+2; \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.groovy index 860ebeac05b3..cab5857e93eb 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.groovy +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.groovy @@ -1,2 +1,2 @@ def a = 5; -while (![1, 2, 3, 4].find {a > it}) a-- \ No newline at end of file +while (![1, 2, 3, 4].find {a > it}) a=a-1 \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.java index 068c3cc6ae1d..c9ae856cbbbd 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.java @@ -8,4 +8,4 @@ while (!org.codehaus.groovy.runtime.DefaultGroovyMethods.find(list, new groovy.l boolean doCall(java.lang.Integer it) { return a.equals(it); } -})) a--; +})) a=a-1; diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.groovy new file mode 100644 index 000000000000..2b74fe6c2da4 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.groovy @@ -0,0 +1,2 @@ +def list = [1, 2, 3] +while (list -[3, 4]) list-=1 diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.java new file mode 100644 index 000000000000..c0070d5b11b1 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.java @@ -0,0 +1,8 @@ +java.util.List list = new java.util.ArrayList(3); +list.add(1); +list.add(2); +list.add(3); +java.util.List list1 = new java.util.ArrayList(2); +list1.add(3); +list1.add(4); +while (!org.codehaus.groovy.runtime.DefaultGroovyMethods.minus(list, list1).isEmpty()) list = org.codehaus.groovy.runtime.DefaultGroovyMethods.minus(list, 1); From f6245f2e922886f25548050f9c78dac761de912c Mon Sep 17 00:00:00 2001 From: sweinreuter Date: Tue, 12 Apr 2011 10:00:12 +0200 Subject: [PATCH 024/100] IDEA-67908 XSLT: empty XPath expression is green --- .../xslt/validation/XsltXmlAnnotator.java | 51 +++++++++++++++++++ .../lang/xpath/xslt/XsltHighlightingTest.java | 4 ++ .../xslt/highlighting/emptyExpression.xsl | 7 +++ .../xpath/xpath-view/src/META-INF/plugin.xml | 1 + 4 files changed, 63 insertions(+) create mode 100644 plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/validation/XsltXmlAnnotator.java create mode 100644 plugins/xpath/xpath-lang/testData/xslt/highlighting/emptyExpression.xsl diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/validation/XsltXmlAnnotator.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/validation/XsltXmlAnnotator.java new file mode 100644 index 000000000000..b16e944f3cf1 --- /dev/null +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/validation/XsltXmlAnnotator.java @@ -0,0 +1,51 @@ +/* + * Copyright 2006 Sascha Weinreuter + * + * 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.intellij.lang.xpath.xslt.validation; + +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.Annotator; +import com.intellij.psi.PsiElement; +import com.intellij.psi.XmlElementVisitor; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlAttributeValue; +import org.intellij.lang.xpath.xslt.XsltSupport; +import org.jetbrains.annotations.NotNull; + +public class XsltXmlAnnotator extends XmlElementVisitor implements Annotator { + + private AnnotationHolder myHolder; + + public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder) { + try { + myHolder = holder; + psiElement.accept(this); + } finally { + myHolder = null; + } + } + + @Override + public void visitXmlAttributeValue(XmlAttributeValue value) { + final String s = value.getValue(); + if (s == null || s.trim().length() == 0) { + final PsiElement parent = value.getParent(); + if (parent instanceof XmlAttribute && XsltSupport.isXPathAttribute((XmlAttribute)parent)) { + myHolder.createErrorAnnotation(value, "Empty XPath expression"); + } + } + super.visitXmlAttributeValue(value); + } +} diff --git a/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltHighlightingTest.java b/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltHighlightingTest.java index 88d163e738e5..9b003072ccca 100644 --- a/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltHighlightingTest.java +++ b/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltHighlightingTest.java @@ -108,6 +108,10 @@ public class XsltHighlightingTest extends TestBase { doXsltHighlighting(); } + public void testEmptyExpression() throws Throwable { + doXsltHighlighting(); + } + public void xtestPerformance() throws Throwable { myFixture.configureByFile(getTestFileName() + ".xsl"); final long l = runHighlighting(); diff --git a/plugins/xpath/xpath-lang/testData/xslt/highlighting/emptyExpression.xsl b/plugins/xpath/xpath-lang/testData/xslt/highlighting/emptyExpression.xsl new file mode 100644 index 000000000000..c21e55c459df --- /dev/null +++ b/plugins/xpath/xpath-lang/testData/xslt/highlighting/emptyExpression.xsl @@ -0,0 +1,7 @@ + + + + "" /> + + + \ No newline at end of file diff --git a/plugins/xpath/xpath-view/src/META-INF/plugin.xml b/plugins/xpath/xpath-view/src/META-INF/plugin.xml index 125f30415bf6..a1de025bb314 100644 --- a/plugins/xpath/xpath-view/src/META-INF/plugin.xml +++ b/plugins/xpath/xpath-view/src/META-INF/plugin.xml @@ -119,6 +119,7 @@ + From b30d1753dda4077f7032cb40a890950b93eb5f5b Mon Sep 17 00:00:00 2001 From: sweinreuter Date: Tue, 12 Apr 2011 14:49:06 +0200 Subject: [PATCH 025/100] EA-26861 - assert: XPathFunctionCallImpl.getQName - diagnostic info added (though probably obsolete) --- .../lang/xpath/psi/impl/XPathBinaryExpressionImpl.java | 4 ++-- .../org/intellij/lang/xpath/psi/impl/XPathElementImpl.java | 6 ++++++ .../lang/xpath/psi/impl/XPathFilterExpressionImpl.java | 2 +- .../intellij/lang/xpath/psi/impl/XPathFunctionCallImpl.java | 4 ++-- .../org/intellij/lang/xpath/psi/impl/XPathNodeTestImpl.java | 2 +- .../lang/xpath/psi/impl/XPathPrefixExpressionImpl.java | 2 +- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathBinaryExpressionImpl.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathBinaryExpressionImpl.java index 675d34434f3c..ebe301e369e6 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathBinaryExpressionImpl.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathBinaryExpressionImpl.java @@ -48,7 +48,7 @@ public class XPathBinaryExpressionImpl extends XPathElementImpl implements XPath public XPathElementType getOperator() { final ASTNode[] nodes = getNode().getChildren(BINARY_OPERATIONS); final XPathElementType elementType = (XPathElementType)(nodes.length > 0 ? nodes[0].getElementType() : null); - assert elementType != null; + assert elementType != null : unexpectedPsiAssertion(); return elementType; } @@ -87,7 +87,7 @@ public class XPathBinaryExpressionImpl extends XPathElementImpl implements XPath return XPath2Type.DAYTIMEDURATION; } if (sameType(lop, rop)) { - assert lop != null; + assert lop != null : unexpectedPsiAssertion(); return lop.getType(); } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathElementImpl.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathElementImpl.java index 96c718fc5f2a..8191b98dde5e 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathElementImpl.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathElementImpl.java @@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.util.NotNullLazyValue; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.impl.PsiTreeDebugBuilder; import com.intellij.util.IncorrectOperationException; import org.intellij.lang.xpath.XPath2ElementTypes; import org.intellij.lang.xpath.XPathElementTypes; @@ -128,6 +129,11 @@ public class XPathElementImpl extends ASTWrapperPsiElement implements XPathEleme return getContainingFile().getXPathVersion(); } + protected String unexpectedPsiAssertion() { + final PsiTreeDebugBuilder builder = new PsiTreeDebugBuilder(); + return "Unexpected PSI structure: " + builder.psiToString(this) + "--\ninside: " + builder.psiToString(getContainingFile()); + } + @Override public final void accept(@NotNull PsiElementVisitor visitor) { if (visitor instanceof XPathElementVisitor) { diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathFilterExpressionImpl.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathFilterExpressionImpl.java index edf9aa109c75..1598f0309527 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathFilterExpressionImpl.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathFilterExpressionImpl.java @@ -51,7 +51,7 @@ public class XPathFilterExpressionImpl extends XPathElementImpl implements XPath @NotNull public XPathPredicate getPredicate() { final ASTNode[] nodes = getNode().getChildren(TokenSet.create(XPathElementTypes.PREDICATE)); - assert nodes.length == 1; + assert nodes.length == 1 : unexpectedPsiAssertion(); return (XPathPredicate)nodes[0].getPsi(); } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathFunctionCallImpl.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathFunctionCallImpl.java index e4ad35267384..466bf6ab01fe 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathFunctionCallImpl.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathFunctionCallImpl.java @@ -76,7 +76,7 @@ public class XPathFunctionCallImpl extends XPathElementImpl implements XPathFunc public String getFunctionName() { final ASTNode node = getNameNode(); final String name = node != null ? node.getText() : null; - assert name != null; + assert name != null : unexpectedPsiAssertion(); return name; } @@ -93,7 +93,7 @@ public class XPathFunctionCallImpl extends XPathElementImpl implements XPathFunc @NotNull public PrefixedName getQName() { final ASTNode node = getNameNode(); - assert node != null; + assert node != null : unexpectedPsiAssertion(); return new PrefixedNameImpl(getPrefixNode(), node); } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathNodeTestImpl.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathNodeTestImpl.java index 47a83f94c4a9..8837dffb776b 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathNodeTestImpl.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathNodeTestImpl.java @@ -32,7 +32,7 @@ public class XPathNodeTestImpl extends XPathElementImpl implements XPathNodeTest @NotNull public XPathStep getStep() { final XPathStep step = PsiTreeUtil.getParentOfType(this, XPathStep.class); - assert step != null; + assert step != null : unexpectedPsiAssertion(); return step; } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathPrefixExpressionImpl.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathPrefixExpressionImpl.java index 30b1047c0261..6c18090b9b5c 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathPrefixExpressionImpl.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/psi/impl/XPathPrefixExpressionImpl.java @@ -49,7 +49,7 @@ public class XPathPrefixExpressionImpl extends XPathElementImpl implements XPath public XPathElementType getOperator() { final ASTNode node = getNode().findChildByType(XPathTokenTypes.ADD_OPS); final XPathElementType elementType = (XPathElementType)(node != null ? node.getElementType() : null); - assert elementType != null; + assert elementType != null : unexpectedPsiAssertion(); return elementType; } From 9e7e22e9c65002f2cca68cdea4894e13bf90e39d Mon Sep 17 00:00:00 2001 From: sweinreuter Date: Wed, 13 Apr 2011 16:50:00 +0200 Subject: [PATCH 026/100] IDEA-67806: correctly select file for configure associations quickfix --- .../intellij/lang/xpath/xslt/context/XsltQuickFixFactory.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/XsltQuickFixFactory.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/XsltQuickFixFactory.java index 424d7a5d7c1a..31fd024313ef 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/XsltQuickFixFactory.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/XsltQuickFixFactory.java @@ -19,6 +19,8 @@ import com.intellij.codeInspection.SuppressIntentionAction; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlFile; import com.intellij.util.IncorrectOperationException; import org.intellij.lang.xpath.psi.XPathExpression; import org.intellij.lang.xpath.psi.XPathNodeTest; @@ -84,7 +86,7 @@ public class XsltQuickFixFactory implements XPathQuickFixFactory { } protected void invokeImpl(final Project project, final PsiFile file) throws IncorrectOperationException { - FileAssociationsConfigurable.editAssociations(project, file); + FileAssociationsConfigurable.editAssociations(project, PsiTreeUtil.getContextOfType(file, XmlFile.class, false)); } @NotNull From dde6d653a014aec62794a307a8e74b378837b219 Mon Sep 17 00:00:00 2001 From: sweinreuter Date: Wed, 13 Apr 2011 17:05:08 +0200 Subject: [PATCH 027/100] IDEA-67806: correctly select file for configure associations quickfix --- .../associations/impl/AssociationsEditor.java | 75 ++++++++++++------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsEditor.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsEditor.java index cb23373a85f0..79e0c91811ba 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsEditor.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsEditor.java @@ -10,19 +10,22 @@ import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.ide.util.treeView.NodeRenderer; import com.intellij.ide.util.treeView.TreeState; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Progressive; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.DimensionService; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.IconLoader; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; import com.intellij.ui.LayeredIcon; +import com.intellij.ui.TreeSpeedSearch; import com.intellij.ui.components.JBList; import com.intellij.ui.treeStructure.Tree; import com.intellij.uiDesigner.core.GridConstraints; import org.intellij.lang.xpath.xslt.XsltSupport; import org.intellij.lang.xpath.xslt.associations.FileAssociationsManager; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -34,7 +37,8 @@ import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; import java.awt.*; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; class AssociationsEditor { @@ -51,7 +55,7 @@ class AssociationsEditor { private final TransactionalManager myManager; private final ProjectTreeBuilder myBuilder; - public AssociationsEditor(final Project project, TreeState oldState) { + public AssociationsEditor(final Project project, final TreeState oldState) { myManager = ((FileAssociationsManagerImpl)FileAssociationsManager.getInstance(project)).getTempManager(); final DefaultActionGroup group = new DefaultActionGroup(); @@ -62,16 +66,29 @@ class AssociationsEditor { myToolbar.add(toolbar.getComponent(), new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null)); final DefaultTreeModel treeModel = new DefaultTreeModel(new DefaultMutableTreeNode()); + myTree.setModel(treeModel); + myBuilder = new ProjectTreeBuilder(project, myTree, treeModel, new MyGroupByTypeComparator(), new MyProjectStructure(project)); - myTree.setModel(treeModel); + myTree.expandRow(0); myTree.setCellRenderer(new MyNodeRenderer(myManager)); + new TreeSpeedSearch(myTree); - if (oldState == null) { - expandTree(treeModel, project, myBuilder); - } else { - oldState.applyTo(myTree); - } + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + if (oldState == null) { + expandTree(treeModel); + } else { + oldState.applyTo(myTree); + } + } + }); + } + }); myListModel = new AssociationsModel(myTree, myManager); myListModel.addListDataListener(new ListDataListener() { @@ -103,25 +120,20 @@ class AssociationsEditor { myList.getEmptyText().setText("No associated files"); } - private void expandTree(DefaultTreeModel newModel, Project project, ProjectTreeBuilder builder) { - final TreePath rootPath = new TreePath(newModel.getRoot()); - myTree.setSelectionPath(rootPath); + private void expandTree(DefaultTreeModel newModel) { + final TreePath rootPath = new TreePath(newModel.getRoot()); - final PsiManager psiManager = PsiManager.getInstance(project); - final Set files = myManager.getAssociations().keySet(); - if (files.size() > 0) { - for (VirtualFile file : files) { - builder.select(psiManager.findFile(file), file, true); - } - } else { - final Enumeration enumeration = ((DefaultMutableTreeNode)myTree.getModel().getRoot()).children(); - while (enumeration.hasMoreElements()) { - DefaultMutableTreeNode node = (DefaultMutableTreeNode)enumeration.nextElement(); - myTree.expandPath(new TreePath(node.getPath())); - } + final Object element = myBuilder.getTreeStructure().getRootElement(); + myBuilder.batch(new Progressive() { + @Override + public void run(@NotNull ProgressIndicator indicator) { + myBuilder.expand(element, null); + myBuilder.expand(myBuilder.getTreeStructure().getChildElements(element), null); } - myTree.setSelectionPath(rootPath); - myTree.scrollRectToVisible(new Rectangle(new Point(0, 0))); + }); + + myTree.setSelectionPath(rootPath); + myTree.scrollRectToVisible(new Rectangle(new Point(0, 0))); } public TreeState getState() { @@ -169,8 +181,13 @@ class AssociationsEditor { myManager.dispose(); } - public void select(PsiFile file) { - myBuilder.select(file, file.getVirtualFile(), true); + public void select(final PsiFile file) { + myBuilder.getReady(this).doWhenDone(new Runnable() { + @Override + public void run() { + myBuilder.select(file, file.getVirtualFile(), true); + } + }); } class AddAssociationActionWrapper extends AddAssociationAction { From a19b29d535e954b2ca3f9728cdaf3ec5afceaf47 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 14 Apr 2011 13:47:20 +0400 Subject: [PATCH 028/100] IDEA-67384 Emacs Tab does not work properly Added Emacs Tab functionality at python-mode (change indent level of the current line if possible) --- .../editorActions/EmacsStyleIndentAction.java | 10 +++ .../emacs/DefaultEmacsProcessingHandler.java | 34 ++++++++++ .../emacs/EmacsProcessingHandler.java | 62 +++++++++++++++++++ .../emacs/LanguageEmacsExtension.java | 32 ++++++++++ .../src/META-INF/LangExtensionPoints.xml | 2 + 5 files changed, 140 insertions(+) create mode 100644 platform/lang-impl/src/com/intellij/codeInsight/editorActions/emacs/DefaultEmacsProcessingHandler.java create mode 100644 platform/lang-impl/src/com/intellij/codeInsight/editorActions/emacs/EmacsProcessingHandler.java create mode 100644 platform/lang-impl/src/com/intellij/codeInsight/editorActions/emacs/LanguageEmacsExtension.java diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EmacsStyleIndentAction.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EmacsStyleIndentAction.java index bbfc43917200..7121fcbcf80e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EmacsStyleIndentAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EmacsStyleIndentAction.java @@ -18,6 +18,8 @@ package com.intellij.codeInsight.editorActions; import com.intellij.codeInsight.CodeInsightActionHandler; import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.codeInsight.editorActions.emacs.EmacsProcessingHandler; +import com.intellij.codeInsight.editorActions.emacs.LanguageEmacsExtension; import com.intellij.lang.LanguageFormatting; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; @@ -57,6 +59,14 @@ public class EmacsStyleIndentAction extends BaseCodeInsightAction implements Dum return; } + EmacsProcessingHandler emacsProcessingHandler = LanguageEmacsExtension.INSTANCE.forLanguage(file.getLanguage()); + if (emacsProcessingHandler != null) { + EmacsProcessingHandler.Result result = emacsProcessingHandler.changeIndent(project, editor, file); + if (result == EmacsProcessingHandler.Result.STOP) { + return; + } + } + final Document document = editor.getDocument(); final int startOffset = editor.getCaretModel().getOffset(); final int line = editor.offsetToLogicalPosition(startOffset).line; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/emacs/DefaultEmacsProcessingHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/emacs/DefaultEmacsProcessingHandler.java new file mode 100644 index 000000000000..63f842a369e7 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/emacs/DefaultEmacsProcessingHandler.java @@ -0,0 +1,34 @@ +/* + * 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.codeInsight.editorActions.emacs; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; + +/** + * @author Denis Zhdanov + * @since 4/11/11 2:36 PM + */ +public class DefaultEmacsProcessingHandler implements EmacsProcessingHandler { + + @NotNull + @Override + public Result changeIndent(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { + return Result.CONTINUE; + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/emacs/EmacsProcessingHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/emacs/EmacsProcessingHandler.java new file mode 100644 index 000000000000..c527150b8325 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/emacs/EmacsProcessingHandler.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.codeInsight.editorActions.emacs; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; + +/** + * This interface is assumed to define general contract for Emacs-like functionality. + * + * @author Denis Zhdanov + * @since 4/11/11 1:56 PM + */ +public interface EmacsProcessingHandler { + + /** + * Enumerates possible processing results. + */ + enum Result { + /** + * Proceed to the next handler in a chain. + */ + CONTINUE, + + /** + * Stop current processing as everything is done by the current handler + */ + STOP + } + + /** + * Emacs handles Tab pressing as + * 'auto indent line' + * most of the time. However, there are extensions to this like python-mode + * that changes indentation level of the current line (makes it belong to the other code block). + *

+ * So, current method may be implemented by changing code block for the active line by changing its indentation. + * {@link Result#STOP} should be returned then. + * + * @param project current project + * @param editor current editor + * @param file current file + * @return processing result + */ + @NotNull + Result changeIndent(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file); +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/emacs/LanguageEmacsExtension.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/emacs/LanguageEmacsExtension.java new file mode 100644 index 000000000000..1a7d6268b2ff --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/emacs/LanguageEmacsExtension.java @@ -0,0 +1,32 @@ +/* + * 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.codeInsight.editorActions.emacs; + +import com.intellij.lang.LanguageExtension; + +/** + * @author Denis Zhdanov + * @since 4/11/11 2:21 PM + */ +public class LanguageEmacsExtension extends LanguageExtension { + + public static final String EP_NAME = "com.intellij.lang.emacs"; + public static final LanguageEmacsExtension INSTANCE = new LanguageEmacsExtension(); + + public LanguageEmacsExtension() { + super(EP_NAME, new DefaultEmacsProcessingHandler()); + } +} diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 05a5f7cca9d1..2f4573781ecf 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -200,6 +200,8 @@ + + From 2c2d0815b95cb3256035abeeb686ab868c9dbec9 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Thu, 14 Apr 2011 13:57:45 +0400 Subject: [PATCH 029/100] do not process jsps here --- .../com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java b/java/java-impl/src/com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java index e3d2e9b9975f..8b90ac321c85 100644 --- a/java/java-impl/src/com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java @@ -62,7 +62,8 @@ public class JavaDirectoryServiceImpl extends JavaDirectoryService { List classes = null; for (PsiFile file : dir.getFiles()) { - if (file instanceof PsiClassOwner) { + FileViewProvider viewProvider = file.getViewProvider(); + if (file instanceof PsiClassOwner && file == viewProvider.getPsi(viewProvider.getBaseLanguage())) { PsiClass[] psiClasses = ((PsiClassOwner)file).getClasses(); if (psiClasses.length == 0) continue; if (classes == null) classes = new ArrayList(); From 95fcd3e30ddb74855f9ca0ad66e2eb700c435b7f Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Thu, 14 Apr 2011 14:11:26 +0400 Subject: [PATCH 030/100] eval deialog in statement mode - editor height fix --- .../src/com/intellij/debugger/ui/DebuggerStatementEditor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerStatementEditor.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerStatementEditor.java index b3a24995596d..5d16074e0706 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerStatementEditor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerStatementEditor.java @@ -61,6 +61,7 @@ public class DebuggerStatementEditor extends DebuggerEditorImpl { return false; } }; + myEditor.setCenterByHeight(false); setLayout(new BorderLayout()); add(myEditor, BorderLayout.CENTER); From 11b6b01b94b455fc61453fc5cd33fc16109d887e Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Apr 2011 12:22:24 +0200 Subject: [PATCH 031/100] don't write logs --- .../util/xml/impl/FileDescriptionCachedValueProvider.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/FileDescriptionCachedValueProvider.java b/xml/dom-impl/src/com/intellij/util/xml/impl/FileDescriptionCachedValueProvider.java index bc6b082c39be..8a1f6cf54cf2 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/FileDescriptionCachedValueProvider.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/FileDescriptionCachedValueProvider.java @@ -15,7 +15,6 @@ */ package com.intellij.util.xml.impl; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Key; @@ -69,11 +68,7 @@ class FileDescriptionCachedValueProvider implements SemEle public final DomFileElementImpl getFileElement() { if (myComputed) return myLastResult; - final StringBuilder log = ApplicationManager.getApplication().isUnitTestMode() ? new StringBuilder() : null; - DomFileElementImpl result = _computeFileElement(false, getRootTag(), log); - if (log != null && result == null) { - System.out.println(log); - } + DomFileElementImpl result = _computeFileElement(false, getRootTag(), null); synchronized (myCondition) { if (myComputed) return myLastResult; From aa9c2efb9f309baebee31862cf2dbec22bef97e5 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Thu, 14 Apr 2011 14:47:51 +0400 Subject: [PATCH 032/100] =?UTF-8?q?OC-607=20"Open=20xcode=20project"=20fai?= =?UTF-8?q?ls=20to=20go=20through=20directories=20with=20"=C3=A9"=20char?= =?UTF-8?q?=20in=20their=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/com/intellij/ui/mac/MacFileChooserDialogImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/mac/MacFileChooserDialogImpl.java b/platform/platform-impl/src/com/intellij/ui/mac/MacFileChooserDialogImpl.java index effadf8b1a61..7cd2a4feeb34 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/MacFileChooserDialogImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/MacFileChooserDialogImpl.java @@ -54,7 +54,7 @@ public class MacFileChooserDialogImpl implements MacFileChooserDialog { public boolean callback(ID self, String selector, ID panel, ID filename) { if (filename == null || filename.intValue() == 0) return false; final String fileName = Foundation.toStringViaUTF8(filename); - final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(fileName); + final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(fileName); return virtualFile != null && (virtualFile.isDirectory() || getDescriptor().isFileSelectable(virtualFile)); } }; @@ -63,7 +63,7 @@ public class MacFileChooserDialogImpl implements MacFileChooserDialog { public boolean callback(ID self, String selector, ID panel, ID filename) { if (filename == null || filename.intValue() == 0) return false; final String fileName = Foundation.toStringViaUTF8(filename); - final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(fileName); + final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(fileName); return virtualFile != null && (!virtualFile.isDirectory() || getDescriptor().isFileSelectable(virtualFile)); } }; From 008f210d759083b51d3a6741e3ac5de5ca42d563 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Apr 2011 13:09:43 +0200 Subject: [PATCH 033/100] fix spring test: prefer java.util.Date to java.sql.Date --- .../com/intellij/psi/util/proximity/KnownElementWeigher.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/java-impl/src/com/intellij/psi/util/proximity/KnownElementWeigher.java b/java/java-impl/src/com/intellij/psi/util/proximity/KnownElementWeigher.java index 7d510277860e..473735f376c9 100644 --- a/java/java-impl/src/com/intellij/psi/util/proximity/KnownElementWeigher.java +++ b/java/java-impl/src/com/intellij/psi/util/proximity/KnownElementWeigher.java @@ -32,6 +32,8 @@ public class KnownElementWeigher extends ProximityWeigher { if (element instanceof PsiClass) { @NonNls final String qname = ((PsiClass)element).getQualifiedName(); if (qname != null) { + if (qname.startsWith("java.lang")) return 4; + if (qname.startsWith("java.util")) return 3; if (qname.startsWith("java.")) return 2; if (qname.startsWith("javax.")) return 1; if (qname.startsWith("com.")) return -1; From 3975825eb4a5c9007b1761f6fd940031578923eb Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Thu, 14 Apr 2011 15:29:36 +0400 Subject: [PATCH 034/100] Fix: IDEA-67827 (Smarter completion of tags) --- .../src/META-INF/XmlPlugin.xml | 2 + .../completion/XmlTagInsertHandler.java | 45 +++++-- .../intellij/xml/util/TagSetRuleProvider.java | 68 ++++++++++ .../xml/util/XmlTagRuleProviderBase.java | 125 ++++++++++++++++++ .../com/intellij/xml/XmlTagRuleProvider.java | 42 ++++++ 5 files changed, 268 insertions(+), 14 deletions(-) create mode 100644 xml/impl/src/com/intellij/xml/util/TagSetRuleProvider.java create mode 100644 xml/impl/src/com/intellij/xml/util/XmlTagRuleProviderBase.java create mode 100644 xml/openapi/src/com/intellij/xml/XmlTagRuleProvider.java diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml index f7c41a14e2b6..dab28f21f1c0 100644 --- a/platform/platform-resources/src/META-INF/XmlPlugin.xml +++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml @@ -45,6 +45,8 @@ + + diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlTagInsertHandler.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlTagInsertHandler.java index 8df86060d087..3592b78e1811 100644 --- a/xml/impl/src/com/intellij/codeInsight/completion/XmlTagInsertHandler.java +++ b/xml/impl/src/com/intellij/codeInsight/completion/XmlTagInsertHandler.java @@ -45,10 +45,7 @@ import com.intellij.psi.html.HtmlTag; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.XmlTag; import com.intellij.psi.xml.XmlTokenType; -import com.intellij.xml.XmlAttributeDescriptor; -import com.intellij.xml.XmlElementDescriptor; -import com.intellij.xml.XmlElementDescriptorWithCDataContent; -import com.intellij.xml.XmlExtension; +import com.intellij.xml.*; import com.intellij.xml.actions.GenerateXmlTagAction; import com.intellij.xml.impl.schema.XmlElementDescriptorImpl; import com.intellij.xml.util.HtmlUtil; @@ -209,7 +206,7 @@ public class XmlTagInsertHandler implements InsertHandler { if (inspection != null) { StringTokenizer tokenizer = new StringTokenizer(inspection.getAdditionalEntries(0)); - notRequiredAttributes = new HashSet(1); + notRequiredAttributes = new HashSet(); while(tokenizer.hasMoreElements()) notRequiredAttributes.add(tokenizer.nextToken()); } @@ -284,22 +281,42 @@ public class XmlTagInsertHandler implements InsertHandler { else if (completionChar == ' ' && template.getSegmentsCount() == 0) { if (WebEditorOptions.getInstance().isAutomaticallyStartAttribute() && (descriptor.getAttributesDescriptors(tag).length > 0 || isTagFromHtml(tag) && !HtmlUtil.isTagWithoutAttributes(tag.getName()))) { - template.addTextSegment(" "); - template.addVariable(new MacroCallNode(new CompleteMacro()), true); - template.addTextSegment("=\""); - template.addEndVariable(); - template.addTextSegment("\""); + completeAttribute(template); return true; } } else if (completionChar == Lookup.AUTO_INSERT_SELECT_CHAR || completionChar == Lookup.NORMAL_SELECT_CHAR) { - if (WebEditorOptions.getInstance().isAutomaticallyInsertClosingTag() && - HtmlUtil.isSingleHtmlTag(tag.getName())) { - + if (WebEditorOptions.getInstance().isAutomaticallyInsertClosingTag() && HtmlUtil.isSingleHtmlTag(tag.getName())) { template.addTextSegment(tag instanceof HtmlTag ? ">" : "/>"); } else { - completeTagTail(template, descriptor, tag.getContainingFile(), tag, true); + if (needAlLeastOneAttribute(tag) && WebEditorOptions.getInstance().isAutomaticallyStartAttribute()) { + completeAttribute(template); + return true; + } + else { + completeTagTail(template, descriptor, tag.getContainingFile(), tag, true); + } + } + } + + return false; + } + + private static void completeAttribute(Template template) { + template.addTextSegment(" "); + template.addVariable(new MacroCallNode(new CompleteMacro()), true); + template.addTextSegment("=\""); + template.addEndVariable(); + template.addTextSegment("\""); + } + + private static boolean needAlLeastOneAttribute(XmlTag tag) { + for (XmlTagRuleProvider ruleProvider : XmlTagRuleProvider.EP_NAME.getExtensions()) { + for (XmlTagRuleProvider.Rule rule : ruleProvider.getTagRule(tag)) { + if (rule.needAtLeastOneAttribute(tag)) { + return true; + } } } diff --git a/xml/impl/src/com/intellij/xml/util/TagSetRuleProvider.java b/xml/impl/src/com/intellij/xml/util/TagSetRuleProvider.java new file mode 100644 index 000000000000..e4e20b9ac570 --- /dev/null +++ b/xml/impl/src/com/intellij/xml/util/TagSetRuleProvider.java @@ -0,0 +1,68 @@ +/* + * 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.xml.util; + +import com.intellij.psi.xml.XmlTag; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Sergey Evdokimov + */ +public abstract class TagSetRuleProvider extends XmlTagRuleProviderBase { + + private final Map map = Collections.synchronizedMap(new HashMap()); + + @Nullable + protected abstract String getNamespace(@NotNull XmlTag tag); + + protected abstract void initMap(TagsRuleMap map, @NotNull String version); + + @Override + public Rule[] getTagRule(@NotNull XmlTag tag) { + String namespace = getNamespace(tag); + if (namespace == null) return Rule.EMPTY_ARRAY; + + return getTagRule(tag, namespace); + } + + public Rule[] getTagRule(@NotNull XmlTag tag, String namespace) { + TagsRuleMap ruleMap = map.get(namespace); + if (ruleMap == null) { + ruleMap = new TagsRuleMap(); + initMap(ruleMap, namespace); + map.put(namespace, ruleMap); + } + + String tagName = tag.getLocalName(); + Rule[] rules = ruleMap.get(tagName); + if (rules == null) return Rule.EMPTY_ARRAY; + + return rules; + } + + protected static class TagsRuleMap extends HashMap { + public void add(String tagName, Rule ... rules) { + assert rules.length > 0; + Rule[] oldValue = put(tagName, rules); + assert oldValue == null; + } + } +} diff --git a/xml/impl/src/com/intellij/xml/util/XmlTagRuleProviderBase.java b/xml/impl/src/com/intellij/xml/util/XmlTagRuleProviderBase.java new file mode 100644 index 000000000000..12ec13ce9a93 --- /dev/null +++ b/xml/impl/src/com/intellij/xml/util/XmlTagRuleProviderBase.java @@ -0,0 +1,125 @@ +/* + * 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.xml.util; + +import com.intellij.codeInsight.daemon.impl.analysis.InsertRequiredAttributeFix; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.tree.RoleFinder; +import com.intellij.psi.xml.XmlChildRole; +import com.intellij.psi.xml.XmlTag; +import com.intellij.xml.XmlTagRuleProvider; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class XmlTagRuleProviderBase extends XmlTagRuleProvider { + + public static RequireAttributeOneOf requireAttr(String ... oneOf) { + return new RequireAttributeOneOf(oneOf); + } + + public static IncompatiblesAttributeRule incompatible(String attribute, String ... excluded) { + return new IncompatiblesAttributeRule(attribute, excluded); + } + + public static ShouldHaveParams shouldHaveParams() { + return new ShouldHaveParams(); + } + + public static class IncompatiblesAttributeRule extends Rule { + private final String[] myExcludedAttributes; + private final String myAttribute; + + public IncompatiblesAttributeRule(String attribute, String ... excluded) { + myAttribute = attribute; + myExcludedAttributes = excluded; + } + } + + public static class ShouldHaveParams extends Rule { + @Override + public boolean needAtLeastOneAttribute(@NotNull XmlTag tag) { + return true; + } + } + + @Nullable + public static PsiElement getTagElement(RoleFinder roleFinder, XmlTag tag) { + ASTNode tagNode = tag.getNode(); + if (tagNode == null) return null; + + ASTNode nameElement = roleFinder.findChild(tagNode); + if (nameElement == null) return null; + + return nameElement.getPsi(); + } + + @Nullable + public static PsiElement getTagNameElement(XmlTag tag) { + return getTagElement(XmlChildRole.START_TAG_NAME_FINDER, tag); + } + + public static boolean isClosedTag(XmlTag tag) { + return getTagElement(XmlChildRole.EMPTY_TAG_END_FINDER, tag) != null || getTagElement(XmlChildRole.CLOSING_TAG_START_FINDER, tag) != null; + } + + public static class RequireAttributeOneOf extends ShouldHaveParams { + private final String[] myAttributeNames; + private final ProblemHighlightType myProblemHighlightType; + + public RequireAttributeOneOf(String ... attributeNames) { + myAttributeNames = attributeNames; + myProblemHighlightType = ProblemHighlightType.GENERIC_ERROR_OR_WARNING; + } + + public RequireAttributeOneOf(@NotNull ProblemHighlightType problemHighlightType, String... attributeNames) { + assert attributeNames.length > 0; + myAttributeNames = attributeNames; + myProblemHighlightType = problemHighlightType; + } + + public String[] getAttributeNames() { + return myAttributeNames; + } + + @Override + public void annotate(@NotNull XmlTag tag, ProblemsHolder holder) { + for (String attributeName : myAttributeNames) { + if (tag.getAttribute(attributeName) != null) { + return; + } + } + + if (!isClosedTag(tag)) return; + + PsiElement tagNameElement = getTagNameElement(tag); + if (tagNameElement == null) return; + + LocalQuickFix[] fixes = new LocalQuickFix[myAttributeNames.length]; + for (int i = 0; i < myAttributeNames.length; i++) { + fixes[i] = new InsertRequiredAttributeFix(tag, myAttributeNames[i], null); + } + + holder.registerProblem(tagNameElement, "Tag should have one of following attributes: " + StringUtil.join(myAttributeNames, ", "), + myProblemHighlightType, + fixes); + } + } +} diff --git a/xml/openapi/src/com/intellij/xml/XmlTagRuleProvider.java b/xml/openapi/src/com/intellij/xml/XmlTagRuleProvider.java new file mode 100644 index 000000000000..69d3bbef1951 --- /dev/null +++ b/xml/openapi/src/com/intellij/xml/XmlTagRuleProvider.java @@ -0,0 +1,42 @@ +/* + * 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.xml; + +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.xml.XmlTag; +import org.jetbrains.annotations.NotNull; + +public abstract class XmlTagRuleProvider { + + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.xml.xmlTagRuleProvider"); + + public abstract Rule[] getTagRule(@NotNull XmlTag tag); + + public static class Rule { + + public static final Rule[] EMPTY_ARRAY = new Rule[0]; + + public void annotate(@NotNull XmlTag tag, ProblemsHolder holder) { + + } + + public boolean needAtLeastOneAttribute(@NotNull XmlTag tag) { + return false; + } + } + +} From 1bd5fb51dc7eaea5d1560f1e7ba81b1d0d8145d3 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 14 Apr 2011 15:44:27 +0400 Subject: [PATCH 035/100] IDEA-68003 Java Formatter: Correct formatting of anonymous classes at method call arguments 1. Returned old indent processing for 'child block that doesn't start new line from parent block' use-case; 2. Corrected java blocks indent construction; --- .../psi/formatter/java/AbstractJavaBlock.java | 2 +- .../formatting/AbstractBlockWrapper.java | 83 ++++++++++++------- .../formatting/CompositeBlockWrapper.java | 9 ++ .../intellij/formatting/LeafBlockWrapper.java | 5 ++ 4 files changed, 66 insertions(+), 33 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java index f654587578f8..aed4ec8201c2 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java @@ -1372,7 +1372,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo ); } final boolean rBrace = isRBrace(child); - Indent childIndent = rBrace ? Indent.getNoneIndent() : getCodeBlockInternalIndent(childrenIndent, true); + Indent childIndent = rBrace ? Indent.getNoneIndent() : getCodeBlockInternalIndent(childrenIndent, false); if (!rBrace && child.getElementType() == JavaElementType.CODE_BLOCK && (getBraceStyle() == CommonCodeStyleSettings.NEXT_LINE_SHIFTED || getBraceStyle() == CommonCodeStyleSettings.NEXT_LINE_SHIFTED2)) diff --git a/platform/lang-impl/src/com/intellij/formatting/AbstractBlockWrapper.java b/platform/lang-impl/src/com/intellij/formatting/AbstractBlockWrapper.java index cf0773617e46..debe73fdb099 100644 --- a/platform/lang-impl/src/com/intellij/formatting/AbstractBlockWrapper.java +++ b/platform/lang-impl/src/com/intellij/formatting/AbstractBlockWrapper.java @@ -21,13 +21,21 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; + +import static java.util.Arrays.asList; /** * @author lesya */ public abstract class AbstractBlockWrapper { + private static final Set RELATIVE_INDENT_TYPES = new HashSet(asList( + Indent.Type.NORMAL, Indent.Type.CONTINUATION, Indent.Type.CONTINUATION_WITHOUT_FIRST + )); + protected WhiteSpace myWhiteSpace; protected CompositeBlockWrapper myParent; protected int myStart; @@ -158,41 +166,40 @@ public abstract class AbstractBlockWrapper { public IndentData getChildOffset(AbstractBlockWrapper child, CodeStyleSettings.IndentOptions options, int targetBlockStartOffset) { final boolean childStartsNewLine = child.getWhiteSpace().containsLineFeeds(); + IndentImpl.Type childIndentType = child.getIndent().getType(); IndentData childIndent; // Calculate child indent. - if (childStartsNewLine) { + if (childStartsNewLine + || (!getWhiteSpace().containsLineFeeds() && RELATIVE_INDENT_TYPES.contains(childIndentType) && indentAlreadyUsedBefore(child))) + { childIndent = getIndent(options, child, targetBlockStartOffset); } - else { - childIndent = new IndentData(0); - } - - // Enforce indent if child doesn't start new line, e.g. prefer the code below: - // void test() { - // foo("test", new Runnable() { - // public void run() { - // } - // }, - // new Runnable() { - // public void run() { - // } - // } - // ); - // } - // to this one: - // void test() { - // foo("test", new Runnable() { - // public void run() { - // } - // }, - // new Runnable() { - // public void run() { - // } - // } - // ); - // } - if (child.getIndent().isEnforceIndentToChildren() && !child.getWhiteSpace().containsLineFeeds()) { + else if (child.getIndent().isEnforceIndentToChildren() && !child.getWhiteSpace().containsLineFeeds()) { + // Enforce indent if child doesn't start new line, e.g. prefer the code below: + // void test() { + // foo("test", new Runnable() { + // public void run() { + // } + // }, + // new Runnable() { + // public void run() { + // } + // } + // ); + // } + // to this one: + // void test() { + // foo("test", new Runnable() { + // public void run() { + // } + // }, + // new Runnable() { + // public void run() { + // } + // } + // ); + // } AlignmentImpl alignment = child.getAlignment(); if (alignment != null) { // Generally, we want to handle situation like the one below: @@ -209,7 +216,7 @@ public abstract class AbstractBlockWrapper { // ); // I.e. we want 'run()' method from the first anonymous class to be aligned with the 'run()' method of the second anonymous class. - AbstractBlockWrapper anchorBlock = alignment.getOffsetRespBlockBefore(child); + AbstractBlockWrapper anchorBlock = alignment.getOffsetRespBlockBefore(child); if (anchorBlock == null) { anchorBlock = this; if (anchorBlock instanceof CompositeBlockWrapper) { @@ -224,7 +231,10 @@ public abstract class AbstractBlockWrapper { } return anchorBlock.getNumberOfSymbolsBeforeBlock(); } - childIndent = childIndent.add(getIndent(options, child, getStartOffset())); + childIndent = getIndent(options, child, getStartOffset()); + } + else { + childIndent = new IndentData(0); } // Use child indent if it's absolute and the child is contained on new line. @@ -287,6 +297,15 @@ public abstract class AbstractBlockWrapper { } } + /** + * Allows to answer if current wrapped block has a child block that is located before given block and has line feed. + * + * @param child target child block to process + * @return true if current block has a child that is located before the given block and contains line feed; + * false otherwise + */ + protected abstract boolean indentAlreadyUsedBefore(final AbstractBlockWrapper child); + /** * Allows to retrieve object that encapsulates information about number of symbols before the current block starting * from the line start. I.e. all symbols (either white space or not) between start of the line where current block begins diff --git a/platform/lang-impl/src/com/intellij/formatting/CompositeBlockWrapper.java b/platform/lang-impl/src/com/intellij/formatting/CompositeBlockWrapper.java index aaec1d4902b1..dca827b624f4 100644 --- a/platform/lang-impl/src/com/intellij/formatting/CompositeBlockWrapper.java +++ b/platform/lang-impl/src/com/intellij/formatting/CompositeBlockWrapper.java @@ -57,6 +57,15 @@ public class CompositeBlockWrapper extends AbstractBlockWrapper{ } } + @Override + protected boolean indentAlreadyUsedBefore(final AbstractBlockWrapper child) { + for (AbstractBlockWrapper childBefore : myChildren) { + if (childBefore == child) return false; + if (childBefore.getWhiteSpace().containsLineFeeds()) return true; + } + return false; + } + @Override protected IndentData getNumberOfSymbolsBeforeBlock() { if (myChildren == null || myChildren.isEmpty()) { diff --git a/platform/lang-impl/src/com/intellij/formatting/LeafBlockWrapper.java b/platform/lang-impl/src/com/intellij/formatting/LeafBlockWrapper.java index 4ee2f339dc46..99b38484192a 100644 --- a/platform/lang-impl/src/com/intellij/formatting/LeafBlockWrapper.java +++ b/platform/lang-impl/src/com/intellij/formatting/LeafBlockWrapper.java @@ -126,6 +126,11 @@ class LeafBlockWrapper extends AbstractBlockWrapper { myNextBlock = nextBlock; } + @Override + protected boolean indentAlreadyUsedBefore(final AbstractBlockWrapper child) { + return false; + } + @Override protected IndentData getNumberOfSymbolsBeforeBlock() { int spaces = getWhiteSpace().getSpaces(); From 0b6f18b18be98777d10a17b3197d2b83062eebed Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Thu, 14 Apr 2011 15:52:56 +0400 Subject: [PATCH 036/100] remove "View as:" useless prefix in project view under Mac OS --- .../ide/projectView/impl/ProjectViewImpl.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java index 849cf1acc0ca..e00dd14a854a 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -269,17 +269,22 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat private void constructUi() { myActionGroupPanel = new JPanel(new BorderLayout()); - myLabel = new JLabel("View as:"); - if (!SystemInfo.isMac) { // See IDEADEV-41315 + myLabel = SystemInfo.isMac ? null : new JLabel("View as:"); + if (myLabel != null && !SystemInfo.isMac) { // See IDEADEV-41315 myLabel.setDisplayedMnemonic('a'); } + myCombo = new ComboBox(); myCombo.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0)); - myLabel.setLabelFor(myCombo); final JPanel combo = new JPanel(new BorderLayout()); combo.setBorder(new EmptyBorder(4, 4, 4, 4)); - combo.add(myLabel, BorderLayout.WEST); + + if(myLabel != null) { + myLabel.setLabelFor(myCombo); + combo.add(myLabel, BorderLayout.WEST); + } + combo.add(myCombo, BorderLayout.CENTER); @@ -655,11 +660,11 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat }; private void installLabelFocusListener() { - myLabel.addFocusListener(myLabelFocusListener); + if (myLabel != null) myLabel.addFocusListener(myLabelFocusListener); } private void removeLabelFocusListener() { - myLabel.removeFocusListener(myLabelFocusListener); + if (myLabel != null) myLabel.removeFocusListener(myLabelFocusListener); } private boolean viewSelectionChanged() { From e56ac7eae9bf1b4f3c4671ea95f03fe3413f6374 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Thu, 14 Apr 2011 16:27:47 +0400 Subject: [PATCH 037/100] IDEA-68080 Super class with optional constructor argument --- .../plugins/groovy/annotator/GroovyAnnotator.java | 8 ++++++++ .../groovy/lang/GroovyHighlightingTest.java | 4 ++++ .../ConstructorWithAllParametersOptional.groovy | 14 ++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 plugins/groovy/testdata/highlighting/ConstructorWithAllParametersOptional.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index 1556dae9a4d3..40e7b5f4d997 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -372,8 +372,16 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { if (className == null) return null; final PsiMethod[] byName = clazz.findMethodsByName(className, true); if (byName.length == 0) return null; + Outer: for (PsiMethod method : byName) { if (method.getParameterList().getParametersCount() == 0) return method; + if (!(method instanceof GrMethod)) continue; + final GrParameter[] parameters = ((GrMethod)method).getParameterList().getParameters(); + + for (GrParameter parameter : parameters) { + if (!parameter.isOptional()) continue Outer; + } + return method; } return null; } 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 1fe08ab782b3..c30faa860fdc 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java @@ -364,4 +364,8 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase { public void testAnonymousClassArgList() { doTest(new GroovyAssignabilityCheckInspection()); } + + public void testConstructorWithAllParametersOptional() { + doTest(); + } } \ No newline at end of file diff --git a/plugins/groovy/testdata/highlighting/ConstructorWithAllParametersOptional.groovy b/plugins/groovy/testdata/highlighting/ConstructorWithAllParametersOptional.groovy new file mode 100644 index 000000000000..5e28c6b1c7a5 --- /dev/null +++ b/plugins/groovy/testdata/highlighting/ConstructorWithAllParametersOptional.groovy @@ -0,0 +1,14 @@ +class Base { + def Base(int x = 0, int y=5){} +} + +class Inheritor extends Base{ +} + +class Base2 { + def Base2(int x){} +} + +class Inheritor2 extends Base2 { + +} \ No newline at end of file From e71480a25c6a83dce12b77bd2624440a2f9dbb9e Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Thu, 14 Apr 2011 16:46:48 +0400 Subject: [PATCH 038/100] IDEA-63340 Add "find usage" to fields in database [initial] --- .../find/findUsages/CustomUsageSearcher.java | 31 +++++++++++++++++++ .../find/findUsages/FindUsagesManager.java | 8 +++++ .../src/META-INF/LangExtensionPoints.xml | 1 + 3 files changed, 40 insertions(+) create mode 100644 platform/lang-impl/src/com/intellij/find/findUsages/CustomUsageSearcher.java diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/CustomUsageSearcher.java b/platform/lang-impl/src/com/intellij/find/findUsages/CustomUsageSearcher.java new file mode 100644 index 000000000000..61b2b5f6f291 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/find/findUsages/CustomUsageSearcher.java @@ -0,0 +1,31 @@ +/* + * 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.find.findUsages; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.PsiElement; +import com.intellij.usages.Usage; +import com.intellij.util.Processor; + +/** + * @author gregsh + */ +public abstract class CustomUsageSearcher { + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.customUsageSearcher"); + + public abstract void processElementUsages(final PsiElement element, final Processor processor, final FindUsagesOptions options); +} 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 5bff937c484d..8748875b854d 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java @@ -380,6 +380,14 @@ public class FindUsagesManager implements JDOMExternalizable { } }); handler.processElementUsages(element, usageInfoProcessor, options); + for (CustomUsageSearcher searcher : Extensions.getExtensions(CustomUsageSearcher.EP_NAME)) { + try { + searcher.processElementUsages(element, processor, options); + } + catch (Exception e) { + LOG.error(e); + } + } } Project project = ApplicationManager.getApplication().runReadAction(new Computable() { diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 2f4573781ecf..6e15798e5d84 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -313,6 +313,7 @@ + From 6a3f252e27c1c4774fa58fd86515b20aa545d36f Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Thu, 14 Apr 2011 17:17:42 +0400 Subject: [PATCH 039/100] resolve operators overloaded by closure-fields --- .../plugins/groovy/GroovyBundle.properties | 1 + .../GroovyAssignabilityCheckInspection.java | 61 ++++---- .../bugs/GroovyRangeTypeCheckInspection.java | 1 + .../expressions/GrSafeCastExpression.java | 4 + .../GroovyExpectedTypesProvider.java | 9 +- .../CompleteReferenceExpression.java | 3 +- .../GrAssignmentExpressionImpl.java | 9 +- .../expressions/GrBinaryExpressionImpl.java | 12 +- .../arithmetic/GrUnaryExpressionImpl.java | 11 +- .../DefaultCallExpressionTypeCalculator.java | 8 +- .../expressions/path/GrIndexPropertyImpl.java | 85 ++++++----- .../types/GrSafeCastExpressionImpl.java | 25 ++- .../groovy/lang/resolve/ResolveUtil.java | 143 ++++++++++++++---- .../processors/CompletionProcessor.java | 2 +- .../processors/MethodResolverProcessor.java | 2 +- .../lang/resolve/ResolvePropertyTest.groovy | 10 +- .../lang/resolve/TypeInferenceTest.java | 11 ++ .../highlighting/CallIsNotApplicable.groovy | 2 +- .../PathCallIsNotApplicable.groovy | 4 +- .../resolve/inference/getAtClosure/A.groovy | 10 ++ .../inference/plusEqualsClosure/A.groovy | 9 ++ .../inference/preferMethodOverloader/A.groovy | 14 ++ .../property/operatorOverloading/A.groovy | 9 ++ .../resolveClosureOverloader/A.groovy | 24 +++ 24 files changed, 331 insertions(+), 138 deletions(-) create mode 100644 plugins/groovy/testdata/resolve/inference/getAtClosure/A.groovy create mode 100644 plugins/groovy/testdata/resolve/inference/plusEqualsClosure/A.groovy create mode 100644 plugins/groovy/testdata/resolve/inference/preferMethodOverloader/A.groovy create mode 100644 plugins/groovy/testdata/resolve/property/operatorOverloading/A.groovy create mode 100644 plugins/groovy/testdata/resolve/property/resolveClosureOverloader/A.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties index 3f1095fbe9e6..45bd0072cacf 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties @@ -347,3 +347,4 @@ groovy.file.extension.is.not.mapped.to.groovy.file.type=*.groovy files are mappe class.is.not.annotation=''{0}'' is not an annotation method.call.is.ambiguous=Method call is ambiguous duplicated.named.parameter=Duplicated named parameter ''{0}'' found +cannot.find.method.call=No signature of method: {0}.call() is applicable for {1} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java index 36732f3c3ac6..abede067a4ad 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java @@ -19,8 +19,6 @@ package org.jetbrains.plugins.groovy.codeInspection.assignment; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.TypeConversionUtil; -import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,7 +33,6 @@ 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.GrConstructorInvocation; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; -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.blocks.GrClosableBlock; @@ -55,7 +52,6 @@ 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 java.util.Collection; import java.util.Map; /** @@ -328,57 +324,66 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection { checkNamedArgumentsType(call); } - private void highlightInapplicableMethodUsage(GroovyResolveResult methodResolveResult, PsiElement place, - PsiMethod method, PsiType[] argumentTypes) { + private void highlightInapplicableMethodUsage(GroovyResolveResult methodResolveResult, + PsiElement place, + PsiMethod method, + PsiType[] argumentTypes) { + final PsiClass containingClass = method.getContainingClass(); + if (containingClass == null) { + registerCannotApplyError(place, argumentTypes, method.getName()); + return; + } + final String typesString = buildArgTypesList(argumentTypes); + final PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); + final PsiClassType containingType = factory.createType(containingClass, methodResolveResult.getSubstitutor()); + final String canonicalText = containingType.getInternalCanonicalText(); + String message = GroovyBundle.message("cannot.apply.method1", method.getName(), canonicalText, typesString); PsiElement elementToHighlight = PsiUtil.getArgumentsList(place); if (elementToHighlight == null || elementToHighlight.getTextRange().getLength() == 0) { elementToHighlight = place; } - - final String typesString = buildArgTypesList(argumentTypes); - String message; - final PsiClass containingClass = method.getContainingClass(); - if (containingClass != null) { - final PsiClassType containingType = JavaPsiFacade.getInstance(method.getProject()).getElementFactory() - .createType(containingClass, methodResolveResult.getSubstitutor()); - message = GroovyBundle.message("cannot.apply.method1", method.getName(), containingType.getInternalCanonicalText(), typesString); - } - else { - message = GroovyBundle.message("cannot.apply.method.or.closure", method.getName(), typesString); - } - registerError(elementToHighlight, message); } + private boolean checkCallApplicability(PsiType type, GroovyPsiElement place) { + + PsiType[] argumentTypes = PsiUtil.getArgumentTypes(place, true); if (type instanceof GrClosureType) { - PsiType[] argumentTypes = PsiUtil.getArgumentTypes(place, true); if (argumentTypes == null) return true; if (PsiUtil.isApplicable(argumentTypes, (GrClosureType)type, place)) return true; - final String typesString = buildArgTypesList(argumentTypes); - String message = GroovyBundle.message("cannot.apply.method.or.closure", place.getText(), typesString); - PsiElement elementToHighlight = PsiUtil.getArgumentsList(place); - if (elementToHighlight == null || elementToHighlight.getTextRange().getLength() == 0) elementToHighlight = place; - registerError(elementToHighlight, message); + registerCannotApplyError(place, argumentTypes, place.getText()); return false; } else if (type != null) { - final GroovyResolveResult[] calls = - ResolveUtil.getMethodCandidates(type, "call", place, PsiUtil.getArgumentTypes(place, true)); + final GroovyResolveResult[] calls = ResolveUtil.getMethodCandidates(type, "call", place, argumentTypes); for (GroovyResolveResult result : calls) { PsiElement resolved = result.getElement(); if (resolved instanceof PsiMethod) { if (!checkMethodApplicability(result, place)) return false; } + else if (resolved instanceof PsiField) { + if (!checkCallApplicability(((PsiField)resolved).getType(), place)) return false; + } + } + if (calls.length == 0) { + registerCannotApplyError(place, argumentTypes, place.getText()); } - return true; } return true; } + private void registerCannotApplyError(PsiElement place, PsiType[] argumentTypes, String invokedText) { + final String typesString = buildArgTypesList(argumentTypes); + String message = GroovyBundle.message("cannot.apply.method.or.closure", invokedText, typesString); + PsiElement elementToHighlight = PsiUtil.getArgumentsList(place); + if (elementToHighlight == null || elementToHighlight.getTextRange().getLength() == 0) elementToHighlight = place; + registerError(elementToHighlight, message); + } + private static String buildArgTypesList(PsiType[] argTypes) { StringBuilder builder = new StringBuilder(); builder.append("("); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyRangeTypeCheckInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyRangeTypeCheckInspection.java index af384d9ce3cd..76d68bdd4c53 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyRangeTypeCheckInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyRangeTypeCheckInspection.java @@ -130,6 +130,7 @@ public class GroovyRangeTypeCheckInspection extends BaseInspection { for (GroovyResolveResult method : methods) { final PsiElement el = method.getElement(); if (el instanceof PsiMethod && !((PsiMethod)el).hasModifierProperty(GrModifier.ABSTRACT)) result++; + else if (el instanceof PsiField) result++; } return result; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSafeCastExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSafeCastExpression.java index b4a5cb565659..b707ff01b6c7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSafeCastExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSafeCastExpression.java @@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions; import com.intellij.psi.PsiPolyVariantReference; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; @@ -25,7 +26,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; * @author ven */ public interface GrSafeCastExpression extends GrExpression, PsiPolyVariantReference { + @Nullable GrTypeElement getCastTypeElement(); + + @NotNull GrExpression getOperand(); @NotNull diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java index d1b609dfafa5..76bd3b74ef0b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java @@ -19,6 +19,7 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -267,9 +268,11 @@ public class GroovyExpectedTypesProvider { TypeConstraint constraint = new TypeConstraint(PsiType.INT) { @Override public boolean satisfied(PsiType type, PsiManager manager, GlobalSearchScope scope) { - return TypesUtil - .getOverloadedOperatorCandidates(TypesUtil.boxPrimitiveType(type, manager, scope), expression.getOperationTokenType(), - expression, PsiType.EMPTY_ARRAY).length > 0; + final PsiType boxed = TypesUtil.boxPrimitiveType(type, manager, scope); + final IElementType opToken = expression.getOperationTokenType(); + final GroovyResolveResult[] candidates = + TypesUtil.getOverloadedOperatorCandidates(boxed, opToken, expression, PsiType.EMPTY_ARRAY); + return candidates.length > 0; } @NotNull diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java index 7452788e63e5..f6ff4cc4b753 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java @@ -46,7 +46,6 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil; -import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.lang.resolve.ClosureMissingMethodContributor; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; @@ -438,7 +437,7 @@ public class CompleteReferenceExpression { @Override public GroovyResolveResult[] getCandidates() { if (!hasCandidates()) return GroovyResolveResult.EMPTY_ARRAY; - final GroovyResolveResult[] results = ResolveUtil.filterSameSignatureCandidates(getCandidatesInternal(), -1); + final GroovyResolveResult[] results = ResolveUtil.filterSameSignatureCandidates(getCandidatesInternal()); List list = new ArrayList(results.length); myPropertyNames.removeAll(myPreferredFieldNames); for (GroovyResolveResult result : results) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrAssignmentExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrAssignmentExpressionImpl.java index bcdbae331cce..37630b24eae9 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrAssignmentExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrAssignmentExpressionImpl.java @@ -39,7 +39,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrRefere import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; -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.ResolverProcessor; /** @@ -62,11 +62,8 @@ public class GrAssignmentExpressionImpl extends GrExpressionImpl implements GrAs PsiType returnType = null; final PsiManager manager = assignment.getManager(); for (GroovyResolveResult result : results) { - final PsiElement element = result.getElement(); - if (element instanceof PsiMethod) { - final PsiType substituted = result.getSubstitutor().substitute(PsiUtil.getSmartReturnType((PsiMethod)element)); - returnType = TypesUtil.getLeastUpperBoundNullable(returnType, substituted, manager); - } + final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(result); + returnType = TypesUtil.getLeastUpperBoundNullable(returnType, substituted, manager); } return returnType; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrBinaryExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrBinaryExpressionImpl.java index c7b04d8eed85..082eef319664 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrBinaryExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrBinaryExpressionImpl.java @@ -19,7 +19,6 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiReference; import com.intellij.psi.PsiType; import com.intellij.psi.impl.source.resolve.ResolveCache; @@ -36,7 +35,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinary import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; -import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; +import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; /** * @author ilyas @@ -70,13 +69,8 @@ public abstract class GrBinaryExpressionImpl extends GrExpressionImpl implements } final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(binary.multiResolve(false)); - final PsiElement resolved = resolveResult.getElement(); - if (resolved instanceof PsiMethod) { - final PsiType returnType = PsiUtil.getSmartReturnType((PsiMethod)resolved); - final PsiType substituted = resolveResult.getSubstitutor().substitute(returnType); - return TypesUtil.boxPrimitiveType(substituted, binary.getManager(), binary.getResolveScope()); - } - return null; + final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(resolveResult); + return TypesUtil.boxPrimitiveType(substituted, binary.getManager(), binary.getResolveScope()); } }; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/arithmetic/GrUnaryExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/arithmetic/GrUnaryExpressionImpl.java index bf082bc4899d..35edaf526047 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/arithmetic/GrUnaryExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/arithmetic/GrUnaryExpressionImpl.java @@ -37,7 +37,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrExpressionImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; -import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; +import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; /** * @author ilyas @@ -54,16 +54,13 @@ public class GrUnaryExpressionImpl extends GrExpressionImpl implements GrUnaryEx PsiType opType = operand.getType(); if (opType == null) return null; - IElementType opToken = unary.getOperationTokenType(); - final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(unary.multiResolve(false)); - final PsiElement resolved = resolveResult.getElement(); - if (resolved instanceof PsiMethod) { - final PsiType smartReturnType = PsiUtil.getSmartReturnType((PsiMethod)resolved); - final PsiType substituted = resolveResult.getSubstitutor().substitute(smartReturnType); + final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(resolveResult); + if (substituted != null) { return TypesUtil.boxPrimitiveType(substituted, unary.getManager(), unary.getResolveScope()); } + IElementType opToken = unary.getOperationTokenType(); if (opToken == GroovyTokenTypes.mBNOT && opType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { return unary.getTypeByFQName(GroovyCommonClassNames.JAVA_UTIL_REGEX_PATTERN); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java index 4af9de2c3893..0ce48ab7a464 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +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.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -105,11 +106,8 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal returnType = null; final PsiManager manager = callExpression.getManager(); for (GroovyResolveResult call : calls) { - final PsiElement element = call.getElement(); - if (element instanceof PsiMethod) { - final PsiType substituted = call.getSubstitutor().substitute(PsiUtil.getSmartReturnType((PsiMethod)element)); - returnType = TypesUtil.getLeastUpperBoundNullable(returnType, substituted, manager); - } + final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(call); + returnType = TypesUtil.getLeastUpperBoundNullable(returnType, substituted, manager); } } return returnType; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrIndexPropertyImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrIndexPropertyImpl.java index 882bb8caa962..b91092fe6a8a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrIndexPropertyImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrIndexPropertyImpl.java @@ -20,6 +20,8 @@ import com.intellij.lang.ASTNode; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.InheritanceUtil; +import com.intellij.util.Function; +import com.intellij.util.NullableFunction; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; @@ -27,19 +29,60 @@ 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.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty; +import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrExpressionImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; +import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; import static com.intellij.psi.util.PsiUtil.substituteTypeParameter; -import static org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.getSmartReturnType; /** * @author ilyas */ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProperty { + private static final Function TYPE_CALCULATOR = new NullableFunction() { + @Override + public PsiType fun(GrIndexPropertyImpl index) { + GrExpression selected = index.getSelectedExpression(); + PsiType thisType = selected.getType(); + + if (thisType == null) return null; + + GrArgumentList argList = index.getArgumentList(); + if (argList == null) return null; + + PsiType[] argTypes = PsiUtil.getArgumentTypes(argList, false, null); + + final PsiManager manager = index.getManager(); + final GlobalSearchScope resolveScope = index.getResolveScope(); + + if (PsiImplUtil.isSimpleArrayAccess(thisType, argTypes, manager, resolveScope)) { + return TypesUtil.boxPrimitiveType(((PsiArrayType)thisType).getComponentType(), manager, resolveScope); + } + + GroovyResolveResult candidate = PsiImplUtil.getIndexPropertyMethodCandidate(thisType, argTypes, index); + PsiType overloadedOperatorType = ResolveUtil.extractReturnTypeFromCandidate(candidate); + + PsiType componentType = extractMapValueType(thisType, argTypes, manager, resolveScope); + + if (overloadedOperatorType != null && + (componentType == null || !TypesUtil.isAssignable(overloadedOperatorType, componentType, manager, resolveScope))) { + return TypesUtil.boxPrimitiveType(overloadedOperatorType, manager, resolveScope); + } + return componentType; + } + + @Nullable + private PsiType extractMapValueType(PsiType thisType, PsiType[] argTypes, PsiManager manager, GlobalSearchScope resolveScope) { + if (argTypes.length != 1 || !InheritanceUtil.isInheritor(thisType, CommonClassNames.JAVA_UTIL_MAP)) return null; + final PsiType substituted = substituteTypeParameter(thisType, CommonClassNames.JAVA_UTIL_MAP, 1, true); + return TypesUtil.boxPrimitiveType(substituted, manager, resolveScope); + } + }; + public GrIndexPropertyImpl(@NotNull ASTNode node) { super(node); } @@ -65,44 +108,6 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp } public PsiType getType() { - GrExpression selected = getSelectedExpression(); - PsiType thisType = selected.getType(); - - if (thisType == null) return null; - - GrArgumentList argList = getArgumentList(); - if (argList == null) return null; - - PsiType[] argTypes = PsiUtil.getArgumentTypes(argList, false, null); - - final PsiManager manager = getManager(); - final GlobalSearchScope resolveScope = getResolveScope(); - - if (PsiImplUtil.isSimpleArrayAccess(thisType, argTypes, manager, resolveScope)) { - return TypesUtil.boxPrimitiveType(((PsiArrayType)thisType).getComponentType(), manager, resolveScope); - } - - PsiType overloadedOperatorType = null; - GroovyResolveResult candidate = PsiImplUtil.getIndexPropertyMethodCandidate(thisType, argTypes, this); - - final PsiElement element = candidate.getElement(); - if (element instanceof PsiMethod) { - overloadedOperatorType = candidate.getSubstitutor().substitute(getSmartReturnType((PsiMethod)element)); - } - - PsiType componentType = extractMapValueType(thisType, argTypes); - - if (overloadedOperatorType != null && - (componentType == null || !TypesUtil.isAssignable(overloadedOperatorType, componentType, manager, resolveScope))) { - return TypesUtil.boxPrimitiveType(overloadedOperatorType, manager, resolveScope); - } - return componentType; - } - - @Nullable - private PsiType extractMapValueType(PsiType thisType, PsiType[] argTypes) { - if (argTypes.length != 1 || !InheritanceUtil.isInheritor(thisType, CommonClassNames.JAVA_UTIL_MAP)) return null; - final PsiType substituted = substituteTypeParameter(thisType, CommonClassNames.JAVA_UTIL_MAP, 1, true); - return TypesUtil.boxPrimitiveType(substituted, getManager(), getResolveScope()); + return GroovyPsiManager.getInstance(getProject()).getType(this, TYPE_CALCULATOR); } } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/types/GrSafeCastExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/types/GrSafeCastExpressionImpl.java index 05f54442c398..101a1e5b2954 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/types/GrSafeCastExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/types/GrSafeCastExpressionImpl.java @@ -21,14 +21,18 @@ import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.ResolveCache; import com.intellij.util.ArrayUtil; +import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.NullableFunction; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSafeCastExpression; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; +import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrExpressionImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; @@ -38,6 +42,15 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt */ public class GrSafeCastExpressionImpl extends GrExpressionImpl implements GrSafeCastExpression, PsiPolyVariantReference { + private static final Function TYPE_CALCULATOR = new NullableFunction() { + @Override + public PsiType fun(GrSafeCastExpressionImpl cast) { + GrTypeElement typeElement = cast.getCastTypeElement(); + if (typeElement != null) return TypesUtil.boxPrimitiveType(typeElement.getType(), cast.getManager(), cast.getResolveScope()); + return null; + } + }; + private static final class OurResolver implements ResolveCache.PolyVariantResolver { @Override public ResolveResult[] resolve(GrSafeCastExpressionImpl cast, boolean incompleteCode) { @@ -46,11 +59,13 @@ public class GrSafeCastExpressionImpl extends GrExpressionImpl implements GrSafe return GroovyResolveResult.EMPTY_ARRAY; } + final GrTypeElement typeElement = cast.getCastTypeElement(); + final PsiType toCast = typeElement == null ? null : typeElement.getType(); return TypesUtil.getOverloadedOperatorCandidates( type, GroovyTokenTypes.kAS, cast, - new PsiType[]{TypesUtil.createJavaLangClassType(cast.getCastTypeElement().getType(), cast.getProject(), cast.getResolveScope())} + new PsiType[]{TypesUtil.createJavaLangClassType(toCast, cast.getProject(), cast.getResolveScope())} ); } } @@ -70,17 +85,17 @@ public class GrSafeCastExpressionImpl extends GrExpressionImpl implements GrSafe } public PsiType getType() { - GrTypeElement typeElement = getCastTypeElement(); - if (typeElement != null) return TypesUtil.boxPrimitiveType(typeElement.getType(), getManager(), getResolveScope()); - return null; + return GroovyPsiManager.getInstance(getProject()).getType(this, TYPE_CALCULATOR); } + @Nullable public GrTypeElement getCastTypeElement() { return findChildByClass(GrTypeElement.class); } + @NotNull public GrExpression getOperand() { - return findChildByClass(GrExpression.class); + return findNotNullChildByClass(GrExpression.class); } @Override diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java index 5b2be689e35a..2f28deb57d8c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java @@ -26,6 +26,9 @@ import com.intellij.psi.scope.JavaScopeProcessorEvent; import com.intellij.psi.scope.NameHint; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.util.*; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.dsl.GroovyDslFileIndex; @@ -46,16 +49,18 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; +import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; -import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; -import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassResolverProcessor; -import org.jetbrains.plugins.groovy.lang.resolve.processors.MethodResolverProcessor; -import org.jetbrains.plugins.groovy.lang.resolve.processors.PropertyResolverProcessor; -import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor; +import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; +import org.jetbrains.plugins.groovy.lang.psi.util.*; +import org.jetbrains.plugins.groovy.lang.resolve.processors.*; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import static org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.getSmartReturnType; + /** * @author ven */ @@ -405,7 +410,7 @@ public class ResolveUtil { return elements; } - public static GroovyResolveResult[] filterSameSignatureCandidates(Collection candidates, int argumentCount) { + public static GroovyResolveResult[] filterSameSignatureCandidates(Collection candidates) { GroovyResolveResult[] array = candidates.toArray(new GroovyResolveResult[candidates.size()]); if (array.length == 1) return array; @@ -533,10 +538,6 @@ public class ResolveUtil { return false; } - public static boolean isInWithContext(GroovyResolveResult resolveResult) { - return isInWithContext(resolveResult.getCurrentFileResolveContext()); - } - public static boolean isInWithContext(GroovyPsiElement resolveContext) { if (resolveContext instanceof GrExpression) { final PsiElement parent = resolveContext.getParent(); @@ -586,27 +587,115 @@ public class ResolveUtil { @Nullable String methodName, @NotNull GroovyPsiElement place, @Nullable PsiType... argumentTypes) { - if (methodName != null) { - MethodResolverProcessor processor = - new MethodResolverProcessor(methodName, place, false, thisType, argumentTypes, PsiType.EMPTY_ARRAY); - final ResolveState state; - if (thisType instanceof PsiClassType) { - final PsiClassType classtype = (PsiClassType)thisType; - final PsiClassType.ClassResolveResult resolveResult = classtype.resolveGenerics(); - final PsiClass lClass = resolveResult.getElement(); - state = ResolveState.initial().put(PsiSubstitutor.KEY, resolveResult.getSubstitutor()); - if (lClass != null) { - lClass.processDeclarations(processor, state, null, place); + if (methodName == null) return GroovyResolveResult.EMPTY_ARRAY; + + MethodResolverProcessor processor = + new MethodResolverProcessor(methodName, place, false, thisType, argumentTypes, PsiType.EMPTY_ARRAY); + processCandidatesInner(thisType, place, processor); + boolean hasApplicableMethods = processor.hasApplicableCandidates(); + final GroovyResolveResult[] methodCandidates = processor.getCandidates(); + if (hasApplicableMethods && methodCandidates.length == 1) return methodCandidates; + + PropertyResolverProcessor propertyResolver = new PropertyResolverProcessor(methodName, place); + processCandidatesInner(thisType, place, propertyResolver); + final GroovyResolveResult[] allPropertyCandidates = propertyResolver.getCandidates(); + + List propertyCandidates = new ArrayList(allPropertyCandidates.length); + for (GroovyResolveResult candidate : allPropertyCandidates) { + final PsiElement resolved = candidate.getElement(); + if (!(resolved instanceof GrField)) continue; + final PsiType type = ((GrField)resolved).getTypeGroovy(); + if (isApplicableClosureType(type, argumentTypes, place)) { + propertyCandidates.add(candidate); + } + } + + for (GroovyResolveResult candidate : propertyCandidates) { + final PsiElement element = candidate.getElement(); + if (element instanceof GrField) { + final PsiClass containingClass = ((PsiField)element).getContainingClass(); + if (containingClass != null && PsiTreeUtil.isContextAncestor(containingClass, place, true)) { + return new GroovyResolveResult[]{candidate}; } } - else { - state = ResolveState.initial(); - } + } - processNonCodeMethods(thisType, processor, place, state); - processCategoryMembers(place, processor); - return processor.getCandidates(); + List allCandidates = new ArrayList(); + if (hasApplicableMethods) { + ContainerUtil.addAll(allCandidates, methodCandidates); + } + ContainerUtil.addAll(allCandidates, propertyCandidates); + + //search for getters + for (String getterName : GroovyPropertyUtils.suggestGettersName(methodName)) { + AccessorResolverProcessor getterResolver = new AccessorResolverProcessor(getterName, place, true); + processCandidatesInner(thisType, place, getterResolver); + final GroovyResolveResult[] candidates = getterResolver.getCandidates(); //can be only one candidate + final List applicable = new ArrayList(); + for (GroovyResolveResult candidate : candidates) { + final PsiType type = getSmartReturnType((PsiMethod)candidate.getElement()); + if (isApplicableClosureType(type, argumentTypes, place)) { + applicable.add(candidate); + } + } + if (applicable.size() == 1) { + return applicable.toArray(new GroovyResolveResult[applicable.size()]); + } + ContainerUtil.addAll(allCandidates, applicable); + } + + if (allCandidates.size() > 0) { + return allCandidates.toArray(new GroovyResolveResult[allCandidates.size()]); } return GroovyResolveResult.EMPTY_ARRAY; } + + private static boolean isApplicableClosureType(PsiType type, PsiType[] argTypes, GroovyPsiElement place) { + if (!(type instanceof GrClosureType)) return false; + + final GrClosureSignature signature = ((GrClosureType)type).getSignature(); + return GrClosureSignatureUtil.isSignatureApplicable(signature, argTypes, place); + } + + private static void processCandidatesInner(PsiType thisType, GroovyPsiElement place, ResolverProcessor processor) { + final ResolveState state; + if (thisType instanceof PsiClassType) { + final PsiClassType classtype = (PsiClassType)thisType; + final PsiClassType.ClassResolveResult resolveResult = classtype.resolveGenerics(); + final PsiClass lClass = resolveResult.getElement(); + state = ResolveState.initial().put(PsiSubstitutor.KEY, resolveResult.getSubstitutor()); + if (lClass != null) { + lClass.processDeclarations(processor, state, null, place); + } + } + else { + state = ResolveState.initial(); + } + + processNonCodeMethods(thisType, processor, place, state); + processCategoryMembers(place, processor); + } + + @Nullable + public static PsiType extractReturnTypeFromCandidate(GroovyResolveResult candidate) { + final PsiElement element = candidate.getElement(); + if (element instanceof PsiMethod && !candidate.isInvokedOnProperty()) { + return candidate.getSubstitutor().substitute(getSmartReturnType((PsiMethod)element)); + } + + final PsiType type; + if (element instanceof GrField) { + type = ((GrField)element).getTypeGroovy(); + } + else if (element instanceof PsiMethod) { + type = getSmartReturnType((PsiMethod)element); + } + else { + return null; + } + if (type instanceof GrClosureType) { + return candidate.getSubstitutor().substitute(((GrClosureType)type).getSignature().getReturnType()); + } + return null; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/CompletionProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/CompletionProcessor.java index 6675e16f2668..699f94697fb7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/CompletionProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/CompletionProcessor.java @@ -57,6 +57,6 @@ public class CompletionProcessor extends ResolverProcessor { @NotNull public GroovyResolveResult[] getCandidates() { if (!super.hasCandidates()) return GroovyResolveResult.EMPTY_ARRAY; - return ResolveUtil.filterSameSignatureCandidates(getCandidatesInternal(), -1); + return ResolveUtil.filterSameSignatureCandidates(getCandidatesInternal()); } } \ No newline at end of file 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 2a2350173575..dfa830e0609d 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 @@ -249,7 +249,7 @@ public class MethodResolverProcessor extends ResolverProcessor { if (!myInapplicableCandidates.isEmpty()) { final Set resultSet = myAllVariants ? myInapplicableCandidates : filterCorrectParameterCount(myInapplicableCandidates); - return ResolveUtil.filterSameSignatureCandidates(resultSet, myArgumentTypes != null ? myArgumentTypes.length : -1); + return ResolveUtil.filterSameSignatureCandidates(resultSet); } return GroovyResolveResult.EMPTY_ARRAY; } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolvePropertyTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolvePropertyTest.groovy index 44146920115f..956083d4745a 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolvePropertyTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolvePropertyTest.groovy @@ -654,7 +654,15 @@ setFoo(2) assertInstanceOf resolved, GrParameter } - public void dontResolveForVarOutsideOfFor(){ + public void testDontResolveForVarOutsideOfFor(){ assertNull resolve("A.groovy") } + + public void testOperatorOverloading() { + assertInstanceOf resolve("A.groovy"), GrAccessorMethod + } + + public void testResolveClosureOverloader() { + assertInstanceOf resolve("A.groovy"), GrAccessorMethod + } } 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 ba42e15a4032..c7fbb0dbb7ce 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 @@ -193,4 +193,15 @@ public class TypeInferenceTest extends GroovyResolveTestCase { public void testPlusEquals3() { assertTypeEquals("java.lang.String", "A.groovy"); } + public void testPlusEqualsClosure() { + assertTypeEquals("java.lang.String", "A.groovy"); + } + + public void testGetAtClosure() { + assertTypeEquals("java.lang.String", "A.groovy"); + } + + public void testPreferMethodOverloader() { + assertTypeEquals("java.lang.String", "A.groovy"); + } } diff --git a/plugins/groovy/testdata/highlighting/CallIsNotApplicable.groovy b/plugins/groovy/testdata/highlighting/CallIsNotApplicable.groovy index 915316db3d7f..6b0cbfd391b6 100644 --- a/plugins/groovy/testdata/highlighting/CallIsNotApplicable.groovy +++ b/plugins/groovy/testdata/highlighting/CallIsNotApplicable.groovy @@ -5,5 +5,5 @@ class IntCategory { } use(IntCategory) { - print 2(3, 4) + print 2(3, 4) } \ No newline at end of file diff --git a/plugins/groovy/testdata/highlighting/PathCallIsNotApplicable.groovy b/plugins/groovy/testdata/highlighting/PathCallIsNotApplicable.groovy index f5e509f62094..833068eb974b 100644 --- a/plugins/groovy/testdata/highlighting/PathCallIsNotApplicable.groovy +++ b/plugins/groovy/testdata/highlighting/PathCallIsNotApplicable.groovy @@ -1,5 +1,5 @@ class IntCategory { - def call(Integer i, int q) { + static def call(Integer i, int q) { return { String s -> s + q; } @@ -7,5 +7,5 @@ class IntCategory { } use(IntCategory) { - print 2(3)("a", "b") + print 2(3)("a", "b") } \ No newline at end of file diff --git a/plugins/groovy/testdata/resolve/inference/getAtClosure/A.groovy b/plugins/groovy/testdata/resolve/inference/getAtClosure/A.groovy new file mode 100644 index 000000000000..65d39113288b --- /dev/null +++ b/plugins/groovy/testdata/resolve/inference/getAtClosure/A.groovy @@ -0,0 +1,10 @@ +class Test { + def getAt = {def a -> + "a" + } +} +def test = new Test() +test = test[2] + +print test + diff --git a/plugins/groovy/testdata/resolve/inference/plusEqualsClosure/A.groovy b/plugins/groovy/testdata/resolve/inference/plusEqualsClosure/A.groovy new file mode 100644 index 000000000000..4fa132d4ee82 --- /dev/null +++ b/plugins/groovy/testdata/resolve/inference/plusEqualsClosure/A.groovy @@ -0,0 +1,9 @@ +class Test { + def plus = {def a -> + "a" + } +} +def test = new Test() +test += 2 +print test + diff --git a/plugins/groovy/testdata/resolve/inference/preferMethodOverloader/A.groovy b/plugins/groovy/testdata/resolve/inference/preferMethodOverloader/A.groovy new file mode 100644 index 000000000000..eae1ac6af4f9 --- /dev/null +++ b/plugins/groovy/testdata/resolve/inference/preferMethodOverloader/A.groovy @@ -0,0 +1,14 @@ +class Base { + def getAt(def a) { + "2" + } +} +class Test extends Base { + def getAt = {def a -> + 2 + } +} +def test = new Test() +test = test[2] +print test + diff --git a/plugins/groovy/testdata/resolve/property/operatorOverloading/A.groovy b/plugins/groovy/testdata/resolve/property/operatorOverloading/A.groovy new file mode 100644 index 000000000000..cb084c713102 --- /dev/null +++ b/plugins/groovy/testdata/resolve/property/operatorOverloading/A.groovy @@ -0,0 +1,9 @@ +class Test { + def plus = {def a -> + "a" + } +} +def test = new Test() +test += 2 +print test + diff --git a/plugins/groovy/testdata/resolve/property/resolveClosureOverloader/A.groovy b/plugins/groovy/testdata/resolve/property/resolveClosureOverloader/A.groovy new file mode 100644 index 000000000000..0894a449f4d3 --- /dev/null +++ b/plugins/groovy/testdata/resolve/property/resolveClosureOverloader/A.groovy @@ -0,0 +1,24 @@ +class Base { + def getAt(def a) { + 2 + } +} +class Test extends Base { + def plus = {int a -> + "a" + } + + def plus(String a) {2} + + def call = { def a -> + "a" + } + + def call() {2} +} + + +def test = new Test() +print test + 2 + + From a9d5de9e7ad04dc3514b5b5d70e5e07d32db82a2 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 14 Apr 2011 17:34:49 +0400 Subject: [PATCH 040/100] NPE fix --- .../intellij/application/options/GeneralCodeStylePanel.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java b/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java index 7d71ea12375e..c2c5070a7e2f 100644 --- a/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java @@ -218,8 +218,12 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel { for(Map.Entry entry : myAdditionalIndentOptions.entrySet()) { FileType fileType = entry.getKey(); + CodeStyleSettings.IndentOptions additionalIndentOptions = settings.getAdditionalIndentOptions(fileType); + if (additionalIndentOptions == null) { + continue; + } IndentOptionsEditor editor = entry.getValue(); - editor.apply(settings, settings.getAdditionalIndentOptions(fileType)); + editor.apply(settings, additionalIndentOptions); } } From 63013d2d73ac5ec35b8a58d096d0e51887d16d4c Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 14 Apr 2011 17:46:04 +0400 Subject: [PATCH 041/100] Reverted the change that disabled formatting during 'join lines' processing. The reason is that that produces ugly code. The problem was that there were PSI elements with postponed format marker on 'join lines' processing start. They were unexpectedly affected by formatting and that broke offsets used by JoinLinesHandler. The fix is to perform postponed formatting before 'join lines' processing. --- .../editorActions/JoinLinesHandler.java | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java index 2ea11eb84164..98d122dc3b54 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java @@ -28,7 +28,6 @@ import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.LogicalPosition; import com.intellij.openapi.editor.ScrollType; @@ -43,7 +42,6 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -96,6 +94,7 @@ public class JoinLinesHandler extends EditorWriteActionHandler { if (i >= doc.getLineCount() - 1) break; int lineEndOffset = doc.getLineEndOffset(startLine); + docManager.doPostponedOperationsAndUnblockDocument(doc); docManager.commitDocument(doc); CharSequence text = doc.getCharsSequence(); int firstNonSpaceOffsetInNextLine = doc.getLineStartOffset(startLine + 1); @@ -120,7 +119,7 @@ public class JoinLinesHandler extends EditorWriteActionHandler { TextRange limits = findStartAndEnd(text, lastNonSpaceOffsetInStartLine, firstNonSpaceOffsetInNextLine, doc.getTextLength()); start = limits.getStartOffset(); end = limits.getEndOffset(); // run raw joiners - for(JoinLinesHandlerDelegate delegate: Extensions.getExtensions(JoinRawLinesHandlerDelegate.EP_NAME)) { + for(JoinLinesHandlerDelegate delegate: Extensions.getExtensions(JoinLinesHandlerDelegate.EP_NAME)) { if (delegate instanceof JoinRawLinesHandlerDelegate) { rc = ((JoinRawLinesHandlerDelegate)delegate).tryJoinRawLines(doc, psiFile, start, end); if (rc != CANNOT_JOIN) { @@ -239,16 +238,16 @@ public class JoinLinesHandler extends EditorWriteActionHandler { } private static void doPostponedOperationsAndUnblockDocument(@NotNull PsiDocumentManager docManager, @NotNull DocumentEx document) { - boolean restore = CodeEditUtil.isSuspendedNodesReformattingAllowed(); - CodeEditUtil.setAllowSuspendNodesReformatting(false); - try { + //boolean restore = CodeEditUtil.isSuspendedNodesReformattingAllowed(); + //CodeEditUtil.setAllowSuspendNodesReformatting(false); + //try { docManager.doPostponedOperationsAndUnblockDocument(document); - } - finally { - if (restore) { - CodeEditUtil.setAllowSuspendNodesReformatting(true); - } - } + //} + //finally { + // if (restore) { + // CodeEditUtil.setAllowSuspendNodesReformatting(true); + // } + //} } private static boolean isCommentElement(final PsiElement element) { From a13bc0deb9894702f15ef130de1359f3dba64159 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Thu, 14 Apr 2011 17:35:24 +0400 Subject: [PATCH 042/100] OC-555: Remove Settings from under File on Macs. --- .../com/intellij/ide/actions/ShowSettingsAction.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsAction.java index 2f17c493787e..c08a10578675 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsAction.java @@ -15,6 +15,7 @@ */ package com.intellij.ide.actions; +import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -26,10 +27,19 @@ import com.intellij.openapi.options.ex.ProjectConfigurablesGroup; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.SystemInfo; import javax.swing.*; public class ShowSettingsAction extends AnAction implements DumbAware { + @Override + public void update(AnActionEvent e) { + if (SystemInfo.isMac && e.getPlace().equals(ActionPlaces.MAIN_MENU)) { + // It's called from Preferences in App menu. + e.getPresentation().setVisible(false); + } + } + public void actionPerformed(AnActionEvent e) { Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); if (project == null) { From 06588c8a6c5183c77ef3310347e5d559b1661979 Mon Sep 17 00:00:00 2001 From: Alexander Doroshko Date: Thu, 14 Apr 2011 19:14:22 +0400 Subject: [PATCH 043/100] IDEA-56002 ability to disable "generate flex configuration" on maven project reimport --- .../AdditionalMavenImportingSettings.java | 13 +++++++ .../project/MavenImportingConfigurable.java | 34 ++++++++++++++++++- .../project/MavenImportingSettingsForm.form | 14 ++++++-- .../project/MavenImportingSettingsForm.java | 6 ++++ .../idea/maven/utils/MavenSettings.java | 2 +- .../src/main/resources/META-INF/plugin.xml | 1 + .../idea/maven/project/MavenSettingsTest.java | 2 +- 7 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 plugins/maven/src/main/java/org/jetbrains/idea/maven/project/AdditionalMavenImportingSettings.java diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/AdditionalMavenImportingSettings.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/AdditionalMavenImportingSettings.java new file mode 100644 index 000000000000..a9bb3f9ddbc6 --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/AdditionalMavenImportingSettings.java @@ -0,0 +1,13 @@ +package org.jetbrains.idea.maven.project; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.options.UnnamedConfigurable; +import com.intellij.openapi.project.Project; + +public interface AdditionalMavenImportingSettings { + + ExtensionPointName EP_NAME = + ExtensionPointName.create("org.jetbrains.idea.maven.additional.importing.settings"); + + UnnamedConfigurable createConfigurable(Project project); +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingConfigurable.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingConfigurable.java index f31a4f0b19f1..d237d20b257c 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingConfigurable.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingConfigurable.java @@ -17,38 +17,70 @@ package org.jetbrains.idea.maven.project; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.SearchableConfigurable; +import com.intellij.openapi.options.UnnamedConfigurable; +import com.intellij.openapi.project.Project; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.util.ArrayList; +import java.util.List; public class MavenImportingConfigurable implements SearchableConfigurable { private final MavenImportingSettings myImportingSettings; private final MavenImportingSettingsForm mySettingsForm = new MavenImportingSettingsForm(false); + private final List myAdditionalConfigurables; - public MavenImportingConfigurable(MavenImportingSettings importingSettings) { + public MavenImportingConfigurable(Project project, MavenImportingSettings importingSettings) { myImportingSettings = importingSettings; + + myAdditionalConfigurables = new ArrayList(); + for (final AdditionalMavenImportingSettings additionalSettings : AdditionalMavenImportingSettings.EP_NAME.getExtensions()) { + myAdditionalConfigurables.add(additionalSettings.createConfigurable(project)); + } } public JComponent createComponent() { + final JPanel panel = mySettingsForm.getAdditionalSettingsPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + for (final UnnamedConfigurable additionalConfigurable : myAdditionalConfigurables) { + panel.add(additionalConfigurable.createComponent()); + } return mySettingsForm.createComponent(); } public void disposeUIResources() { + for (final UnnamedConfigurable additionalConfigurable : myAdditionalConfigurables) { + additionalConfigurable.disposeUIResources(); + } } public boolean isModified() { + for (final UnnamedConfigurable additionalConfigurable : myAdditionalConfigurables) { + if (additionalConfigurable.isModified()) { + return true; + } + } + return mySettingsForm.isModified(myImportingSettings); } public void apply() throws ConfigurationException { mySettingsForm.getData(myImportingSettings); + + for (final UnnamedConfigurable additionalConfigurable : myAdditionalConfigurables) { + additionalConfigurable.apply(); + } } public void reset() { mySettingsForm.setData(myImportingSettings); + + for (final UnnamedConfigurable additionalConfigurable : myAdditionalConfigurables) { + additionalConfigurable.reset(); + } } @Nls diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.form b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.form index e06e35a38d19..d00ad63de073 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.form +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.form @@ -1,6 +1,6 @@

- + @@ -10,7 +10,7 @@ - + @@ -165,9 +165,19 @@ + + + + + + + + + + diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.java index 4178aca2c998..b22fbe179706 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.java @@ -46,6 +46,8 @@ public class MavenImportingSettingsForm { private JCheckBox myDownloadSourcesCheckBox; private JCheckBox myDownloadDocsCheckBox; + private JPanel myAdditionalSettingsPanel; + public MavenImportingSettingsForm(boolean isImportStep) { if (!isImportStep) { mySearchRecursivelyCheckBox.setVisible(false); @@ -136,4 +138,8 @@ public class MavenImportingSettingsForm { public void updateData(WizardContext wizardContext) { myProjectFormatPanel.updateData(wizardContext); } + + public JPanel getAdditionalSettingsPanel() { + return myAdditionalSettingsPanel; + } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenSettings.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenSettings.java index f9b3479d70fb..bd2e48699545 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenSettings.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenSettings.java @@ -47,7 +47,7 @@ public class MavenSettings implements SearchableConfigurable.Parent { }; myChildren = new ArrayList(); - myChildren.add(new MavenImportingConfigurable(MavenProjectsManager.getInstance(myProject).getImportingSettings())); + myChildren.add(new MavenImportingConfigurable(myProject, MavenProjectsManager.getInstance(myProject).getImportingSettings())); myChildren.add(new MavenIgnoredFilesConfigurable(MavenProjectsManager.getInstance(myProject))); myChildren.add(new MavenRunnerConfigurable(myProject, false) { diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml index fc51b0b761e6..b1ada2e25ba8 100644 --- a/plugins/maven/src/main/resources/META-INF/plugin.xml +++ b/plugins/maven/src/main/resources/META-INF/plugin.xml @@ -7,6 +7,7 @@ + diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenSettingsTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenSettingsTest.java index 8427614bab1e..b735c3043853 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenSettingsTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenSettingsTest.java @@ -66,7 +66,7 @@ public class MavenSettingsTest extends MavenTestCase { public void testImportingSettings() throws Exception { assertTrue(new MavenImportingSettings().equals(new MavenImportingSettings())); - MavenImportingConfigurable importingConfigurable = new MavenImportingConfigurable(new MavenImportingSettings()); + MavenImportingConfigurable importingConfigurable = new MavenImportingConfigurable(myProject, new MavenImportingSettings()); importingConfigurable.reset(); assertFalse(importingConfigurable.isModified()); } From c2e750c2696665176a63d716a8d3d79c17f245fb Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 14 Apr 2011 14:57:48 +0400 Subject: [PATCH 044/100] + getProject(e) --- .../roots/ui/configuration/actions/NewModuleAction.java | 6 ------ .../history/integration/ui/actions/LocalHistoryAction.java | 4 ---- .../src/com/intellij/openapi/actionSystem/AnAction.java | 7 +++++++ .../src/com/intellij/ui/switcher/ApplySwitchAction.java | 3 --- .../actions/ShowFeatureUsageStatisticsAction.java | 4 ---- .../intellij/ide/actions/SynchronizeCurrentFileAction.java | 4 ---- .../xdebugger/impl/breakpoints/XLineBreakpointImpl.java | 2 +- .../xpath/xslt/associations/impl/AssociationsGroup.java | 5 ----- 8 files changed, 8 insertions(+), 27 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java index eccd2d3a32fd..9450408c18b5 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java @@ -90,10 +90,4 @@ public class NewModuleAction extends AnAction implements DumbAware { super.update(e); e.getPresentation().setEnabled(getProject(e) != null); } - - @Nullable - private static Project getProject(AnActionEvent e) { - return e.getData(PlatformDataKeys.PROJECT); - } - } diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryAction.java b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryAction.java index c59d39a24186..c9384f5bea62 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryAction.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryAction.java @@ -74,8 +74,4 @@ public abstract class LocalHistoryAction extends AnAction implements DumbAware { } return commonParent; } - - protected Project getProject(AnActionEvent e) { - return e.getData(PlatformDataKeys.PROJECT); - } } diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/AnAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/AnAction.java index bbcea138302f..de5c19b73b33 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/AnAction.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/AnAction.java @@ -18,10 +18,12 @@ package com.intellij.openapi.actionSystem; import com.intellij.openapi.Disposable; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.ArrayList; @@ -302,4 +304,9 @@ public abstract class AnAction { public interface TransparentUpdate { } + + @Nullable + public static Project getProject(AnActionEvent e) { + return e == null ? null : e.getData(PlatformDataKeys.PROJECT); + } } diff --git a/platform/platform-api/src/com/intellij/ui/switcher/ApplySwitchAction.java b/platform/platform-api/src/com/intellij/ui/switcher/ApplySwitchAction.java index c96de3a16e4d..c7f990fe445e 100644 --- a/platform/platform-api/src/com/intellij/ui/switcher/ApplySwitchAction.java +++ b/platform/platform-api/src/com/intellij/ui/switcher/ApplySwitchAction.java @@ -48,9 +48,6 @@ public class ApplySwitchAction extends AnAction { } } - private static Project getProject(AnActionEvent e) { - return PlatformDataKeys.PROJECT.getData(e.getDataContext()); - } @Override public void actionPerformed(AnActionEvent e) { diff --git a/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsAction.java b/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsAction.java index 411441284f4b..7ce776f0586c 100644 --- a/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsAction.java +++ b/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsAction.java @@ -30,8 +30,4 @@ public class ShowFeatureUsageStatisticsAction extends AnAction implements DumbAw super.update(e); e.getPresentation().setEnabled(getProject(e) != null); } - - private Project getProject(AnActionEvent e) { - return PlatformDataKeys.PROJECT.getData(e.getDataContext()); - } } \ No newline at end of file diff --git a/platform/vcs-impl/src/com/intellij/ide/actions/SynchronizeCurrentFileAction.java b/platform/vcs-impl/src/com/intellij/ide/actions/SynchronizeCurrentFileAction.java index c7037855449d..b6ddb4d72e99 100644 --- a/platform/vcs-impl/src/com/intellij/ide/actions/SynchronizeCurrentFileAction.java +++ b/platform/vcs-impl/src/com/intellij/ide/actions/SynchronizeCurrentFileAction.java @@ -73,10 +73,6 @@ public class SynchronizeCurrentFileAction extends AnAction implements DumbAware WindowManager.getInstance().getStatusBar(project).setInfo(message); } - private static Project getProject(AnActionEvent e) { - return e.getData(PlatformDataKeys.PROJECT); - } - private static VirtualFile[] getFiles(AnActionEvent e) { return e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); } 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 a6fc5cf3da55..d4bfd1db5096 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 @@ -429,7 +429,7 @@ public class XLineBreakpointImpl

extends XBreak } public void actionPerformed(final AnActionEvent e) { - XDebuggerUtil.getInstance().removeBreakpoint(getProject(), XLineBreakpointImpl.this); + XDebuggerUtil.getInstance().removeBreakpoint(XLineBreakpointImpl.this.getProject(), XLineBreakpointImpl.this); } } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsGroup.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsGroup.java index 83d9566f92ea..424f80b09b6a 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsGroup.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsGroup.java @@ -80,11 +80,6 @@ public class AssociationsGroup extends ActionGroup { return XsltSupport.isXsltFile(psiFile); } - @Nullable - static Project getProject(@Nullable AnActionEvent e) { - return e != null ? LangDataKeys.PROJECT.getData(e.getDataContext()) : null; - } - @Nullable static PsiFile getPsiFile(@Nullable AnActionEvent e) { return e != null ? LangDataKeys.PSI_FILE.getData(e.getDataContext()) : null; From 493c986dc29482ce250a3d2b4f6208d8b7337ff9 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 14 Apr 2011 17:31:41 +0400 Subject: [PATCH 045/100] keep selection order --- .../src/com/intellij/ide/util/treeView/AbstractTreeUi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java index 3453c92d5016..7af773067a1d 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java @@ -3736,7 +3736,7 @@ public class AbstractTreeUi { final Set getSelectedElements() { final TreePath[] paths = myTree.getSelectionPaths(); - Set result = new HashSet(); + Set result = new LinkedHashSet(); if (paths != null) { for (TreePath eachPath : paths) { if (eachPath.getLastPathComponent() instanceof DefaultMutableTreeNode) { From 285ffc871458bf81d9e2606ac42ffb7859e83363 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 14 Apr 2011 18:43:30 +0400 Subject: [PATCH 046/100] setting to configure different dir diffs components --- .../intellij/ide/diff/DirDiffSettings.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 platform/platform-api/src/com/intellij/ide/diff/DirDiffSettings.java diff --git a/platform/platform-api/src/com/intellij/ide/diff/DirDiffSettings.java b/platform/platform-api/src/com/intellij/ide/diff/DirDiffSettings.java new file mode 100644 index 000000000000..53c74b076c95 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/diff/DirDiffSettings.java @@ -0,0 +1,29 @@ +/* + * 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.diff; + +/** + * @author Konstantin Bulenkov + */ +public class DirDiffSettings { + public boolean showSize = true; + public boolean showDate = true; + + public boolean showEqual = false; + public boolean showDifferent = true; + public boolean showNewOnSource = true; + public boolean showNewOnTarget = true; +} From 43b1f29b4dabf2366d5b4e6f8e2af3941a49e72f Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 14 Apr 2011 18:50:56 +0400 Subject: [PATCH 047/100] Db Diff support + API changes for Dir Diff --- .../com/intellij/ide/diff/DiffElement.java | 22 ++++- .../intellij/openapi/diff/DirDiffManager.java | 3 +- .../openapi/diff/impl/dir/DirDiffDialog.java | 14 ++- .../openapi/diff/impl/dir/DirDiffElement.java | 5 + .../diff/impl/dir/DirDiffManagerImpl.java | 8 +- .../openapi/diff/impl/dir/DirDiffPanel.java | 9 +- .../impl/dir/DirDiffTableCellRenderer.java | 9 +- .../diff/impl/dir/DirDiffTableModel.java | 92 +++++++++++-------- .../diff/impl/dir/TestDirDiffAction.java | 3 +- 9 files changed, 111 insertions(+), 54 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/diff/DiffElement.java b/platform/platform-api/src/com/intellij/ide/diff/DiffElement.java index f06fe968c3d1..88a80da4c239 100644 --- a/platform/platform-api/src/com/intellij/ide/diff/DiffElement.java +++ b/platform/platform-api/src/com/intellij/ide/diff/DiffElement.java @@ -25,17 +25,20 @@ import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.encoding.EncodingManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.io.IOException; +import java.nio.charset.Charset; /** * @author Konstantin Bulenkov */ public abstract class DiffElement { + public static final DiffElement[] EMPTY_ARRAY = new DiffElement[0]; private DiffPanel myDiffPanel; private Editor myEditor; @@ -54,7 +57,7 @@ public abstract class DiffElement { public abstract boolean isContainer(); - public abstract DiffElement[] getChildren(); + public abstract DiffElement[] getChildren() throws IOException; @Nullable public abstract DiffElement findFileByRelativePath(String path); @@ -67,6 +70,10 @@ public abstract class DiffElement { @Nullable public abstract byte[] getContent() throws IOException; + public Charset getCharset() { + return EncodingManager.getInstance().getDefaultCharset(); + } + @Nullable public JComponent getViewComponent(Project project) { disposeViewComponent(); @@ -97,6 +104,8 @@ public abstract class DiffElement { myDiffPanel = DiffManager.getInstance().createDiffPanel(parentWindow, project); myDiffPanel.setRequestFocus(false); myDiffPanel.setDiffRequest(request); + myDiffPanel.setTitle1(getName()); + myDiffPanel.setTitle2(element.getName()); return myDiffPanel.getComponent(); } @@ -126,7 +135,7 @@ public abstract class DiffElement { @Nullable protected DiffContent createDiffContent() { try { - return new SimpleContent(new String(getContent()), getFileType()); + return new SimpleContent(new String(getContent(), getCharset()), getFileType()); } catch (IOException e) {// } @@ -148,4 +157,13 @@ public abstract class DiffElement { myDiffPanel = null; } } + + public String getSeparator() { + return "/"; + } + + @Nullable + public Icon getIcon() { + return null; + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/DirDiffManager.java b/platform/platform-impl/src/com/intellij/openapi/diff/DirDiffManager.java index ad8c1361a1f1..6a7fc044dfb5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/DirDiffManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/DirDiffManager.java @@ -16,6 +16,7 @@ package com.intellij.openapi.diff; import com.intellij.ide.diff.DiffElement; +import com.intellij.ide.diff.DirDiffSettings; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; @@ -28,7 +29,7 @@ public abstract class DirDiffManager { return ServiceManager.getService(project, DirDiffManager.class); } - public abstract void showDiff(@NotNull DiffElement dir1, @NotNull DiffElement dir2); + public abstract void showDiff(@NotNull DiffElement dir1, @NotNull DiffElement dir2, DirDiffSettings settings); public abstract boolean canShow(@NotNull DiffElement dir1, @NotNull DiffElement dir2); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffDialog.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffDialog.java index 80242e511937..c75e55e6772b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffDialog.java @@ -15,8 +15,10 @@ */ package com.intellij.openapi.diff.impl.dir; +import com.intellij.ide.diff.DirDiffSettings; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.table.JBTable; import javax.swing.*; @@ -25,15 +27,21 @@ import javax.swing.*; */ public class DirDiffDialog extends DialogWrapper { private final DirDiffTableModel myModel; + private final DirDiffSettings mySettings; private DirDiffPanel myDiffPanel; - public DirDiffDialog(Project project, DirDiffTableModel model) { + public DirDiffDialog(Project project, DirDiffTableModel model, DirDiffSettings settings) { super(project); myModel = model; + mySettings = settings; setSize(600, 600); setTitle("Directory Diff"); init(); - myDiffPanel.getTable().changeSelection(myModel.getElementAt(0).isSeparator() ? 1: 0, 3, false, false); + final JBTable table = myDiffPanel.getTable(); + table.changeSelection(myModel.getElementAt(0).isSeparator() ? 1 : 0, 3, false, false); + table.setColumnSelectionAllowed(false); + table.getTableHeader().setReorderingAllowed(false); + table.getTableHeader().setResizingAllowed(false); } @Override @@ -43,7 +51,7 @@ public class DirDiffDialog extends DialogWrapper { @Override protected JComponent createCenterPanel() { - myDiffPanel = new DirDiffPanel(myModel, this); + myDiffPanel = new DirDiffPanel(myModel, this, mySettings); return myDiffPanel.getPanel(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffElement.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffElement.java index 28df55a7c9e4..7bd7e8545496 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffElement.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffElement.java @@ -19,6 +19,7 @@ import com.intellij.ide.diff.DiffElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.sql.Date; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -150,4 +151,8 @@ public class DirDiffElement { } public static enum ElementType {SOURCE, TARGET, SEPARATOR, CHANGED} + + public Icon getIcon() { + return mySource != null ? mySource.getIcon() : myTarget.getIcon(); + } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffManagerImpl.java index 4ac2d4119cb0..65bfcb362a6c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffManagerImpl.java @@ -16,6 +16,7 @@ package com.intellij.openapi.diff.impl.dir; import com.intellij.ide.diff.DiffElement; +import com.intellij.ide.diff.DirDiffSettings; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diff.DirDiffManager; import com.intellij.openapi.progress.ProgressIndicator; @@ -23,7 +24,6 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; /** @@ -37,18 +37,18 @@ public class DirDiffManagerImpl extends DirDiffManager { } @Override - public void showDiff(@NotNull final DiffElement dir1, @NotNull final DiffElement dir2) { + public void showDiff(@NotNull final DiffElement dir1, @NotNull final DiffElement dir2, final DirDiffSettings settings) { Task.Backgroundable task = new Task.Backgroundable(myProject, "Directory comparison", true) { @Override public void run(@NotNull ProgressIndicator indicator) { indicator.setText("Calculating differences"); - final DirDiffTableModel model = new DirDiffTableModel(myProject, dir1, dir2, indicator); + final DirDiffTableModel model = new DirDiffTableModel(myProject, dir1, dir2, indicator, settings); final Runnable run = new Runnable() { public void run() { if (model.getRowCount() == 0) { Messages.showInfoMessage(myProject, "No difference has been found", "Directory Diff Tool"); } else { - new DirDiffDialog(myProject, model).show(); + new DirDiffDialog(myProject, model, settings).show(); } } }; diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.java index 3208d4a30ef3..8849338c9002 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.java @@ -16,6 +16,7 @@ package com.intellij.openapi.diff.impl.dir; import com.intellij.ide.diff.DiffElement; +import com.intellij.ide.diff.DirDiffSettings; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.diff.impl.dir.actions.DirDiffToolbarActions; @@ -29,6 +30,7 @@ import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -56,7 +58,7 @@ public class DirDiffPanel { private JComponent myViewComponent; private DiffElement myCurrentElement; - public DirDiffPanel(DirDiffTableModel model, DirDiffDialog dirDiffDialog) { + public DirDiffPanel(DirDiffTableModel model, DirDiffDialog dirDiffDialog, DirDiffSettings settings) { myModel = model; myDialog = dirDiffDialog; mySourceDirField.setText(model.getSourceDir().getPath()); @@ -128,11 +130,12 @@ public class DirDiffPanel { } if (0 <= row && row < rows && !myModel.getElementAt(row).isSeparator()) { e.consume(); - myTable.changeSelection(row, 3, false, false); + myTable.changeSelection(row, (myModel.getColumnCount() - 1) / 2, false, false); } } }); - final TableColumn operationColumn = myTable.getColumnModel().getColumn(3); + final TableColumnModel columnModel = myTable.getColumnModel(); + final TableColumn operationColumn = columnModel.getColumn((columnModel.getColumnCount() - 1) / 2); operationColumn.setMaxWidth(25); operationColumn.setMinWidth(25); final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar("DirDiff", new DirDiffToolbarActions(myModel), true); diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableCellRenderer.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableCellRenderer.java index 2cb81f2ff76e..127c952f1571 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableCellRenderer.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableCellRenderer.java @@ -78,19 +78,20 @@ public class DirDiffTableCellRenderer extends DefaultTableCellRenderer { } final DirDiffOperation op = element.getOperation(); - if (column == 3) { + if (column == (table.getColumnCount() - 1) / 2) { label.setIcon(op.getIcon()); label.setHorizontalAlignment(CENTER); return label; } else { - label.setIcon(null); + label.setIcon(element.getIcon()); } Color fg = isSelected ? UIUtil.getTableSelectionForeground() : getForegroundColor(op); label.setForeground(fg); - if (column == 2 || column == 4) { + final String name = table.getColumnName(column); + if (DirDiffTableModel.COLUMN_DATE.equals(name)) { label.setHorizontalAlignment(CENTER); - } else if (column == 1 || column == 5) { + } else if (DirDiffTableModel.COLUMN_SIZE.equals(name)) { label.setHorizontalAlignment(RIGHT); label.setText(label.getText() + " "); } else { diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java index 1eff7a6d7f9c..5c9cebd83e93 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java @@ -16,6 +16,7 @@ package com.intellij.openapi.diff.impl.dir; import com.intellij.ide.diff.DiffElement; +import com.intellij.ide.diff.DirDiffSettings; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.util.containers.HashSet; @@ -29,26 +30,32 @@ import java.util.*; * @author Konstantin Bulenkov */ public class DirDiffTableModel extends AbstractTableModel { + public static final String COLUMN_NAME = "Name"; + public static final String COLUMN_SIZE = "Size"; + public static final String COLUMN_DATE = "Date"; private final Project myProject; + private final DirDiffSettings mySettings; private DiffElement mySrc; + private HashMap mySrcPaths = new HashMap(); + private HashMap myTrgPaths = new HashMap(); private DiffElement myTrg; final List myElements = new ArrayList(); - private boolean showEqual = false; - private boolean showDifferent = true; - private boolean showNewOnSource = true; - private boolean showNewOnTarget = true; - public DirDiffTableModel(Project project, DiffElement src, DiffElement trg, ProgressIndicator indicator) { + public DirDiffTableModel(Project project, DiffElement src, DiffElement trg, ProgressIndicator indicator, DirDiffSettings settings) { myProject = project; + mySettings = settings; loadModel(src, trg, indicator); } public void loadModel(DiffElement src, DiffElement trg, ProgressIndicator indicator) { mySrc = src; myTrg = trg; + scan("", src, mySrcPaths, indicator, true); + scan("", trg, myTrgPaths, indicator, true); + final HashSet files = new HashSet(); - scan("", src, files, indicator, true); - scan("", trg, files, indicator, true); + files.addAll(mySrcPaths.keySet()); + files.addAll(myTrgPaths.keySet()); final ArrayList pathes = new ArrayList(files); Collections.sort(pathes, new Comparator() { @Override @@ -77,8 +84,8 @@ public class DirDiffTableModel extends AbstractTableModel { }); for (String path : pathes) { - final DiffElement srcFile = src.findFileByRelativePath(path); - final DiffElement trgFile = trg.findFileByRelativePath(path); + final DiffElement srcFile = mySrcPaths.get(path); + final DiffElement trgFile = myTrgPaths.get(path); if (srcFile == null && trgFile != null) { myElements.add(DirDiffElement.createTargetOnly(trgFile)); } else if (srcFile != null && trgFile == null) { @@ -144,18 +151,23 @@ public class DirDiffTableModel extends AbstractTableModel { return myTrg; } - private static void scan(String prefix, DiffElement file, HashSet files, ProgressIndicator indicator, boolean isRoot) { + private static void scan(String prefix, DiffElement file, HashMap files, ProgressIndicator indicator, boolean isRoot) { if (file.isContainer()) { indicator.setText2(file.getPath()); String p = isRoot ? "" : prefix + file.getName() + "/"; if (!isRoot) { - files.add(p); + files.put(p, file); } - for (DiffElement f : file.getChildren()) { - scan(p, f, files, indicator, false); + try { + for (DiffElement f : file.getChildren()) { + scan(p, f, files, indicator, false); + } + } + catch (IOException e) { + //TODO: error message } } else { - files.add(prefix + file.getName()); + files.put(prefix + file.getName(), file); } } @@ -166,7 +178,10 @@ public class DirDiffTableModel extends AbstractTableModel { @Override public int getColumnCount() { - return 7; + int count = 3; + if (mySettings.showDate) count += 2; + if (mySettings.showSize) count += 2; + return count; } @Nullable @@ -176,25 +191,30 @@ public class DirDiffTableModel extends AbstractTableModel { if (element.isSeparator()) { return columnIndex == 0 ? element.getName() : null; } - switch (columnIndex) { - case 0: return element.getSourceName(); - case 1: return element.getSourceSize(); - case 2: return element.getSourceModificationDate(); - case 3: return ""; - case 4: return element.getTargetModificationDate(); - case 5: return element.getTargetSize(); - case 6: return element.getTargetName(); + + final String name = getColumnName(columnIndex); + boolean isSrc = columnIndex < getColumnCount() / 2; + if (name.equals(COLUMN_NAME)) { + return isSrc ? element.getSourceName() : element.getTargetName(); + } else if (name.equals(COLUMN_SIZE)) { + return isSrc ? element.getSourceSize() : element.getTargetSize(); + } else if (name.equals(COLUMN_DATE)) { + return isSrc ? element.getSourceModificationDate() : element.getTargetModificationDate(); } - return null; + return ""; } @Override public String getColumnName(int column) { + final int count = (getColumnCount() - 1) / 2; + if (column == count) return "*"; + if (column > count) { + column = getColumnCount() - 1 - column; + } switch (column) { - case 0: case 6: return "Name"; - case 1: case 5: return "Size"; - case 2: case 4: return "Date"; - case 3: return "*"; + case 0: return COLUMN_NAME; + case 1: return mySettings.showSize ? COLUMN_SIZE : COLUMN_DATE; + case 2: return COLUMN_DATE; } return ""; } @@ -204,34 +224,34 @@ public class DirDiffTableModel extends AbstractTableModel { } public boolean isShowEqual() { - return showEqual; + return mySettings.showEqual; } public void setShowEqual(boolean show) { - this.showEqual = show; + mySettings.showEqual = show; } public boolean isShowDifferent() { - return showDifferent; + return mySettings.showDifferent; } public void setShowDifferent(boolean show) { - this.showDifferent = show; + mySettings.showDifferent = show; } public boolean isShowNewOnSource() { - return showNewOnSource; + return mySettings.showNewOnSource; } public void setShowNewOnSource(boolean show) { - this.showNewOnSource = show; + mySettings.showNewOnSource = show; } public boolean isShowNewOnTarget() { - return showNewOnTarget; + return mySettings.showNewOnTarget; } public void setShowNewOnTarget(boolean show) { - this.showNewOnTarget = show; + mySettings.showNewOnTarget = show; } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/TestDirDiffAction.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/TestDirDiffAction.java index 76c3c07b64de..92112bc1043b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/TestDirDiffAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/TestDirDiffAction.java @@ -16,6 +16,7 @@ package com.intellij.openapi.diff.impl.dir; import com.intellij.ide.diff.DiffElement; +import com.intellij.ide.diff.DirDiffSettings; import com.intellij.ide.diff.VirtualFileDiffElement; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -46,7 +47,7 @@ public class TestDirDiffAction extends AnAction { DiffElement elem2 = new VirtualFileDiffElement(files2[0]); final DirDiffManager diffManager = DirDiffManager.getInstance(project); if (diffManager.canShow(elem1, elem2)) { - diffManager.showDiff(elem1, elem2); + diffManager.showDiff(elem1, elem2, new DirDiffSettings()); } } } From 53b1b4ddee493e6423c6e1e718ad7c687f94693c Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 14 Apr 2011 20:19:28 +0400 Subject: [PATCH 048/100] make big and small checked icons with respect to selection --- platform/icons/src/actions/checked.png | Bin 135 -> 235 bytes .../icons/src/actions/checked_selected.png | Bin 0 -> 234 bytes platform/icons/src/actions/checked_small.png | Bin 0 -> 135 bytes .../src/actions/checked_small_selected.png | Bin 0 -> 138 bytes .../OptionTableWithPreviewPanel.java | 1 + .../JBComboBoxTableCellEditorComponent.java | 22 ++++++++++++++---- .../src/com/intellij/util/Icons.java | 3 +++ 7 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 platform/icons/src/actions/checked_selected.png create mode 100644 platform/icons/src/actions/checked_small.png create mode 100644 platform/icons/src/actions/checked_small_selected.png diff --git a/platform/icons/src/actions/checked.png b/platform/icons/src/actions/checked.png index 366b1b532cd6ab984f9591ed3172ee1bb4659abc..0cdacea486cb9ae5b9e4e01efde54ce526cb9d98 100644 GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1Gy`CZfj;PTc9u}y0nbP0l+XkKr@T#c literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhex5FlAr-fh6C^YQc#f1eSj?H= zl&Mh1d8GEpj9Y9+Zg-X*N>(sCpsL9fI)U}bM29`y6EYPY{>XLc3qRHrn89>pedCPD i5=Z|y-0?14z|8Qlh9~cNQMNtMWCl-HKbLh*2~7YwW-R0Y diff --git a/platform/icons/src/actions/checked_selected.png b/platform/icons/src/actions/checked_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..59042e8c0308ff7d7ae958c6681567dc9c46312a GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1GJ)SO(Ar-fh{`~)M&#c+d*5i& eWx~M3!=T$MI_dDUGa*2CF?hQAxvX(sCpsL9fI)U}bM29`y6EYPY{>XLc3qRHrn89>pedCPD i5=Z|y-0?14z|8Qlh9~cNQMNtMWCl-HKbLh*2~7YwW-R0Y literal 0 HcmV?d00001 diff --git a/platform/icons/src/actions/checked_small_selected.png b/platform/icons/src/actions/checked_small_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..7911a95b4192d5fbccfb0fe0eb375b7007778b50 GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhfu1goAr-fh6C?ya{Qv(yL17>B zk%uiJUd$i872YWyyJDtr&u@*e9P>s-Jx{?EO*#sFERSMae7G4OeRrstxnTJMsbvfw mvlX7HxEb0Dd=HX&$MF7Yh}s_BT~R>889ZJ6T-G@yGywo8 Date: Thu, 14 Apr 2011 20:38:26 +0400 Subject: [PATCH 049/100] Add rules for some Grails tags. --- .../xml/util/XmlTagRuleProviderBase.java | 156 +++++++++++++++--- 1 file changed, 135 insertions(+), 21 deletions(-) diff --git a/xml/impl/src/com/intellij/xml/util/XmlTagRuleProviderBase.java b/xml/impl/src/com/intellij/xml/util/XmlTagRuleProviderBase.java index 12ec13ce9a93..c5953c453aba 100644 --- a/xml/impl/src/com/intellij/xml/util/XmlTagRuleProviderBase.java +++ b/xml/impl/src/com/intellij/xml/util/XmlTagRuleProviderBase.java @@ -19,49 +19,69 @@ import com.intellij.codeInsight.daemon.impl.analysis.InsertRequiredAttributeFix; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.codeInspection.htmlInspections.RemoveAttributeIntentionAction; import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.RoleFinder; +import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlChildRole; +import com.intellij.psi.xml.XmlElement; import com.intellij.psi.xml.XmlTag; +import com.intellij.util.ArrayUtil; import com.intellij.xml.XmlTagRuleProvider; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public abstract class XmlTagRuleProviderBase extends XmlTagRuleProvider { - public static RequireAttributeOneOf requireAttr(String ... oneOf) { - return new RequireAttributeOneOf(oneOf); - } - - public static IncompatiblesAttributeRule incompatible(String attribute, String ... excluded) { - return new IncompatiblesAttributeRule(attribute, excluded); + public static RequireAttributeOneOf requireAttr(String ... attributeNames) { + return new RequireAttributeOneOf(attributeNames); } public static ShouldHaveParams shouldHaveParams() { return new ShouldHaveParams(); } - public static class IncompatiblesAttributeRule extends Rule { - private final String[] myExcludedAttributes; - private final String myAttribute; - - public IncompatiblesAttributeRule(String attribute, String ... excluded) { - myAttribute = attribute; - myExcludedAttributes = excluded; + public static Rule unusedIfPresent(String attrPresent, String ... attrUnused) { + Effect[] effects = new Effect[attrUnused.length]; + for (int i = 0; i < effects.length; i++) { + effects[i] = unused(attrUnused[i], "The attribute '" + attrUnused[i] + "' is unused because the attribute '" + attrPresent + "' is present"); } + + return new ConditionRule(ifAttrPresent(attrPresent), effects); } - public static class ShouldHaveParams extends Rule { - @Override - public boolean needAtLeastOneAttribute(@NotNull XmlTag tag) { - return true; - } + public static Rule unusedAllIfPresent(String attrPresent, String ... attrUnused) { + return new ConditionRule(ifAttrPresent(attrPresent), + new InvalidAllExpectSome("The attribute is unused because the attribute " + attrPresent + " is present", + ProblemHighlightType.LIKE_UNUSED_SYMBOL, + ArrayUtil.append(attrUnused, attrPresent))); + } + + public static Effect invalid(String attrName, String text) { + return new InvalidAttrEffect(attrName, text, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + } + + public static Effect unused(String attrName) { + return new InvalidAttrEffect(attrName, "Attribute '" + attrName + "' is unused", ProblemHighlightType.LIKE_UNUSED_SYMBOL); + } + + public static Effect unused(String attrName, String text) { + return new InvalidAttrEffect(attrName, text, ProblemHighlightType.LIKE_UNUSED_SYMBOL); + } + + public static Effect unusedAll(String text, String... attrNames) { + return new InvalidAllExpectSome(text, ProblemHighlightType.LIKE_UNUSED_SYMBOL, attrNames); + } + + public static Rule rule(Condition condition, Effect ... effect) { + return new ConditionRule(condition, effect); } @Nullable - public static PsiElement getTagElement(RoleFinder roleFinder, XmlTag tag) { + public static PsiElement getXmlElement(RoleFinder roleFinder, XmlElement tag) { ASTNode tagNode = tag.getNode(); if (tagNode == null) return null; @@ -73,11 +93,105 @@ public abstract class XmlTagRuleProviderBase extends XmlTagRuleProvider { @Nullable public static PsiElement getTagNameElement(XmlTag tag) { - return getTagElement(XmlChildRole.START_TAG_NAME_FINDER, tag); + return getXmlElement(XmlChildRole.START_TAG_NAME_FINDER, tag); + } + + @Nullable + public static PsiElement getAttributeNameElement(XmlAttribute attribute) { + return getXmlElement(XmlChildRole.ATTRIBUTE_NAME_FINDER, attribute); } public static boolean isClosedTag(XmlTag tag) { - return getTagElement(XmlChildRole.EMPTY_TAG_END_FINDER, tag) != null || getTagElement(XmlChildRole.CLOSING_TAG_START_FINDER, tag) != null; + return getXmlElement(XmlChildRole.EMPTY_TAG_END_FINDER, tag) != null || getXmlElement(XmlChildRole.CLOSING_TAG_START_FINDER, tag) != null; + } + + public static Condition ifAttrPresent(final String attrName) { + return new Condition() { + @Override + public boolean value(XmlTag tag) { + return tag.getAttribute(attrName) != null; + } + }; + } + + // ---=== Classes ===--- + + public static abstract class Effect { + public abstract void annotate(@NotNull XmlTag tag, ProblemsHolder holder); + } + + public static class InvalidAttrEffect extends Effect { + private final String myAttrName; + private final String myText; + private final ProblemHighlightType myType; + + public InvalidAttrEffect(String attrName, String text, ProblemHighlightType type) { + myAttrName = attrName; + myText = text; + myType = type; + } + + @Override + public void annotate(@NotNull XmlTag tag, ProblemsHolder holder) { + XmlAttribute attribute = tag.getAttribute(myAttrName); + if (attribute != null) { + PsiElement attributeNameElement = getAttributeNameElement(attribute); + if (attributeNameElement != null) { + holder.registerProblem(attributeNameElement, myText, myType, new RemoveAttributeIntentionAction(myAttrName)); + } + } + } + } + + public static class InvalidAllExpectSome extends Effect { + private final String[] myAttrNames; + private final String myText; + private final ProblemHighlightType myType; + + public InvalidAllExpectSome(String text, ProblemHighlightType type, String... attrNames) { + myAttrNames = attrNames; + myText = text; + myType = type; + } + + @Override + public void annotate(@NotNull XmlTag tag, ProblemsHolder holder) { + for (XmlAttribute xmlAttribute : tag.getAttributes()) { + String attrName = xmlAttribute.getName(); + if (!ArrayUtil.contains(attrName, myAttrNames)) { + PsiElement attributeNameElement = getAttributeNameElement(xmlAttribute); + if (attributeNameElement != null) { + holder.registerProblem(attributeNameElement, myText, myType, new RemoveAttributeIntentionAction(attrName)); + } + } + } + } + } + + public static class ConditionRule extends Rule { + private final Condition myCondition; + private final Effect[] myEffect; + + public ConditionRule(Condition condition, Effect ... effect) { + this.myCondition = condition; + this.myEffect = effect; + } + + @Override + public void annotate(@NotNull XmlTag tag, ProblemsHolder holder) { + if (myCondition.value(tag)) { + for (Effect effect : myEffect) { + effect.annotate(tag, holder); + } + } + } + } + + public static class ShouldHaveParams extends Rule { + @Override + public boolean needAtLeastOneAttribute(@NotNull XmlTag tag) { + return true; + } } public static class RequireAttributeOneOf extends ShouldHaveParams { From 94aa1230cdc128ae6c54b27f46912d5849d3811e Mon Sep 17 00:00:00 2001 From: andrey zaytsev Date: Thu, 14 Apr 2011 21:16:25 +0400 Subject: [PATCH 050/100] IDEA-68093 IDEA-68128 --- .../src/com/intellij/find/FindUtil.java | 39 +++++++++---------- .../LivePreviewControllerBase.java | 22 +++++++++-- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/FindUtil.java b/platform/lang-impl/src/com/intellij/find/FindUtil.java index 15d2712b1db7..f8e5207a4dcb 100644 --- a/platform/lang-impl/src/com/intellij/find/FindUtil.java +++ b/platform/lang-impl/src/com/intellij/find/FindUtil.java @@ -96,30 +96,27 @@ public class FindUtil { } public static void configureFindModel(boolean replace, Editor editor, FindModel model) { - String selectedText = editor.getSelectionModel().getSelectedText(); - model.setReplaceState(replace); - if (selectedText != null) { - if (replace) { - if (!StringUtil.isEmpty(selectedText)) { - if (selectedText.indexOf('\n') >= 0) { - model.setGlobal(false); - } - else { - model.setStringToFind(selectedText); - model.setGlobal(true); - } - } else { - model.setGlobal(true); - } - } else { - model.setStringToFind(selectedText); - model.setGlobal(true); - } + final String selectedText = editor.getSelectionModel().getSelectedText(); - if (model.isGlobal()) { - model.setStringToFind(selectedText); + boolean isGlobal = true; + String stringToFind = null; + if (!StringUtil.isEmpty(selectedText)) { + if (selectedText.indexOf('\n') >= 0) { + if (replace){ + isGlobal = false; + stringToFind = model.getStringToFind(); + } } + if (stringToFind == null) { + stringToFind = selectedText; + } + } else { + stringToFind = model.getStringToFind(); } + + model.setReplaceState(replace); + model.setStringToFind(stringToFind); + model.setGlobal(isGlobal); model.setPromptOnReplace(false); } diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewControllerBase.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewControllerBase.java index 5a58b33cb458..874996687195 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewControllerBase.java +++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewControllerBase.java @@ -138,7 +138,9 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil myLivePreviewAlarm.cancelAllRequests(); if (findModel == null) return; final boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode(); - final FindModel copy = (FindModel)findModel.clone(); + final FindModel copy = new FindModel(); + copy.copyFrom(findModel); + final ModalityState modalityState = ModalityState.current(); Runnable request = new Runnable() { @Override @@ -219,9 +221,21 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil public void performReplaceAll(Editor e) { if (!Utils.ensureOkToWrite(e)) return; if (mySearchResults.getFindModel() != null) { - FindUtil.replace(e.getProject(), e, - mySearchResults.getFindModel().isGlobal() ? 0 : mySearchResults.getEditor().getSelectionModel().getSelectionStart(), - mySearchResults.getFindModel(), this); + final FindModel copy = new FindModel(); + copy.copyFrom(mySearchResults.getFindModel()); + + final SelectionModel selectionModel = mySearchResults.getEditor().getSelectionModel(); + + int offset; + if (selectionModel.getSelectedText() != null) { + offset = selectionModel.getSelectionStart(); + } else { + offset = 0; + copy.setGlobal(true); + } + + FindUtil.replace(e.getProject(), e, offset, copy, this); + if (myReplaceListener != null) { myReplaceListener.replaceAllPerformed(e); } From a70cf1c7ed2964ffbb25f6caab847bd550497d08 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Apr 2011 14:24:43 +0200 Subject: [PATCH 051/100] IDEA-67951 Suggest comparator type in Collections.sort() --- .../intellij/codeInsight/CodeInsightUtil.java | 15 ++++++++++----- .../NoWrongSubstitutorFromStats-out.java | 16 ++++++++++++++++ .../smartType/NoWrongSubstitutorFromStats.java | 10 ++++++++++ .../completion/SmartTypeCompletionTest.java | 7 +++++++ 4 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/NoWrongSubstitutorFromStats-out.java create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/NoWrongSubstitutorFromStats.java diff --git a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java index a3d28c1a5aa6..7b83ace2eada 100644 --- a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java @@ -302,17 +302,19 @@ public class CodeInsightUtil { return ApplicationManager.getApplication().runReadAction(new Computable() { public Boolean compute() { - if (!context.isValid() || !inheritor.isValid() || !facade.getResolveHelper().isAccessible(inheritor, context, null)) return true; + if (!context.isValid() || !inheritor.isValid() || !facade.getResolveHelper().isAccessible(inheritor, context, null)) + return true; - if(inheritor.getQualifiedName() == null && !manager.areElementsEquivalent(inheritor.getContainingFile(), context.getContainingFile().getOriginalFile())){ + if (inheritor.getQualifiedName() == null && + !manager.areElementsEquivalent(inheritor.getContainingFile(), context.getContainingFile().getOriginalFile())) { return true; } if (JavaCompletionUtil.isInExcludedPackage(inheritor)) return true; PsiSubstitutor superSubstitutor = TypeConversionUtil.getClassSubstitutor(baseClass, inheritor, PsiSubstitutor.EMPTY); - if(superSubstitutor == null) return true; - if(getRawSubtypes){ + if (superSubstitutor == null) return true; + if (getRawSubtypes) { result.add(createType(inheritor, facade.getElementFactory().createRawSubstitutor(inheritor), arrayDim)); return true; } @@ -322,7 +324,10 @@ public class CodeInsightUtil { for (PsiTypeParameter baseParameter : PsiUtil.typeParametersIterable(baseClass)) { final PsiType substituted = superSubstitutor.substitute(baseParameter); PsiType arg = baseSubstitutor.substitute(baseParameter); - if (arg instanceof PsiWildcardType) arg = ((PsiWildcardType)arg).getExtendsBound(); + if (arg instanceof PsiWildcardType) { + PsiType bound = ((PsiWildcardType)arg).getBound(); + arg = bound != null ? bound : ((PsiWildcardType)arg).getExtendsBound(); + } PsiType substitution = resolveHelper.getSubstitutionForTypeParameter(inheritorParameter, substituted, arg, diff --git a/java/java-tests/testData/codeInsight/completion/smartType/NoWrongSubstitutorFromStats-out.java b/java/java-tests/testData/codeInsight/completion/smartType/NoWrongSubstitutorFromStats-out.java new file mode 100644 index 000000000000..4f68901ba4b6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/NoWrongSubstitutorFromStats-out.java @@ -0,0 +1,16 @@ +import java.util.Comparator; +import java.util.List; +import java.util.Collections; + +public class Foo { + private List myList; + + private void sort() { + Collections.sort(myList, new Comparator() { + @Override + public int compare(String o1, String o2) { + return 0; //To change body of implemented methods use File | Settings | File Templates. + } + }); + } +} diff --git a/java/java-tests/testData/codeInsight/completion/smartType/NoWrongSubstitutorFromStats.java b/java/java-tests/testData/codeInsight/completion/smartType/NoWrongSubstitutorFromStats.java new file mode 100644 index 000000000000..0e4c7a811db3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/NoWrongSubstitutorFromStats.java @@ -0,0 +1,10 @@ +import java.util.List; +import java.util.Collections; + +public class Foo { + private List myList; + + private void sort() { + Collections.sort(myList, new Comparator); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java index 9e77c2091a63..08cd420d3ae2 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java @@ -11,6 +11,7 @@ import com.intellij.codeInsight.template.TemplateContextType; import com.intellij.codeInsight.template.TemplateManager; import com.intellij.codeInsight.template.impl.TemplateImpl; import com.intellij.codeInsight.template.impl.TemplateSettings; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.util.Condition; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; @@ -984,6 +985,12 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase { assertStringItems("Bar", "Goo"); } + public void testNoWrongSubstitutorFromStats() throws Throwable { + doTest(); + FileDocumentManager.getInstance().saveDocument(myFixture.getEditor().getDocument()); + doTest(); // stats are changed now + } + public void testCommonPrefixWithSelection() throws Throwable { doItemTest(); } From e32c7644b5a3c50df83d9283225333e43723612c Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Apr 2011 16:16:24 +0200 Subject: [PATCH 052/100] IDEA-67250 Invoke completion automatically when none of the predefined live template variants match --- .../completion/JavaAutoPopupTest.groovy | 27 +++++++++++++++++++ .../codeInsight/lookup/impl/LookupImpl.java | 9 +++++++ .../lookup/impl/LookupManagerImpl.java | 3 +++ 3 files changed, 39 insertions(+) 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 22d144e12c6e..2937be8f2913 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -19,6 +19,8 @@ import com.intellij.codeInsight.completion.impl.CompletionServiceImpl import com.intellij.codeInsight.lookup.Lookup import com.intellij.codeInsight.lookup.LookupManager import com.intellij.codeInsight.lookup.impl.LookupImpl +import com.intellij.codeInsight.template.TemplateManager +import com.intellij.codeInsight.template.impl.TemplateManagerImpl import com.intellij.ide.DataManager import com.intellij.ide.ui.UISettings import com.intellij.openapi.actionSystem.IdeActions @@ -690,4 +692,29 @@ class Foo { assert myFixture.editor.document.text.contains('foo(aaa,)') } + public void testCompletionWhenLiveTemplateAreNotSufficient() { + ((TemplateManagerImpl)TemplateManager.getInstance(getProject())).setTemplateTesting(true); + try { + myFixture.configureByText("a.java", """ + class Foo { + { + Iterable l1 = null; + Iterable l2 = null; + Object asdf = null; + iter + } + } + """) + type '\t' + assert myFixture.lookupElementStrings == ['l2', 'l1'] + type 'as' + assert lookup + assert myFixture.lookupElementStrings == ['asdf', 'assert'] + } + finally { + ((TemplateManagerImpl)TemplateManager.getInstance(getProject())).setTemplateTesting(false); + } + + } + } 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 a2775f74286b..d96a658c88fc 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 @@ -20,6 +20,7 @@ import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.completion.CompletionLookupArranger; import com.intellij.codeInsight.completion.PrefixMatcher; import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; +import com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler; import com.intellij.codeInsight.hint.HintManager; import com.intellij.codeInsight.hint.HintManagerImpl; import com.intellij.codeInsight.lookup.*; @@ -124,6 +125,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { private JLabel mySortingLabel; private final JScrollPane myScrollPane; private JButton myScrollBarIncreaseButton; + private boolean myStartCompletionWhenNothingMatches; public LookupImpl(Project project, Editor editor, @NotNull LookupArranger arranger){ super(new JPanel(new BorderLayout())); @@ -328,6 +330,13 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { myFrozenItems.clear(); refreshUi(); ensureSelectionVisible(); + if (myStartCompletionWhenNothingMatches && myList.getModel().getSize() == 1 && myList.getModel().getElementAt(0) instanceof EmptyLookupItem) { + CompletionAutoPopupHandler.scheduleAutoPopup(myProject, myEditor, getPsiFile()); + } + } + + public void setStartCompletionWhenNothingMatches(boolean startCompletionWhenNothingMatches) { + myStartCompletionWhenNothingMatches = startCompletionWhenNothingMatches; } private void ensureSelectionVisible() { 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 48c5e91d9aa6..43025279fe71 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 @@ -113,6 +113,9 @@ public class LookupManagerImpl extends LookupManager { final LookupImpl lookup = createLookup(editor, items, prefix, arranger); lookup.show(); + if (CodeInsightSettings.getInstance().AUTO_POPUP_COMPLETION_LOOKUP) { + lookup.setStartCompletionWhenNothingMatches(true); + } return lookup; } From cabb823fd2e43ad063c2cf5a553a8a3e7cfc48c5 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Apr 2011 17:30:09 +0200 Subject: [PATCH 053/100] word completion in groovy/java string literals (IDEA-61238) --- .../completion/JavaCompletionContributor.java | 28 +++++++++++++------ .../completion/word/InJavaLiterals.java | 3 ++ .../completion/word/InJavaLiterals_after.java | 3 ++ .../completion/WordCompletionTest.java | 19 +++++-------- .../GroovyCompletionContributor.java | 27 ++++++++++++++++-- .../completion/GroovyCompletionTest.groovy | 10 ++----- .../completion/GroovyCompletionTestBase.java | 14 ++++++++++ 7 files changed, 73 insertions(+), 31 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/word/InJavaLiterals.java create mode 100644 java/java-tests/testData/codeInsight/completion/word/InJavaLiterals_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index a63b81fe9e5e..6eb834e8870a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -50,10 +50,7 @@ import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.*; import static com.intellij.patterns.PsiJavaPatterns.*; @@ -198,7 +195,6 @@ public class JavaCompletionContributor extends CompletionContributor { return; } - final CompletionResultSet result = JavaCompletionSorting.addJavaSorting(parameters, _result); if (ANNOTATION_ATTRIBUTE_NAME.accepts(position)) { @@ -216,10 +212,17 @@ public class JavaCompletionContributor extends CompletionContributor { result.addElement(LookupElementBuilder.create("*")); } - addReferenceVariants(parameters, result, inheritors); + Set usedWords = addReferenceVariants(parameters, result, inheritors); addKeywords(parameters, result); + if (psiElement().inside(PsiLiteralExpression.class).accepts(position)) { + PsiReference reference = position.getContainingFile().findReferenceAt(parameters.getOffset()); + if (reference == null || reference.isSoft()) { + WordCompletionContributor.addWordCompletionVariants(result, parameters, usedWords); + } + } + addAllClasses(parameters, result, inheritors); result.stopHere(); } @@ -239,7 +242,8 @@ public class JavaCompletionContributor extends CompletionContributor { } } - private static void addReferenceVariants(final CompletionParameters parameters, CompletionResultSet result, final InheritorsHolder inheritors) { + private static Set addReferenceVariants(final CompletionParameters parameters, CompletionResultSet result, final InheritorsHolder inheritors) { + final Set usedWords = new HashSet(); final PsiElement position = parameters.getPosition(); final boolean checkAccess = parameters.getInvocationCount() <= 1; LegacyCompletionContributor.processReferences(parameters, result, new PairConsumer() { @@ -291,19 +295,25 @@ public class JavaCompletionContributor extends CompletionContributor { LOG.error("Position=" + position + "\n;Reference=" + reference + "\n;variants=" + Arrays.toString(variants)); } if (completion instanceof LookupElement && !inheritors.alreadyProcessed((LookupElement)completion)) { + usedWords.add(((LookupElement)completion).getLookupString()); result.addElement((LookupElement)completion); } else if (completion instanceof PsiClass) { if (!inheritors.alreadyProcessed((PsiClass)completion)) { - result.addElement(JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)completion, true)); + JavaPsiClassReferenceElement item = JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)completion, true); + usedWords.add(item.getLookupString()); + result.addElement(item); } } else { - result.addElement(LookupItemUtil.objectToLookupItem(completion)); + LookupElement element = LookupItemUtil.objectToLookupItem(completion); + usedWords.add(element.getLookupString()); + result.addElement(element); } } } }); + return usedWords; } private static void addKeywords(CompletionParameters parameters, CompletionResultSet result) { diff --git a/java/java-tests/testData/codeInsight/completion/word/InJavaLiterals.java b/java/java-tests/testData/codeInsight/completion/word/InJavaLiterals.java new file mode 100644 index 000000000000..49bce3236819 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/word/InJavaLiterals.java @@ -0,0 +1,3 @@ +public class MyClass { + String b = "My"; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/word/InJavaLiterals_after.java b/java/java-tests/testData/codeInsight/completion/word/InJavaLiterals_after.java new file mode 100644 index 000000000000..5a3075cdc74e --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/word/InJavaLiterals_after.java @@ -0,0 +1,3 @@ +public class MyClass { + String b = "MyClass"; +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/WordCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/WordCompletionTest.java index af12e034f247..e244c329f92f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/WordCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/WordCompletionTest.java @@ -40,17 +40,12 @@ public class WordCompletionTest extends CompletionTestCase { @Override @NotNull public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) { - return new PsiReference[]{new PsiReferenceBase(element) { + return new PsiReference[]{new PsiReferenceBase(element, true) { @Override public PsiElement resolve() { return null; } - @Override - public boolean isSoft() { - return true; - } - @Override @NotNull public Object[] getVariants() { @@ -63,17 +58,12 @@ public class WordCompletionTest extends CompletionTestCase { @Override @NotNull public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) { - return new PsiReference[]{new PsiReferenceBase(element) { + return new PsiReference[]{new PsiReferenceBase(element, false) { @Override public PsiElement resolve() { return null; } - @Override - public boolean isSoft() { - return false; - } - @Override @NotNull public Object[] getVariants() { @@ -89,6 +79,11 @@ public class WordCompletionTest extends CompletionTestCase { checkResultByFile(BASE_PATH + "3_after.java"); } + public void testInJavaLiterals() throws Exception { + configureByFile(BASE_PATH + "InJavaLiterals.java"); + checkResultByFile(BASE_PATH + "InJavaLiterals_after.java"); + } + public void testComments() throws Throwable { configureByFile(BASE_PATH + "4.java"); checkResultByFile(BASE_PATH + "4_after.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 0061f91895ba..83811bf3114a 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 @@ -39,6 +39,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Consumer; import com.intellij.util.PairConsumer; import com.intellij.util.ProcessingContext; +import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; @@ -48,6 +49,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; 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.literals.GrLiteral; 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; @@ -63,7 +65,8 @@ import static com.intellij.patterns.PlatformPatterns.psiElement; import static com.intellij.patterns.PsiJavaPatterns.elementType; import static com.intellij.util.containers.CollectionFactory.hashMap; import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*; -import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.*; +import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.SEPARATORS; +import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.WHITE_SPACES_OR_COMMENTS; /** * @author ilyas @@ -233,8 +236,7 @@ public class GroovyCompletionContributor extends CompletionContributor { } }); - - extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider() { + extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @@ -292,6 +294,25 @@ public class GroovyCompletionContributor extends CompletionContributor { } }); + extend(CompletionType.BASIC, psiElement().withParent(GrLiteral.class), new CompletionProvider() { + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull final CompletionResultSet result) { + final Set usedWords = new THashSet(); + result.runRemainingContributors(parameters, new Consumer() { + public void consume(LookupElement element) { + result.addElement(element); + usedWords.add(element.getLookupString()); + } + }); + PsiReference reference = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset()); + if (reference == null || reference.isSoft()) { + WordCompletionContributor.addWordCompletionVariants(result, parameters, usedWords); + } + } + }); + } private static void addKeywords(CompletionParameters parameters, CompletionResultSet result) { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index ef233c91590e..52d033f8335d 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -604,13 +604,6 @@ def foo(def a) {2} return foo()""" } - void checkCompletion(String before, String type, String after) { - myFixture.configureByText("a.groovy", before) - myFixture.completeBasic() - myFixture.type(type) - myFixture.checkResult(after) - } - public void testFinishClassNameWithSquareBracket() { myFixture.addClass("class AbcdClass {}; class AbcdeClass {}") checkCompletion("Abcd", '[', "AbcdClass[]") @@ -674,6 +667,9 @@ a.""") return completion.find {println it.lookupString;itemToCheck == it.lookupString} } + public void testWordCompletionInLiterals() { + checkSingleItemCompletion('def foo = "fo"', 'def foo = "foo"') + } public void testShowAccessor() { assertNotNull doContainsTest("getFoo", """ diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTestBase.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTestBase.java index b1395b7ef8f0..8ceaaa150941 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTestBase.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTestBase.java @@ -48,4 +48,18 @@ abstract public class GroovyCompletionTestBase extends LightCodeInsightFixtureTe assertNotNull(list); UsefulTestCase.assertOrderedEquals(list, variants); } + + public void checkCompletion(String before, String type, String after) { + myFixture.configureByText("a.groovy", before); + myFixture.completeBasic(); + myFixture.type(type); + myFixture.checkResult(after); + } + + public void checkSingleItemCompletion(String before, String after) { + myFixture.configureByText("a.groovy", before); + myFixture.completeBasic(); + myFixture.checkResult(after); + } + } From 868418935f1bbf093e6fd8b01d55fe3d6950dc04 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Apr 2011 17:53:05 +0200 Subject: [PATCH 054/100] don't autopopup with word suggestions in groovy/java literals --- .../completion/JavaAutoPopupTest.groovy | 7 +++ .../completion/SkipAutopopupInStrings.java | 54 +++++++++++++++++++ .../impl/providers/FileReference.java | 8 --- .../GroovyCompletionConfidence.java | 9 ++++ .../completion/GroovyAutoPopupTest.groovy | 6 +++ .../references/PropertyReferenceBase.java | 5 -- resources/src/META-INF/IdeaPlugin.xml | 1 + 7 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 platform/lang-api/src/com/intellij/codeInsight/completion/SkipAutopopupInStrings.java 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 2937be8f2913..e910b3a75524 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -717,4 +717,11 @@ class Foo { } + public void testNoWordCompletionAutoPopup() { + myFixture.configureByText "a.java", 'class Bar { void foo() { "f" }}' + type 'o' + assert !lookup + } + + } diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/SkipAutopopupInStrings.java b/platform/lang-api/src/com/intellij/codeInsight/completion/SkipAutopopupInStrings.java new file mode 100644 index 000000000000..e6eab89815c8 --- /dev/null +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/SkipAutopopupInStrings.java @@ -0,0 +1,54 @@ +/* + * 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.codeInsight.completion; + +import com.intellij.lang.LanguageParserDefinitions; +import com.intellij.lang.ParserDefinition; +import com.intellij.patterns.ElementPattern; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiUtilBase; +import com.intellij.util.ThreeState; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author peter + */ +public class SkipAutopopupInStrings extends CompletionConfidence { + @NotNull + @Override + public ThreeState shouldFocusLookup(@NotNull CompletionParameters parameters) { + return ThreeState.UNSURE; + } + + @NotNull + @Override + public ThreeState shouldSkipAutopopup(@Nullable PsiElement contextElement, @NotNull PsiFile psiFile, int offset) { + if (contextElement != null) { + ParserDefinition definition = LanguageParserDefinitions.INSTANCE.forLanguage(PsiUtilBase.getLanguageAtOffset(psiFile, offset)); + if (definition != null) { + ElementPattern pattern = PlatformPatterns.psiElement().withElementType(definition.getStringLiteralElements()); + if (pattern.accepts(contextElement) || pattern.accepts(contextElement.getParent())) { + return ThreeState.YES; + } + } + } + + return ThreeState.UNSURE; + } +} diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java index 0778acf2efb6..7a1a1ad63a57 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java @@ -16,8 +16,6 @@ package com.intellij.psi.impl.source.resolve.reference.impl.providers; -import com.intellij.codeInsight.completion.CompletionProcess; -import com.intellij.codeInsight.completion.CompletionService; import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider; import com.intellij.codeInsight.daemon.QuickFixProvider; import com.intellij.codeInsight.daemon.impl.HighlightInfo; @@ -238,12 +236,6 @@ public class FileReference implements FileReferenceOwner, PsiPolyVariantReferenc @NotNull public Object[] getVariants() { - final CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion(); - if (process != null && process.isAutopopupCompletion() && isSoft()) { - return ArrayUtil.EMPTY_OBJECT_ARRAY; - } - - final String s = getText(); if (s != null && s.equals("/")) { return ArrayUtil.EMPTY_OBJECT_ARRAY; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionConfidence.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionConfidence.java index 9a8e82fb37a4..3baa252083b6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionConfidence.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionConfidence.java @@ -14,10 +14,13 @@ package org.jetbrains.plugins.groovy.lang.completion; import com.intellij.codeInsight.completion.CompletionConfidence; import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.SkipAutopopupInStrings; import com.intellij.patterns.PsiJavaPatterns; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.util.ThreeState; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.gpp.GppTypeConverter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -61,4 +64,10 @@ public class GroovyCompletionConfidence extends CompletionConfidence { } return ThreeState.UNSURE; } + + @NotNull + @Override + public ThreeState shouldSkipAutopopup(@Nullable PsiElement contextElement, @NotNull PsiFile psiFile, int offset) { + return new SkipAutopopupInStrings().shouldSkipAutopopup(contextElement, psiFile, offset); + } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyAutoPopupTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyAutoPopupTest.groovy index b533e24f6cda..e45f0617ccbe 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyAutoPopupTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyAutoPopupTest.groovy @@ -95,4 +95,10 @@ class GroovyAutoPopupTest extends CompletionAutoPopupTestCase { assert myFixture.lookupElementStrings == [ArrayIndexOutOfBoundsException.simpleName] } + public void testNoWordCompletionAutoPopup() { + myFixture.configureByText "a.groovy", 'def foo = "f"' + type 'o' + assert !lookup + } + } diff --git a/plugins/properties/src/com/intellij/lang/properties/references/PropertyReferenceBase.java b/plugins/properties/src/com/intellij/lang/properties/references/PropertyReferenceBase.java index b81b57931a3c..1ad321d84f7a 100644 --- a/plugins/properties/src/com/intellij/lang/properties/references/PropertyReferenceBase.java +++ b/plugins/properties/src/com/intellij/lang/properties/references/PropertyReferenceBase.java @@ -182,11 +182,6 @@ public abstract class PropertyReferenceBase implements PsiPolyVariantReference, @NotNull public Object[] getVariants() { - final CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion(); - if (process != null && process.isAutopopupCompletion() && isSoft()) { - return ArrayUtil.EMPTY_OBJECT_ARRAY; - } - final Set variants = new THashSet(new TObjectHashingStrategy() { public int computeHashCode(final Object object) { if (object instanceof Property) { diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index e4cd2a2d5187..985c190de36f 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -240,6 +240,7 @@ + From b4a4ef72938d56e70a3b11df59403fb52f45b158 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Apr 2011 19:10:33 +0200 Subject: [PATCH 055/100] don't calculate grails domain return types on service initialization --- .../util/dynamicMembers/DynamicMemberUtils.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/dynamicMembers/DynamicMemberUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/dynamicMembers/DynamicMemberUtils.java index 7548e3cc7e2b..1ccfd03583a8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/dynamicMembers/DynamicMemberUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/dynamicMembers/DynamicMemberUtils.java @@ -244,8 +244,6 @@ public class DynamicMemberUtils { private static class GrDynamicMethodWithCache extends GrDynamicMethodImpl implements DynamicElement { - private PsiType myInferredReturnType; - private PsiType myReturnType; private PsiTypeParameter[] myTypeParameters; private GrParameterList myParameterList; private String[] namedParameters; @@ -254,8 +252,6 @@ public class DynamicMemberUtils { public GrDynamicMethodWithCache(GrMethod method, String source) { super(method); - myInferredReturnType = super.getInferredReturnType(); - myReturnType = super.getReturnType(); myTypeParameters = super.getTypeParameters(); myParameterList = super.getParameterList(); namedParameters = super.getNamedParametersArray(); @@ -267,16 +263,6 @@ public class DynamicMemberUtils { return myMethod.getText(); } - @Override - public PsiType getInferredReturnType() { - return myInferredReturnType; - } - - @Override - public PsiType getReturnType() { - return myReturnType; - } - @NotNull @Override public PsiTypeParameter[] getTypeParameters() { From 380ae32ce4867926c44f0bf35fdce51ee4bf5d65 Mon Sep 17 00:00:00 2001 From: sweinreuter Date: Thu, 14 Apr 2011 12:18:25 +0200 Subject: [PATCH 056/100] XmlFile.getVirtualFile() may be null here --- .../lang/xpath/xslt/impl/XsltIncludeIndex.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeIndex.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeIndex.java index a1720eca436d..d503c7d38428 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeIndex.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeIndex.java @@ -54,10 +54,15 @@ public class XsltIncludeIndex { } public static boolean processBackwardDependencies(@NotNull XmlFile file, Processor processor) { - Project project = file.getProject(); + final VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile == null) { + return true; + } + final Project project = file.getProject(); final PsiManager psiManager = PsiManager.getInstance(project); - VirtualFile[] files = FileIncludeManager.getManager(project).getIncludingFiles(file.getVirtualFile(), true); - PsiFile[] psiFiles = ContainerUtil.map2Array(files, PsiFile.class, new NullableFunction() { + + final VirtualFile[] files = FileIncludeManager.getManager(project).getIncludingFiles(virtualFile, true); + final PsiFile[] psiFiles = ContainerUtil.map2Array(files, PsiFile.class, new NullableFunction() { public PsiFile fun(VirtualFile file) { return psiManager.findFile(file); } From 9dcf89ecbbc9bba0e80e5fa900dccb787bc80c0e Mon Sep 17 00:00:00 2001 From: sweinreuter Date: Thu, 14 Apr 2011 13:13:16 +0200 Subject: [PATCH 057/100] IDEA-67497 XSLT: "Unused XML schema declaration" inspection: false positive for namespace declaration used in stylesheet object qualified name --- .../xslt/impl/references/SelfReference.java | 9 +- .../references/XsltReferenceProvider.java | 467 +++++++++--------- 2 files changed, 243 insertions(+), 233 deletions(-) diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/SelfReference.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/SelfReference.java index 600699a6f0be..26f18d257c2b 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/SelfReference.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/SelfReference.java @@ -37,7 +37,7 @@ class SelfReference implements PsiReference { myStartOffset = startOffset; } - public SelfReference(XmlAttribute element, PsiElement target) { + SelfReference(XmlAttribute element, PsiElement target) { this(element, target, 0); } @@ -79,4 +79,11 @@ class SelfReference implements PsiReference { public boolean isSoft() { return false; } + + public static SelfReference create(XmlAttribute element, PsiElement target) { + if (element.getValue().contains(":")) { + return new SelfReference(element, target, element.getValue().indexOf(':') + 1); + } + return new SelfReference(element, target); + } } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/XsltReferenceProvider.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/XsltReferenceProvider.java index 3972b2469771..e1601fa35fdb 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/XsltReferenceProvider.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/XsltReferenceProvider.java @@ -1,4 +1,3 @@ - package org.intellij.lang.xpath.xslt.impl.references; import com.intellij.javaee.ExternalResourceManager; @@ -28,258 +27,262 @@ import org.intellij.lang.xpath.xslt.util.*; import org.jetbrains.annotations.NotNull; public class XsltReferenceProvider extends PsiReferenceProvider { - private static final Key> CACHED_XSLT_REFS = Key.create("CACHED_XSLT_REFS"); + private static final Key> CACHED_XSLT_REFS = Key.create("CACHED_XSLT_REFS"); - private final CachedValuesManager myCacheManager; - private final XsltElementFactory myXsltElementFactory = XsltElementFactory.getInstance(); + private final CachedValuesManager myCacheManager; + private final XsltElementFactory myXsltElementFactory = XsltElementFactory.getInstance(); - public XsltReferenceProvider(Project project) { - myCacheManager = CachedValuesManager.getManager(project); + public XsltReferenceProvider(Project project) { + myCacheManager = CachedValuesManager.getManager(project); + } + + @NotNull + public PsiReference[] getReferencesByElement(@NotNull PsiElement e, @NotNull ProcessingContext context) { + final PsiElement element = e.getParent(); + if (element instanceof XmlAttribute) { + final XmlAttribute attribute = (XmlAttribute)element; + + CachedValue cachedValue = attribute.getUserData(CACHED_XSLT_REFS); + if (cachedValue == null) { + cachedValue = myCacheManager.createCachedValue(new ReferenceProvider(attribute), false); + attribute.putUserData(CACHED_XSLT_REFS, cachedValue); + } + + final PsiReference[] value = cachedValue.getValue(); + assert value != null; + return value; + } else { + return PsiReference.EMPTY_ARRAY; + } + } + + private class ReferenceProvider implements CachedValueProvider { + private final XmlAttribute myAttribute; + + ReferenceProvider(XmlAttribute attribute) { + myAttribute = attribute; } - @NotNull - public PsiReference[] getReferencesByElement(@NotNull PsiElement e, @NotNull ProcessingContext context) { - final PsiElement element = e.getParent(); - if (element instanceof XmlAttribute) { - final XmlAttribute attribute = (XmlAttribute)element; + public Result compute() { + final PsiReference[] referencesImpl = getReferencesImpl(myAttribute); + final Object[] refs = new PsiElement[referencesImpl.length]; + for (int i = 0; i < refs.length; i++) { + refs[i] = referencesImpl[i].getElement(); + } + return new Result(referencesImpl, ArrayUtil.append(refs, myAttribute.getValueElement())); + } - CachedValue cachedValue = attribute.getUserData(CACHED_XSLT_REFS); - if (cachedValue == null) { - cachedValue = myCacheManager.createCachedValue(new ReferenceProvider(attribute), false); - attribute.putUserData(CACHED_XSLT_REFS, cachedValue); - } + private PsiReference[] getReferencesImpl(final XmlAttribute attribute) { + final PsiReference[] psiReferences; + final XmlTag tag = attribute.getParent(); - final PsiReference[] value = cachedValue.getValue(); - assert value != null; - return value; + if (XsltSupport.isTemplateCallName(attribute)) { + psiReferences = createReferencesWithPrefix(attribute, new TemplateReference(attribute)); + } else if (XsltSupport.isTemplateCallParamName(attribute)) { + final String paramName = attribute.getValue(); + final XmlTag templateCall = PsiTreeUtil.getParentOfType(tag, XmlTag.class); + + if (templateCall != null) { + if (XsltSupport.isTemplateCall(templateCall)) { + final XsltCallTemplate call = myXsltElementFactory.wrapElement(templateCall, XsltCallTemplate.class); + final ResolveUtil.Matcher matcher = new MyParamMatcher(paramName, call); + psiReferences = new PsiReference[]{ new AttributeReference(attribute, matcher, true) }; + } else if (XsltSupport.isApplyTemplates(templateCall)) { + final XsltApplyTemplates call = myXsltElementFactory.wrapElement(templateCall, XsltApplyTemplates.class); + final ResolveUtil.Matcher matcher = new MyParamMatcher2(paramName, call); + psiReferences = new PsiReference[]{ new ParamReference(attribute, matcher) }; + } else { + psiReferences = PsiReference.EMPTY_ARRAY; + } } else { - return PsiReference.EMPTY_ARRAY; + psiReferences = PsiReference.EMPTY_ARRAY; } + } else if (XsltSupport.isParam(attribute) && isInsideUnnamedTemplate(tag)) { + final XsltParameter myParam = myXsltElementFactory.wrapElement(tag, XsltParameter.class); + psiReferences = new PsiReference[]{ new MySelfReference(attribute, myParam) }; + } else if (XsltSupport.isVariableOrParamName(attribute) || XsltSupport.isTemplateName(attribute)) { + final XsltElement myElement = myXsltElementFactory.wrapElement(tag, XsltElement.class); + psiReferences = createReferencesWithPrefix(attribute, SelfReference.create(attribute, myElement)); + } else if (XsltSupport.isFunctionName(attribute)) { + final XsltFunction myElement = myXsltElementFactory.wrapElement(tag, XsltFunction.class); + psiReferences = createReferencesWithPrefix(attribute, SelfReference.create(attribute, myElement)); + } else if (XsltSupport.isIncludeOrImportHref(attribute)) { + final String href = attribute.getValue(); + final String resourceLocation = ExternalResourceManager.getInstance().getResourceLocation(href, attribute.getProject()); + //noinspection StringEquality + if (href == resourceLocation) { + // not a configured external resource + if (!href.contains("://")) { + // a local file reference + final FileReferenceSet filereferenceset = new FileReferenceSet( + href, + attribute.getValueElement(), 1, XsltReferenceProvider.this, true); + psiReferences = filereferenceset.getAllReferences(); + } else { + // external, but unknown resource + psiReferences = new PsiReference[]{ new ExternalResourceReference(attribute) }; + } + } else { + // external, known resource + psiReferences = new PsiReference[]{ new ExternalResourceReference(attribute) }; + } + } else if (XsltSupport.isMode(attribute)) { + psiReferences = ModeReference.create(attribute, XsltSupport.isTemplate(tag, false)); + } else { + psiReferences = PsiReference.EMPTY_ARRAY; + } + + return psiReferences; } - private class ReferenceProvider implements CachedValueProvider { - private final XmlAttribute myAttribute; - - ReferenceProvider(XmlAttribute attribute) { - myAttribute = attribute; - } - - public Result compute() { - final PsiReference[] referencesImpl = getReferencesImpl(myAttribute); - final Object[] refs = new PsiElement[referencesImpl.length]; - for (int i = 0; i < refs.length; i++) { - refs[i] = referencesImpl[i].getElement(); - } - return new Result(referencesImpl, ArrayUtil.append(refs, myAttribute.getValueElement())); - } - - private PsiReference[] getReferencesImpl(final XmlAttribute attribute) { - final PsiReference[] psiReferences; - final XmlTag tag = attribute.getParent(); - - if (XsltSupport.isTemplateCallName(attribute)) { - psiReferences = new PsiReference[]{ new TemplateReference(attribute) }; - } else if (XsltSupport.isTemplateCallParamName(attribute)) { - final String paramName = attribute.getValue(); - final XmlTag templateCall = PsiTreeUtil.getParentOfType(tag, XmlTag.class); - - if (templateCall != null) { - if (XsltSupport.isTemplateCall(templateCall)) { - final XsltCallTemplate call = myXsltElementFactory.wrapElement(templateCall, XsltCallTemplate.class); - final ResolveUtil.Matcher matcher = new MyParamMatcher(paramName, call); - psiReferences = new PsiReference[]{ new AttributeReference(attribute, matcher, true) }; - } else if (XsltSupport.isApplyTemplates(templateCall)) { - final XsltApplyTemplates call = myXsltElementFactory.wrapElement(templateCall, XsltApplyTemplates.class); - final ResolveUtil.Matcher matcher = new MyParamMatcher2(paramName, call); - psiReferences = new PsiReference[]{ new ParamReference(attribute, matcher) }; - } else { - psiReferences = PsiReference.EMPTY_ARRAY; - } - } else { - psiReferences = PsiReference.EMPTY_ARRAY; - } - } else if (XsltSupport.isParam(attribute) && isInsideUnnamedTemplate(tag)) { - final XsltParameter myParam = myXsltElementFactory.wrapElement(tag, XsltParameter.class); - psiReferences = new PsiReference[]{ new MySelfReference(attribute, myParam) }; - } else if (XsltSupport.isVariableOrParamName(attribute) || XsltSupport.isTemplateName(attribute)) { - final XsltElement myElement = myXsltElementFactory.wrapElement(tag, XsltElement.class); - psiReferences = new PsiReference[]{ new SelfReference(attribute, myElement) }; - } else if (XsltSupport.isFunctionName(attribute)) { - final XsltFunction myElement = myXsltElementFactory.wrapElement(tag, XsltFunction.class); - if (attribute.getValue().contains(":")) { - psiReferences = new PsiReference[]{ new PrefixReference(attribute), new SelfReference(attribute, myElement, attribute.getValue().indexOf(':') + 1) }; - } else { - psiReferences = new PsiReference[]{ new SelfReference(attribute, myElement) }; - } - } else if (XsltSupport.isIncludeOrImportHref(attribute)) { - final String href = attribute.getValue(); - final String resourceLocation = ExternalResourceManager.getInstance().getResourceLocation(href, attribute.getProject()); - //noinspection StringEquality - if (href == resourceLocation) { - // not a configured external resource - if (href.indexOf("://") == -1) { - // a local file reference - final FileReferenceSet filereferenceset = new FileReferenceSet( - href, - attribute.getValueElement(), 1, XsltReferenceProvider.this, true); - psiReferences = filereferenceset.getAllReferences(); - } else { - // external, but unknown resource - psiReferences = new PsiReference[]{ new ExternalResourceReference(attribute) }; - } - } else { - // external, known resource - psiReferences = new PsiReference[]{ new ExternalResourceReference(attribute) }; - } - } else if (XsltSupport.isMode(attribute)) { - psiReferences = ModeReference.create(attribute, XsltSupport.isTemplate(tag, false)); - } else { - psiReferences = PsiReference.EMPTY_ARRAY; - } - - return psiReferences; - } - - private class MySelfReference extends SelfReference { - private final XsltParameter myParam; - private final XmlTag myTag; - - public MySelfReference(XmlAttribute attribute, XsltParameter param) { - super(attribute, param); - myParam = param; - myTag = param.getTag(); + private PsiReference[] createReferencesWithPrefix(XmlAttribute attribute, PsiReference reference) { + if (attribute.getValue().contains(":")) { + return new PsiReference[]{ new PrefixReference(attribute), reference }; + } else { + return new PsiReference[]{ reference }; + } } + private class MySelfReference extends SelfReference { + private final XsltParameter myParam; + private final XmlTag myTag; - public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { - if (!newElementName.equals(myParam.getName())) { - myParam.setName(newElementName); - } - final XmlAttribute attribute = myParam.getNameAttribute(); - assert attribute != null; - //noinspection ConstantConditions - return attribute.getValueElement(); - } + public MySelfReference(XmlAttribute attribute, XsltParameter param) { + super(attribute, param); + myParam = param; + myTag = param.getTag(); + } - public boolean isReferenceTo(PsiElement element) { - // self-reference is only a trick to enable rename/find usages etc. but it shouldn't actually - // refer to itself because this would list the element to be renamed/searched for twice - assert !super.isReferenceTo(element); - if (element == myParam) return false; - if (!(element instanceof XsltParameter)) return false; - - final XsltParameter param = ((XsltParameter)element); - final String name = param.getName(); - if (name == null || !name.equals(myParam.getName())) return false; - - final XsltTemplate template = XsltCodeInsightUtil.getTemplate(myTag, false); - final XsltTemplate myTemplate = XsltCodeInsightUtil.getTemplate(param.getTag(), false); - if (template == myTemplate) return true; - if (template == null || myTemplate == null) return false; - - if (!Comparing.equal(template.getMode(), myTemplate.getMode())) { - return false; - } - - final XmlFile xmlFile = (XmlFile)element.getContainingFile(); - final XmlFile myFile = (XmlFile)myParam.getContainingFile(); - if (myFile == xmlFile) return true; - - return XsltIncludeIndex.isReachableFrom(myFile, xmlFile); - } + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + if (!newElementName.equals(myParam.getName())) { + myParam.setName(newElementName); } + final XmlAttribute attribute = myParam.getNameAttribute(); + assert attribute != null; + //noinspection ConstantConditions + return attribute.getValueElement(); + } + + public boolean isReferenceTo(PsiElement element) { + // self-reference is only a trick to enable rename/find usages etc. but it shouldn't actually + // refer to itself because this would list the element to be renamed/searched for twice + assert !super.isReferenceTo(element); + + if (element == myParam) return false; + if (!(element instanceof XsltParameter)) return false; + + final XsltParameter param = ((XsltParameter)element); + final String name = param.getName(); + if (name == null || !name.equals(myParam.getName())) return false; + + final XsltTemplate template = XsltCodeInsightUtil.getTemplate(myTag, false); + final XsltTemplate myTemplate = XsltCodeInsightUtil.getTemplate(param.getTag(), false); + if (template == myTemplate) return true; + if (template == null || myTemplate == null) return false; + + if (!Comparing.equal(template.getMode(), myTemplate.getMode())) { + return false; + } + + final XmlFile xmlFile = (XmlFile)element.getContainingFile(); + final XmlFile myFile = (XmlFile)myParam.getContainingFile(); + if (myFile == xmlFile) return true; + + return XsltIncludeIndex.isReachableFrom(myFile, xmlFile); + } + } + } + + private static boolean isInsideUnnamedTemplate(XmlTag tag) { + final XmlTag t = XsltCodeInsightUtil.getTemplateTag(tag, false, false); + return t != null && t.getAttribute("name", null) == null; + } + + static class MyParamMatcher extends NamedTemplateMatcher { + private final XsltCallTemplate myCall; + private final String myParamName; + private String[] myExcludedNames = ArrayUtil.EMPTY_STRING_ARRAY; + + MyParamMatcher(String paramName, XsltCallTemplate call) { + super(XsltCodeInsightUtil.getDocument(call), call.getTemplateName()); + myCall = call; + myParamName = paramName; } - private static boolean isInsideUnnamedTemplate(XmlTag tag) { - final XmlTag t = XsltCodeInsightUtil.getTemplateTag(tag, false, false); - return t != null && t.getAttribute("name", null) == null; + private MyParamMatcher(String paramName, XsltCallTemplate call, String[] excludedNames) { + super(getDocument(call), call.getTemplateName()); + myCall = call; + myParamName = paramName; + myExcludedNames = excludedNames; } - static class MyParamMatcher extends NamedTemplateMatcher { - private final XsltCallTemplate myCall; - private final String myParamName; - private String[] myExcludedNames = ArrayUtil.EMPTY_STRING_ARRAY; - - MyParamMatcher(String paramName, XsltCallTemplate call) { - super(XsltCodeInsightUtil.getDocument(call), call.getTemplateName()); - myCall = call; - myParamName = paramName; - } - - private MyParamMatcher(String paramName, XsltCallTemplate call, String[] excludedNames) { - super(getDocument(call), call.getTemplateName()); - myCall = call; - myParamName = paramName; - myExcludedNames = excludedNames; - } - - private static XmlDocument getDocument(XsltCallTemplate call) { - final XsltTemplate template = call.getTemplate(); - return XsltCodeInsightUtil.getDocument(template != null ? template : call); - } - - @Override - protected ResolveUtil.Matcher changeDocument(XmlDocument document) { - return new MyParamMatcher(myParamName, myCall, myExcludedNames); - } - - @Override - protected Result matchImpl(XmlTag element) { - if (matches(element)) { - return Result.create(new ParamMatcher(element, myExcludedNames, myParamName)); - } - return null; - } - - @Override - public ResolveUtil.Matcher variantMatcher() { - final PsiElement[] suppliedArgs = ResolveUtil.collect(new ArgumentMatcher(myCall)); - final String[] excludedNames = new String[suppliedArgs.length]; - for (int i = 0; i < suppliedArgs.length; i++) { - excludedNames[i] = ((XmlTag)suppliedArgs[i]).getAttributeValue("name"); - } - return new MyParamMatcher(null, myCall, excludedNames); - } + private static XmlDocument getDocument(XsltCallTemplate call) { + final XsltTemplate template = call.getTemplate(); + return XsltCodeInsightUtil.getDocument(template != null ? template : call); } - static class MyParamMatcher2 extends MatchTemplateMatcher { - private final String myParamName; - private final XsltApplyTemplates myCall; - private String[] myExcludedNames = ArrayUtil.EMPTY_STRING_ARRAY; - - MyParamMatcher2(String paramName, XsltApplyTemplates call) { - super(XsltCodeInsightUtil.getDocument(call), call.getMode()); - myParamName = paramName; - myCall = call; - } - - private MyParamMatcher2(String paramName, XsltApplyTemplates call, String[] excludedNames) { - this(paramName, call); - myExcludedNames = excludedNames; - } - - @Override - protected Result matchImpl(XmlTag element) { - if (matches(element)) { - return Result.create(new ParamMatcher(element, myExcludedNames, myParamName)); - } - return null; - } - - @Override - protected ResolveUtil.Matcher changeDocument(XmlDocument document) { - return new MyParamMatcher2(myParamName, myCall); - } - - @Override - public ResolveUtil.Matcher variantMatcher() { - final PsiElement[] suppliedArgs = ResolveUtil.collect(new ArgumentMatcher(myCall)); - final String[] excludedNames = new String[suppliedArgs.length]; - for (int i = 0; i < suppliedArgs.length; i++) { - excludedNames[i] = ((XmlTag)suppliedArgs[i]).getAttributeValue("name"); - } - return new MyParamMatcher2(null, myCall, excludedNames); - } + @Override + protected ResolveUtil.Matcher changeDocument(XmlDocument document) { + return new MyParamMatcher(myParamName, myCall, myExcludedNames); } + + @Override + protected Result matchImpl(XmlTag element) { + if (matches(element)) { + return Result.create(new ParamMatcher(element, myExcludedNames, myParamName)); + } + return null; + } + + @Override + public ResolveUtil.Matcher variantMatcher() { + final PsiElement[] suppliedArgs = ResolveUtil.collect(new ArgumentMatcher(myCall)); + final String[] excludedNames = new String[suppliedArgs.length]; + for (int i = 0; i < suppliedArgs.length; i++) { + excludedNames[i] = ((XmlTag)suppliedArgs[i]).getAttributeValue("name"); + } + return new MyParamMatcher(null, myCall, excludedNames); + } + } + + static class MyParamMatcher2 extends MatchTemplateMatcher { + private final String myParamName; + private final XsltApplyTemplates myCall; + private String[] myExcludedNames = ArrayUtil.EMPTY_STRING_ARRAY; + + MyParamMatcher2(String paramName, XsltApplyTemplates call) { + super(XsltCodeInsightUtil.getDocument(call), call.getMode()); + myParamName = paramName; + myCall = call; + } + + private MyParamMatcher2(String paramName, XsltApplyTemplates call, String[] excludedNames) { + this(paramName, call); + myExcludedNames = excludedNames; + } + + @Override + protected Result matchImpl(XmlTag element) { + if (matches(element)) { + return Result.create(new ParamMatcher(element, myExcludedNames, myParamName)); + } + return null; + } + + @Override + protected ResolveUtil.Matcher changeDocument(XmlDocument document) { + return new MyParamMatcher2(myParamName, myCall); + } + + @Override + public ResolveUtil.Matcher variantMatcher() { + final PsiElement[] suppliedArgs = ResolveUtil.collect(new ArgumentMatcher(myCall)); + final String[] excludedNames = new String[suppliedArgs.length]; + for (int i = 0; i < suppliedArgs.length; i++) { + excludedNames[i] = ((XmlTag)suppliedArgs[i]).getAttributeValue("name"); + } + return new MyParamMatcher2(null, myCall, excludedNames); + } + } } From 8d77cdf1b3f7f22c46e5854d4737499a61f4dfc3 Mon Sep 17 00:00:00 2001 From: sweinreuter Date: Thu, 14 Apr 2011 13:29:08 +0200 Subject: [PATCH 058/100] IDEA-66799: Explicit conversion to any-type isn't safe to be removed --- .../xpath/validation/inspections/RedundantTypeConversion.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/validation/inspections/RedundantTypeConversion.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/validation/inspections/RedundantTypeConversion.java index c161de532549..6071f2678299 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/validation/inspections/RedundantTypeConversion.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/validation/inspections/RedundantTypeConversion.java @@ -36,7 +36,7 @@ public class RedundantTypeConversion extends XPathInspection { @NonNls private static final String SHORT_NAME = "RedundantTypeConversion"; - public boolean CHECK_ANY = true; + public boolean CHECK_ANY = false; @NotNull public String getDisplayName() { @@ -46,7 +46,7 @@ public class RedundantTypeConversion extends XPathInspection { @NotNull @NonNls public String getShortName() { - return RedundantTypeConversion.SHORT_NAME; + return SHORT_NAME; } public boolean isEnabledByDefault() { From c90e6736993bfeb399eb31be01507a568638934b Mon Sep 17 00:00:00 2001 From: sweinreuter Date: Thu, 14 Apr 2011 13:29:37 +0200 Subject: [PATCH 059/100] IDEA-67497 XSLT: "Unused XML schema declaration" inspection: false positive for namespace declaration used in stylesheet object qualified name --- .../intellij/lang/xpath/xslt/XsltHighlightingTest.java | 8 ++++++++ .../testData/xslt/highlighting/templateWithPrefix.xsl | 7 +++++++ 2 files changed, 15 insertions(+) create mode 100644 plugins/xpath/xpath-lang/testData/xslt/highlighting/templateWithPrefix.xsl diff --git a/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltHighlightingTest.java b/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltHighlightingTest.java index 9b003072ccca..2db116f6d1be 100644 --- a/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltHighlightingTest.java +++ b/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltHighlightingTest.java @@ -15,6 +15,8 @@ */ package org.intellij.lang.xpath.xslt; +import com.intellij.codeInsight.daemon.impl.analysis.XmlUnusedNamespaceInspection; +import com.intellij.javaee.ExternalResourceManagerEx; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; @@ -34,6 +36,7 @@ public class XsltHighlightingTest extends TestBase { protected void setUp() throws Exception { super.setUp(); myFixture.enableInspections(XsltStuffProvider.INSPECTION_CLASSES); + ExternalResourceManagerEx.getInstanceEx().addIgnoredResource("urn:my"); } public void xtestBackwardIncludedVariable() throws Throwable { @@ -112,6 +115,11 @@ public class XsltHighlightingTest extends TestBase { doXsltHighlighting(); } + public void testTemplateWithPrefix() throws Throwable { + myFixture.enableInspections(XmlUnusedNamespaceInspection.class); + doXsltHighlighting(); + } + public void xtestPerformance() throws Throwable { myFixture.configureByFile(getTestFileName() + ".xsl"); final long l = runHighlighting(); diff --git a/plugins/xpath/xpath-lang/testData/xslt/highlighting/templateWithPrefix.xsl b/plugins/xpath/xpath-lang/testData/xslt/highlighting/templateWithPrefix.xsl new file mode 100644 index 000000000000..f7db1f52d7b7 --- /dev/null +++ b/plugins/xpath/xpath-lang/testData/xslt/highlighting/templateWithPrefix.xsl @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file From 32ee3ea91adfc818f6ec2fb2cfe5f99deb32d59f Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 14 Apr 2011 17:52:34 +0200 Subject: [PATCH 060/100] StringBuffer->StringBuilder --- .../debugger/ui/impl/DebuggerTreeBase.java | 56 +++++++++---------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeBase.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeBase.java index 5c8578e6bbf3..c5f730109d16 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeBase.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeBase.java @@ -345,43 +345,37 @@ public class DebuggerTreeBase extends DnDAwareTree implements Disposable { if (tabSize < 0) { tabSize = 0; } - final StringBuffer buf = new StringBuffer(); - try { - boolean special = false; - for (int idx = 0; idx < text.length(); idx++) { - char c = text.charAt(idx); - if (special) { - if (c == 't') { // convert tabs to spaces - for (int i = 0; i < tabSize; i++) { - buf.append(' '); - } + final StringBuilder buf = new StringBuilder(); + boolean special = false; + for (int idx = 0; idx < text.length(); idx++) { + char c = text.charAt(idx); + if (special) { + if (c == 't') { // convert tabs to spaces + for (int i = 0; i < tabSize; i++) { + buf.append(' '); } - else if (c == 'r') { // remove occurrences of '\r' - } - else if (c == 'n') { - buf.append('\n'); - } - else { - buf.append('\\'); - buf.append(c); - } - special = false; + } + else if (c == 'r') { // remove occurrences of '\r' + } + else if (c == 'n') { + buf.append('\n'); } else { - if (c == '\\') { - special = true; - } - else { - buf.append(c); - } + buf.append('\\'); + buf.append(c); + } + special = false; + } + else { + if (c == '\\') { + special = true; + } + else { + buf.append(c); } } - - return buf.toString(); - } - finally { - } + return buf.toString(); } public void dispose() { From b1a50f79fa664d74721165f2eace1f31d16a39ca Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 14 Apr 2011 19:47:21 +0200 Subject: [PATCH 061/100] fix dumb-mode race condition on startup (IDEA-67563) --- .../codeInsight/daemon/DaemonAnalyzerTestCase.java | 6 ++++-- .../com/intellij/ide/startup/impl/StartupManagerImpl.java | 5 ++--- .../intellij/openapi/project/impl/ProjectManagerImpl.java | 4 +++- .../com/intellij/testFramework/LightPlatformTestCase.java | 4 +++- .../src/com/intellij/testFramework/PlatformTestCase.java | 7 +++++-- .../fixtures/impl/HeavyIdeaTestFixtureImpl.java | 1 + 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java index 08daa1cc75a4..1ce2f15b1870 100644 --- a/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java @@ -169,8 +169,10 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase { DaemonCodeAnalyzerImpl daemonCodeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject()); toInitializeDaemon = !daemonCodeAnalyzer.isInitialized(); daemonCodeAnalyzer.prepareForTest(toInitializeDaemon); - ((StartupManagerImpl)StartupManagerEx.getInstanceEx(getProject())).runStartupActivities(); - ((StartupManagerImpl)StartupManagerEx.getInstanceEx(getProject())).runPostStartupActivities(); + final StartupManagerImpl startupManager = (StartupManagerImpl)StartupManagerEx.getInstanceEx(getProject()); + startupManager.runStartupActivities(); + startupManager.startCacheUpdate(); + startupManager.runPostStartupActivities(); DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false); if (isPerformanceTest()) { diff --git a/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java index 73ce114153d3..efbad4ccb6d0 100644 --- a/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java @@ -117,7 +117,6 @@ public class StartupManagerImpl extends StartupManagerEx { myStartupActivitiesRunning = false; - startCacheUpdate(); myStartupActivitiesPassed = true; } finally { @@ -170,9 +169,9 @@ public class StartupManagerImpl extends StartupManagerEx { Registry.get("ide.firstStartup").setValue(false); } - private void startCacheUpdate() { + public void startCacheUpdate() { try { - DumbServiceImpl.getInstance(myProject).queueCacheUpdate(myCacheUpdaters); + DumbServiceImpl.getInstance(myProject).queueCacheUpdateInDumbMode(myCacheUpdaters); } catch (ProcessCanceledException e) { throw e; diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java index f56995801a68..23de8bec50d7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -391,7 +391,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt notifyProjectOpenFailed(); return false; } - + + startupManager.startCacheUpdate(); + startupManager.runPostStartupActivities(); if (!ApplicationManager.getApplication().isHeadlessEnvironment() && !ApplicationManager.getApplication().isUnitTestMode()) { diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java index 635712957238..ebaec0f6a621 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java @@ -300,7 +300,9 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da }); - ((StartupManagerImpl)StartupManager.getInstance(ourProject)).runStartupActivities(); + final StartupManagerImpl startupManager = (StartupManagerImpl)StartupManager.getInstance(ourProject); + startupManager.runStartupActivities(); + startupManager.startCacheUpdate(); } }.execute().throwException(); } diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 53c481f95d52..20a8b74833ee 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -234,8 +234,10 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } protected void runStartupActivities() { - ((StartupManagerImpl)StartupManager.getInstance(myProject)).runStartupActivities(); - ((StartupManagerImpl)StartupManager.getInstance(myProject)).runPostStartupActivities(); + final StartupManagerImpl startupManager = (StartupManagerImpl)StartupManager.getInstance(myProject); + startupManager.runStartupActivities(); + startupManager.startCacheUpdate(); + startupManager.runPostStartupActivities(); } protected File getIprFile() throws IOException { @@ -448,6 +450,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro mm.projectOpened(); setUpJdk(); sm.runStartupActivities(); + sm.startCacheUpdate(); // extra init for libraries sm.runPostStartupActivities(); } diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java index fa619fa3e76d..ede3db26db1b 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java @@ -157,6 +157,7 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu StartupManagerImpl sm = (StartupManagerImpl)StartupManager.getInstance(myProject); sm.runStartupActivities(); + sm.startCacheUpdate(); sm.runPostStartupActivities(); ProjectManagerEx.getInstanceEx().setCurrentTestProject(myProject); From f85c93ff064dfa9ca046e6ac20090530b46fd589 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 14 Apr 2011 20:06:14 +0200 Subject: [PATCH 062/100] Move Member conflict analysis delegated into handler --- .../codeInsight/ChangeContextUtil.java | 25 +-- .../moveMembers/MoveJavaMemberHandler.java | 152 +++++++++++++--- .../move/moveMembers/MoveMemberHandler.java | 44 +++-- .../moveMembers/MoveMembersProcessor.java | 170 +++++++----------- .../util/RefactoringConflictsUtil.java | 143 +++++++++------ .../move/MoveGroovyMemberHandler.java | 83 +++------ 6 files changed, 337 insertions(+), 280 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/ChangeContextUtil.java b/java/java-impl/src/com/intellij/codeInsight/ChangeContextUtil.java index be7b52124491..cc5ccf8441c5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ChangeContextUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/ChangeContextUtil.java @@ -1,4 +1,3 @@ - /* * Copyright 2000-2009 JetBrains s.r.o. * @@ -24,6 +23,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.util.FieldConflictsResolver; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class ChangeContextUtil { @@ -112,28 +112,28 @@ public class ChangeContextUtil { } } - public static PsiElement decodeContextInfo(PsiElement scope, - PsiClass thisClass, + public static PsiElement decodeContextInfo(@NotNull PsiElement scope, + @Nullable PsiClass thisClass, @Nullable PsiExpression thisAccessExpr) throws IncorrectOperationException { - if (scope.getCopyableUserData(ENCODED_KEY) != null){ + if (scope.getCopyableUserData(ENCODED_KEY) != null) { scope.putCopyableUserData(ENCODED_KEY, null); - if (scope instanceof PsiThisExpression){ + if (scope instanceof PsiThisExpression) { PsiThisExpression thisExpr = (PsiThisExpression)scope; scope = decodeThisExpression(thisExpr, thisClass, thisAccessExpr); } - else if (scope instanceof PsiReferenceExpression){ + else if (scope instanceof PsiReferenceExpression) { scope = decodeReferenceExpression((PsiReferenceExpression)scope, thisAccessExpr, thisClass); } else { PsiClass refClass = scope.getCopyableUserData(REF_CLASS_KEY); scope.putCopyableUserData(REF_CLASS_KEY, null); - if (refClass != null && refClass.isValid()){ + if (refClass != null && refClass.isValid()) { PsiReference ref = scope.getReference(); if (ref != null) { final String qualifiedName = refClass.getQualifiedName(); - if (qualifiedName != null){ + if (qualifiedName != null) { if (JavaPsiFacade.getInstance(refClass.getProject()).findClass(qualifiedName, scope.getResolveScope()) != null) { scope = ref.bindToElement(refClass); } @@ -143,14 +143,15 @@ public class ChangeContextUtil { } } - if (scope instanceof PsiClass){ - if (thisAccessExpr != null){ + if (scope instanceof PsiClass) { + if (thisAccessExpr != null) { thisAccessExpr = (PsiExpression)qualifyThis(thisAccessExpr, thisClass); } } - for(PsiElement child = scope.getFirstChild(); child != null; child = child.getNextSibling()){ - child = decodeContextInfo(child, thisClass, thisAccessExpr); + PsiElement child = scope.getFirstChild(); + while (child != null) { + child = decodeContextInfo(child, thisClass, thisAccessExpr).getNextSibling(); } return scope; diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java index 5f0ba5be7c99..41182af7d128 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java @@ -16,16 +16,21 @@ package com.intellij.refactoring.move.moveMembers; import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector; import com.intellij.psi.*; +import com.intellij.psi.impl.source.resolve.JavaResolveUtil; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.MethodSignatureUtil; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiUtilBase; -import com.intellij.refactoring.util.EnumConstantsUtil; -import com.intellij.refactoring.util.RefactoringHierarchyUtil; -import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.util.*; import com.intellij.util.IncorrectOperationException; import com.intellij.util.VisibilityUtil; +import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -33,12 +38,13 @@ import java.util.*; /** * @author Maxim.Medvedev */ - public class MoveJavaMemberHandler implements MoveMemberHandler { - public MoveMembersProcessor.MoveMembersUsageInfo getUsage(PsiMember member, - PsiReference psiReference, - Set membersToMove, - PsiClass targetClass) { + @Override + @Nullable + public MoveMembersProcessor.MoveMembersUsageInfo getUsage(@NotNull PsiMember member, + @NotNull PsiReference psiReference, + @NotNull Set membersToMove, + @NotNull PsiClass targetClass) { PsiElement ref = psiReference.getElement(); if (ref instanceof PsiReferenceExpression) { PsiReferenceExpression refExpr = (PsiReferenceExpression)ref; @@ -70,15 +76,102 @@ public class MoveJavaMemberHandler implements MoveMemberHandler { return null; } - private static boolean isInMovedElement(PsiElement element, Set membersToMove) { + protected static boolean isInMovedElement(PsiElement element, Set membersToMove) { for (PsiMember member : membersToMove) { if (PsiTreeUtil.isAncestor(member, element, false)) return true; } return false; } - public boolean changeExternalUsage(MoveMembersOptions options, MoveMembersProcessor.MoveMembersUsageInfo usage) { - if (!usage.getElement().isValid()) return true; + @Override + public void checkConflictsOnUsage(@NotNull MoveMembersProcessor.MoveMembersUsageInfo usageInfo, + @Nullable String newVisibility, + @Nullable PsiModifierList modifierListCopy, + @NotNull PsiClass targetClass, + @NotNull Set membersToMove, + @NotNull MultiMap conflicts) { + final PsiElement element = usageInfo.getElement(); + if (element == null) return; + + final PsiMember member = usageInfo.member; + if (element instanceof PsiReferenceExpression) { + PsiExpression qualifier = ((PsiReferenceExpression)element).getQualifierExpression(); + PsiClass accessObjectClass = null; + if (qualifier != null) { + accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement(); + } + + if (!JavaResolveUtil.isAccessible(member, targetClass, modifierListCopy, element, accessObjectClass, null)) { + String visibility = newVisibility != null ? newVisibility : VisibilityUtil.getVisibilityStringToDisplay(member); + String message = RefactoringBundle.message("0.with.1.visibility.is.not.accessible.from.2", + RefactoringUIUtil.getDescription(member, false), + visibility, + RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true)); + conflicts.putValue(member, CommonRefactoringUtil.capitalize(message)); + } + } + + if (member instanceof PsiField && targetClass.isInterface()) { + ReadWriteAccessDetector accessDetector = ReadWriteAccessDetector.findDetector(member); + if (accessDetector != null) { + ReadWriteAccessDetector.Access access = accessDetector.getExpressionAccess(element); + if (access != ReadWriteAccessDetector.Access.Read) { + String message = RefactoringUIUtil.getDescription(member, true) + " has write access but is moved to an interface"; + conflicts.putValue(element, CommonRefactoringUtil.capitalize(message)); + } + } + } + + final PsiReference reference = usageInfo.getReference(); + if (reference != null) { + RefactoringConflictsUtil.checkAccessibilityConflicts(reference, member, modifierListCopy, targetClass, membersToMove, conflicts); + } + } + + @Override + public void checkConflictsOnMember(@NotNull PsiMember member, + @Nullable String newVisibility, + @Nullable PsiModifierList modifierListCopy, + @NotNull PsiClass targetClass, + @NotNull Set membersToMove, + @NotNull MultiMap conflicts) { + if (member instanceof PsiMethod && hasMethod(targetClass, (PsiMethod)member) || + member instanceof PsiField && hasField(targetClass, (PsiField)member)) { + String message = RefactoringBundle.message("0.already.exists.in.the.target.class", RefactoringUIUtil.getDescription(member, false)); + conflicts.putValue(member, CommonRefactoringUtil.capitalize(message)); + } + + RefactoringConflictsUtil.checkUsedElements(member, member, membersToMove, null, targetClass, targetClass, conflicts); + } + + protected static boolean hasMethod(PsiClass targetClass, PsiMethod method) { + PsiMethod[] targetClassMethods = targetClass.getMethods(); + for (PsiMethod candidate : targetClassMethods) { + if (candidate != method && + MethodSignatureUtil.areSignaturesEqual(method.getSignature(PsiSubstitutor.EMPTY), + candidate.getSignature(PsiSubstitutor.EMPTY))) { + return true; + } + } + return false; + } + + protected static boolean hasField(PsiClass targetClass, PsiField field) { + String fieldName = field.getName(); + PsiField[] targetClassFields = targetClass.getFields(); + for (PsiField candidate : targetClassFields) { + if (candidate != field && + fieldName.equals(candidate.getName())) { + return true; + } + } + return false; + } + + @Override + public boolean changeExternalUsage(@NotNull MoveMembersOptions options, @NotNull MoveMembersProcessor.MoveMembersUsageInfo usage) { + final PsiElement element = usage.getElement(); + if (element == null || !element.isValid()) return true; if (usage.reference instanceof PsiReferenceExpression) { PsiReferenceExpression refExpr = (PsiReferenceExpression)usage.reference; @@ -101,14 +194,24 @@ public class MoveJavaMemberHandler implements MoveMemberHandler { return false; } - public PsiMember doMove(MoveMembersOptions options, PsiMember member, PsiElement anchor, PsiClass targetClass) { + protected static void changeQualifier(PsiReferenceExpression refExpr, PsiClass aClass, PsiMember member) throws IncorrectOperationException { + if (RefactoringUtil.hasOnDemandStaticImport(refExpr, aClass)) { + refExpr.setQualifierExpression(null); + } + else if (!RefactoringUtil.hasStaticImportOn(refExpr, member)){ + PsiElementFactory factory = JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory(); + refExpr.setQualifierExpression(factory.createReferenceExpression(aClass)); + } + } + + @Override + @NotNull + public PsiMember doMove(@NotNull MoveMembersOptions options, @NotNull PsiMember member, PsiElement anchor, @NotNull PsiClass targetClass) { if (member instanceof PsiVariable) { ((PsiVariable)member).normalizeDeclaration(); } ChangeContextUtil.encodeContextInfo(member, true); - if (targetClass == null) return null; - final PsiMember memberCopy; if (options.makeEnumConstant() && @@ -118,8 +221,9 @@ public class MoveJavaMemberHandler implements MoveMemberHandler { } else { memberCopy = (PsiMember)member.copy(); - if (member.getContainingClass().isInterface() && !targetClass.isInterface()) { - //might need to make modifiers explicit, see IDEADEV-11416 + final PsiClass containingClass = member.getContainingClass(); + if (containingClass != null && containingClass.isInterface() && !targetClass.isInterface()) { + // might need to make modifiers explicit, see IDEADEV-11416 final PsiModifierList list = memberCopy.getModifierList(); assert list != null; list.setModifierProperty(PsiModifier.STATIC, member.hasModifierProperty(PsiModifier.STATIC)); @@ -131,22 +235,14 @@ public class MoveJavaMemberHandler implements MoveMemberHandler { return anchor != null ? (PsiMember)targetClass.addAfter(memberCopy, anchor) : (PsiMember)targetClass.add(memberCopy); } - public void decodeContextInfo(PsiElement scope) { + @Override + public void decodeContextInfo(@NotNull PsiElement scope) { ChangeContextUtil.decodeContextInfo(scope, null, null); } - private static void changeQualifier(PsiReferenceExpression refExpr, PsiClass aClass, PsiMember member) throws IncorrectOperationException { - if (RefactoringUtil.hasOnDemandStaticImport(refExpr, aClass)) { - refExpr.setQualifierExpression(null); - } - else if (!RefactoringUtil.hasStaticImportOn(refExpr, member)){ - PsiElementFactory factory = JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory(); - refExpr.setQualifierExpression(factory.createReferenceExpression(aClass)); - } - } - + @Override @Nullable - public PsiElement getAnchor(final PsiMember member, final PsiClass targetClass) { + public PsiElement getAnchor(@NotNull final PsiMember member, @NotNull final PsiClass targetClass) { if (member instanceof PsiField && member.hasModifierProperty(PsiModifier.STATIC)) { final List afterFields = new ArrayList(); final PsiExpression psiExpression = ((PsiField)member).getInitializer(); diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMemberHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMemberHandler.java index 0200f83e5194..ce028217ec3e 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMemberHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMemberHandler.java @@ -16,10 +16,9 @@ package com.intellij.refactoring.move.moveMembers; import com.intellij.lang.LanguageExtension; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiMember; -import com.intellij.psi.PsiReference; +import com.intellij.psi.*; +import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Set; @@ -30,17 +29,36 @@ import java.util.Set; public interface MoveMemberHandler { LanguageExtension EP_NAME = new LanguageExtension("com.intellij.refactoring.moveMemberHandler"); - MoveMembersProcessor.MoveMembersUsageInfo getUsage(PsiMember member, - PsiReference ref, - Set membersToMove, - PsiClass targetClass); + @Nullable + MoveMembersProcessor.MoveMembersUsageInfo getUsage(@NotNull PsiMember member, + @NotNull PsiReference ref, + @NotNull Set membersToMove, + @NotNull PsiClass targetClass); - boolean changeExternalUsage(MoveMembersOptions options, MoveMembersProcessor.MoveMembersUsageInfo usage); + void checkConflictsOnUsage(@NotNull MoveMembersProcessor.MoveMembersUsageInfo usageInfo, + @Nullable String newVisibility, + @Nullable PsiModifierList modifierListCopy, + @NotNull PsiClass targetClass, + @NotNull Set membersToMove, + @NotNull MultiMap conflicts); - PsiMember doMove(MoveMembersOptions options, PsiMember member, PsiElement anchor, PsiClass targetClass); - - void decodeContextInfo(PsiElement scope); + void checkConflictsOnMember(@NotNull PsiMember member, + @Nullable String newVisibility, + @Nullable PsiModifierList modifierListCopy, + @NotNull PsiClass targetClass, + @NotNull Set membersToMove, + @NotNull MultiMap conflicts); @Nullable - PsiElement getAnchor(PsiMember member, PsiClass targetClass); + PsiElement getAnchor(@NotNull PsiMember member, @NotNull PsiClass targetClass); + + boolean changeExternalUsage(@NotNull MoveMembersOptions options, @NotNull MoveMembersProcessor.MoveMembersUsageInfo usage); + + @NotNull + PsiMember doMove(@NotNull MoveMembersOptions options, + @NotNull PsiMember member, + @Nullable PsiElement anchor, + @NotNull PsiClass targetClass); + + void decodeContextInfo(@NotNull PsiElement scope); } diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java index 5560118bd8f2..6dfaa8e2c303 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java @@ -15,17 +15,13 @@ */ package com.intellij.refactoring.move.moveMembers; -import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; -import com.intellij.psi.impl.source.resolve.JavaResolveUtil; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; -import com.intellij.psi.util.MethodSignatureUtil; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.HelpID; @@ -34,7 +30,9 @@ import com.intellij.refactoring.listeners.RefactoringElementListener; import com.intellij.refactoring.move.MoveCallback; import com.intellij.refactoring.move.MoveHandler; import com.intellij.refactoring.move.MoveMemberViewDescriptor; -import com.intellij.refactoring.util.*; +import com.intellij.refactoring.util.CommonRefactoringUtil; +import com.intellij.refactoring.util.MoveRenameUsageInfo; +import com.intellij.refactoring.util.RefactoringConflictsUtil; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; import com.intellij.usageView.UsageViewUtil; @@ -44,6 +42,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -61,16 +60,16 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor { private String myCommandName = MoveMembersImpl.REFACTORING_NAME; private MoveMembersOptions myOptions; - public MoveMembersProcessor(Project project, MoveCallback moveCallback, MoveMembersOptions options) { + public MoveMembersProcessor(Project project, MoveMembersOptions options) { + this(project, null, options); + } + + public MoveMembersProcessor(Project project, @Nullable MoveCallback moveCallback, MoveMembersOptions options) { super(project); myMoveCallback = moveCallback; setOptions(options); } - public MoveMembersProcessor(Project project, MoveMembersOptions options) { - this(project, null, options); - } - protected String getCommandName() { return myCommandName; } @@ -152,10 +151,11 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor { protected void performRefactoring(final UsageInfo[] usages) { try { - // correct references to moved members from the outside PsiClass targetClass = JavaPsiFacade.getInstance(myProject).findClass(myOptions.getTargetClassName(), GlobalSearchScope.projectScope(myProject)); if (targetClass == null) return; + + // collect anchors to place moved members at final Map anchors = new HashMap(); for (PsiMember member : myMembersToMove) { final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(member.getLanguage()); @@ -163,12 +163,14 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor { anchors.put(member, handler.getAnchor(member, targetClass)); } } + + // correct references to moved members from the outside ArrayList otherUsages = new ArrayList(); for (UsageInfo usageInfo : usages) { MoveMembersUsageInfo usage = (MoveMembersUsageInfo)usageInfo; if (!usage.reference.isValid()) continue; final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(usageInfo.getElement().getLanguage()); - if (handler!=null) { + if (handler != null) { if (handler.changeExternalUsage(myOptions, usage)) continue; } otherUsages.add(usage); @@ -190,7 +192,7 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor { final RefactoringElementListener elementListener = getTransaction().getElementListener(member); final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(member.getLanguage()); if (handler != null) { - PsiMember newMember=handler.doMove(myOptions, member, anchors.get(member), targetClass); + PsiMember newMember = handler.doMove(myOptions, member, anchors.get(member), targetClass); elementListener.elementMoved(newMember); fixModifierList(newMember, usages); @@ -201,7 +203,6 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor { } // qualifier info must be decoded after members are moved - //ChangeContextUtil.decodeContextInfo(myTargetClass, null, null); final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(myTargetClass.getLanguage()); if (handler != null) handler.decodeContextInfo(myTargetClass); @@ -236,65 +237,63 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor { protected boolean preprocessUsages(Ref refUsages) { final MultiMap conflicts = new MultiMap(); final UsageInfo[] usages = refUsages.get(); - try { - addInaccessibleConflicts(conflicts, usages); - } - catch (IncorrectOperationException e) { - LOG.error(e); - } - analyzeMoveConflicts(myMembersToMove, myTargetClass, myNewVisibility, conflicts); - RefactoringConflictsUtil.analyzeModuleConflicts(myProject, myMembersToMove, usages, myTargetClass, conflicts); - return showConflicts(conflicts, usages); - } - private void addInaccessibleConflicts(final MultiMap conflicts, final UsageInfo[] usages) throws IncorrectOperationException { String newVisibility = myNewVisibility; - if (VisibilityUtil.ESCALATE_VISIBILITY.equals(newVisibility)) { //Still need to check for access object + if (VisibilityUtil.ESCALATE_VISIBILITY.equals(newVisibility)) { // still need to check for access object newVisibility = PsiModifier.PUBLIC; } - Map modifierListCopies = new HashMap(); + final Map modifierListCopies = new HashMap(); for (PsiMember member : myMembersToMove) { - PsiModifierList copy = member.getModifierList(); - if (copy != null) copy = (PsiModifierList)copy.copy(); - if (newVisibility != null) { - if (copy != null) VisibilityUtil.setVisibility(copy, newVisibility); + PsiModifierList modifierListCopy = member.getModifierList(); + if (modifierListCopy != null) { + modifierListCopy = (PsiModifierList)modifierListCopy.copy(); } - modifierListCopies.put(member, copy); + if (modifierListCopy != null && newVisibility != null) { + try { + VisibilityUtil.setVisibility(modifierListCopy, newVisibility); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + modifierListCopies.put(member, modifierListCopy); } + analyzeConflictsOnUsages(usages, myMembersToMove, newVisibility, myTargetClass, modifierListCopies, conflicts); + analyzeConflictsOnMembers(myMembersToMove, newVisibility, myTargetClass, modifierListCopies, conflicts); + + RefactoringConflictsUtil.analyzeModuleConflicts(myProject, myMembersToMove, usages, myTargetClass, conflicts); + + return showConflicts(conflicts, usages); + } + + private static void analyzeConflictsOnUsages(UsageInfo[] usages, + Set membersToMove, + String newVisibility, + PsiClass targetClass, + Map modifierListCopies, + MultiMap conflicts) { for (UsageInfo usage : usages) { - if (usage instanceof MoveMembersUsageInfo) { - final MoveMembersUsageInfo usageInfo = (MoveMembersUsageInfo)usage; - PsiElement element = usage.getElement(); - if (element != null) { - final PsiMember member = usageInfo.member; - if (element instanceof PsiReferenceExpression) { - PsiExpression qualifier = ((PsiReferenceExpression)element).getQualifierExpression(); - PsiClass accessObjectClass = null; - if (qualifier != null) { - accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement(); - } + if (!(usage instanceof MoveMembersUsageInfo)) continue; + final MoveMembersUsageInfo usageInfo = (MoveMembersUsageInfo)usage; + final PsiMember member = usageInfo.member; + final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(member.getLanguage()); + if (handler != null) { + handler.checkConflictsOnUsage(usageInfo, newVisibility, modifierListCopies.get(member), targetClass, membersToMove, conflicts); + } + } + } - if (!JavaResolveUtil.isAccessible(member, myTargetClass, modifierListCopies.get(member), element, accessObjectClass, null)) { - newVisibility = newVisibility == null ? VisibilityUtil.getVisibilityStringToDisplay(member) : newVisibility; - String message = - CommonRefactoringUtil.capitalize(RefactoringBundle.message("0.with.1.visibility.is.not.accessible.from.2", RefactoringUIUtil.getDescription(member, false), - newVisibility, RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true))); - conflicts.putValue(member, message); - } - } - - if (member instanceof PsiField && myTargetClass.isInterface()) { - final ReadWriteAccessDetector accessDetector = ReadWriteAccessDetector.findDetector(member); - if (accessDetector != null) { - final ReadWriteAccessDetector.Access access = accessDetector.getExpressionAccess(element); - if (access != ReadWriteAccessDetector.Access.Read) { - conflicts.putValue(element, CommonRefactoringUtil.capitalize(RefactoringUIUtil.getDescription(member, true)) + " has write access but is moved to an interface"); - } - } - } - } + private static void analyzeConflictsOnMembers(Set membersToMove, + String newVisibility, + PsiClass targetClass, + Map modifierListCopies, + MultiMap conflicts) { + for (final PsiMember member : membersToMove) { + final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(member.getLanguage()); + if (handler != null) { + handler.checkConflictsOnMember(member, newVisibility, modifierListCopies.get(member), targetClass, membersToMove, conflicts); } } } @@ -308,53 +307,6 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor { super.doRun(); } - private static void analyzeMoveConflicts(@NotNull Set membersToMove, final PsiClass targetClass, final String newVisibility, - MultiMap conflicts) { - for (final PsiMember member : membersToMove) { - if (member instanceof PsiMethod) { - PsiMethod method = (PsiMethod)member; - if (hasMethod(targetClass, method)) { - String message = RefactoringBundle.message("0.already.exists.in.the.target.class", RefactoringUIUtil.getDescription(method, false)); - message = CommonRefactoringUtil.capitalize(message); - conflicts.putValue(method, message); - } - } - else if (member instanceof PsiField) { - PsiField field = (PsiField)member; - if (hasField(targetClass, field)) { - String message = RefactoringBundle.message("0.already.exists.in.the.target.class", RefactoringUIUtil.getDescription(field, false)); - message = CommonRefactoringUtil.capitalize(message); - conflicts.putValue(field, message); - } - } - } - RefactoringConflictsUtil.analyzeAccessibilityConflicts(membersToMove, targetClass, conflicts, newVisibility); - } - - private static boolean hasMethod(PsiClass targetClass, PsiMethod method) { - PsiMethod[] targetClassMethods = targetClass.getMethods(); - for (PsiMethod candidate : targetClassMethods) { - if (candidate != method && - MethodSignatureUtil.areSignaturesEqual(method.getSignature(PsiSubstitutor.EMPTY), - candidate.getSignature(PsiSubstitutor.EMPTY))) { - return true; - } - } - return false; - } - - private static boolean hasField(PsiClass targetClass, PsiField field) { - String fieldName = field.getName(); - PsiField[] targetClassFields = targetClass.getFields(); - for (PsiField candidate : targetClassFields) { - if (candidate != field && - fieldName.equals(candidate.getName())) { - return true; - } - } - return false; - } - public List getMembers() { return new ArrayList(myMembersToMove); } diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java index e8b6538af7cd..53b4e9aea17c 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java @@ -48,13 +48,16 @@ public class RefactoringConflictsUtil { private RefactoringConflictsUtil() { } public static void analyzeAccessibilityConflicts(@NotNull Set membersToMove, - @NotNull final PsiClass targetClass, - final MultiMap conflicts, String newVisibility) { + @NotNull PsiClass targetClass, + @NotNull MultiMap conflicts, + @Nullable String newVisibility) { analyzeAccessibilityConflicts(membersToMove, targetClass, conflicts, newVisibility, targetClass, null); } - public static void analyzeAccessibilityConflicts(@NotNull Set membersToMove, @Nullable final PsiClass targetClass, final MultiMap conflicts, - String newVisibility, + public static void analyzeAccessibilityConflicts(@NotNull Set membersToMove, + @Nullable PsiClass targetClass, + @NotNull MultiMap conflicts, + @Nullable String newVisibility, @NotNull PsiElement context, @Nullable Set abstractMethods) { if (VisibilityUtil.ESCALATE_VISIBILITY.equals(newVisibility)) { //Still need to check for access object @@ -63,41 +66,65 @@ public class RefactoringConflictsUtil { for (PsiMember member : membersToMove) { checkUsedElements(member, member, membersToMove, abstractMethods, targetClass, context, conflicts); + checkAccessibilityConflicts(member, newVisibility, targetClass, membersToMove, conflicts); + } + } - PsiModifierList modifierList = member.getModifierList(); - if (modifierList != null) modifierList = (PsiModifierList)modifierList.copy(); - - if (newVisibility != null) { - try { - if (modifierList != null) VisibilityUtil.setVisibility(modifierList, newVisibility); - } - catch (IncorrectOperationException ex) { - /* do nothing and hope for the best */ - } + public static void checkAccessibilityConflicts(@NotNull PsiMember member, + @Nullable String newVisibility, + @Nullable PsiClass targetClass, + @NotNull Set membersToMove, + @NotNull MultiMap conflicts) { + PsiModifierList modifierListCopy = member.getModifierList(); + if (modifierListCopy != null) { + modifierListCopy = (PsiModifierList)modifierListCopy.copy(); + } + if (newVisibility != null && modifierListCopy != null) { + try { + VisibilityUtil.setVisibility(modifierListCopy, newVisibility); } - JavaPsiFacade manager = JavaPsiFacade.getInstance(member.getProject()); - for (PsiReference psiReference : ReferencesSearch.search(member)) { - PsiElement ref = psiReference.getElement(); - if (!RefactoringHierarchyUtil.willBeInTargetClass(ref, membersToMove, targetClass, false)) { - //Check for target class accessibility - if (targetClass != null && !manager.getResolveHelper().isAccessible(targetClass, targetClass.getModifierList(), ref, null, null)) { - String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class", - RefactoringUIUtil.getDescription(targetClass, true), - VisibilityUtil.getVisibilityStringToDisplay(targetClass), - RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(ref), true)); - message = CommonRefactoringUtil.capitalize(message); - conflicts.putValue(targetClass, message); - } - //check for member accessibility - else if (!manager.getResolveHelper().isAccessible(member, modifierList, ref, null, null)) { - String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class", - RefactoringUIUtil.getDescription(member, true), - VisibilityUtil.getVisibilityStringToDisplay(member), - RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(ref), true)); - message = CommonRefactoringUtil.capitalize(message); - conflicts.putValue(member, message); - } - } + catch (IncorrectOperationException ignore) { } // do nothing and hope for the best + } + + checkAccessibilityConflicts(member, modifierListCopy, targetClass, membersToMove, conflicts); + } + + public static void checkAccessibilityConflicts(@NotNull PsiMember member, + @Nullable PsiModifierList modifierListCopy, + @Nullable PsiClass targetClass, + @NotNull Set membersToMove, + @NotNull MultiMap conflicts) { + for (PsiReference psiReference : ReferencesSearch.search(member)) { + checkAccessibilityConflicts(psiReference, member, modifierListCopy, targetClass, membersToMove, conflicts); + } + } + + public static void checkAccessibilityConflicts(@NotNull PsiReference reference, + @NotNull PsiMember member, + @Nullable PsiModifierList modifierListCopy, + @Nullable PsiClass targetClass, + @NotNull Set membersToMove, + @NotNull MultiMap conflicts) { + JavaPsiFacade manager = JavaPsiFacade.getInstance(member.getProject()); + PsiElement ref = reference.getElement(); + if (!RefactoringHierarchyUtil.willBeInTargetClass(ref, membersToMove, targetClass, false)) { + // check for target class accessibility + if (targetClass != null && !manager.getResolveHelper().isAccessible(targetClass, targetClass.getModifierList(), ref, null, null)) { + String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class", + RefactoringUIUtil.getDescription(targetClass, true), + VisibilityUtil.getVisibilityStringToDisplay(targetClass), + RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(ref), true)); + message = CommonRefactoringUtil.capitalize(message); + conflicts.putValue(targetClass, message); + } + // check for member accessibility + else if (!manager.getResolveHelper().isAccessible(member, modifierListCopy, ref, null, null)) { + String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class", + RefactoringUIUtil.getDescription(member, true), + VisibilityUtil.getVisibilityStringToDisplay(member), + RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(ref), true)); + message = CommonRefactoringUtil.capitalize(message); + conflicts.putValue(member, message); } } } @@ -155,7 +182,7 @@ public class RefactoringConflictsUtil { public static void checkAccessibility(PsiMember refMember, @NotNull PsiElement newContext, - PsiClass accessClass, + @Nullable PsiClass accessClass, PsiMember member, MultiMap conflicts) { if (!PsiUtil.isAccessible(refMember, newContext, accessClass)) { @@ -176,24 +203,24 @@ public class RefactoringConflictsUtil { } } - public static void analyzeModuleConflicts(Project project, - Collection scope, + public static void analyzeModuleConflicts(final Project project, + final Collection scopes, final UsageInfo[] usages, - PsiElement target, + final PsiElement target, final MultiMap conflicts) { - if (scope == null) return; + if (scopes == null) return; final VirtualFile vFile = PsiUtilBase.getVirtualFile(target); if (vFile == null) return; - analyzeModuleConflicts(project, scope, usages, vFile, conflicts); + + analyzeModuleConflicts(project, scopes, usages, vFile, conflicts); } - public static void analyzeModuleConflicts(Project project, + public static void analyzeModuleConflicts(final Project project, final Collection scopes, final UsageInfo[] usages, final VirtualFile vFile, final MultiMap conflicts) { if (scopes == null) return; - for (final PsiElement scope : scopes) { if (scope instanceof PsiPackage || scope instanceof PsiDirectory) return; } @@ -207,16 +234,16 @@ public class RefactoringConflictsUtil { @Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { super.visitReferenceElement(reference); final PsiElement resolved = reference.resolve(); - if (resolved != null && !reported.contains(resolved) && !CommonRefactoringUtil.isAncestor(resolved, scopes) && + if (resolved != null && + !reported.contains(resolved) && + !CommonRefactoringUtil.isAncestor(resolved, scopes) && !PsiSearchScopeUtil.isInScope(resolveScope, resolved)) { - final String scopeDescription = - RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(reference), true); + final String scopeDescription = RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(reference), true); final String message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.in.module.2", - CommonRefactoringUtil.capitalize( - RefactoringUIUtil.getDescription(resolved, true)), scopeDescription, - CommonRefactoringUtil.htmlEmphasize( - targetModule.getName())); - conflicts.putValue(resolved, message); + RefactoringUIUtil.getDescription(resolved, true), + scopeDescription, + CommonRefactoringUtil.htmlEmphasize(targetModule.getName())); + conflicts.putValue(resolved, CommonRefactoringUtil.capitalize(message)); reported.add(resolved); } } @@ -255,19 +282,17 @@ public class RefactoringConflictsUtil { assert referencedElement != null : moveRenameUsageInfo; if (module == targetModule && isInTestSources) { message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.production.of.module.2", - CommonRefactoringUtil.capitalize( - RefactoringUIUtil.getDescription(referencedElement, true)), + RefactoringUIUtil.getDescription(referencedElement, true), scopeDescription, CommonRefactoringUtil.htmlEmphasize(module.getName())); } else { message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.module.2", - CommonRefactoringUtil.capitalize( - RefactoringUIUtil.getDescription(referencedElement, true)), + RefactoringUIUtil.getDescription(referencedElement, true), scopeDescription, CommonRefactoringUtil.htmlEmphasize(module.getName())); } - conflicts.putValue(referencedElement, message); + conflicts.putValue(referencedElement, CommonRefactoringUtil.capitalize(message)); } } } @@ -275,4 +300,4 @@ public class RefactoringConflictsUtil { } } } -} \ No newline at end of file +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyMemberHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyMemberHandler.java index 3e7b7da2d96f..6c6e0232fa27 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyMemberHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyMemberHandler.java @@ -20,17 +20,16 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.psi.*; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilBase; -import com.intellij.refactoring.move.moveMembers.MoveMemberHandler; +import com.intellij.refactoring.move.moveMembers.MoveJavaMemberHandler; import com.intellij.refactoring.move.moveMembers.MoveMembersOptions; import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor; import com.intellij.refactoring.util.EnumConstantsUtil; -import com.intellij.refactoring.util.RefactoringHierarchyUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.VisibilityUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; @@ -48,55 +47,19 @@ import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatem import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.refactoring.GroovyChangeContextUtil; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; /** * @author Maxim.Medvedev */ -public class MoveGroovyMemberHandler implements MoveMemberHandler { - public MoveMembersProcessor.MoveMembersUsageInfo getUsage(PsiMember member, - PsiReference psiReference, - Set membersToMove, - PsiClass targetClass) { - PsiElement ref = psiReference.getElement(); - if (ref instanceof GrReferenceExpression) { - GrReferenceExpression refExpr = (GrReferenceExpression)ref; - GrExpression qualifier = refExpr.getQualifierExpression(); - if (RefactoringHierarchyUtil.willBeInTargetClass(refExpr, membersToMove, targetClass, true)) { - // both member and the reference to it will be in target class - if (!isInMovedElement(refExpr, membersToMove)) { - if (qualifier != null) { - return new MoveMembersProcessor.MoveMembersUsageInfo(member, refExpr, null, qualifier, psiReference); // remove qualifier - } - } - else { - if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(member.getContainingClass())) { - return new MoveMembersProcessor.MoveMembersUsageInfo(member, refExpr, null, qualifier, psiReference); // change qualifier - } - } - } - else { - // member in target class, the reference will be outside target class - if (qualifier == null) { - return new MoveMembersProcessor.MoveMembersUsageInfo(member, refExpr, targetClass, refExpr, psiReference); // add qualifier - } - else { - return new MoveMembersProcessor.MoveMembersUsageInfo(member, refExpr, targetClass, qualifier, psiReference); // change qualifier - } - } - } - return null; - } - - private static boolean isInMovedElement(PsiElement element, Set membersToMove) { - for (PsiMember member : membersToMove) { - if (PsiTreeUtil.isAncestor(member, element, false)) return true; - } - return false; - } - - public boolean changeExternalUsage(MoveMembersOptions options, MoveMembersProcessor.MoveMembersUsageInfo usage) { - if (!usage.getElement().isValid()) return true; +public class MoveGroovyMemberHandler extends MoveJavaMemberHandler { + @Override + public boolean changeExternalUsage(@NotNull MoveMembersOptions options, @NotNull MoveMembersProcessor.MoveMembersUsageInfo usage) { + final PsiElement element = usage.getElement(); + if (element == null || !element.isValid()) return true; if (usage.reference instanceof GrReferenceExpression) { GrReferenceExpression refExpr = (GrReferenceExpression)usage.reference; @@ -119,14 +82,14 @@ public class MoveGroovyMemberHandler implements MoveMemberHandler { return false; } - public PsiMember doMove(MoveMembersOptions options, PsiMember member, PsiElement anchor, PsiClass targetClass) { - - PsiMember memberCopy; - + @Override + @NotNull + public PsiMember doMove(@NotNull MoveMembersOptions options, @NotNull PsiMember member, PsiElement anchor, @NotNull PsiClass targetClass) { GroovyChangeContextUtil.encodeContextInfo(member); + PsiMember memberCopy; if (options.makeEnumConstant() && - member instanceof PsiVariable && + member instanceof GrVariable && EnumConstantsUtil.isSuitableForEnumConstant(((PsiVariable)member).getType(), targetClass)) { memberCopy = createEnumConstant(member.getName(), ((GrVariable)member).getInitializerGroovy(), member.getProject()); member.delete(); @@ -186,7 +149,8 @@ public class MoveGroovyMemberHandler implements MoveMemberHandler { return memberCopy; } - public void decodeContextInfo(PsiElement scope) { + @Override + public void decodeContextInfo(@NotNull PsiElement scope) { GroovyChangeContextUtil.decodeContextInfo(scope, null, null); } @@ -222,7 +186,7 @@ public class MoveGroovyMemberHandler implements MoveMemberHandler { return false; } - public static boolean hasOnDemandStaticImport(final PsiElement element, final PsiClass aClass) { + private static boolean hasOnDemandStaticImport(final PsiElement element, final PsiClass aClass) { if (element.getContainingFile() instanceof GroovyFile) { final GrImportStatement[] importStatements = ((GroovyFile)element.getContainingFile()).getImportStatements(); for (GrImportStatement stmt : importStatements) { @@ -235,8 +199,9 @@ public class MoveGroovyMemberHandler implements MoveMemberHandler { return false; } + @Override @Nullable - public PsiElement getAnchor(final PsiMember member, final PsiClass targetClass) { + public PsiElement getAnchor(@NotNull final PsiMember member, @NotNull final PsiClass targetClass) { if (member instanceof GrField && member.hasModifierProperty(PsiModifier.STATIC)) { final List referencedFields = new ArrayList(); final GrExpression psiExpression = ((GrField)member).getInitializerGroovy(); @@ -274,13 +239,13 @@ public class MoveGroovyMemberHandler implements MoveMemberHandler { return elementFactory.createEnumConstantFromText(enumConstantText); } - private static PsiElement addEnumConstant(PsiClass targetClass, GrEnumConstant constant, PsiElement anchor) { + private static PsiElement addEnumConstant(PsiClass targetClass, GrEnumConstant constant, @Nullable PsiElement anchor) { if (targetClass instanceof GrEnumTypeDefinition) { final GrEnumTypeDefinition enumeration = (GrEnumTypeDefinition)targetClass; final GrEnumConstantList constantList = enumeration.getEnumConstantList(); if (constantList != null) { ASTNode node = constantList.getNode(); - node.addLeaf(GroovyElementTypes.mCOMMA, ",", node.getFirstChildNode()); + node.addLeaf(GroovyTokenTypes.mCOMMA, ",", node.getFirstChildNode()); return constantList.addBefore(constant, constantList.getFirstChild()); } else { From ff473e1ce05d3aa98e567a152167e90fbf3a13c6 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Apr 2011 19:49:11 +0200 Subject: [PATCH 063/100] no more word completion autopopup, even in plain text (IDEA-64781) --- .../lang/java/JavaWordCompletionFilter.java | 5 ---- .../lang/DefaultWordCompletionFilter.java | 5 ---- .../completion/WordCompletionContributor.java | 23 ++++--------------- .../PropertiesWordCompletionFilter.java | 5 ---- .../lang/xml/XmlWordCompletionFilter.java | 4 ---- 5 files changed, 5 insertions(+), 37 deletions(-) diff --git a/java/java-impl/src/com/intellij/lang/java/JavaWordCompletionFilter.java b/java/java-impl/src/com/intellij/lang/java/JavaWordCompletionFilter.java index 0c752ae2e23b..ef0e3cb44b04 100644 --- a/java/java-impl/src/com/intellij/lang/java/JavaWordCompletionFilter.java +++ b/java/java-impl/src/com/intellij/lang/java/JavaWordCompletionFilter.java @@ -32,11 +32,6 @@ public class JavaWordCompletionFilter implements WordCompletionElementFilter { JavaDocTokenType.DOC_COMMENT_DATA, JavaTokenType.STRING_LITERAL); public boolean isWordCompletionEnabledIn(final IElementType element) { - final CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion(); - if (process != null && process.isAutopopupCompletion()) { - return false; - } - return ENABLED_TOKENS.contains(element); } } \ No newline at end of file diff --git a/platform/lang-api/src/com/intellij/lang/DefaultWordCompletionFilter.java b/platform/lang-api/src/com/intellij/lang/DefaultWordCompletionFilter.java index 813c893c80c2..10748cde4272 100644 --- a/platform/lang-api/src/com/intellij/lang/DefaultWordCompletionFilter.java +++ b/platform/lang-api/src/com/intellij/lang/DefaultWordCompletionFilter.java @@ -25,11 +25,6 @@ import com.intellij.psi.tree.IElementType; public class DefaultWordCompletionFilter implements WordCompletionElementFilter { public boolean isWordCompletionEnabledIn(final IElementType element) { - final CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion(); - if (process != null && process.isAutopopupCompletion()) { - return false; - } - final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(element.getLanguage()); return parserDefinition != null && parserDefinition.getCommentTokens().contains(element); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java index b43ed802a0ca..1b4de9688e44 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java @@ -19,7 +19,6 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.lang.ASTNode; import com.intellij.lang.LanguageWordCompletion; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; import com.intellij.psi.PlainTextTokenTypes; @@ -71,6 +70,10 @@ public class WordCompletionContributor extends CompletionContributor implements return true; } + if (parameters.getInvocationCount() == 0) { + return false; + } + final PsiFile file = insertedElement.getContainingFile(); final CompletionData data = CompletionUtil.getCompletionDataByElement(insertedElement, file); if (data != null && !(data instanceof SyntaxTableCompletionData)) { @@ -95,8 +98,7 @@ public class WordCompletionContributor extends CompletionContributor implements ASTNode textContainer = element != null ? element.getNode() : null; while (textContainer != null) { final IElementType elementType = textContainer.getElementType(); - if (LanguageWordCompletion.INSTANCE.isEnabledIn(elementType) || - isPlainText(parameters, elementType)) { + if (LanguageWordCompletion.INSTANCE.isEnabledIn(elementType) || elementType == PlainTextTokenTypes.PLAIN_TEXT) { return true; } textContainer = textContainer.getTreeParent(); @@ -104,19 +106,4 @@ public class WordCompletionContributor extends CompletionContributor implements return false; } - private static boolean isPlainText(CompletionParameters parameters, IElementType elementType) { - if (elementType != PlainTextTokenTypes.PLAIN_TEXT) { - return false; - } - - if (ApplicationManager.getApplication().isUnitTestMode()) { - return true; - } - - if (parameters.getInvocationCount() > 0) { - return true; - } - - return parameters.getOriginalFile().getViewProvider().getVirtualFile().isInLocalFileSystem(); - } } diff --git a/plugins/properties/src/com/intellij/lang/properties/PropertiesWordCompletionFilter.java b/plugins/properties/src/com/intellij/lang/properties/PropertiesWordCompletionFilter.java index f9b71b8e5b9f..01d2430bdc33 100644 --- a/plugins/properties/src/com/intellij/lang/properties/PropertiesWordCompletionFilter.java +++ b/plugins/properties/src/com/intellij/lang/properties/PropertiesWordCompletionFilter.java @@ -27,11 +27,6 @@ import com.intellij.psi.tree.IElementType; public class PropertiesWordCompletionFilter extends DefaultWordCompletionFilter { public boolean isWordCompletionEnabledIn(final IElementType element) { - final CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion(); - if (process != null && process.isAutopopupCompletion()) { - return false; - } - return super.isWordCompletionEnabledIn(element) || element == PropertiesElementTypes.PROPERTY; } } \ No newline at end of file diff --git a/xml/impl/src/com/intellij/lang/xml/XmlWordCompletionFilter.java b/xml/impl/src/com/intellij/lang/xml/XmlWordCompletionFilter.java index 5c3ae233a136..3fbd001cb180 100644 --- a/xml/impl/src/com/intellij/lang/xml/XmlWordCompletionFilter.java +++ b/xml/impl/src/com/intellij/lang/xml/XmlWordCompletionFilter.java @@ -32,10 +32,6 @@ public class XmlWordCompletionFilter extends DefaultWordCompletionFilter { XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN, XmlTokenType.XML_DATA_CHARACTERS); public boolean isWordCompletionEnabledIn(final IElementType element) { - final CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion(); - if (process != null && process.isAutopopupCompletion()) { - return false; - } return super.isWordCompletionEnabledIn(element) || ENABLED_TOKENS.contains(element); } } \ No newline at end of file From 54d554f1d1b03a7519636ed7c7670c68a7ecd99f Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Apr 2011 20:01:57 +0200 Subject: [PATCH 064/100] IDEA-63335 complete current statement error when statement spans on 2 lines --- .../smartEnter/MissingReturnExpressionFixer.java | 14 +++++++------- .../completeStatement/MultilineReturn.java | 6 ++++++ .../completeStatement/MultilineReturn_after.java | 6 ++++++ .../codeInsight/CompleteStatementTest.java | 3 ++- 4 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completeStatement/MultilineReturn.java create mode 100644 java/java-tests/testData/codeInsight/completeStatement/MultilineReturn_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingReturnExpressionFixer.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingReturnExpressionFixer.java index c117dcd8503c..df86f53a19c0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingReturnExpressionFixer.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingReturnExpressionFixer.java @@ -33,18 +33,18 @@ public class MissingReturnExpressionFixer implements Fixer { throws IncorrectOperationException { if (psiElement instanceof PsiReturnStatement) { PsiReturnStatement retStatement = (PsiReturnStatement) psiElement; - if (retStatement.getReturnValue() != null && - startLine(editor, retStatement) == startLine(editor, retStatement.getReturnValue())) { + PsiExpression returnValue = retStatement.getReturnValue(); + if (returnValue != null && + lineNumber(editor, editor.getCaretModel().getOffset()) == lineNumber(editor, returnValue.getTextRange().getStartOffset())) { return; } PsiElement parent = PsiTreeUtil.getParentOfType(psiElement, PsiClassInitializer.class, PsiMethod.class); if (parent instanceof PsiMethod) { - PsiMethod method = (PsiMethod) parent; - final PsiType returnType = method.getReturnType(); + final PsiType returnType = ((PsiMethod) parent).getReturnType(); if (returnType != null && returnType != PsiType.VOID) { final int startOffset = retStatement.getTextRange().getStartOffset(); - if (retStatement.getReturnValue() != null) { + if (returnValue != null) { editor.getDocument().insertString(startOffset + "return".length(), ";"); } @@ -54,7 +54,7 @@ public class MissingReturnExpressionFixer implements Fixer { } } - private int startLine(Editor editor, PsiElement psiElement) { - return editor.getDocument().getLineNumber(psiElement.getTextRange().getStartOffset()); + private static int lineNumber(Editor editor, int offset) { + return editor.getDocument().getLineNumber(offset); } } diff --git a/java/java-tests/testData/codeInsight/completeStatement/MultilineReturn.java b/java/java-tests/testData/codeInsight/completeStatement/MultilineReturn.java new file mode 100644 index 000000000000..29fb958d20a5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completeStatement/MultilineReturn.java @@ -0,0 +1,6 @@ +class Test { + Object method() { + return + null + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completeStatement/MultilineReturn_after.java b/java/java-tests/testData/codeInsight/completeStatement/MultilineReturn_after.java new file mode 100644 index 000000000000..7dcbe27e45fa --- /dev/null +++ b/java/java-tests/testData/codeInsight/completeStatement/MultilineReturn_after.java @@ -0,0 +1,6 @@ +class Test { + Object method() { + return + null; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java index 5ccafe430ead..8e6711825467 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java @@ -5,7 +5,6 @@ import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.testFramework.EditorActionTestCase; @@ -185,6 +184,8 @@ public class CompleteStatementTest extends EditorActionTestCase { public void testIDEADEV40479() throws Exception { doTest(); } + public void testMultilineReturn() throws Exception { doTest(); } + public void testIDEADEV13019() throws Exception { doTestBracesNextLineStyle(); } From 60267d800abab2658cddf1a36886b71d268eaa3b Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Apr 2011 20:20:04 +0200 Subject: [PATCH 065/100] remove the old console folding API --- .../filters/AuxiliaryCallsFolding.java | 33 ------------------- .../filters/ReflectionStackFrameFilter.java | 17 ---------- .../filters/RmiStackFrameFilter.java | 28 ---------------- .../execution/filters/StackFrameFilter.java | 13 -------- .../src/META-INF/LangExtensions.xml | 4 --- plugins/groovy/src/META-INF/plugin.xml | 1 - .../GroovyDebuggerClassFilterProvider.java | 3 +- resources/src/META-INF/IdeaPlugin.xml | 12 +++---- 8 files changed, 6 insertions(+), 105 deletions(-) delete mode 100644 java/execution/impl/src/com/intellij/execution/filters/AuxiliaryCallsFolding.java delete mode 100644 java/execution/openapi/src/com/intellij/execution/filters/ReflectionStackFrameFilter.java delete mode 100644 java/execution/openapi/src/com/intellij/execution/filters/RmiStackFrameFilter.java delete mode 100644 java/execution/openapi/src/com/intellij/execution/filters/StackFrameFilter.java diff --git a/java/execution/impl/src/com/intellij/execution/filters/AuxiliaryCallsFolding.java b/java/execution/impl/src/com/intellij/execution/filters/AuxiliaryCallsFolding.java deleted file mode 100644 index 83df6698588d..000000000000 --- a/java/execution/impl/src/com/intellij/execution/filters/AuxiliaryCallsFolding.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.intellij.execution.filters; - -import com.intellij.execution.ConsoleFolding; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.Trinity; - -import java.util.List; - -/** - * @author peter - */ -public class AuxiliaryCallsFolding extends ConsoleFolding { - @Override - public boolean shouldFoldLine(String line) { - final Trinity pair = ExceptionFilter.parseExceptionLine(line); - return pair != null && shouldFold(pair.first, pair.second); - } - - private static boolean shouldFold(String className, String methodName) { - for (StackFrameFilter provider : StackFrameFilter.EP_NAME.getExtensions()) { - if (provider.isAuxiliaryFrame(className, methodName)) { - return true; - } - } - return false; - } - - - @Override - public String getPlaceholderText(List lines) { - return " <" + lines.size() + " internal calls>"; - } -} diff --git a/java/execution/openapi/src/com/intellij/execution/filters/ReflectionStackFrameFilter.java b/java/execution/openapi/src/com/intellij/execution/filters/ReflectionStackFrameFilter.java deleted file mode 100644 index 3cd61a5d95f8..000000000000 --- a/java/execution/openapi/src/com/intellij/execution/filters/ReflectionStackFrameFilter.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.intellij.execution.filters; - -/** - * @author peter - */ -public class ReflectionStackFrameFilter extends StackFrameFilter { - public boolean isAuxiliaryFrame(String className, String methodName) { - if (className.equals("java.lang.reflect.Method") && methodName.equals("invoke")) { - return true; - } - if (className.equals("java.lang.reflect.Constructor") && methodName.equals("newInstance")) { - return true; - } - - return className.startsWith("sun.reflect."); - } -} diff --git a/java/execution/openapi/src/com/intellij/execution/filters/RmiStackFrameFilter.java b/java/execution/openapi/src/com/intellij/execution/filters/RmiStackFrameFilter.java deleted file mode 100644 index 878b911b26f8..000000000000 --- a/java/execution/openapi/src/com/intellij/execution/filters/RmiStackFrameFilter.java +++ /dev/null @@ -1,28 +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.execution.filters; - -/** - * @author Gregory.Shrago - */ -public class RmiStackFrameFilter extends StackFrameFilter { - public boolean isAuxiliaryFrame(String className, String methodName) { - if (className.startsWith("java.rmi.") && methodName.startsWith("invoke")) { - return true; - } - return className.startsWith("sun.rmi."); - } -} \ No newline at end of file diff --git a/java/execution/openapi/src/com/intellij/execution/filters/StackFrameFilter.java b/java/execution/openapi/src/com/intellij/execution/filters/StackFrameFilter.java deleted file mode 100644 index 25f6cdb1b07c..000000000000 --- a/java/execution/openapi/src/com/intellij/execution/filters/StackFrameFilter.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.intellij.execution.filters; - -import com.intellij.openapi.extensions.ExtensionPointName; - -/** - * @author peter - */ -public abstract class StackFrameFilter { - public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.stackFrameFilter"); - - public abstract boolean isAuxiliaryFrame(String className, String methodName); - -} diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index b74d5e3e7830..266312e61dee 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -396,10 +396,6 @@ - - - - diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 6d7eb36e55f2..1692c19ad1b7 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -214,7 +214,6 @@ - diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/filters/GroovyDebuggerClassFilterProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/filters/GroovyDebuggerClassFilterProvider.java index 0d3f16fb22c9..ac50c0773ec6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/filters/GroovyDebuggerClassFilterProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/filters/GroovyDebuggerClassFilterProvider.java @@ -15,7 +15,6 @@ */ package org.jetbrains.plugins.groovy.debugger.filters; -import com.intellij.execution.filters.StackFrameFilter; import com.intellij.ui.classFilter.ClassFilter; import com.intellij.ui.classFilter.DebuggerClassFilterProvider; import com.intellij.util.containers.ContainerUtil; @@ -27,7 +26,7 @@ import java.util.List; /** * @author ilyas */ -public class GroovyDebuggerClassFilterProvider extends StackFrameFilter implements DebuggerClassFilterProvider { +public class GroovyDebuggerClassFilterProvider implements DebuggerClassFilterProvider { private static final ClassFilter[] FILTERS = {new ClassFilter("org.codehaus.groovy.*"), new ClassFilter("groovy.*")}; public List getFilters() { diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 985c190de36f..963a850b80ad 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -147,8 +147,6 @@ - - @@ -725,8 +723,6 @@ - - - - - + + + + + From 0a259250b0f7c01669a5f272dd85a43df3162025 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Apr 2011 20:22:28 +0200 Subject: [PATCH 066/100] IDEA-60268 When running unit tests in user project, stacktrace lines from IntelliJ JUnit runtime should be folded as internal calls --- plugins/junit/src/META-INF/plugin.xml | 2 ++ resources/src/META-INF/IdeaPlugin.xml | 1 + 2 files changed, 3 insertions(+) diff --git a/plugins/junit/src/META-INF/plugin.xml b/plugins/junit/src/META-INF/plugin.xml index 0d91587353f2..03df6e105923 100644 --- a/plugins/junit/src/META-INF/plugin.xml +++ b/plugins/junit/src/META-INF/plugin.xml @@ -40,6 +40,8 @@ + + diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 963a850b80ad..a0a238c1df62 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -781,6 +781,7 @@ + From e3bea1a2c80409becf7453c6a490f1bf581f71d5 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 14 Apr 2011 15:19:16 +0200 Subject: [PATCH 067/100] render long expressions (IDEA-68031) --- .../impl/quickfix/AccessStaticViaInstanceFix.java | 3 ++- .../impl/quickfix/RemoveUnusedVariableFix.java | 14 +++++++++++++- .../codeInspection/defUse/DefUseInspection.java | 6 +++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java index 93811cb51981..baa316044e8d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java @@ -32,6 +32,7 @@ import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.PsiExpressionTrimRenderer; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiUtilBase; @@ -113,7 +114,7 @@ public class AccessStaticViaInstanceFix implements LocalQuickFix { qualifiedWithClassName.setQualifierExpression(factory.createReferenceExpression(containingClass)); final boolean canCopeWithSideEffects = hasSideEffects; final SideEffectWarningDialog dialog = - new SideEffectWarningDialog(project, false, null, sideEffects.get(0).getText(), qualifierExpression.getText(), + new SideEffectWarningDialog(project, false, null, sideEffects.get(0).getText(), PsiExpressionTrimRenderer.render(qualifierExpression), canCopeWithSideEffects){ @Override protected String sideEffectsDescription() { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java index b1fbc12df379..248008af096b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java @@ -28,6 +28,7 @@ import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiExpressionTrimRenderer; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.refactoring.psi.PropertyUtils; @@ -149,7 +150,18 @@ public class RemoveUnusedVariableFix implements IntentionAction { PsiVariable variable, Editor editor, boolean canCopeWithSideEffects) { - String text = sideEffects.isEmpty() ? "" : sideEffects.get(0).getText(); + String text; + if (sideEffects.isEmpty()) { + text = ""; + } + else { + final PsiElement sideEffect = sideEffects.get(0); + if (sideEffect instanceof PsiExpression) { + text = PsiExpressionTrimRenderer.render((PsiExpression)sideEffect); + } else { + text = sideEffect.getText(); + } + } return showSideEffectsWarning(sideEffects, variable, editor, canCopeWithSideEffects, text, text); } diff --git a/java/java-impl/src/com/intellij/codeInspection/defUse/DefUseInspection.java b/java/java-impl/src/com/intellij/codeInspection/defUse/DefUseInspection.java index 106d6b6f4b3f..530363520bcb 100644 --- a/java/java-impl/src/com/intellij/codeInspection/defUse/DefUseInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/defUse/DefUseInspection.java @@ -35,6 +35,7 @@ import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.controlFlow.DefUseUtil; +import com.intellij.psi.util.PsiExpressionTrimRenderer; import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import gnu.trove.THashSet; @@ -243,7 +244,10 @@ public class DefUseInspection extends BaseLocalInspectionTool { int res = SideEffectWarningDialog.DELETE_ALL; if (hasSideEffects) { hasSideEffects = PsiUtil.isStatement(psiInitializer); - res = RemoveUnusedVariableFix.showSideEffectsWarning(sideEffects, variable, FileEditorManager.getInstance(project).getSelectedTextEditor(), hasSideEffects, sideEffects.get(0).getText(), variable.getTypeElement().getText() + " " + variable.getName() + ";
" + psiInitializer.getText()); + res = RemoveUnusedVariableFix.showSideEffectsWarning(sideEffects, variable, + FileEditorManager.getInstance(project).getSelectedTextEditor(), + hasSideEffects, sideEffects.get(0).getText(), + variable.getTypeElement().getText() + " " + variable.getName() + ";
" + PsiExpressionTrimRenderer.render((PsiExpression)psiInitializer)); } try { if (res == SideEffectWarningDialog.DELETE_ALL) { From 39e2c8eeeb83f0c218e6d9752e3db4dbd70b74a5 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 14 Apr 2011 15:33:11 +0200 Subject: [PATCH 068/100] EA-26929 - IAE: PsiBundle.visibilityPresentation --- .../introduceField/InplaceIntroduceConstantPopup.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java index 6fa66246a4aa..47351d230872 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java @@ -212,6 +212,7 @@ public class InplaceIntroduceConstantPopup { visibilityCombo.setRenderer(new ListCellRendererWrapper(visibilityCombo.getRenderer()) { @Override public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) { + if (value == null) return; setText(PsiBundle.visibilityPresentation(value)); } }); From aa0198b19bfd1998feecac4961e1070fddec6a23 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 14 Apr 2011 20:51:25 +0200 Subject: [PATCH 069/100] inplace: merge in one undo --- .../InplaceIntroduceConstantPopup.java | 7 ++++--- .../introduceField/InplaceIntroduceFieldPopup.java | 9 +++++---- .../AbstractInplaceIntroducer.java | 10 ++++++---- .../InplaceIntroduceParameterPopup.java | 7 +++++-- .../introduceVariable/IntroduceVariableBase.java | 2 +- .../VariableInplaceIntroducer.java | 13 +++++++------ 6 files changed, 28 insertions(+), 20 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java index 47351d230872..c1f9de00e9e8 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java @@ -284,7 +284,7 @@ public class InplaceIntroduceConstantPopup { renamer.performInplaceRename(false, nameSuggestions); } } - }, IntroduceConstantHandler.REFACTORING_NAME, null); + }, IntroduceConstantHandler.REFACTORING_NAME, IntroduceConstantHandler.REFACTORING_NAME); } private PsiField createFieldToStartTemplateOn(final String[] names, final PsiType psiType) { @@ -340,7 +340,8 @@ public class InplaceIntroduceConstantPopup { super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()), myEditor, field, false, myTypeSelectorManager.getTypesForAll().length > 1, - myExpr != null && myExpr.isPhysical() ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null, InplaceIntroduceConstantPopup.this.getOccurrenceMarkers()); + myExpr != null && myExpr.isPhysical() ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null, InplaceIntroduceConstantPopup.this.getOccurrenceMarkers(), + IntroduceConstantHandler.REFACTORING_NAME); myDefaultParameterTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(myTypeSelectorManager.getDefaultType()); @@ -437,7 +438,7 @@ public class InplaceIntroduceConstantPopup { protected JComponent getComponent() { if (!myInitListeners) { myInitListeners = true; - final VisibilityListener visibilityListener = new VisibilityListener(myProject, myEditor) { + final VisibilityListener visibilityListener = new VisibilityListener(myProject, IntroduceConstantHandler.REFACTORING_NAME, myEditor) { @Override protected String getVisibility() { return getSelectedVisibility(); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java index 45cd42225d79..50ae57f05937 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java @@ -176,7 +176,7 @@ public class InplaceIntroduceFieldPopup { renamer.performInplaceRename(false, nameSuggestions); } } - }, IntroduceFieldHandler.REFACTORING_NAME, null); + }, IntroduceFieldHandler.REFACTORING_NAME, IntroduceFieldHandler.REFACTORING_NAME); } private PsiField createFieldToStartTemplateOn(final String[] names, @@ -230,7 +230,8 @@ public class InplaceIntroduceFieldPopup { super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()), myEditor, psiVariable, false, myTypeSelectorManager.getTypesForAll().length > 1, - myInitializerExpression != null && myInitializerExpression.isPhysical() ? myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null, InplaceIntroduceFieldPopup.this.getOccurrenceMarkers()); + myInitializerExpression != null && myInitializerExpression.isPhysical() ? myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null, InplaceIntroduceFieldPopup.this.getOccurrenceMarkers(), + IntroduceFieldHandler.REFACTORING_NAME); myDefaultParameterTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(myTypeSelectorManager.getDefaultType()); myFieldRangeStart = myEditor.getDocument().createRangeMarker(psiVariable.getTextRange()); @@ -276,13 +277,13 @@ public class InplaceIntroduceFieldPopup { protected JComponent getComponent() { if (!myInitListeners) { myInitListeners = true; - myIntroduceFieldPanel.addVisibilityListener(new VisibilityListener(myProject, myEditor){ + myIntroduceFieldPanel.addVisibilityListener(new VisibilityListener(myProject, IntroduceFieldHandler.REFACTORING_NAME, myEditor){ @Override protected String getVisibility() { return myIntroduceFieldPanel.getFieldVisibility(); } }); - final FinalListener finalListener = new FinalListener(myProject); + final FinalListener finalListener = new FinalListener(myProject, IntroduceFieldHandler.REFACTORING_NAME); myIntroduceFieldPanel.addFinalListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractInplaceIntroducer.java index 6506cca2fb90..10d3d8886f3b 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractInplaceIntroducer.java @@ -57,8 +57,8 @@ public abstract class AbstractInplaceIntroducer extends VariableInplaceIntroduce boolean cantChangeFinalModifier, boolean hasTypeSuggestion, RangeMarker exprMarker, - List occurrenceMarkers) { - super(project, expression, editor, elementToRename, cantChangeFinalModifier, hasTypeSuggestion, exprMarker, occurrenceMarkers); + List occurrenceMarkers, String commandName) { + super(project, expression, editor, elementToRename, cantChangeFinalModifier, hasTypeSuggestion, exprMarker, occurrenceMarkers, commandName); } protected abstract boolean isReplaceAllOccurrences(); @@ -143,16 +143,18 @@ public abstract class AbstractInplaceIntroducer extends VariableInplaceIntroduce protected abstract class VisibilityListener implements ChangeListener { private Project myProject; + private final String myCommandName; private Editor myEditor; - protected VisibilityListener(Project project, Editor editor) { + protected VisibilityListener(Project project, String commandName, Editor editor) { myProject = project; + myCommandName = commandName; myEditor = editor; } @Override public void stateChanged(ChangeEvent e) { - new WriteCommandAction(myProject) { + new WriteCommandAction(myProject, myCommandName, myCommandName) { @Override protected void run(Result result) throws Throwable { final Document document = myEditor.getDocument(); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java index 2156d294d038..def824918107 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java @@ -20,7 +20,9 @@ import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; import com.intellij.ide.ui.ListCellRendererWrapper; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.Result; import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.ScrollType; @@ -202,7 +204,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { renamer.performInplaceRename(false, nameSuggestions); } } - }, IntroduceParameterHandler.REFACTORING_NAME, null); + }, IntroduceParameterHandler.REFACTORING_NAME, IntroduceParameterHandler.REFACTORING_NAME); } @Override @@ -234,7 +236,8 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { public ParameterInplaceIntroducer(PsiParameter parameter) { super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()), myEditor, parameter, myMustBeFinal, - myTypeSelectorManager.getTypesForAll().length > 1, myExprMarker, InplaceIntroduceParameterPopup.this.getOccurrenceMarkers()); + myTypeSelectorManager.getTypesForAll().length > 1, myExprMarker, InplaceIntroduceParameterPopup.this.getOccurrenceMarkers(), + IntroduceParameterHandler.REFACTORING_NAME); myDefaultParameterTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(parameter.getType()); } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index 784b3772ad1a..01c6be53da7d 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -478,7 +478,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme final boolean cantChangeFinalModifier = hasWriteAccess || (inFinalContext && choice == OccurrencesChooser.ReplaceChoice.ALL); final VariableInplaceRenamer renamer = new VariableInplaceIntroducer(project, expression, editor, elementToRename, cantChangeFinalModifier, - typeSelectorManager.getTypesForAll().length > 1, exprMarker, occurrenceMarkers); + typeSelectorManager.getTypesForAll().length > 1, exprMarker, occurrenceMarkers, IntroduceVariableBase.REFACTORING_NAME); PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); renamer.performInplaceRename(false, new LinkedHashSet(Arrays.asList(suggestedName.names))); } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java index 50a4ca5a891f..9b584aaacde2 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java @@ -38,7 +38,6 @@ import com.intellij.openapi.ui.popup.BalloonBuilder; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; @@ -52,7 +51,6 @@ import com.intellij.refactoring.ui.TypeSelectorManagerImpl; import com.intellij.ui.NonFocusableCheckBox; import com.intellij.ui.TitlePanel; import com.intellij.ui.awt.RelativePoint; -import com.intellij.util.ui.PositionTracker; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -87,7 +85,8 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { final boolean cantChangeFinalModifier, final boolean hasTypeSuggestion, final RangeMarker exprMarker, - final List occurrenceMarkers) { + final List occurrenceMarkers, + final String commandName) { super(elementToRename, editor); myProject = project; myEditor = editor; @@ -110,7 +109,7 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { myCanBeFinal = new NonFocusableCheckBox("Declare final"); myCanBeFinal.setSelected(createFinals()); myCanBeFinal.setMnemonic('f'); - myCanBeFinal.addActionListener(new FinalListener(project)); + myCanBeFinal.addActionListener(new FinalListener(project, commandName)); } } @@ -381,9 +380,11 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { public class FinalListener implements ActionListener { private final Project myProject; + private final String myCommandName; - public FinalListener(Project project) { + public FinalListener(Project project, String commandName) { myProject = project; + myCommandName = commandName; } @Override @@ -396,7 +397,7 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { } public void perform(final boolean generateFinal, final String modifier) { - new WriteCommandAction(myProject){ + new WriteCommandAction(myProject, myCommandName, myCommandName){ @Override protected void run(com.intellij.openapi.application.Result result) throws Throwable { final Document document = myEditor.getDocument(); From fca3fe03cc6b958a9f7ff86b65555b000efbafcd Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 14 Apr 2011 21:08:40 +0200 Subject: [PATCH 070/100] EA-26124 - RE: BuildNumber.parseBuildNumber --- platform/util/src/com/intellij/openapi/util/BuildNumber.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/openapi/util/BuildNumber.java b/platform/util/src/com/intellij/openapi/util/BuildNumber.java index d5a3fa065412..ec19e8cadb85 100644 --- a/platform/util/src/com/intellij/openapi/util/BuildNumber.java +++ b/platform/util/src/com/intellij/openapi/util/BuildNumber.java @@ -83,7 +83,9 @@ public class BuildNumber implements Comparable { int buildNumber; if (baselineVersionSeparator > 0) { try { - baselineVersion = Integer.parseInt(code.substring(0, baselineVersionSeparator)); + final String baselineVersionString = code.substring(0, baselineVersionSeparator); + if (baselineVersionString.isEmpty()) return null; + baselineVersion = Integer.parseInt(baselineVersionString); code = code.substring(baselineVersionSeparator + 1); } catch (NumberFormatException e) { From a96895fac0ff02ef9c9efa0ed8f00332cbb45108 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 14 Apr 2011 21:10:34 +0200 Subject: [PATCH 071/100] restore offline inspections results --- .../intellij/codeInspection/ex/GlobalInspectionContextImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c5271749f496..7f993a74af38 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java @@ -321,7 +321,7 @@ public class GlobalInspectionContextImpl extends UserDataHolderBase implements G new File(outputPath).mkdirs(); final File file = new File(outputPath, toolName + ext); if (isLocalTool) { - FileUtil.writeToFile(file, ""); + FileUtil.writeToFile(file, ("").getBytes("UTF-8"), true); } else { PathMacroManager.getInstance(getProject()).collapsePaths(doc.getRootElement()); From 1d420a7c6d5a0198c11d58c4d82100cf1a1afcce Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 14 Apr 2011 21:25:02 +0200 Subject: [PATCH 072/100] compilation fix --- .../debugger/ui/breakpoints/BreakpointWithHighlighter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4f0f3d15c370..e8dff17807f2 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 @@ -654,7 +654,7 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { return new AnAction() { public void actionPerformed(AnActionEvent e) { ENABLED = !ENABLED; - DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager().fireBreakpointChanged(BreakpointWithHighlighter.this); + DebuggerManagerEx.getInstanceEx(BreakpointWithHighlighter.this.getProject()).getBreakpointManager().fireBreakpointChanged(BreakpointWithHighlighter.this); updateUI(); } }; From e2db9ee050c52531eaf2bcce6e5dde230e4be482 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 14 Apr 2011 22:36:32 +0200 Subject: [PATCH 073/100] fix compilation --- .../roots/ui/configuration/actions/NewModuleAction.java | 4 ++-- .../history/integration/ui/actions/LocalHistoryAction.java | 2 +- .../integration/ui/actions/LocalHistoryActionWithDialog.java | 2 +- .../history/integration/ui/actions/RecentChangesAction.java | 2 +- .../src/com/intellij/openapi/actionSystem/AnAction.java | 2 +- .../src/com/intellij/ui/switcher/ApplySwitchAction.java | 4 ++-- .../actions/ShowFeatureUsageStatisticsAction.java | 4 ++-- .../intellij/ide/actions/SynchronizeCurrentFileAction.java | 4 ++-- .../xpath/xslt/associations/impl/AddAssociationAction.java | 2 +- .../lang/xpath/xslt/associations/impl/AssociationsGroup.java | 4 ++-- .../xpath/xslt/associations/impl/ToggleAssociationAction.java | 2 +- 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java index 9450408c18b5..a5d578396ebb 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleAction.java @@ -40,7 +40,7 @@ public class NewModuleAction extends AnAction implements DumbAware { } public void actionPerformed(AnActionEvent e) { - final Project project = getProject(e); + final Project project = getEventProject(e); if (project == null) { return; } @@ -88,6 +88,6 @@ public class NewModuleAction extends AnAction implements DumbAware { public void update(AnActionEvent e) { super.update(e); - e.getPresentation().setEnabled(getProject(e) != null); + e.getPresentation().setEnabled(getEventProject(e) != null); } } diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryAction.java b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryAction.java index c9384f5bea62..65f1d9e824b1 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryAction.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryAction.java @@ -33,7 +33,7 @@ public abstract class LocalHistoryAction extends AnAction implements DumbAware { @Override public void update(AnActionEvent e) { Presentation p = e.getPresentation(); - if (getProject(e) == null) { + if (getEventProject(e) == null) { p.setVisible(false); p.setEnabled(false); return; diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryActionWithDialog.java b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryActionWithDialog.java index 094401debfaf..c35bec135947 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryActionWithDialog.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryActionWithDialog.java @@ -24,7 +24,7 @@ import com.intellij.openapi.vfs.VirtualFile; public abstract class LocalHistoryActionWithDialog extends LocalHistoryAction { @Override public void actionPerformed(AnActionEvent e) { - showDialog(getProject(e), getGateway(), getFile(e), e); + showDialog(getEventProject(e), getGateway(), getFile(e), e); } protected abstract void showDialog(Project p, IdeaGateway gw, VirtualFile f, AnActionEvent e); diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/RecentChangesAction.java b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/RecentChangesAction.java index a7ac09e7ab39..b478f1bea934 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/RecentChangesAction.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/RecentChangesAction.java @@ -22,6 +22,6 @@ import com.intellij.openapi.actionSystem.AnActionEvent; public class RecentChangesAction extends LocalHistoryAction { @Override public void actionPerformed(AnActionEvent e) { - new RecentChangesPopup(getProject(e), getGateway(), getVcs()).show(); + new RecentChangesPopup(getEventProject(e), getGateway(), getVcs()).show(); } } diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/AnAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/AnAction.java index de5c19b73b33..7ca22d912bd8 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/AnAction.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/AnAction.java @@ -306,7 +306,7 @@ public abstract class AnAction { } @Nullable - public static Project getProject(AnActionEvent e) { + public static Project getEventProject(AnActionEvent e) { return e == null ? null : e.getData(PlatformDataKeys.PROJECT); } } diff --git a/platform/platform-api/src/com/intellij/ui/switcher/ApplySwitchAction.java b/platform/platform-api/src/com/intellij/ui/switcher/ApplySwitchAction.java index c7f990fe445e..f9ab352448b1 100644 --- a/platform/platform-api/src/com/intellij/ui/switcher/ApplySwitchAction.java +++ b/platform/platform-api/src/com/intellij/ui/switcher/ApplySwitchAction.java @@ -26,7 +26,7 @@ public class ApplySwitchAction extends AnAction { @Override public void update(AnActionEvent e) { - Project project = getProject(e); + Project project = getEventProject(e); if (project == null) { e.getPresentation().setEnabled(false); return; @@ -51,7 +51,7 @@ public class ApplySwitchAction extends AnAction { @Override public void actionPerformed(AnActionEvent e) { - Project project = getProject(e); + Project project = getEventProject(e); SwitchManager switchManager = SwitchManager.getInstance(project); if (switchManager.canApplySwitch()) { diff --git a/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsAction.java b/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsAction.java index 7ce776f0586c..2352f3487f0b 100644 --- a/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsAction.java +++ b/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsAction.java @@ -23,11 +23,11 @@ import com.intellij.openapi.project.DumbAware; public class ShowFeatureUsageStatisticsAction extends AnAction implements DumbAware { public void actionPerformed(AnActionEvent e) { - new ShowFeatureUsageStatisticsDialog(getProject(e)).show(); + new ShowFeatureUsageStatisticsDialog(getEventProject(e)).show(); } public void update(AnActionEvent e) { super.update(e); - e.getPresentation().setEnabled(getProject(e) != null); + e.getPresentation().setEnabled(getEventProject(e) != null); } } \ No newline at end of file diff --git a/platform/vcs-impl/src/com/intellij/ide/actions/SynchronizeCurrentFileAction.java b/platform/vcs-impl/src/com/intellij/ide/actions/SynchronizeCurrentFileAction.java index b6ddb4d72e99..cf2a07db23af 100644 --- a/platform/vcs-impl/src/com/intellij/ide/actions/SynchronizeCurrentFileAction.java +++ b/platform/vcs-impl/src/com/intellij/ide/actions/SynchronizeCurrentFileAction.java @@ -30,7 +30,7 @@ public class SynchronizeCurrentFileAction extends AnAction implements DumbAware public void update(AnActionEvent e) { VirtualFile[] files = getFiles(e); - if (getProject(e) == null || files == null || files.length == 0) { + if (getEventProject(e) == null || files == null || files.length == 0) { e.getPresentation().setEnabled(false); return; } @@ -48,7 +48,7 @@ public class SynchronizeCurrentFileAction extends AnAction implements DumbAware } public void actionPerformed(AnActionEvent e) { - final Project project = getProject(e); + final Project project = getEventProject(e); final VirtualFile[] files = getFiles(e); ApplicationManager.getApplication().runWriteAction(new Runnable() { diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AddAssociationAction.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AddAssociationAction.java index 4ccf453edfb4..0b104a4af5c9 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AddAssociationAction.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AddAssociationAction.java @@ -47,7 +47,7 @@ class AddAssociationAction extends AnAction { } protected void addAssociation(AnActionEvent e, PsiFile psiFile) { - final Project project = AssociationsGroup.getProject(e); + final Project project = AssociationsGroup.getEventProject(e); if (project == null) return; final VirtualFile virtualFile = psiFile.getVirtualFile(); diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsGroup.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsGroup.java index 424f80b09b6a..9ec3a3bf98c0 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsGroup.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/AssociationsGroup.java @@ -36,7 +36,7 @@ public class AssociationsGroup extends ActionGroup { public AnAction[] getChildren(@Nullable AnActionEvent e) { if (!isEnabled(e)) return AnAction.EMPTY_ARRAY; - final Project project = getProject(e); + final Project project = getEventProject(e); if (project == null) return AnAction.EMPTY_ARRAY; final PsiFile psiFile = getPsiFile(e); if (psiFile == null) return AnAction.EMPTY_ARRAY; @@ -69,7 +69,7 @@ public class AssociationsGroup extends ActionGroup { final PsiFile psiFile = getPsiFile(e); if (psiFile == null) return false; if (!XsltSupport.isXsltFile(psiFile)) return false; - final Project project = getProject(e); + final Project project = getEventProject(e); if (project == null) return false; return PsiManager.getInstance(project).isInProject(psiFile); } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/ToggleAssociationAction.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/ToggleAssociationAction.java index 0410a9f4e0d8..7a7691498919 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/ToggleAssociationAction.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/ToggleAssociationAction.java @@ -69,6 +69,6 @@ class ToggleAssociationAction extends ToggleAction { public void setSelected(AnActionEvent e, boolean state) { assert !state; myFileAssociationsManager.removeAssociation(myPsiFile, myAssoc); - DaemonCodeAnalyzer.getInstance(AssociationsGroup.getProject(e)).restart(); + DaemonCodeAnalyzer.getInstance(AssociationsGroup.getEventProject(e)).restart(); } } From de881091a4bc541cb547b092fa11419f26059855 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Apr 2011 23:29:49 +0200 Subject: [PATCH 074/100] avoid unnecessary Class.isInstance --- .../reference/ReferenceProvidersRegistry.java | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java index 4c803fa08d3c..5147240cf015 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java @@ -121,20 +121,17 @@ public class ReferenceProvidersRegistry extends PsiReferenceRegistrar { final PsiNamePatternCondition nameCondition = ContainerUtil.findInstance(pattern.getCondition().getConditions(), PsiNamePatternCondition.class); if (nameCondition != null) { - final ValuePatternCondition valueCondition = - ContainerUtil.findInstance(nameCondition.getNamePattern().getCondition().getConditions(), ValuePatternCondition.class); - if (valueCondition != null) { - final Collection strings = valueCondition.getValues(); - registerNamedReferenceProvider(ArrayUtil.toStringArray(strings), nameCondition, scope, true, provider, priority, pattern); - return; - } - - final CaseInsensitiveValuePatternCondition ciCondition = - ContainerUtil - .findInstance(nameCondition.getNamePattern().getCondition().getConditions(), CaseInsensitiveValuePatternCondition.class); - if (ciCondition != null) { - registerNamedReferenceProvider(ciCondition.getValues(), nameCondition, scope, false, provider, priority, pattern); - return; + for (PatternCondition condition : nameCondition.getNamePattern().getCondition().getConditions()) { + if (condition instanceof ValuePatternCondition) { + final Collection strings = ((ValuePatternCondition)condition).getValues(); + registerNamedReferenceProvider(ArrayUtil.toStringArray(strings), nameCondition, scope, true, provider, priority, pattern); + return; + } + if (condition instanceof CaseInsensitiveValuePatternCondition) { + final String[] strings = ((CaseInsensitiveValuePatternCondition)condition).getValues(); + registerNamedReferenceProvider(strings, nameCondition, scope, false, provider, priority, pattern); + return; + } } } From fa3a66abcc9c32cff9ddae32d3c922beb7b8b284 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 15 Apr 2011 11:28:06 +0400 Subject: [PATCH 075/100] fix testdata path --- .../convertToJava/CodeBlockGenerationTest.groovy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy index 58a2a302cd16..532604d641b8 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy @@ -41,8 +41,8 @@ public class CodeBlockGenerationTest extends LightCodeInsightFixtureTestCase { public static final DefaultLightProjectDescriptor GROOVY_17_PROJECT_DESCRIPTOR = new DefaultLightProjectDescriptor() { @Override public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { - final Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary("GROOVY").getModifiableModel(); - final VirtualFile groovyJar = JarFileSystem.getInstance().refreshAndFindFileByPath(TestUtils.getMockGroovy1_7LibraryName() + "!/"); + final Library.ModifiableModel modifiableModel = model.moduleLibraryTable.createLibrary("GROOVY").modifiableModel; + final VirtualFile groovyJar = JarFileSystem.instance.refreshAndFindFileByPath(TestUtils.mockGroovy1_7LibraryName + "!/"); modifiableModel.addRoot(groovyJar, OrderRootType.CLASSES); modifiableModel.commit(); } @@ -56,7 +56,7 @@ public class CodeBlockGenerationTest extends LightCodeInsightFixtureTestCase { @Override protected String getBasePath() { - return TestUtils.testDataPath + "/refactoring/convertGroovyToJava/codeBlock"; + return TestUtils.testDataPath + "refactoring/convertGroovyToJava/codeBlock"; } private void doTest() { From dfb783ab984132870d12ec65498ae99c25b532a8 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 14 Apr 2011 18:02:54 +0400 Subject: [PATCH 076/100] EA-26971 - assert: CaretModelImpl.moveToOffset 1. Debug info is added; 2. Green code policy is applied; --- .../intellij/openapi/editor/impl/CaretModelImpl.java | 5 ++++- .../intellij/openapi/editor/impl/FoldingModelImpl.java | 10 ++++++++++ .../openapi/editor/impl/SoftWrapModelImpl.java | 5 +++++ 3 files changed, 19 insertions(+), 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 91d6c9fb3ab1..b82c5b4c67f4 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 @@ -182,7 +182,10 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener, validateCallContext(); moveToLogicalPosition(myEditor.offsetToLogicalPosition(offset), locateBeforeSoftWrap); if (!myEditor.offsetToLogicalPosition(myOffset).equals(myEditor.offsetToLogicalPosition(offset))) { - LOG.error("caret moved to wrong offset. Requested:" + offset + " but actual:" + myOffset); + LOG.error( + "caret moved to wrong offset. Requested:" + offset + " but actual:" + myOffset + + ". Soft wraps data: " + myEditor.getSoftWrapModel() + ", folding data: " + myEditor.getFoldingModel() + + ", document:\n" + myEditor.getDocument().getText()); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java index 061242bced1e..8d12d6f0143b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java @@ -38,6 +38,7 @@ import com.intellij.openapi.editor.ex.PrioritizedDocumentListener; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.awt.*; import java.util.Arrays; @@ -219,6 +220,7 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList return myFoldTree.fetchAllRegions(); } + @Nullable public FoldRegion getCollapsedRegionAtOffset(int offset) { return myFoldTree.fetchOutermost(offset); } @@ -227,6 +229,7 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList return myFoldTree.getLastTopLevelIndexBefore(offset); } + @Nullable public FoldRegion getFoldingPlaceholderAt(Point p) { assertReadAccess(); LogicalPosition pos = myEditor.xyToLogicalPosition(p); @@ -410,10 +413,12 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList return myFoldTree.getFoldedLinesCountBefore(offset); } + @Nullable public FoldRegion[] fetchTopLevel() { return myFoldTree.fetchTopLevel(); } + @Nullable public FoldRegion fetchOutermost(int offset) { return myFoldTree.fetchOutermost(offset); } @@ -478,4 +483,9 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList listener.onFoldRegionStateChange(foldRegion); } } + + @Override + public String toString() { + return Arrays.toString(myFoldTree.fetchTopLevel()); + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java index a048f2cf7cc0..1ed621d490a9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java @@ -654,6 +654,11 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi } } + @Override + public String toString() { + return myDataMapper.toString(); + } + /** * Defines generic interface for the command that may be proceeded in both 'soft wraps aware' and * 'soft wraps unaware' modes. From 62c224aaed9fcc49d1c53598017586c543bc5cbb Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 14 Apr 2011 18:30:01 +0400 Subject: [PATCH 077/100] EA-26940 - : EditorUtil.calcColumnNumber Debug info is added --- .../intellij/openapi/editor/ex/util/EditorUtil.java | 6 +++--- .../com/intellij/openapi/editor/impl/DocumentImpl.java | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java index 3e023d3a7f85..0bcaa23b1886 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java @@ -349,7 +349,7 @@ public class EditorUtil { return calcColumnNumber(editor, text, start, offset, getTabSize(editor)); } - public static int calcColumnNumber(Editor editor, CharSequence text, int start, int offset, int tabSize) { + public static int calcColumnNumber(Editor editor, CharSequence text, final int start, final int offset, final int tabSize) { boolean useOptimization = true; if (editor != null) { SoftWrap softWrap = editor.getSoftWrapModel().getSoftWrap(start); @@ -375,8 +375,8 @@ public class EditorUtil { for (int i = start; i < offset; i++) { char c = text.charAt(i); assert c != '\n' && c != '\r' : - String.format("Symbol: %c, its index: %d, given start: %d, given offset: %d, given tab size: %d, text: '%s'", - c, i, start, offset, tabSize, text); + String.format("Symbol: %c, its index: %d, given start: %d, given offset: %d, given tab size: %d, document info: %s%ntext: '%s'", + c, i, start, offset, tabSize, editor.getDocument(), text); if (c == '\t') { shift += getTabLength(i + shift - start, tabSize) - 1; } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java index 39f446ac2b6b..b74905633d47 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java @@ -784,6 +784,16 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { } } + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + int linesNumber = getLineCount(); + for (int i = 0; i < linesNumber; i++) { + buffer.append(i).append(": ").append(getLineStartOffset(i)).append("-").append(getLineEndOffset(i)).append("\n"); + } + return super.toString(); + } + private static class MyCharArray extends CharArray { public MyCharArray() { super(0); From 79e5f79238891f76e400be6a9f7f792e714b6ada Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 14 Apr 2011 18:31:47 +0400 Subject: [PATCH 078/100] EA-26930 - IOOBE: SegmentArray.findSegmentIndex --- .../src/com/intellij/openapi/editor/impl/EditorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9ab0234dfe3a..808e82f69904 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 @@ -306,7 +306,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi int start = highlighter.getAffectedAreaStartOffset(); int end = highlighter.getAffectedAreaEndOffset(); int startLine = myDocument.getLineNumber(start); - int endLine = myDocument.getLineNumber(end); + int endLine = end < myDocument.getTextLength() ? myDocument.getLineNumber(end) : myDocument.getLineCount() - 1; repaintLines(Math.max(0, startLine - 1), Math.min(endLine + 1, getDocument().getLineCount())); ((EditorMarkupModelImpl)getMarkupModel()).markDirtied(); ((EditorMarkupModelImpl)getMarkupModel()).repaint(start, end); From 60825d5357eac3f7f47de61115ea993cbd6577ff Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 14 Apr 2011 18:35:13 +0400 Subject: [PATCH 079/100] EA-26802 - SIOOBE: SelectWordUtil.getCamelSelectionRange --- .../intellij/codeInsight/editorActions/SelectWordUtil.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectWordUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectWordUtil.java index 938b42fe5d8d..31e22d90a43f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectWordUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectWordUtil.java @@ -34,6 +34,9 @@ public class SelectWordUtil { private static boolean ourExtensionsLoaded = false; + private SelectWordUtil() { + } + public static void registerSelectioner(ExtendWordSelectionHandler selectioner) { SELECTIONERS = ArrayUtil.append(SELECTIONERS, selectioner); } @@ -60,7 +63,11 @@ public class SelectWordUtil { } } + @Nullable private static TextRange getCamelSelectionRange(CharSequence editorText, int cursorOffset) { + if (cursorOffset < 0 || cursorOffset >= editorText.length()) { + return null; + } if (cursorOffset > 0 && !Character.isJavaIdentifierPart(editorText.charAt(cursorOffset)) && Character.isJavaIdentifierPart(editorText.charAt(cursorOffset - 1))) { cursorOffset--; From e3efceba267efaacb08c45194919ee92a8ddbb38 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 14 Apr 2011 18:38:22 +0400 Subject: [PATCH 080/100] EA-26552 - SIOOBE: TextChangesStorage.substring --- .../src/com/intellij/openapi/vcs/ex/DocumentWrapper.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java index c74188166afe..bf71a2ffee7c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java @@ -55,7 +55,11 @@ public class DocumentWrapper { } private String getLine(final int i) { - return myDocument.getText(new TextRange(myDocument.getLineStartOffset(i), myDocument.getLineEndOffset(i))); + TextRange range = new TextRange(myDocument.getLineStartOffset(i), myDocument.getLineEndOffset(i)); + if (range.getLength() < 0) { + assert false : myDocument; + } + return myDocument.getText(range); } } From 8bd63a79f5833c2c0b703dd8bf45b1632a1b05d8 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 14 Apr 2011 19:25:23 +0400 Subject: [PATCH 081/100] NPE fix. Not sure who introduced it. --- .../application/options/GeneralCodeStylePanel.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java b/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java index c2c5070a7e2f..9e76d183d11c 100644 --- a/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java @@ -283,9 +283,13 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel { } for(Map.Entry entry : myAdditionalIndentOptions.entrySet()) { - IndentOptionsEditor editor = entry.getValue(); FileType fileType = entry.getKey(); - if (editor.isModified(settings, settings.getAdditionalIndentOptions(fileType))) { + CodeStyleSettings.IndentOptions additionalIndentOptions = settings.getAdditionalIndentOptions(fileType); + if (additionalIndentOptions == null) { + continue; + } + IndentOptionsEditor editor = entry.getValue(); + if (editor.isModified(settings, additionalIndentOptions)) { return true; } } From b5774a29242363c341e8c28d8eceb279cac9e283 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Fri, 15 Apr 2011 13:20:37 +0400 Subject: [PATCH 082/100] EA-26844 - AIOOBE: BulkChangesMerger$Context.processPositiveGroup 1. Debug info is added; 2. Recovering on failed in-place merging attempt is added; 3. New test is added; --- .../formatting/BulkChangesMergerTest.java | 6 +++++ .../editor/impl/BulkChangesMerger.java | 26 ++++++++++++++----- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/testSrc/com/intellij/formatting/BulkChangesMergerTest.java b/platform/lang-impl/testSrc/com/intellij/formatting/BulkChangesMergerTest.java index 34cfbd154679..36b46eb302ec 100644 --- a/platform/lang-impl/testSrc/com/intellij/formatting/BulkChangesMergerTest.java +++ b/platform/lang-impl/testSrc/com/intellij/formatting/BulkChangesMergerTest.java @@ -116,6 +116,12 @@ public class BulkChangesMergerTest { public void insufficientLengthForInplaceMerge() { doTest("0123", "", c("", 1, 3), c("abc", 4)); } + + @Config(inplace = true) + @Test + public void overlapWithPositiveGroupOnStart() { + doTest("0123456789ABC", "0abc1358d9eBC", c("abc", 1), c("", 2, 3), c("", 4, 5), c("", 6, 8), c("d", 9), c("e", 10, 11)); + } private static TextChangeImpl c(String text, int offset) { return c(text, offset, offset); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/BulkChangesMerger.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/BulkChangesMerger.java index a23ad662b501..49c056bc5f42 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/BulkChangesMerger.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/BulkChangesMerger.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.editor.impl; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.TextChange; import org.jetbrains.annotations.NotNull; @@ -33,6 +34,7 @@ import java.util.List; public class BulkChangesMerger { public static final BulkChangesMerger INSTANCE = new BulkChangesMerger(); + private static final Logger LOG = Logger.getInstance("#" + BulkChangesMerger.class.getName()); /** * Merges given changes within the given text and returns result as a new char sequence. @@ -105,7 +107,7 @@ public class BulkChangesMerger { throws IllegalArgumentException { // Consider two corner cases: - // 1. Every given change increase text length, i.e. change text length is more than changed region length. We can calculate + // 1. Every given change increases text length, i.e. change text length is more than changed region length. We can calculate // resulting text length and start merging the changes from the right end then; // 2. Every given change reduces text length, start from the left end then; // The general idea is to group all of the given changes by 'add text'/ 'remove text' criteria and process them sequentially. @@ -118,7 +120,7 @@ public class BulkChangesMerger { // 6) replace one symbol by three (diff +2); // Algorithm: // 1. Define the first group of change. First change diff is '+3', hence, iterate all changes until the resulting diff becomes - // equal or less to the zero. So, the first four changes conduct the first group. Initial change increased text length, hence, + // less or equal to the zero. So, the first four changes conduct the first group. Initial change increased text length, hence, // we process the changes from right to left starting at offset '4-th change start + 1'; // 2. Current diff is '-2' (4-th change diff is '-3' and one slot was necessary for previous group completion), so, that means // that we should process the 4-th and 5-th changes as the second group. Initial change direction is negative, hence, we @@ -138,12 +140,22 @@ public class BulkChangesMerger { + "minimum size: %d", data.length, length + diff )); } - - for (Context context = new Context(changes, data, length, length + diff); !context.isComplete();) { - if (!context.startGroup()) { - return; + + try { + for (Context context = new Context(changes, data, length, length + diff); !context.isComplete();) { + if (!context.startGroup()) { + return; + } + context.endGroup(); } - context.endGroup(); + } + catch (RuntimeException e) { + LOG.error(String.format( + "Invalid attempt to perform in-place document changes merge detected. Initial text length: %d, changes: %s, " + + "changes diff: %d, initial text: '%s'", length, changes, diff, Arrays.toString(data) + ), e); + char[] merged = mergeToCharArray(data, length, changes); + System.arraycopy(merged, 0, data, 0, length + diff); } } From e09ae18d6bc682222fdccfda12ba34b4d66e995a Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 15 Apr 2011 10:11:58 +0400 Subject: [PATCH 083/100] extracted non java specific code from value markers in debugger --- .../debugger/actions/MarkObjectAction.java | 31 +++- .../actions/ObjectMarkupPropertiesDialog.form | 29 ++++ .../actions/ObjectMarkupPropertiesDialog.java | 140 ++++-------------- .../CodeFragmentFactoryContextWrapper.java | 2 +- .../ui/impl/DebuggerTreeRenderer.java | 2 +- .../debugger/ui/impl/FramesListRenderer.java | 2 +- .../ui/impl/watch/DebuggerTreeNodeImpl.java | 2 +- .../ui/impl/watch/NodeDescriptorImpl.java | 2 +- .../impl/watch/StackFrameDescriptorImpl.java | 2 +- .../ui/impl/watch/ValueDescriptorImpl.java | 2 +- .../debugger/ui/tree/ValueDescriptor.java | 1 + .../src/com/intellij/ui/ColorChooser.java | 8 +- .../tree/ValueMarkerPresentationDialog.form | 61 ++++++++ .../tree/ValueMarkerPresentationDialog.java | 97 ++++++++++++ .../xdebugger/impl}/ui/tree/ValueMarkup.java | 15 +- 15 files changed, 253 insertions(+), 143 deletions(-) create mode 100644 java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.form create mode 100644 platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.form create mode 100644 platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.java rename {java/debugger/impl/src/com/intellij/debugger => platform/xdebugger-impl/src/com/intellij/xdebugger/impl}/ui/tree/ValueMarkup.java (64%) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/MarkObjectAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/MarkObjectAction.java index f7c328d21e8d..37b129cd385f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/MarkObjectAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/MarkObjectAction.java @@ -15,6 +15,7 @@ */ package com.intellij.debugger.actions; +import com.intellij.codeInsight.daemon.impl.HighlightInfoType; import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; @@ -25,19 +26,23 @@ import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; import com.intellij.debugger.ui.tree.ValueDescriptor; -import com.intellij.debugger.ui.tree.ValueMarkup; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.intellij.idea.ActionsBundle; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.util.containers.HashMap; import com.sun.jdi.*; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Collections; import java.util.List; import java.util.Map; @@ -48,6 +53,7 @@ import java.util.Map; */ public class MarkObjectAction extends DebuggerAction { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.MarkObjectAction"); + public static final long AUTO_MARKUP_REFERRING_OBJECTS_LIMIT = 100L; // todo: some reasonable limit private final String MARK_TEXT = ActionsBundle.message("action.Debugger.MarkObject.text"); private final String UNMARK_TEXT = ActionsBundle.message("action.Debugger.MarkObject.unmark.text"); @@ -79,13 +85,17 @@ public class MarkObjectAction extends DebuggerAction { valueDescriptor.setMarkup(debugProcess, null); } else { - final ValueMarkup suggestedMarkup = new ValueMarkup(valueDescriptor.getName(), Color.RED); + final String defaultText = valueDescriptor.getName(); final Ref> result = new Ref>(null); try { final boolean suggestAdditionalMarkup = canSuggestAdditionalMarkup(debugProcess, valueDescriptor.getValue()); SwingUtilities.invokeAndWait(new Runnable() { public void run() { - result.set(ObjectMarkupPropertiesDialog.chooseMarkup(suggestedMarkup, suggestAdditionalMarkup)); + ObjectMarkupPropertiesDialog dialog = new ObjectMarkupPropertiesDialog(defaultText, suggestAdditionalMarkup); + dialog.show(); + if (dialog.isOK()) { + result.set(Pair.create(dialog.getConfiguredMarkup(), dialog.isMarkAdditionalFields())); + } } }); } @@ -176,7 +186,7 @@ public class MarkObjectAction extends DebuggerAction { final ValueMarkup markup = result.get((ObjectReference)fieldValue); final String fieldName = field.name(); - final Color autoMarkupColor = ValueMarkup.getAutoMarkupColor(); + final Color autoMarkupColor = getAutoMarkupColor(); if (markup == null) { result.put((ObjectReference)fieldValue, new ValueMarkup(fieldName, autoMarkupColor, createMarkupTooltipText(null, refType, fieldName))); } @@ -197,8 +207,9 @@ public class MarkObjectAction extends DebuggerAction { // invoke the following method using Reflection in order to remain compilable on jdk 1.5 // java.util.List referringObjects(long l); try { - final java.lang.reflect.Method apiMethod = ObjectReference.class.getMethod("referringObjects", long.class); - return (List)apiMethod.invoke(value, ValueMarkup.AUTO_MARKUP_REFERRING_OBJECTS_LIMIT); + final Method apiMethod = ObjectReference.class.getMethod("referringObjects", long.class); + //noinspection unchecked + return (List)apiMethod.invoke(value, AUTO_MARKUP_REFERRING_OBJECTS_LIMIT); } catch (IllegalAccessException e) { LOG.error(e); // should not happen @@ -211,7 +222,7 @@ public class MarkObjectAction extends DebuggerAction { return Collections.emptyList(); } - private static String createMarkupTooltipText(String prefix, ReferenceType refType, String fieldName) { + private static String createMarkupTooltipText(@Nullable String prefix, ReferenceType refType, String fieldName) { final StringBuilder builder = new StringBuilder(); if (prefix == null) { builder.append("Value referenced from:"); @@ -241,4 +252,10 @@ public class MarkObjectAction extends DebuggerAction { presentation.setVisible(enable); presentation.setText(text); } + + public static Color getAutoMarkupColor() { + final EditorColorsManager manager = EditorColorsManager.getInstance(); + final TextAttributes textAttributes = manager.getGlobalScheme().getAttributes(HighlightInfoType.STATIC_FIELD.getAttributesKey()); + return textAttributes.getForegroundColor(); + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.form b/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.form new file mode 100644 index 000000000000..a0b7a67cbe5e --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.form @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java b/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java index 7182194109ca..15ef421bdea1 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java @@ -15,140 +15,56 @@ */ package com.intellij.debugger.actions; -import com.intellij.debugger.ui.tree.ValueMarkup; -import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.FixedSizeButton; +import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.ui.ex.MultiLineLabel; -import com.intellij.openapi.util.Pair; -import com.intellij.ui.ColorChooser; -import com.intellij.ui.DocumentAdapter; -import com.intellij.ui.SimpleColoredComponent; -import com.intellij.ui.SimpleTextAttributes; -import com.intellij.util.Alarm; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkerPresentationDialog; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.event.DocumentEvent; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; /** * @author Eugene Zhuravlev * Date: Feb 4, 2007 */ -public class ObjectMarkupPropertiesDialog extends DialogWrapper { - private final JTextField myTextMarkupField; - private final JCheckBox myCbMarkAdditionalFields; - private final SimpleColoredComponent myColorSample; - private SimpleTextAttributes myAttributes; - private final Alarm myUpdateAlarm; - private static final int UPDATE_DELAY = 200; - private static Boolean ourMarkCbSavedState; +public class ObjectMarkupPropertiesDialog extends ValueMarkerPresentationDialog { + @NonNls private static final String MARK_ALL_REFERENCED_VALUES_KEY = "debugger.mark.all.referenced.values"; + private JCheckBox myCbMarkAdditionalFields; private final boolean mySuggestAdditionalMarkup; + private JPanel myAdditionalPropertiesPanel; + private MultiLineLabel myDescriptionLabel; - public ObjectMarkupPropertiesDialog(@NotNull final ValueMarkup suggestion, boolean suggestAdditionalMarkup) { - super(true); + public ObjectMarkupPropertiesDialog(@NotNull final String defaultText, boolean suggestAdditionalMarkup) { + super(defaultText); mySuggestAdditionalMarkup = suggestAdditionalMarkup; - setTitle("Select object label"); - setModal(true); - myTextMarkupField = new JTextField(30); - myCbMarkAdditionalFields = new JCheckBox("Mark values referenced from constant fields", ourMarkCbSavedState == null? suggestAdditionalMarkup : ourMarkCbSavedState); - myCbMarkAdditionalFields.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - ourMarkCbSavedState = myCbMarkAdditionalFields.isSelected(); - } - }); - myColorSample = new SimpleColoredComponent(); - myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); - myAttributes = createAttributes(suggestion.getColor()); - SwingUtilities.invokeLater(new Runnable() { - public void run() { - myTextMarkupField.setText(suggestion.getText().trim()); - updateLabelSample(0); - } - }); + myDescriptionLabel.setText("If the value is referenced by a constant field of an abstract class,\n" + + "IDEA could additionally mark all values referenced from this class with the names of referencing fields."); + myCbMarkAdditionalFields.setSelected(PropertiesComponent.getInstance().getBoolean(MARK_ALL_REFERENCED_VALUES_KEY, true)); init(); } - - public JComponent getPreferredFocusedComponent() { - return myTextMarkupField; - } - - protected void dispose() { - myUpdateAlarm.dispose(); - super.dispose(); - } - - @Nullable - protected JComponent createCenterPanel() { - final JPanel mainPanel = new JPanel(new GridBagLayout()); - mainPanel.add(new JLabel("Label:"), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); - mainPanel.add(myTextMarkupField, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); - - final JPanel samplePanel = new JPanel(new BorderLayout()); - samplePanel.add(myColorSample, BorderLayout.CENTER); - samplePanel.setBorder(BorderFactory.createEtchedBorder()); - final FixedSizeButton chooseColorButton = new FixedSizeButton(samplePanel); - - double weighty = mySuggestAdditionalMarkup ? 0.0 : 1.0; - mainPanel.add(new JLabel("Preview: "), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, weighty, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 0, 0), 0, 0)); - mainPanel.add(samplePanel, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, weighty, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 0, 0), 0, 0)); - mainPanel.add(chooseColorButton, new GridBagConstraints(2, GridBagConstraints.RELATIVE, 1, 1, 0.0, weighty, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 0, 0, 0), 0, 0)); - + @Override + protected void doOKAction() { if (mySuggestAdditionalMarkup) { - final JPanel panel = new JPanel(new BorderLayout()); - panel.add(new MultiLineLabel( - "If the value is referenced by a constant field of an abstract class,\nIDEA could additionally mark all values referenced from this class with the names of referencing fields." - ), BorderLayout.CENTER); - panel.add(myCbMarkAdditionalFields, BorderLayout.SOUTH); - myCbMarkAdditionalFields.setMnemonic('M'); - - mainPanel.add(panel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 0.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 0, 0), 0, 0)); + PropertiesComponent.getInstance().setValue(MARK_ALL_REFERENCED_VALUES_KEY, Boolean.toString(myCbMarkAdditionalFields.isSelected())); } - - myTextMarkupField.getDocument().addDocumentListener(new DocumentAdapter() { - protected void textChanged(final DocumentEvent e) { - updateLabelSample(UPDATE_DELAY); - } - }); - chooseColorButton.addActionListener(new ActionListener() { - public void actionPerformed(final ActionEvent e) { - final Color color = ColorChooser.chooseColor(myColorSample, "Choose label color", null); - myAttributes = createAttributes(color); - updateLabelSample(UPDATE_DELAY); - } - }); - return mainPanel; + super.doOKAction(); } - private void updateLabelSample(final int updateDelay) { - myUpdateAlarm.cancelAllRequests(); - myUpdateAlarm.addRequest(new Runnable() { - public void run() { - myColorSample.clear(); - myColorSample.append(myTextMarkupField.getText().trim(), myAttributes); - myColorSample.repaint(); - } - }, updateDelay); - } - - public static Pair chooseMarkup(ValueMarkup suggestion, boolean suggestAdditionalMarkup) { - final ObjectMarkupPropertiesDialog dialog = new ObjectMarkupPropertiesDialog(suggestion, suggestAdditionalMarkup); - dialog.show(); - if (dialog.isOK()) { - final String text = dialog.myTextMarkupField.getText().trim(); - final Color color = dialog.myAttributes.getFgColor(); - return text.length() > 0? new Pair(new ValueMarkup(text, color, suggestion.getToolTipText()), dialog.myCbMarkAdditionalFields.isSelected()) : null; + @Override + protected JComponent createCenterPanel() { + JComponent mainPanel = super.createCenterPanel(); + if (!mySuggestAdditionalMarkup) { + return mainPanel; } - return null; + JPanel panel = new JPanel(new BorderLayout()); + panel.add(BorderLayout.CENTER, mainPanel); + panel.add(BorderLayout.SOUTH, myAdditionalPropertiesPanel); + return panel; } - private static SimpleTextAttributes createAttributes(final Color color) { - return new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, color); + public boolean isMarkAdditionalFields() { + return myCbMarkAdditionalFields.isSelected(); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/CodeFragmentFactoryContextWrapper.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/CodeFragmentFactoryContextWrapper.java index cda720cb0897..8c2a1de39bc4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/CodeFragmentFactoryContextWrapper.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/CodeFragmentFactoryContextWrapper.java @@ -18,7 +18,7 @@ package com.intellij.debugger.engine.evaluation; import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; -import com.intellij.debugger.ui.tree.ValueMarkup; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java index 47987f3086a4..9cc837b5f151 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java @@ -20,7 +20,7 @@ import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.ui.impl.watch.*; import com.intellij.debugger.ui.tree.ValueDescriptor; -import com.intellij.debugger.ui.tree.ValueMarkup; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.ColoredTreeCellRenderer; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java index b28f350e2c2e..ccacf43c595b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java @@ -16,7 +16,7 @@ package com.intellij.debugger.ui.impl; import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; -import com.intellij.debugger.ui.tree.ValueMarkup; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.util.Comparing; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java index 02ba340ba5e1..665a6a1ad25d 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java @@ -29,7 +29,7 @@ import com.intellij.debugger.ui.impl.tree.TreeBuilderNode; import com.intellij.debugger.ui.tree.DebuggerTreeNode; import com.intellij.debugger.ui.tree.NodeDescriptor; import com.intellij.debugger.ui.tree.ValueDescriptor; -import com.intellij.debugger.ui.tree.ValueMarkup; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; import com.intellij.debugger.ui.tree.render.NodeRenderer; import com.intellij.openapi.application.ApplicationManager; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java index 92228696b128..fc9c87ad6208 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java @@ -21,7 +21,7 @@ import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.ui.tree.NodeDescriptor; -import com.intellij.debugger.ui.tree.ValueMarkup; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Key; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java index 93a257cef10e..5ed274b7aa35 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java @@ -25,7 +25,7 @@ import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.settings.ThreadsViewSettings; import com.intellij.debugger.ui.tree.StackFrameDescriptor; -import com.intellij.debugger.ui.tree.ValueMarkup; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.roots.ProjectFileIndex; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java index 8039f7083821..0895b5447e0f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java @@ -29,7 +29,7 @@ import com.intellij.debugger.jdi.VirtualMachineProxyImpl; import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.ui.tree.NodeDescriptor; import com.intellij.debugger.ui.tree.ValueDescriptor; -import com.intellij.debugger.ui.tree.ValueMarkup; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.intellij.debugger.ui.tree.render.ClassRenderer; import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; import com.intellij.debugger.ui.tree.render.NodeRenderer; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueDescriptor.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueDescriptor.java index 9c30a24ba63d..284334301e23 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueDescriptor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueDescriptor.java @@ -19,6 +19,7 @@ import com.intellij.debugger.DebuggerContext; import com.intellij.debugger.engine.DebugProcess; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.psi.PsiExpression; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.sun.jdi.Value; import org.jetbrains.annotations.Nullable; diff --git a/platform/platform-api/src/com/intellij/ui/ColorChooser.java b/platform/platform-api/src/com/intellij/ui/ColorChooser.java index a82749c87f9b..032b80104f77 100644 --- a/platform/platform-api/src/com/intellij/ui/ColorChooser.java +++ b/platform/platform-api/src/com/intellij/ui/ColorChooser.java @@ -15,6 +15,8 @@ */ package com.intellij.ui; +import org.jetbrains.annotations.Nullable; + import javax.swing.*; import java.awt.*; import java.lang.reflect.Field; @@ -27,7 +29,7 @@ import java.lang.reflect.Field; public class ColorChooser { private ColorChooser() {} - public static Color chooseColor(Component parent, String caption, Color preselectedColor) { + public static Color chooseColor(Component parent, String caption, @Nullable Color preselectedColor) { Color c = JColorChooser.showDialog(parent, caption, preselectedColor); try { // JColorChooser.ColorChooserDialog.cancelButton static field leaks parent dialogs thus finally Project. sigh... @@ -51,8 +53,6 @@ public class ColorChooser { catch (Exception e) { // Do nothing. Something changed in JColorChooser so we've failed to avoid memory leak in worst case. } - finally { - return c; - } + return c; } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.form b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.form new file mode 100644 index 000000000000..1a09d3670a7a --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.form @@ -0,0 +1,61 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.java new file mode 100644 index 000000000000..57164045b3d8 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkerPresentationDialog.java @@ -0,0 +1,97 @@ +/* + * 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.xdebugger.impl.ui.tree; + +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.FixedSizeButton; +import com.intellij.ui.ColorChooser; +import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.SimpleTextAttributes; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author nik + */ +public abstract class ValueMarkerPresentationDialog extends DialogWrapper { + private static final Color DEFAULT_COLOR = Color.RED; + private SimpleColoredComponent myColorSample; + private Color myColor; + private JPanel myMainPanel; + private JTextField myLabelField; + private FixedSizeButton myChooseColorButton; + private JPanel mySamplePanel; + + public ValueMarkerPresentationDialog(final @Nullable String defaultText) { + super(true); + setTitle("Select Object Label"); + setModal(true); + myLabelField.getDocument().addDocumentListener(new DocumentAdapter() { + protected void textChanged(final DocumentEvent e) { + updateLabelSample(); + } + }); + myChooseColorButton.addActionListener(new ActionListener() { + public void actionPerformed(final ActionEvent e) { + final Color color = ColorChooser.chooseColor(myColorSample, "Choose Label Color", myColor); + if (color != null) { + myColor = color; + updateLabelSample(); + } + } + }); + myColor = DEFAULT_COLOR; + if (defaultText != null) { + myLabelField.setText(defaultText.trim()); + updateLabelSample(); + } + } + + public JComponent getPreferredFocusedComponent() { + return myLabelField; + } + + @Override + protected JComponent createCenterPanel() { + return myMainPanel; + } + + private void updateLabelSample() { + myColorSample.clear(); + SimpleTextAttributes attributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, myColor); + myColorSample.append(myLabelField.getText().trim(), attributes); + } + + @Nullable + public ValueMarkup getConfiguredMarkup() { + final String text = myLabelField.getText().trim(); + return text.isEmpty() ? null : new ValueMarkup(text, myColor, null); + } + + private void createUIComponents() { + myColorSample = new SimpleColoredComponent(); + mySamplePanel = new JPanel(new BorderLayout()); + mySamplePanel.setBorder(BorderFactory.createEtchedBorder()); + mySamplePanel.add(BorderLayout.CENTER, myColorSample); + myChooseColorButton = new FixedSizeButton(mySamplePanel); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueMarkup.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkup.java similarity index 64% rename from java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueMarkup.java rename to platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkup.java index ed4ec28f2b83..06a45c48b09b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueMarkup.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/ValueMarkup.java @@ -13,11 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.debugger.ui.tree; +package com.intellij.xdebugger.impl.ui.tree; -import com.intellij.codeInsight.daemon.impl.HighlightInfoType; -import com.intellij.openapi.editor.colors.EditorColorsManager; -import com.intellij.openapi.editor.markup.TextAttributes; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -28,8 +25,6 @@ import java.awt.*; * Date: Jan 27, 2007 */ public class ValueMarkup { - public static final long AUTO_MARKUP_REFERRING_OBJECTS_LIMIT = 100L; // todo: some reasonable limit - private final String myText; private final Color myColor; @Nullable @@ -39,7 +34,7 @@ public class ValueMarkup { this(text, color, null); } - public ValueMarkup(final String text, final Color color, String toolTipText) { + public ValueMarkup(final String text, final Color color, @Nullable String toolTipText) { myText = text; myColor = color; myToolTipText = toolTipText; @@ -58,10 +53,4 @@ public class ValueMarkup { public String getToolTipText() { return myToolTipText; } - - public static Color getAutoMarkupColor() { - final EditorColorsManager manager = EditorColorsManager.getInstance(); - final TextAttributes textAttributes = manager.getGlobalScheme().getAttributes(HighlightInfoType.STATIC_FIELD.getAttributesKey()); - return textAttributes.getForegroundColor(); - } } From 57c4e31d08fa0e2214bc1dce050a06bb6ab3d249 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 15 Apr 2011 10:35:43 +0400 Subject: [PATCH 084/100] EA-25105 - NPE: XDebuggerUtilImpl.iterateLine --- .../src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java index 2f79a7efdcbd..d5094a6f6b8a 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java @@ -209,6 +209,8 @@ public class XDebuggerUtilImpl extends XDebuggerUtil { public void iterateLine(@NotNull Project project, @NotNull Document document, int line, @NotNull Processor processor) { PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); + if (file == null) return; + int lineStart; int lineEnd; From 2b406b1771e9ef64def28f978dd24171e6ed1e93 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 15 Apr 2011 11:37:14 +0400 Subject: [PATCH 085/100] notnullification --- .../src/com/intellij/xdebugger/XDebugProcess.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java index 514bb10bc0e6..9a2079acb9b4 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java @@ -22,7 +22,6 @@ import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.ui.ExecutionConsole; import com.intellij.execution.ui.RunnerLayoutUi; import com.intellij.openapi.actionSystem.DefaultActionGroup; -import com.intellij.openapi.util.Ref; import com.intellij.xdebugger.breakpoints.XBreakpointHandler; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.stepping.XSmartStepIntoHandler; @@ -134,7 +133,7 @@ public abstract class XDebugProcess { /** * Check is it is possible to perform commands such as resume, step etc. And notify user if necessary - * @return true if process can actually perform user requests at this moment + * @return {@code true} if process can actually perform user requests at this moment */ public boolean checkCanPerformCommands() { return true; From 02779a99c3001c9367853b06a8247e31e9f22b3b Mon Sep 17 00:00:00 2001 From: andrey zaytsev Date: Fri, 15 Apr 2011 14:21:41 +0400 Subject: [PATCH 086/100] IDEA-68148 --- .../src/com/intellij/find/impl/FindDialog.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java index 0f818f3e59f6..b713ee70980c 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java @@ -97,7 +97,7 @@ class FindDialog extends DialogWrapper { private final FindModel myModel; private final Runnable myOkHandler; private FixedSizeButton mySelectDirectoryButton; - private StateRestoringCheckBox useFileFilter; + private StateRestoringCheckBox myUseFileFilter; private ComboBox myFileFilter; private JCheckBox myCbToSkipResultsWhenOneUsage; private final Project myProject; @@ -405,7 +405,7 @@ class FindDialog extends DialogWrapper { myFileFilter = new ComboBox(100); initCombobox(myFileFilter); - filterPanel.add(useFileFilter = createCheckbox(FindBundle.message("find.filter.file.mask.checkbox")),BorderLayout.WEST); + filterPanel.add(myUseFileFilter = createCheckbox(FindBundle.message("find.filter.file.mask.checkbox")),BorderLayout.WEST); filterPanel.add(myFileFilter,BorderLayout.CENTER); myFileFilter.setEditable(true); String[] fileMasks = FindSettings.getInstance().getRecentFileMasks(); @@ -414,10 +414,10 @@ class FindDialog extends DialogWrapper { } myFileFilter.setEnabled(false); - useFileFilter.addActionListener( + myUseFileFilter.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { - if (!useFileFilter.isSelected()) { + if (!myUseFileFilter.isSelected()) { myFileFilter.setEnabled(false); } else { myFileFilter.setEnabled(true); @@ -533,7 +533,7 @@ class FindDialog extends DialogWrapper { } } - final String mask = myFileFilter == null ? null : (String)myFileFilter.getSelectedItem(); + final String mask = (myFileFilter == null || !myUseFileFilter.isSelected()) ? null : (String)myFileFilter.getSelectedItem(); if (mask != null) { if (mask.length() == 0) { @@ -1031,7 +1031,7 @@ class FindDialog extends DialogWrapper { model.setFindAll(findAll); String mask = null; - if (useFileFilter!=null && useFileFilter.isSelected()) { + if (myUseFileFilter !=null && myUseFileFilter.isSelected()) { mask = (String)myFileFilter.getSelectedItem(); } model.setFileFilter(mask); @@ -1109,7 +1109,7 @@ class FindDialog extends DialogWrapper { if (myModel.getFileFilter()!=null && myModel.getFileFilter().length() > 0) { myFileFilter.setSelectedItem(myModel.getFileFilter()); myFileFilter.setEnabled(true); - useFileFilter.setSelected(true); + myUseFileFilter.setSelected(true); } } else { From ab44fbc3e3f072c40e40572e9e812458b4c3004f Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Fri, 15 Apr 2011 14:40:45 +0400 Subject: [PATCH 087/100] IDEA-67958 in console: first character of each entered line is skipped User input is not purged on moving deferred output to the console editor --- .../com/intellij/execution/impl/ConsoleBuffer.java | 12 ++++++++++-- .../com/intellij/execution/impl/ConsoleViewImpl.java | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleBuffer.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleBuffer.java index 6a50c4d0bb42..28e5ecfb07f0 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleBuffer.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleBuffer.java @@ -95,7 +95,9 @@ public class ConsoleBuffer { private int myDeferredOutputLength; /** - * Buffer for deferred stdin and stderr output. + * Buffer for deferred stdin output. + *

+ * Is assumed to store user input data until it's delivered to the target process. That activity is driven from outside this class. */ private StringBuffer myDeferredUserInput = new StringBuffer(); @@ -201,6 +203,10 @@ public class ConsoleBuffer { } public void clear() { + clear(true); + } + + public void clear(boolean clearUserInputAsWell) { if (myUseCyclicBuffer) { myDeferredOutput.clear(); myDeferredOutput.add(new StringBuilder(myCyclicBufferUnitSize)); @@ -212,8 +218,10 @@ public class ConsoleBuffer { } myDeferredOutputLength = 0; myDeferredTypes.clear(); - myDeferredUserInput = new StringBuffer(); myDeferredTokens.clear(); + if (clearUserInputAsWell) { + myDeferredUserInput = new StringBuffer(); + } } @Nullable diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java index c2c091863bc6..401ce8fda28a 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java @@ -563,7 +563,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo addToken(deferredToken.getLength(), deferredToken.getHyperlinkInfo(), deferredToken.contentType); } deferredTokensSize = deferredTokens.size(); - myBuffer.clear(); + myBuffer.clear(false); } final Document document = myEditor.getDocument(); final int oldLineCount = document.getLineCount(); From 40ea2114811089c5bff9cf35b71f81dc01ac6db0 Mon Sep 17 00:00:00 2001 From: andrey zaytsev Date: Fri, 15 Apr 2011 15:00:29 +0400 Subject: [PATCH 088/100] OC-662 --- .../util/xml/impl/DomManagerImpl.java | 3 ++- .../ide/highlighter/DomSupportEnabled.java | 26 +++++++++++++++++++ .../intellij/ide/highlighter/XmlFileType.java | 2 +- 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 xml/impl/src/com/intellij/ide/highlighter/DomSupportEnabled.java diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java index 4c46c38775bb..10b8cc700921 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java @@ -1,5 +1,6 @@ package com.intellij.util.xml.impl; +import com.intellij.ide.highlighter.DomSupportEnabled; import com.intellij.ide.startup.StartupManagerEx; import com.intellij.openapi.Disposable; import com.intellij.openapi.components.ServiceManager; @@ -337,7 +338,7 @@ public final class DomManagerImpl extends DomManager { @Nullable public final DomFileElementImpl getFileElement(XmlFile file) { if (file == null) return null; - if (!StdFileTypes.XML.equals(file.getFileType())) return null; + if (file.getFileType() instanceof DomSupportEnabled) return null; final VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile != null && virtualFile.isDirectory()) return null; return this.getOrCreateCachedValueProvider(file).getFileElement(); diff --git a/xml/impl/src/com/intellij/ide/highlighter/DomSupportEnabled.java b/xml/impl/src/com/intellij/ide/highlighter/DomSupportEnabled.java new file mode 100644 index 000000000000..ff27af059112 --- /dev/null +++ b/xml/impl/src/com/intellij/ide/highlighter/DomSupportEnabled.java @@ -0,0 +1,26 @@ +/* + * 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.highlighter; + +/** + * Created by IntelliJ IDEA. + * User: zajac + * Date: 15.04.11 + * Time: 14:57 + * To change this template use File | Settings | File Templates. + */ +public interface DomSupportEnabled { +} diff --git a/xml/impl/src/com/intellij/ide/highlighter/XmlFileType.java b/xml/impl/src/com/intellij/ide/highlighter/XmlFileType.java index 5b90121be6ef..1a720d69eb9d 100644 --- a/xml/impl/src/com/intellij/ide/highlighter/XmlFileType.java +++ b/xml/impl/src/com/intellij/ide/highlighter/XmlFileType.java @@ -24,7 +24,7 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; -public class XmlFileType extends XmlLikeFileType { +public class XmlFileType extends XmlLikeFileType implements DomSupportEnabled { public static final XmlFileType INSTANCE = new XmlFileType(); @NonNls public static final String DEFAULT_EXTENSION = "xml"; @NonNls public static final String DOT_DEFAULT_EXTENSION = "."+DEFAULT_EXTENSION; From 891dea62bdae9b97f12d3a745c30d4017c41273b Mon Sep 17 00:00:00 2001 From: andrey zaytsev Date: Fri, 15 Apr 2011 15:04:39 +0400 Subject: [PATCH 089/100] sorry, previous commit is bad. --- xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java index 10b8cc700921..27e7ef1d3f97 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java @@ -338,7 +338,7 @@ public final class DomManagerImpl extends DomManager { @Nullable public final DomFileElementImpl getFileElement(XmlFile file) { if (file == null) return null; - if (file.getFileType() instanceof DomSupportEnabled) return null; + if (!(file.getFileType() instanceof DomSupportEnabled)) return null; final VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile != null && virtualFile.isDirectory()) return null; return this.getOrCreateCachedValueProvider(file).getFileElement(); From a1aeacd4991f7153d9ecf1d2621cce516a86f1e3 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 15 Apr 2011 09:40:36 +0400 Subject: [PATCH 090/100] leaks in AddAnnotationFix --- .../daemon/impl/actions/SuppressFix.java | 3 +- .../intention/AddAnnotationFix.java | 182 +++++++----------- .../impl/AddAnnotationIntention.java | 96 +++++++++ ...=> AddDeprecationAnnotationIntention.java} | 29 +-- .../impl/AddNotNullAnnotationFix.java | 13 +- .../impl/AddNotNullAnnotationIntention.java | 45 +++++ .../impl/AddNullableAnnotationFix.java | 12 +- .../impl/AddNullableAnnotationIntention.java | 45 +++++ .../impl/AddNullableNotNullAnnotationFix.java | 16 +- .../impl/AddOverrideAnnotationAction.java | 4 +- .../codeInspection/AnnotateMethodFix.java | 2 +- ...ossibleHeapPollutionVarargsInspection.java | 6 +- .../AnnotateOverriddenMethodParameterFix.java | 3 +- .../nullable/NullableStuffInspection.java | 114 +++++++---- .../daemon/quickFix/AnnotateMethodTest.java | 23 ++- .../src/messages/CodeInsightBundle.properties | 1 - .../StringConcatenationInspection.java | 4 +- .../tostring/GenerateToStringWorker.java | 5 +- .../relaxNG/inspections/BaseInspection.java | 6 +- resources/src/META-INF/IdeaPlugin.xml | 6 +- 20 files changed, 389 insertions(+), 226 deletions(-) create mode 100644 java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java rename java/java-impl/src/com/intellij/codeInsight/intention/impl/{AddDeprecationAnnotationFix.java => AddDeprecationAnnotationIntention.java} (51%) create mode 100644 java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationIntention.java create mode 100644 java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationIntention.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/actions/SuppressFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/actions/SuppressFix.java index f647d669e1ca..c8ff3bed488d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/actions/SuppressFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/actions/SuppressFix.java @@ -140,7 +140,8 @@ public class SuppressFix extends SuppressIntentionAction { if (newAnnotation != null) { if (annotation != null && annotation.isPhysical()) { annotation.replace(newAnnotation); - } else { + } + else { final PsiNameValuePair[] attributes = newAnnotation.getParameterList().getAttributes(); new AddAnnotationFix(SuppressManager.SUPPRESS_INSPECTIONS_ANNOTATION_NAME, modifierOwner, attributes).invoke(project, editor, container.getContainingFile()); } diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/AddAnnotationFix.java b/java/java-impl/src/com/intellij/codeInsight/intention/AddAnnotationFix.java index 0088f7be3f7f..2d31bbb0971d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/AddAnnotationFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/AddAnnotationFix.java @@ -20,71 +20,59 @@ import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.CodeInsightUtilBase; import com.intellij.codeInsight.ExternalAnnotationsManager; -import com.intellij.codeInspection.LocalQuickFix; -import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement; import com.intellij.lang.findUsages.FindUsagesProvider; import com.intellij.lang.findUsages.LanguageFindUsages; import com.intellij.openapi.command.undo.UndoUtil; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; -import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; -import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * @author ven */ -public class AddAnnotationFix extends PsiElementBaseIntentionAction implements LocalQuickFix { - private final String myAnnotation; - private final PsiModifierListOwner myModifierListOwner; +public class AddAnnotationFix extends LocalQuickFixAndIntentionActionOnPsiElement { + protected final String myAnnotation; private final String[] myAnnotationsToRemove; - private final PsiNameValuePair[] myPairs; + private final PsiNameValuePair[] myPairs; // not used when registering local quick fix private static final Logger LOG = Logger.getInstance("#" + AddAnnotationFix.class.getName()); + private final String myText; - public AddAnnotationFix(String fqn, PsiModifierListOwner modifierListOwner, String... annotationsToRemove) { - myAnnotation = fqn; - myModifierListOwner = modifierListOwner; - myAnnotationsToRemove = annotationsToRemove; - myPairs = null; + public AddAnnotationFix(@NotNull String fqn, @NotNull PsiModifierListOwner modifierListOwner, @NotNull String... annotationsToRemove) { + this(fqn, modifierListOwner, PsiNameValuePair.EMPTY_ARRAY, annotationsToRemove); } - public AddAnnotationFix(String fqn, PsiModifierListOwner modifierListOwner, PsiNameValuePair[] values, String... annotationsToRemove) { + public AddAnnotationFix(@NotNull String fqn, @NotNull PsiModifierListOwner modifierListOwner, @NotNull PsiNameValuePair[] values, @NotNull String... annotationsToRemove) { + super(modifierListOwner); myAnnotation = fqn; - myModifierListOwner = modifierListOwner; myAnnotationsToRemove = annotationsToRemove; myPairs = values; + + myText = calcText(modifierListOwner, myAnnotation); } - public AddAnnotationFix(@NonNls final String fqn, @NonNls String... annotationsToRemove) { - this(fqn, null,annotationsToRemove); + public static String calcText(PsiModifierListOwner modifierListOwner, @NotNull String annotation) { + final String shortName = annotation.substring(annotation.lastIndexOf('.') + 1); + if (modifierListOwner instanceof PsiNamedElement) { + final String name = ((PsiNamedElement)modifierListOwner).getName(); + if (name != null) { + FindUsagesProvider provider = LanguageFindUsages.INSTANCE.forLanguage(modifierListOwner.getLanguage()); + return CodeInsightBundle + .message("inspection.i18n.quickfix.annotate.element.as", provider.getType(modifierListOwner), name, shortName); + } + } + return CodeInsightBundle.message("inspection.i18n.quickfix.annotate.as", shortName); } @NotNull public String getText() { - final String shortName = myAnnotation.substring(myAnnotation.lastIndexOf('.') + 1); - if (myModifierListOwner instanceof PsiNamedElement) { - final String name = ((PsiNamedElement)myModifierListOwner).getName(); - if (name != null) { - FindUsagesProvider provider = LanguageFindUsages.INSTANCE.forLanguage(myModifierListOwner.getLanguage()); - return CodeInsightBundle.message("inspection.i18n.quickfix.annotate.element.as", provider.getType(myModifierListOwner), name, shortName); - } - } - return myModifierListOwner != null ? - CodeInsightBundle.message("inspection.i18n.quickfix.annotate.as", shortName) : - CodeInsightBundle.message("add.external.annotation.test", shortName); - } - - @NotNull - public String getName() { - return getText(); + return myText; } @NotNull @@ -92,17 +80,13 @@ public class AddAnnotationFix extends PsiElementBaseIntentionAction implements L return CodeInsightBundle.message("intention.add.annotation.family"); } - public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - try { - invoke(project, null, descriptor.getPsiElement().getContainingFile()); - } - catch (IncorrectOperationException e) { - LOG.error(e); - } + @Override + public boolean startInWriteAction() { + return true; } @Nullable - protected static PsiModifierListOwner getContainer(final PsiElement element) { + public static PsiModifierListOwner getContainer(final PsiElement element) { PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(element, PsiParameter.class, false); if (listOwner == null) { final PsiIdentifier psiIdentifier = PsiTreeUtil.getParentOfType(element, PsiIdentifier.class, false); @@ -113,86 +97,60 @@ public class AddAnnotationFix extends PsiElementBaseIntentionAction implements L return listOwner; } - public boolean isAvailable(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) { - if (!element.isValid()) return false; - if (!PsiUtil.isLanguageLevel5OrHigher(element)) return false; - final PsiModifierListOwner owner; - if (myModifierListOwner != null) { - if (!myModifierListOwner.isValid()) return false; - //if (!PsiManager.getInstance(project).isInProject(myModifierListOwner) - // || myModifierListOwner.getModifierList() == null) { - // if (!myModifierListOwner.isPhysical()) { //we might want to apply fix to just created method - // return true; - // } - //} - - owner = myModifierListOwner; - } - else if (!element.getManager().isInProject(element) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) { - owner = getContainer(element); - } - else { - owner = null; - } - return owner != null && !AnnotationUtil.isAnnotated(owner, myAnnotation, false); + @Override + public boolean isAvailable(@NotNull Project project, + @NotNull PsiFile file, + @NotNull PsiElement startElement, + @NotNull PsiElement endElement) { + if (!startElement.isValid()) return false; + if (!PsiUtil.isLanguageLevel5OrHigher(startElement)) return false; + final PsiModifierListOwner myModifierListOwner = (PsiModifierListOwner)startElement; + + return !AnnotationUtil.isAnnotated(myModifierListOwner, myAnnotation, false); } @Override - public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) { - final PsiElement element; - if (myModifierListOwner != null) { - element = myModifierListOwner; - } - else { - final CaretModel caretModel = editor.getCaretModel(); - final int position = caretModel.getOffset(); - element = file.findElementAt(position); - } - return element != null && isAvailable(project, editor, element); - } + public void invoke(@NotNull Project project, + @NotNull PsiFile file, + @Nullable("is null when called from inspection") Editor editor, + @NotNull PsiElement startElement, + @NotNull PsiElement endElement) { + final PsiModifierListOwner myModifierListOwner = (PsiModifierListOwner)startElement; - public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { final ExternalAnnotationsManager annotationsManager = ExternalAnnotationsManager.getInstance(project); - if (myModifierListOwner != null) { - final PsiModifierList modifierList = myModifierListOwner.getModifierList(); - LOG.assertTrue(modifierList != null); - if (modifierList.findAnnotation(myAnnotation) != null) return; - final ExternalAnnotationsManager.AnnotationPlace annotationAnnotationPlace = annotationsManager.chooseAnnotationsPlace(myModifierListOwner); - if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.NOWHERE) return; - if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.EXTERNAL) { - for (String fqn : myAnnotationsToRemove) { - annotationsManager.deannotate(myModifierListOwner, fqn); - } - annotationsManager.annotateExternally(myModifierListOwner, myAnnotation, file, myPairs); - } - else { - final PsiFile containingFile = myModifierListOwner.getContainingFile(); - if (!CodeInsightUtilBase.preparePsiElementForWrite(containingFile)) return; - for (String fqn : myAnnotationsToRemove) { - PsiAnnotation annotation = AnnotationUtil.findAnnotation(myModifierListOwner, fqn); - if (annotation != null) { - annotation.delete(); - } - } - - final @NotNull PsiAnnotation inserted = modifierList.addAnnotation(myAnnotation); - if (myPairs != null) { - for (PsiNameValuePair pair : myPairs) { - inserted.setDeclaredAttributeValue(pair.getName(), pair.getValue()); - } - } - JavaCodeStyleManager.getInstance(project).shortenClassReferences(inserted); - if (containingFile != file) { - UndoUtil.markPsiFileForUndo(file); - } + final PsiModifierList modifierList = myModifierListOwner.getModifierList(); + LOG.assertTrue(modifierList != null); + if (modifierList.findAnnotation(myAnnotation) != null) return; + final ExternalAnnotationsManager.AnnotationPlace annotationAnnotationPlace = annotationsManager.chooseAnnotationsPlace(myModifierListOwner); + if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.NOWHERE) return; + if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.EXTERNAL) { + for (String fqn : myAnnotationsToRemove) { + annotationsManager.deannotate(myModifierListOwner, fqn); } + annotationsManager.annotateExternally(myModifierListOwner, myAnnotation, file, myPairs); } else { - final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); - annotationsManager.annotateExternally(PsiTreeUtil.getParentOfType(element, PsiModifierListOwner.class, false), myAnnotation, file, null); + final PsiFile containingFile = myModifierListOwner.getContainingFile(); + if (!CodeInsightUtilBase.preparePsiElementForWrite(containingFile)) return; + for (String fqn : myAnnotationsToRemove) { + PsiAnnotation annotation = AnnotationUtil.findAnnotation(myModifierListOwner, fqn); + if (annotation != null) { + annotation.delete(); + } + } + + PsiAnnotation inserted = modifierList.addAnnotation(myAnnotation); + for (PsiNameValuePair pair : myPairs) { + inserted.setDeclaredAttributeValue(pair.getName(), pair.getValue()); + } + JavaCodeStyleManager.getInstance(project).shortenClassReferences(inserted); + if (containingFile != file) { + UndoUtil.markPsiFileForUndo(file); + } } } + @NotNull public String[] getAnnotationsToRemove() { return myAnnotationsToRemove; } diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java new file mode 100644 index 000000000000..c115b96f83ce --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java @@ -0,0 +1,96 @@ +/* + * 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. + */ + +/* + * Created by IntelliJ IDEA. + * User: cdr + * Date: Jul 20, 2007 + * Time: 2:57:38 PM + */ +package com.intellij.codeInsight.intention.impl; + +import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.intention.AddAnnotationFix; +import com.intellij.openapi.editor.CaretModel; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; + +public abstract class AddAnnotationIntention extends BaseIntentionAction { + @NotNull + @Override + public String getFamilyName() { + return CodeInsightBundle.message("intention.add.annotation.family"); + } + + @NotNull + public abstract Pair getAnnotations(@NotNull Project project); + + // include not in project files + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + CaretModel caretModel = editor.getCaretModel(); + int position = caretModel.getOffset(); + PsiElement element = file.findElementAt(position); + return element != null && isAvailable(project, element); + } + + public boolean isAvailable(@NotNull final Project project, @NotNull final PsiElement element) { + if (!element.isValid()) return false; + if (!PsiUtil.isLanguageLevel5OrHigher(element)) return false; + final PsiModifierListOwner owner; + if (!element.getManager().isInProject(element) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) { + owner = AddAnnotationFix.getContainer(element); + } + else { + return false; + } + if (owner == null) return false; + Pair annotations = getAnnotations(project); + String toAdd = annotations.first; + String[] toRemove = annotations.second; + if (toRemove.length > 0 && AnnotationUtil.isAnnotated(owner, toRemove[0], false)) return false; + setText(AddAnnotationFix.calcText(owner, toAdd)); + if (AnnotationUtil.isAnnotated(owner, toAdd, false)) return false; + + if (owner instanceof PsiMethod) { + PsiType returnType = ((PsiMethod)owner).getReturnType(); + + return returnType != null && !(returnType instanceof PsiPrimitiveType); + } + return true; + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + CaretModel caretModel = editor.getCaretModel(); + int position = caretModel.getOffset(); + PsiElement element = file.findElementAt(position); + + PsiModifierListOwner owner = AddAnnotationFix.getContainer(element); + if (owner == null || !owner.isValid()) return; + Pair annotations = getAnnotations(project); + String toAdd = annotations.first; + String[] toRemove = annotations.second; + AddAnnotationFix fix = new AddAnnotationFix(toAdd, owner, toRemove); + fix.invoke(project, editor, file); + } +} \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddDeprecationAnnotationFix.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddDeprecationAnnotationIntention.java similarity index 51% rename from java/java-impl/src/com/intellij/codeInsight/intention/impl/AddDeprecationAnnotationFix.java rename to java/java-impl/src/com/intellij/codeInsight/intention/impl/AddDeprecationAnnotationIntention.java index c8e21c39d886..bcc4e4c1cb5d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddDeprecationAnnotationFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddDeprecationAnnotationIntention.java @@ -22,32 +22,15 @@ */ package com.intellij.codeInsight.intention.impl; -import com.intellij.codeInsight.intention.AddAnnotationFix; -import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.psi.*; +import com.intellij.openapi.util.Pair; +import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; -public class AddDeprecationAnnotationFix extends AddAnnotationFix { - public AddDeprecationAnnotationFix() { - super("java.lang.annotation.Deprecated"); - } - - +public class AddDeprecationAnnotationIntention extends AddAnnotationIntention { + @NotNull @Override - public boolean isAvailable(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) { - if (!super.isAvailable(project, editor, element)) { - return false; - } - PsiModifierListOwner owner = getContainer(element); - if (owner == null) { - return false; - } - if (owner instanceof PsiMethod) { - PsiType returnType = ((PsiMethod)owner).getReturnType(); - - return returnType != null && !(returnType instanceof PsiPrimitiveType); - } - return true; + public Pair getAnnotations(@NotNull Project project) { + return new Pair("java.lang.annotation.Deprecated", ArrayUtil.EMPTY_STRING_ARRAY); } } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationFix.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationFix.java index 86a23fcce8f1..dd04cd154ded 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationFix.java @@ -22,26 +22,23 @@ */ package com.intellij.codeInsight.intention.impl; -import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.psi.PsiModifierListOwner; import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; import java.util.List; public class AddNotNullAnnotationFix extends AddNullableNotNullAnnotationFix { - @Deprecated - public AddNotNullAnnotationFix() { - super(AnnotationUtil.NOT_NULL, AnnotationUtil.NULLABLE); - } - public AddNotNullAnnotationFix(PsiModifierListOwner owner) { + public AddNotNullAnnotationFix(@NotNull PsiModifierListOwner owner) { super(NullableNotNullManager.getInstance(owner.getProject()).getDefaultNotNull(), owner, getNullables(owner)); } - private static String[] getNullables(PsiModifierListOwner owner) { + @NotNull + private static String[] getNullables(@NotNull PsiModifierListOwner owner) { final List nullables = NullableNotNullManager.getInstance(owner.getProject()).getNullables(); return ArrayUtil.toStringArray(nullables); } -} \ No newline at end of file +} diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationIntention.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationIntention.java new file mode 100644 index 000000000000..b5e322503b4c --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationIntention.java @@ -0,0 +1,45 @@ +/* + * 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. + */ + +/* + * Created by IntelliJ IDEA. + * User: cdr + * Date: Jul 20, 2007 + * Time: 2:57:38 PM + */ +package com.intellij.codeInsight.intention.impl; + +import com.intellij.codeInsight.NullableNotNullManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class AddNotNullAnnotationIntention extends AddAnnotationIntention { + @NotNull + @Override + public Pair getAnnotations(@NotNull Project project) { + return new Pair(NullableNotNullManager.getInstance(project).getDefaultNotNull(), getNullables(project)); + } + + @NotNull + private static String[] getNullables(@NotNull Project project) { + final List nullables = NullableNotNullManager.getInstance(project).getNullables(); + return ArrayUtil.toStringArray(nullables); + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationFix.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationFix.java index cc995bf84509..9d6a4f1057b1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationFix.java @@ -22,26 +22,22 @@ */ package com.intellij.codeInsight.intention.impl; -import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.psi.PsiModifierListOwner; import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; import java.util.List; public class AddNullableAnnotationFix extends AddNullableNotNullAnnotationFix { - @Deprecated - public AddNullableAnnotationFix() { - super(AnnotationUtil.NULLABLE, AnnotationUtil.NOT_NULL); - } - - public AddNullableAnnotationFix(PsiModifierListOwner owner) { + public AddNullableAnnotationFix(@NotNull PsiModifierListOwner owner) { super(NullableNotNullManager.getInstance(owner.getProject()).getDefaultNullable(), owner, getNotNulls(owner)); } - private static String[] getNotNulls(PsiModifierListOwner owner) { + @NotNull + private static String[] getNotNulls(@NotNull PsiModifierListOwner owner) { final List notnulls = NullableNotNullManager.getInstance(owner.getProject()).getNotNulls(); return ArrayUtil.toStringArray(notnulls); } diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationIntention.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationIntention.java new file mode 100644 index 000000000000..3979218b069a --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationIntention.java @@ -0,0 +1,45 @@ +/* + * 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. + */ + +/* + * Created by IntelliJ IDEA. + * User: cdr + * Date: Jul 20, 2007 + * Time: 2:57:59 PM + */ +package com.intellij.codeInsight.intention.impl; + +import com.intellij.codeInsight.NullableNotNullManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class AddNullableAnnotationIntention extends AddAnnotationIntention { + @NotNull + @Override + public Pair getAnnotations(@NotNull Project project) { + return new Pair(NullableNotNullManager.getInstance(project).getDefaultNullable(), getNotNulls(project)); + } + + @NotNull + private static String[] getNotNulls(@NotNull Project project) { + final List notnulls = NullableNotNullManager.getInstance(project).getNotNulls(); + return ArrayUtil.toStringArray(notnulls); + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java index 30428a04233d..fee586a57aee 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java @@ -24,26 +24,24 @@ package com.intellij.codeInsight.intention.impl; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.intention.AddAnnotationFix; -import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; public class AddNullableNotNullAnnotationFix extends AddAnnotationFix { - public AddNullableNotNullAnnotationFix(final String annotation, final String... annotationToRemove) { - super(annotation, annotationToRemove); - } - - public AddNullableNotNullAnnotationFix(final String fqn, final PsiModifierListOwner owner, final String... annotationToRemove) { + public AddNullableNotNullAnnotationFix(@NotNull String fqn, @NotNull PsiModifierListOwner owner, @NotNull String... annotationToRemove) { super(fqn, owner, annotationToRemove); } @Override - public boolean isAvailable(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) { - if (!super.isAvailable(project, editor, element)) { + public boolean isAvailable(@NotNull Project project, + @NotNull PsiFile file, + @NotNull PsiElement startElement, + @NotNull PsiElement endElement) { + if (!super.isAvailable(project, file, startElement, endElement)) { return false; } - PsiModifierListOwner owner = getContainer(element); + PsiModifierListOwner owner = getContainer(startElement); if (owner == null || AnnotationUtil.isAnnotated(owner, getAnnotationsToRemove()[0], false)) { return false; } diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddOverrideAnnotationAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddOverrideAnnotationAction.java index 8a3a22b2f791..8a3e048b54e6 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddOverrideAnnotationAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddOverrideAnnotationAction.java @@ -61,7 +61,9 @@ public class AddOverrideAnnotationAction implements IntentionAction { public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { PsiMethod method = findMethod(file, editor.getCaretModel().getOffset()); - new AddAnnotationFix(JAVA_LANG_OVERRIDE, method).invoke(project, editor, file); + if (method != null) { + new AddAnnotationFix(JAVA_LANG_OVERRIDE, method).invoke(project, editor, file); + } } private static PsiMethod findMethod(PsiFile file, int offset) { diff --git a/java/java-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java b/java/java-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java index 62949153b313..740891f12c8f 100644 --- a/java/java-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java +++ b/java/java-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java @@ -109,7 +109,7 @@ public class AnnotateMethodFix implements LocalQuickFix { return getName(); } - private void annotateMethod(final PsiMethod method) { + private void annotateMethod(@NotNull PsiMethod method) { try { new AddAnnotationFix(myAnnotation, method, myAnnotationsToRemove).invoke(method.getProject(), null, method.getContainingFile()); } diff --git a/java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java b/java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java index 767b932079e2..8eebe7f115ef 100644 --- a/java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java @@ -25,11 +25,9 @@ import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.search.searches.OverridingMethodsSearch; import com.intellij.psi.search.searches.ReferencesSearch; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; -import sun.util.LocaleServiceProviderPool; /** * User: anna @@ -111,7 +109,9 @@ public class PossibleHeapPollutionVarargsInspection extends BaseJavaLocalInspect final PsiElement psiElement = descriptor.getPsiElement(); if (psiElement instanceof PsiIdentifier) { final PsiMethod psiMethod = (PsiMethod)psiElement.getParent(); - new AddAnnotationFix("java.lang.SafeVarargs", psiMethod).applyFix(project, descriptor); + if (psiMethod != null) { + new AddAnnotationFix("java.lang.SafeVarargs", psiMethod).applyFix(project, descriptor); + } } } } diff --git a/java/java-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java b/java/java-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java index 66caf769d4c0..eaca9acd2f6d 100644 --- a/java/java-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java +++ b/java/java-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java @@ -80,6 +80,7 @@ public class AnnotateOverriddenMethodParameterFix implements LocalQuickFix { CodeInsightUtilBase.preparePsiElementsForWrite(toAnnotate); for (PsiParameter psiParam : toAnnotate) { try { + assert psiParam != null : toAnnotate; new AddAnnotationFix(myAnnotation, psiParam, myAnnosToRemove).invoke(project, null, psiParam.getContainingFile()); } catch (IncorrectOperationException e) { @@ -92,4 +93,4 @@ public class AnnotateOverriddenMethodParameterFix implements LocalQuickFix { public String getFamilyName() { return getName(); } -} \ No newline at end of file +} diff --git a/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java b/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java index ef36d3d08461..499a3452e92d 100644 --- a/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java @@ -23,11 +23,12 @@ import com.intellij.codeInsight.intention.impl.AddNotNullAnnotationFix; import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix; import com.intellij.codeInspection.*; import com.intellij.codeInspection.ex.BaseLocalInspectionTool; -import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import com.intellij.psi.codeStyle.*; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.OverridingMethodsSearch; @@ -76,13 +77,9 @@ public class NullableStuffInspection extends BaseLocalInspectionTool { for (int i = 0, expressionsLength = expressions.length; i < Math.min(expressionsLength, parameters.length); i++) { PsiExpression psiExpression = expressions[i]; if (psiExpression.getType() == PsiType.NULL) { - if (!AnnotationUtil.isNullable(parameters[i]) && !AnnotationUtil.isNotNull(parameters[i])) { - holder.registerProblem(psiExpression, "Null is passed to parameter which is not yet @Nullable", new AddNullableAnnotationFix(parameters[i]){ - @Override - public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { - return true; - } - }); + final PsiParameter parameter = parameters[i]; + if (!AnnotationUtil.isNullable(parameter) && !AnnotationUtil.isNotNull(parameter)) { + holder.registerProblem(psiExpression, "Null is passed to parameter which is not yet @Nullable", new MyAddNullableAnnotationFix(parameter)); } } } @@ -107,21 +104,22 @@ public class NullableStuffInspection extends BaseLocalInspectionTool { final PsiMethod getter = PropertyUtil.findPropertyGetter(field.getContainingClass(), propName, isStatic, false); final String nullableSimpleName = StringUtil.getShortName(manager.getDefaultNullable()); final String notNullSimpleName = StringUtil.getShortName(manager.getDefaultNotNull()); - if (getter != null) { + final PsiIdentifier nameIdentifier = getter == null ? null : getter.getNameIdentifier(); + if (nameIdentifier != null) { if (REPORT_NOT_ANNOTATED_GETTER) { if (!AnnotationUtil.isAnnotated(getter, manager.getAllAnnotations()) && !TypeConversionUtil.isPrimitiveAndNotNull(getter.getReturnType())) { - holder.registerProblem(getter.getNameIdentifier(), InspectionsBundle + holder.registerProblem(nameIdentifier, InspectionsBundle .message("inspection.nullable.problems.annotated.field.getter.not.annotated", StringUtil.getShortName(anno)), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove))); } } if (annotated.isDeclaredNotNull && manager.isNullable(getter, false)) { - holder.registerProblem(getter.getNameIdentifier(), InspectionsBundle.message( + holder.registerProblem(nameIdentifier, InspectionsBundle.message( "inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), nullableSimpleName), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove))); } else if (annotated.isDeclaredNullable && manager.isNotNull(getter, false)) { - holder.registerProblem(getter.getNameIdentifier(), InspectionsBundle.message( + holder.registerProblem(nameIdentifier, InspectionsBundle.message( "inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), notNullSimpleName), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove))); } @@ -131,23 +129,31 @@ public class NullableStuffInspection extends BaseLocalInspectionTool { final PsiMethod setter = PropertyUtil.findPropertySetter(containingClass, propName, isStatic, false); if (setter != null) { final PsiParameter[] parameters = setter.getParameterList().getParameters(); - assert parameters.length == 1; + assert parameters.length == 1 : setter.getText(); final PsiParameter parameter = parameters[0]; + assert parameter != null : setter.getText(); if (REPORT_NOT_ANNOTATED_SETTER_PARAMETER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations()) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) { - holder.registerProblem(parameter.getNameIdentifier(), + final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier(); + assert nameIdentifier1 != null : parameter; + holder.registerProblem(nameIdentifier1, InspectionsBundle.message("inspection.nullable.problems.annotated.field.setter.parameter.not.annotated", StringUtil.getShortName(anno)), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove))); } if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) { - holder.registerProblem(parameter.getNameIdentifier(), InspectionsBundle.message( + final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier(); + assert nameIdentifier1 != null : parameter; + holder.registerProblem(nameIdentifier1, InspectionsBundle.message( "inspection.nullable.problems.annotated.field.setter.parameter.conflict", StringUtil.getShortName(anno), nullableSimpleName), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove))); - } else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) { - holder.registerProblem(parameter.getNameIdentifier(), InspectionsBundle.message( + } + else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) { + final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier(); + assert nameIdentifier1 != null : parameter; + holder.registerProblem(nameIdentifier1, InspectionsBundle.message( "inspection.nullable.problems.annotated.field.setter.parameter.conflict", StringUtil.getShortName(anno), notNullSimpleName), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove))); @@ -187,20 +193,27 @@ public class NullableStuffInspection extends BaseLocalInspectionTool { return true; } if (REPORT_NOT_ANNOTATED_SETTER_PARAMETER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations())) { - holder.registerProblem(parameter.getNameIdentifier(), InspectionsBundle + final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier(); + assert nameIdentifier2 != null : parameter; + holder.registerProblem(nameIdentifier2, InspectionsBundle .message("inspection.nullable.problems.annotated.field.constructor.parameter.not.annotated", StringUtil.getShortName(anno)), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove))); return true; } if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) { - holder.registerProblem(parameter.getNameIdentifier(), InspectionsBundle.message( + final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier(); + assert nameIdentifier2 != null : parameter; + holder.registerProblem(nameIdentifier2, InspectionsBundle.message( "inspection.nullable.problems.annotated.field.constructor.parameter.conflict", StringUtil.getShortName(anno), nullableSimpleName), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove))); - } else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) { - holder.registerProblem(parameter.getNameIdentifier(), InspectionsBundle.message( + } + else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) { + final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier(); + assert nameIdentifier2 != null : parameter; + holder.registerProblem(nameIdentifier2, InspectionsBundle.message( "inspection.nullable.problems.annotated.field.constructor.parameter.conflict", StringUtil.getShortName(anno), notNullSimpleName), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, @@ -306,14 +319,11 @@ public class NullableStuffInspection extends BaseLocalInspectionTool { && !annotated.isDeclaredNotNull && AnnotationUtil.isNotNull(superMethod)) { reported_not_annotated_method_overrides_notnull = true; + final String defaultNotNull = nullableManager.getDefaultNotNull(); + final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables()); holder.registerProblem(method.getNameIdentifier(), InspectionsBundle.message("inspection.nullable.problems.method.overrides.NotNull"), - ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix( - nullableManager.getDefaultNotNull(), ArrayUtil.toStringArray(nullableManager.getNullables())) { - public int annotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) { - return NullableStuffInspection.this.annotateBaseMethod(method, superMethod, project); - } - }); + ProblemHighlightType.GENERIC_ERROR_OR_WARNING, createAnnotateMethodFix(defaultNotNull, annotationsToRemove)); } if (REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE || REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL) { PsiParameter[] superParameters = superMethod.getParameterList().getParameters(); @@ -366,17 +376,11 @@ public class NullableStuffInspection extends BaseLocalInspectionTool { && !nullableManager.isNotNull(overriding, false)) { method.getNameIdentifier(); //load tree PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, nullableManager.getNotNulls()); + final String defaultNotNull = nullableManager.getDefaultNotNull(); + final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables()); holder.registerProblem(annotation, InspectionsBundle.message("nullable.stuff.problems.overridden.methods.are.not.annotated"), - ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(nullableManager.getDefaultNotNull(), ArrayUtil.toStringArray(nullableManager.getNullables())){ - protected boolean annotateOverriddenMethods() { - return true; - } - - @NotNull - public String getName() { - return InspectionsBundle.message("annotate.overridden.methods.as.notnull"); - } - }); + ProblemHighlightType.GENERIC_ERROR_OR_WARNING, + new MyAnnotateMethodFix(defaultNotNull, annotationsToRemove)); methodQuickFixSuggested = true; } if (hasAnnotatedParameter) { @@ -400,9 +404,8 @@ public class NullableStuffInspection extends BaseLocalInspectionTool { } } - protected int annotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) { - final NullableNotNullManager manager = NullableNotNullManager.getInstance(project); - return new AnnotateMethodFix(manager.getDefaultNotNull(), ArrayUtil.toStringArray(manager.getNullables())).annotateBaseMethod(method, superMethod, project); + protected AnnotateMethodFix createAnnotateMethodFix(final String defaultNotNull, final String[] annotationsToRemove) { + return new AnnotateMethodFix(defaultNotNull, annotationsToRemove); } private static void reportNullableNotNullConflict(final ProblemsHolder holder, final PsiModifierListOwner listOwner, final PsiAnnotation declaredNullable, @@ -419,6 +422,35 @@ public class NullableStuffInspection extends BaseLocalInspectionTool { return new OptionsPanel(); } + private static class MyAddNullableAnnotationFix extends AddNullableAnnotationFix { + public MyAddNullableAnnotationFix(PsiParameter parameter) { + super(parameter); + } + + @Override + public boolean isAvailable(@NotNull Project project, + @NotNull PsiFile file, + @NotNull PsiElement startElement, + @NotNull PsiElement endElement) { + return true; + } + } + + private static class MyAnnotateMethodFix extends AnnotateMethodFix { + public MyAnnotateMethodFix(String defaultNotNull, String[] annotationsToRemove) { + super(defaultNotNull, annotationsToRemove); + } + + protected boolean annotateOverriddenMethods() { + return true; + } + + @NotNull + public String getName() { + return InspectionsBundle.message("annotate.overridden.methods.as.notnull"); + } + } + private class OptionsPanel extends JPanel { private JCheckBox myNNParameterOverridesN; private JCheckBox myNAMethodOverridesNN; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java index 23fbfa6298d5..59683ae56fcc 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java @@ -1,9 +1,10 @@ package com.intellij.codeInsight.daemon.quickFix; +import com.intellij.codeInspection.AnnotateMethodFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.nullable.NullableStuffInspection; -import com.intellij.psi.PsiMethod; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiMethod; import org.jetbrains.annotations.NonNls; public class AnnotateMethodTest extends LightQuickFix15TestCase { @@ -18,14 +19,20 @@ public class AnnotateMethodTest extends LightQuickFix15TestCase { protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{new NullableStuffInspection(){ @Override - protected int annotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) { - @NonNls String name = method.getName(); - int ret = name.startsWith("annotateBase") ? 0 // yes, annotate all - : name.startsWith("dontAnnotateBase") ? 1 // do not annotate base - : 2; //abort - myMustBeAvailableAfterInvoke = ret == 2; - return ret; + protected AnnotateMethodFix createAnnotateMethodFix(String defaultNotNull, String[] annotationsToRemove) { + return new AnnotateMethodFix(defaultNotNull, annotationsToRemove){ + @Override + public int annotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) { + @NonNls String name = method.getName(); + int ret = name.startsWith("annotateBase") ? 0 // yes, annotate all + : name.startsWith("dontAnnotateBase") ? 1 // do not annotate base + : 2; //abort + myMustBeAvailableAfterInvoke = ret == 2; + return ret; + } + }; } + }}; } diff --git a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties index 4185d953bb3b..80b26d17b51e 100644 --- a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties +++ b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties @@ -444,7 +444,6 @@ intentions.category.ejb=EJB set.language.level=Set language level set.language.level.to.0=Set language level to {0} remove.annotation=Remove annotation -add.external.annotation.test=Add external annotation @{0} deannotate.intention.action.text=Deannotate deannotate.intention.chooser.title=Choose annotation to delete javadoc.type.parameters=Type parameters: diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/internationalization/StringConcatenationInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/internationalization/StringConcatenationInspection.java index 7ea12ec8ea63..986cd29af58a 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/internationalization/StringConcatenationInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/internationalization/StringConcatenationInspection.java @@ -88,9 +88,11 @@ public class StringConcatenationInspection extends BaseInspection { final PsiMethod method = PsiTreeUtil.getParentOfType(expressionParent, PsiMethod.class); + if (method != null) { final InspectionGadgetsFix fix = new DelegatingFix( new AddAnnotationFix(AnnotationUtil.NON_NLS, method)); result.add(fix); + } } return result.toArray(new InspectionGadgetsFix[result.size()]); } @@ -191,4 +193,4 @@ public class StringConcatenationInspection extends BaseInspection { registerError(sign, expression); } } -} \ No newline at end of file +} diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringWorker.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringWorker.java index fa5614ffc46e..e0871b8a29e5 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringWorker.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/GenerateToStringWorker.java @@ -33,6 +33,7 @@ import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.util.IncorrectOperationException; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.generate.tostring.config.*; import org.jetbrains.generate.tostring.element.*; @@ -389,11 +390,11 @@ public class GenerateToStringWorker { PsiAdapterFactory.getPsiAdapter().executeCommand(clazz.getProject(), writeCommand); } - private static void annotate(final PsiMethod result, String fqn) throws IncorrectOperationException { + private static void annotate(@NotNull PsiMethod result, String fqn) throws IncorrectOperationException { Project project = result.getProject(); AddAnnotationFix fix = new AddAnnotationFix(fqn, result); if (fix.isAvailable(project, null, result.getContainingFile())) { fix.invoke(project, null, result.getContainingFile()); } } -} \ No newline at end of file +} diff --git a/plugins/relaxng/src/org/intellij/plugins/relaxNG/inspections/BaseInspection.java b/plugins/relaxng/src/org/intellij/plugins/relaxNG/inspections/BaseInspection.java index 0467ccd26912..501be380a45c 100644 --- a/plugins/relaxng/src/org/intellij/plugins/relaxNG/inspections/BaseInspection.java +++ b/plugins/relaxng/src/org/intellij/plugins/relaxNG/inspections/BaseInspection.java @@ -105,7 +105,7 @@ public abstract class BaseInspection extends XmlSuppressableInspectionTool { } @SuppressWarnings({ "SSBasedInspection" }) - public boolean isAvailable(@NotNull Project project, Editor editor, @Nullable PsiElement element) { + public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { return super.isAvailable(project, editor, element) && getTarget(element).getText().startsWith("grammar "); } } @@ -123,7 +123,7 @@ public abstract class BaseInspection extends XmlSuppressableInspectionTool { action.invoke(project, editor, element); } - public boolean isAvailable(@NotNull Project project, Editor editor, @Nullable PsiElement element) { + public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { return element != null && element.getContainingFile().getFileType() == StdFileTypes.XML && action.isAvailable(project, editor, element); } @@ -210,7 +210,7 @@ public abstract class BaseInspection extends XmlSuppressableInspectionTool { suppress(element.getContainingFile(), getTarget(element)); } - public boolean isAvailable(@NotNull Project project, Editor editor, @Nullable PsiElement element) { + public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { return getTarget(element) != null; } diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index a0a238c1df62..cee0711237de 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -495,17 +495,17 @@ Control Flow - com.intellij.codeInsight.intention.impl.AddNotNullAnnotationFix + com.intellij.codeInsight.intention.impl.AddNotNullAnnotationIntention Control Flow AddAnnotationFix - com.intellij.codeInsight.intention.impl.AddDeprecationAnnotationFix + com.intellij.codeInsight.intention.impl.AddDeprecationAnnotationIntention Control Flow AddAnnotationFix - com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix + com.intellij.codeInsight.intention.impl.AddNullableAnnotationIntention Control Flow AddAnnotationFix From 206d5dc8eba2b2b1c44c75458def717c7b788d28 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 15 Apr 2011 12:01:16 +0400 Subject: [PATCH 091/100] IDEA-68098 Groovy: 'continue' & 'break' is not exist in completion. --- .../filters/control/BranchFilter.java | 29 +------------------ .../completion/GroovyCompletionTest.groovy | 9 ++++++ 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/filters/control/BranchFilter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/filters/control/BranchFilter.java index 66f3970264b0..074dab1eeee8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/filters/control/BranchFilter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/filters/control/BranchFilter.java @@ -19,11 +19,8 @@ package org.jetbrains.plugins.groovy.lang.completion.filters.control; import com.intellij.psi.PsiElement; import com.intellij.psi.filters.ElementFilter; import org.jetbrains.annotations.NonNls; -import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrForStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrWhileStatement; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; @@ -34,31 +31,7 @@ public class BranchFilter implements ElementFilter { public boolean isAcceptable(Object element, PsiElement context) { if (context.getParent() != null) { PsiElement parent = context.getParent(); - - if (parent instanceof GrReferenceExpression && - treeWalkUp(parent)) { - PsiElement superParent = parent.getParent(); - if ((superParent instanceof GrOpenBlock || - superParent instanceof GrCaseSection || - superParent instanceof GrClosableBlock)) { - return true; - } - - if (superParent instanceof GrWhileStatement) { - PsiElement elem = parent.getPrevSibling(); - while (elem != null && - !GroovyElementTypes.mRPAREN.equals(elem.getNode().getElementType())) { - elem = elem.getPrevSibling(); - } - if (elem != null) { - return true; - } else { - return false; - } - } - } - - return false; + return parent instanceof GrReferenceExpression && treeWalkUp(parent); } return false; } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index 52d033f8335d..755f174daee9 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -681,4 +681,13 @@ def a = new MyClass() a.g """) } + + public void testContinue() { + assertNotNull doContainsTest("continue", """ +def conti = 4 +while(true) { + if (tst) cont +}""") + + } } \ No newline at end of file From 927b94ff88bcf8234cc37366be6298f69c33b76d Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 15 Apr 2011 12:21:11 +0400 Subject: [PATCH 092/100] IDEA-68142 Groovy: false "Variable already defined" inspection --- .../lang/psi/api/statements/GrForStatement.java | 12 +++++++----- .../psi/impl/statements/GrForStatementImpl.java | 14 ++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrForStatement.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrForStatement.java index a3939d8451ee..a6f1982010ce 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrForStatement.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrForStatement.java @@ -16,9 +16,9 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.formatter.GrControlStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForClause; -import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import com.intellij.psi.PsiElement; /** @@ -26,12 +26,14 @@ import com.intellij.psi.PsiElement; */ public interface GrForStatement extends GrControlStatement, GrLoopStatement { - public GrForClause getClause(); + @Nullable + GrForClause getClause(); - public GrStatement getBody(); + @Nullable + GrStatement getBody(); - public PsiElement getRParenth(); + PsiElement getRParenth(); - public PsiElement getLParenth(); + PsiElement getLParenth(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrForStatementImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrForStatementImpl.java index db10038af539..bcf67bf428a0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrForStatementImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrForStatementImpl.java @@ -18,12 +18,12 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiModifierList; import com.intellij.psi.ResolveState; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; @@ -52,10 +52,12 @@ public class GrForStatementImpl extends GroovyPsiElementImpl implements GrForSta return "For statement"; } + @Nullable public GrForClause getClause() { return findChildByClass(GrForClause.class); } + @Nullable public GrStatement getBody() { return findChildByClass(GrStatement.class); } @@ -67,15 +69,11 @@ public class GrForStatementImpl extends GroovyPsiElementImpl implements GrForSta GrForClause forClause = getClause(); final GrVariable varScope = PsiTreeUtil.getParentOfType(place, GrVariable.class); if (forClause == null) return true; + if (lastParent == null || lastParent instanceof GrForInClause) return true; GrVariable var = forClause.getDeclaredVariable(); - if (var == null) return true; - - final PsiModifierList modifierList = var.getModifierList(); - boolean isAvailableOutsideOfFor = modifierList == null || modifierList.getTextLength() == 0; - if (lastParent != null && !(lastParent instanceof GrForInClause) || lastParent == null && isAvailableOutsideOfFor) { - if (!var.equals(varScope) && !ResolveUtil.processElement(processor, var, state)) return false; - } + if (var == null || var.equals(varScope)) return true; + if (!ResolveUtil.processElement(processor, var, state)) return false; return true; } From 250953e74fdb702ee428863323d9f37abf1199e5 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 15 Apr 2011 12:24:54 +0400 Subject: [PATCH 093/100] cleanup --- .../groovy/lang/psi/impl/types/GrClosureSignatureImpl.java | 2 +- .../groovy/lang/psi/impl/types/GrClosureSignatureUtil.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java index 39cdd09bafe5..dffa1b24dcb7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java @@ -48,7 +48,7 @@ public class GrClosureSignatureImpl implements GrClosureSignature { mySubstitutor = substitutor; } - public GrClosureSignatureImpl(PsiParameter[] parameters, PsiType returnType) { + public GrClosureSignatureImpl(PsiParameter[] parameters, @Nullable PsiType returnType) { this(parameters, returnType, PsiSubstitutor.EMPTY); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java index 71272388901e..c97be457a42e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java @@ -119,7 +119,7 @@ public class GrClosureSignatureUtil { }; } - public static GrClosureSignature createSignature(PsiParameter[] parameters, PsiType returnType) { + public static GrClosureSignature createSignature(PsiParameter[] parameters, @Nullable PsiType returnType) { return new GrClosureSignatureImpl(parameters, returnType); } From 0d7eabce6dc498408453218e7b8bc71a3eee4b8f Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 15 Apr 2011 13:41:39 +0400 Subject: [PATCH 094/100] skip dummy files in resolve of 'this' --- .../plugins/groovy/lang/psi/GroovyPsiElementFactory.java | 3 +++ .../groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java | 2 +- .../statements/expressions/GrThisReferenceExpressionImpl.java | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java index ae37d188e462..1b1e5d39e216 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java @@ -20,6 +20,7 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment; @@ -55,6 +56,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; */ public abstract class GroovyPsiElementFactory { + @NonNls public static final String DUMMY_FILE_NAME = "DUMMY__."; + public static GroovyPsiElementFactory getInstance(Project project) { return ServiceManager.getService(project, GroovyPsiElementFactory.class); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java index 412c5cad4465..8b7aaf8e3b14 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java @@ -259,7 +259,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory { } private GroovyFileImpl createDummyFile(String text, boolean physical) { - final String fileName = "DUMMY__." + GroovyFileType.GROOVY_FILE_TYPE.getDefaultExtension(); + final String fileName = DUMMY_FILE_NAME + GroovyFileType.GROOVY_FILE_TYPE.getDefaultExtension(); final long stamp = System.currentTimeMillis(); final PsiFileFactory factory = PsiFileFactory.getInstance(myProject); return (GroovyFileImpl) factory.createFileFromText(fileName, GroovyFileType.GROOVY_FILE_TYPE, text, stamp, physical); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java index 4f250081fffe..a02960a6f9f2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; @@ -34,6 +35,9 @@ public class GrThisReferenceExpressionImpl extends GrThisSuperReferenceExpressio final GrReferenceExpression qualifier = getQualifier(); if (qualifier == null) { GroovyPsiElement context = PsiTreeUtil.getContextOfType(this, GrTypeDefinition.class, GroovyFile.class); + if (context instanceof GroovyFile && GroovyPsiElementFactory.DUMMY_FILE_NAME.equals(((GroovyFile)context).getName())) { + context = PsiTreeUtil.getContextOfType(context, true, GrTypeDefinition.class, GroovyFile.class); + } if (context instanceof GrTypeDefinition) { return createType((PsiClass)context); } From c74936f2ce18c4b07a8acb044901bd5bf20415d0 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 15 Apr 2011 15:14:31 +0400 Subject: [PATCH 095/100] GrStatementOwner should contain getStatements() --- .../groovy/lang/psi/api/statements/blocks/GrCodeBlock.java | 3 --- .../lang/psi/api/statements/clauses/GrCaseSection.java | 5 ----- .../plugins/groovy/lang/psi/api/util/GrStatementOwner.java | 2 ++ .../plugins/groovy/lang/psi/impl/GroovyFileBaseImpl.java | 6 ++++++ .../lang/psi/impl/statements/clauses/GrCaseSectionImpl.java | 1 + 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/blocks/GrCodeBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/blocks/GrCodeBlock.java index e873fd7d4675..2c6ab42266ca 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/blocks/GrCodeBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/blocks/GrCodeBlock.java @@ -29,9 +29,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.util.GrDeclarationHolder; * @author ilyas */ public interface GrCodeBlock extends GrControlFlowOwner, GrVariableDeclarationOwner, GrStatementOwner, GrDeclarationHolder { - @NotNull - GrStatement[] getStatements(); - @Nullable PsiElement getLBrace(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/clauses/GrCaseSection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/clauses/GrCaseSection.java index 3624c8325098..2c7e573010a6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/clauses/GrCaseSection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/clauses/GrCaseSection.java @@ -17,7 +17,6 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrVariableDeclarationOwner; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrDeclarationHolder; @@ -26,9 +25,5 @@ import org.jetbrains.plugins.groovy.lang.psi.api.util.GrDeclarationHolder; * @author ilyas */ public interface GrCaseSection extends GroovyPsiElement, GrVariableDeclarationOwner, GrStatementOwner, GrDeclarationHolder { - GrCaseLabel getCaseLabel(); - - GrStatement[] getStatements(); - } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/util/GrStatementOwner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/util/GrStatementOwner.java index c01582ce84f0..ebe539bda523 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/util/GrStatementOwner.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/util/GrStatementOwner.java @@ -31,4 +31,6 @@ public interface GrStatementOwner extends GroovyPsiElement { void removeElements(PsiElement[] elements) throws IncorrectOperationException; + @NotNull + GrStatement[] getStatements(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileBaseImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileBaseImpl.java index 0a305969d230..39caeac704cb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileBaseImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileBaseImpl.java @@ -147,6 +147,12 @@ public abstract class GroovyFileBaseImpl extends PsiFileBase implements GroovyFi } } + @NotNull + @Override + public GrStatement[] getStatements() { + return findChildrenByClass(GrStatement.class); + } + public GrStatement addStatementBefore(@NotNull GrStatement statement, @Nullable GrStatement anchor) throws IncorrectOperationException { final PsiElement result = addBefore(statement, anchor); if (anchor != null) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/clauses/GrCaseSectionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/clauses/GrCaseSectionImpl.java index 2ccb93a65a93..7c5e86806d17 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/clauses/GrCaseSectionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/clauses/GrCaseSectionImpl.java @@ -68,6 +68,7 @@ public class GrCaseSectionImpl extends GroovyPsiElementImpl implements GrCaseSec return findChildByClass(GrCaseLabel.class); } + @NotNull public GrStatement[] getStatements() { return findChildrenByClass(GrStatement.class); } From 6594cb2fe41a0cf0c30b5c7606f013b2f63543c0 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 15 Apr 2011 15:28:10 +0400 Subject: [PATCH 096/100] skip dummy file in resolve --- .../lang/psi/GroovyPsiElementFactory.java | 2 +- .../psi/impl/GroovyPsiElementFactoryImpl.java | 2 +- .../GrThisReferenceExpressionImpl.java | 26 ++++++++++++------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java index 1b1e5d39e216..0f0b209d4511 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java @@ -56,7 +56,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; */ public abstract class GroovyPsiElementFactory { - @NonNls public static final String DUMMY_FILE_NAME = "DUMMY__."; + @NonNls public static final String DUMMY_FILE_NAME = "DUMMY__"; public static GroovyPsiElementFactory getInstance(Project project) { return ServiceManager.getService(project, GroovyPsiElementFactory.class); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java index 8b7aaf8e3b14..84e48f951fc8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java @@ -259,7 +259,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory { } private GroovyFileImpl createDummyFile(String text, boolean physical) { - final String fileName = DUMMY_FILE_NAME + GroovyFileType.GROOVY_FILE_TYPE.getDefaultExtension(); + final String fileName = DUMMY_FILE_NAME + '.' + GroovyFileType.GROOVY_FILE_TYPE.getDefaultExtension(); final long stamp = System.currentTimeMillis(); final PsiFileFactory factory = PsiFileFactory.getInstance(myProject); return (GroovyFileImpl) factory.createFileFromText(fileName, GroovyFileType.GROOVY_FILE_TYPE, text, stamp, physical); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java index a02960a6f9f2..1ffe4899cb58 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java @@ -2,6 +2,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions; import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; @@ -34,10 +35,7 @@ public class GrThisReferenceExpressionImpl extends GrThisSuperReferenceExpressio public PsiType getType() { final GrReferenceExpression qualifier = getQualifier(); if (qualifier == null) { - GroovyPsiElement context = PsiTreeUtil.getContextOfType(this, GrTypeDefinition.class, GroovyFile.class); - if (context instanceof GroovyFile && GroovyPsiElementFactory.DUMMY_FILE_NAME.equals(((GroovyFile)context).getName())) { - context = PsiTreeUtil.getContextOfType(context, true, GrTypeDefinition.class, GroovyFile.class); - } + GroovyPsiElement context = getFileContext(); if (context instanceof GrTypeDefinition) { return createType((PsiClass)context); } @@ -63,6 +61,15 @@ public class GrThisReferenceExpressionImpl extends GrThisSuperReferenceExpressio return null; } + private GroovyPsiElement getFileContext() { + GroovyPsiElement context = PsiTreeUtil.getContextOfType(this, GrTypeDefinition.class, GroovyFile.class); + if (context instanceof GroovyFile && GroovyPsiElementFactory.DUMMY_FILE_NAME.equals(FileUtil.getNameWithoutExtension( + ((GroovyFile)context).getName()))) { + context = PsiTreeUtil.getContextOfType(context, true, GrTypeDefinition.class, GroovyFile.class); + } + return context; + } + private PsiType createType(PsiClass context) { PsiElementFactory elementFactory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); if (PsiUtil.isInStaticContext(this)) { @@ -87,11 +94,12 @@ public class GrThisReferenceExpressionImpl extends GrThisSuperReferenceExpressio return qualifier.resolve(); } - final GrTypeDefinition containingClass = PsiTreeUtil.getContextOfType(this, GrTypeDefinition.class, true, GroovyFile.class); - if (containingClass != null) return containingClass; - final PsiFile containingFile = getContainingFile(); - if (containingFile instanceof GroovyFile) { - return ((GroovyFile)containingFile).getScriptClass(); + final GroovyPsiElement context = getFileContext(); + if (context instanceof GrTypeDefinition) { + return context; + } + else if (context instanceof GroovyFile) { + return ((GroovyFile)context).getScriptClass(); } return null; } From 09492d35160fb9fe71f170839bba900e30c7d4a9 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 15 Apr 2011 15:29:46 +0400 Subject: [PATCH 097/100] IDEA-68098 Groovy: 'continue' & 'break' is not exist in completion. --- .../GroovyExtractMethodHandler.java | 21 ++++++++++++++++++- .../extractMethod/ExtractMethodTest.java | 2 ++ ...stBlockStatementInterruptsControlFlow.test | 15 +++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 plugins/groovy/testdata/groovy/refactoring/extractMethod/lastBlockStatementInterruptsControlFlow.test diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractMethod/GroovyExtractMethodHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractMethod/GroovyExtractMethodHandler.java index 298eb237c02e..28bf846f49a2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractMethod/GroovyExtractMethodHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractMethod/GroovyExtractMethodHandler.java @@ -34,13 +34,16 @@ import com.intellij.refactoring.HelpID; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.util.CommonRefactoringUtil; +import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrMemberOwner; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; @@ -181,7 +184,8 @@ public class GroovyExtractMethodHandler implements RefactoringActionHandler { List returnStatementsCopy = new ArrayList(returnStatements.size()); returnStatementsCopy.addAll(returnStatements); boolean isReturnStatement = ExtractMethodUtil.isReturnStatement(statements[statements.length - 1], returnStatementsCopy); - if (!isReturnStatement && hasReturns || hasInterruptingStatements) { + boolean isLastStatementOfMethod = isLastStatementOfMethodOrClosure(statements); + if (hasReturns && !isLastStatementOfMethod && !isReturnStatement || hasInterruptingStatements) { String message = GroovyRefactoringBundle.message("refactoring.is.not.supported.when.return.statement.interrupts.the.execution.flow"); showErrorMessage(message, project, editor); return false; @@ -210,6 +214,21 @@ public class GroovyExtractMethodHandler implements RefactoringActionHandler { return true; } + private static boolean isLastStatementOfMethodOrClosure(GrStatement[] statements) { + final GrStatement statement0 = statements[0]; + + PsiElement returnFrom = PsiTreeUtil.getParentOfType(statement0, GrMethod.class, GrClosableBlock.class, GroovyFile.class); + if (returnFrom instanceof GrMethod) { + returnFrom = ((GrMethod)returnFrom).getBlock(); + } + LOG.assertTrue(returnFrom instanceof GrStatementOwner); + + final GrStatement[] blockStatements = ((GrStatementOwner)returnFrom).getStatements(); + final GrStatement lastFromBlock = ArrayUtil.getLastElement(blockStatements); + final GrStatement lastStatement = ArrayUtil.getLastElement(statements); + return statement0.getManager().areElementsEquivalent(lastFromBlock, lastStatement); + } + private void runRefactoring(final String methodName, @NotNull final ExtractMethodInfoHelper helper, @NotNull final GrMemberOwner owner, diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/extractMethod/ExtractMethodTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/extractMethod/ExtractMethodTest.java index 386a7d4063e8..f94cbb390a0d 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/extractMethod/ExtractMethodTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/extractMethod/ExtractMethodTest.java @@ -97,4 +97,6 @@ public class ExtractMethodTest extends LightGroovyTestCase { public void testMultiOutput5() {doTest();} public void testDontShortenRefsIncorrect() {doTest();} + + public void testLastBlockStatementInterruptsControlFlow() {doTest();} } \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/refactoring/extractMethod/lastBlockStatementInterruptsControlFlow.test b/plugins/groovy/testdata/groovy/refactoring/extractMethod/lastBlockStatementInterruptsControlFlow.test new file mode 100644 index 000000000000..e6b0b43605fc --- /dev/null +++ b/plugins/groovy/testdata/groovy/refactoring/extractMethod/lastBlockStatementInterruptsControlFlow.test @@ -0,0 +1,15 @@ +def foo() { + if (abc) { + println 'def' + } +} +----- +def foo() { + testMethod() +} + +private def testMethod() { + if (abc) { + println 'def' + } +} \ No newline at end of file From 8daf5892fc67b563aa673f3d1bd075a09df9620e Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 15 Apr 2011 15:57:41 +0400 Subject: [PATCH 098/100] convert simple reference expressions --- .../convertToJava/CodeBlockGenerator.java | 26 ++--- .../convertToJava/ExpressionGenerator.java | 109 +++++++++++++----- .../convertToJava/GenerationUtil.java | 25 +++- .../CodeBlockGenerationTest.groovy | 16 +++ .../codeBlock/refExpr.groovy | 10 ++ .../codeBlock/refExpr.java | 6 + .../codeBlock/switch3.java | 6 +- .../codeBlock/switch4.java | 4 +- 8 files changed, 155 insertions(+), 47 deletions(-) create mode 100644 plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/refExpr.groovy create mode 100644 plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/refExpr.java diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java index be909e23cc79..8f1b931b28da 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java @@ -73,13 +73,16 @@ public class CodeBlockGenerator extends Generator { @Override public void visitOpenBlock(GrOpenBlock block) { builder.append("{\n"); - super.visitOpenBlock(block); + final GrStatement[] statements = block.getStatements(); + for (GrStatement statement : statements) { + statement.accept(this); + builder.append('\n'); + } builder.append("}\n"); } - @Override public void visitStatement(GrStatement statement) { - super.visitStatement(statement); //To change body of overridden methods use File | Settings | File Templates. + LOG.assertTrue(false, "all statements must be overloaded"); } @Override @@ -191,6 +194,7 @@ public class CodeBlockGenerator extends Generator { @Override public void visitForStatement(GrForStatement forStatement) { final StringBuilder builder = new StringBuilder(); + builder.append("for("); final GrForClause clause = forStatement.getClause(); ExpressionContext forContext = context.extend(); @@ -199,16 +203,14 @@ public class CodeBlockGenerator extends Generator { final GrVariable declaredVariable = clause.getDeclaredVariable(); LOG.assertTrue(declaredVariable != null); - builder.append("for("); writeVariableWithoutSemicolonAndInitializer(builder, declaredVariable); builder.append(" : "); if (expression != null) { final ExpressionContext context = forContext.copy(); expression.accept(new ExpressionGenerator(builder, context)); } - builder.append(")"); } - else { + else if (clause instanceof GrTraditionalForClause) { final GrTraditionalForClause cl = (GrTraditionalForClause)clause; final GrCondition initialization = cl.getInitialization(); final GrExpression condition = cl.getCondition(); @@ -244,10 +246,13 @@ public class CodeBlockGenerator extends Generator { if (update != null) { genForPart(builder, update, forContext.copy()); } - builder.append(")"); } + builder.append(")"); - forStatement.getBody().accept(new CodeBlockGenerator(builder, forContext)); + final GrStatement body = forStatement.getBody(); + if (body != null) { + body.accept(new CodeBlockGenerator(builder, forContext)); + } } private static void genForPart(StringBuilder builder, GrExpression part, final ExpressionContext context) { @@ -486,11 +491,6 @@ public class CodeBlockGenerator extends Generator { } } - private void writeVariable(GrVariable variable) { - //todo - throw new UnsupportedOperationException(); - } - private static String getTypeText(PsiType varType) { final StringBuilder builder = new StringBuilder(); GenerationUtil.writeType(builder, varType); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java index 6d1d61cfe394..babcf42555e9 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java @@ -21,7 +21,6 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.tree.IElementType; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.intentions.conversions.ConvertGStringToStringIntention; @@ -32,6 +31,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation; +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.arguments.GrArgumentLabel; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; @@ -59,6 +59,9 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; 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.refactoring.GroovyRefactoringUtil; + +import static org.jetbrains.plugins.groovy.refactoring.convertToJava.GenerationUtil.*; /** * @author Maxim.Medvedev @@ -128,7 +131,7 @@ public class ExpressionGenerator extends Generator { } } - GenerationUtil.invokeMethodByName(invoked, "call", exprs, namedArgs, clArgs, this, methodCallExpression); + invokeMethodByName(invoked, "call", exprs, namedArgs, clArgs, this, methodCallExpression); } @Override @@ -140,8 +143,8 @@ public class ExpressionGenerator extends Generator { final String varName; if (hasFieldInitialization) { builder = new StringBuilder(); - varName = GenerationUtil.suggestVarName(type, newExpression, this.context); - GenerationUtil.writeType(builder, type); + varName = suggestVarName(type, newExpression, this.context); + writeType(builder, type); builder.append(" ").append(varName).append(" = "); } else { @@ -164,10 +167,10 @@ public class ExpressionGenerator extends Generator { final PsiType builtIn = typeElement.getType(); LOG.assertTrue(builtIn instanceof PsiPrimitiveType); final PsiType boxed = TypesUtil.boxPrimitiveType(builtIn, newExpression.getManager(), newExpression.getResolveScope()); - GenerationUtil.writeType(builder, boxed); + writeType(builder, boxed); } else if (referenceElement != null) { - GenerationUtil.writeCodeReferenceElement(builder, referenceElement); + writeCodeReferenceElement(builder, referenceElement); } final GrArgumentList argList = newExpression.getArgumentList(); @@ -259,7 +262,7 @@ public class ExpressionGenerator extends Generator { private static boolean hasFieldInitialization(GrNewExpression newExpression) { final GrArgumentList argumentList = newExpression.getArgumentList(); if (argumentList == null) return false; - if (argumentList.getNamedArguments().length > 0) return false; + if (argumentList.getNamedArguments().length == 0) return false; final GrCodeReferenceElement refElement = newExpression.getReferenceElement(); if (refElement == null) return false; @@ -275,7 +278,7 @@ public class ExpressionGenerator extends Generator { } private void writeTypeBody(StringBuilder builder, GrAnonymousClassDefinition anonymous) { - //todo + //todo write type body for anonymous class throw new UnsupportedOperationException(); } @@ -460,6 +463,8 @@ public class ExpressionGenerator extends Generator { else { builder.append(value); } + + //todo replace with character in some cases } @Override @@ -471,16 +476,70 @@ public class ExpressionGenerator extends Generator { @Override public void visitReferenceExpression(GrReferenceExpression referenceExpression) { - final GrExpression qualifier = referenceExpression.getQualifier(); - final PsiElement refNameElement = referenceExpression.getReferenceNameElement(); - final GroovyResolveResult resolveResult = referenceExpression.advancedResolve(); + LOG.assertTrue(!(referenceExpression.getParent() instanceof GrMethodCall)); - if (qualifier != null) { - qualifier.accept(this); - builder.append("."); + final GrExpression qualifier = referenceExpression.getQualifier(); + final GroovyResolveResult resolveResult = referenceExpression.advancedResolve(); + final PsiElement resolved = resolveResult.getElement(); + + final IElementType type = referenceExpression.getDotTokenType(); + + GrExpression qualifierToUse = qualifier; + + if (type == GroovyTokenTypes.mOPTIONAL_DOT) { + LOG.assertTrue(qualifier != null); + + String qualifierName = createVarByInitializer(qualifier); + builder.append(qualifierName).append(" == null ? null : "); + + qualifierToUse = factory.createReferenceExpressionFromText(qualifierName, referenceExpression); } - builder.append(referenceExpression.getReferenceName()); - //todo make reference expression + + + if (resolveResult.isInvokedOnProperty()) { + LOG.assertTrue(resolved instanceof PsiMethod); + invokeMethodOn( + ((PsiMethod)resolved), + qualifierToUse, + GrExpression.EMPTY_ARRAY, + GrNamedArgument.EMPTY_ARRAY, + GrClosableBlock.EMPTY_ARRAY, + resolveResult.getSubstitutor(), + referenceExpression + ); + } + else { + if (qualifierToUse != null) { + qualifierToUse.accept(this); + builder.append('.'); + } + final String refName = + resolved instanceof PsiNamedElement ? ((PsiNamedElement)resolved).getName() : referenceExpression.getReferenceName(); + builder.append(refName); + } + } + + private String createVarByInitializer(GrExpression initializer) { + if (initializer instanceof GrReferenceExpression) { + final GrExpression qualifier = ((GrReferenceExpression)initializer).getQualifier(); + if (qualifier == null) { + final PsiElement resolved = ((GrReferenceExpression)initializer).resolve(); + if (resolved instanceof GrVariable && GroovyRefactoringUtil.isLocalVariable((GrVariable)resolved)) { + + //don't create new var. it is already exists + return ((GrVariable)resolved).getName(); + } + } + } + final String name = suggestVarName(initializer, context); + final StringBuilder builder = new StringBuilder(); + builder.append("final "); + writeType(builder, initializer.getType()); + builder.append(' ').append(name).append(" = "); + initializer.accept(new ExpressionGenerator(builder, context)); + builder.append(';'); + context.myStatements.add(builder.toString()); + return name; } @Override @@ -490,14 +549,8 @@ public class ExpressionGenerator extends Generator { final PsiElement resolved = expr.resolve(); LOG.assertTrue(resolved instanceof PsiClass); - final PsiElement firstContainingClass = PsiTreeUtil.getParentOfType(expr, GrClosableBlock.class, PsiClass.class); - if (expr.getManager().areElementsEquivalent(firstContainingClass, resolved)) { - builder.append(expr.getReferenceName()); - } - else { - builder.append(((PsiClass)resolved).getQualifiedName()).append(".").append(expr.getReferenceName()); - } + builder.append(((PsiClass)resolved).getQualifiedName()).append(".").append(expr.getReferenceName()); } @Override @@ -611,8 +664,8 @@ public class ExpressionGenerator extends Generator { } final GroovyResolveResult candidate = PsiImplUtil.getIndexPropertyMethodCandidate(thisType, argTypes, expression); - GenerationUtil.invokeMethodByResolveResult( - selectedExpression, candidate, "getAt", exprArgs, namedArgs, GrClosableBlock.EMPTY_ARRAY, this,expression + invokeMethodByResolveResult( + selectedExpression, candidate, "getAt", exprArgs, namedArgs, GrClosableBlock.EMPTY_ARRAY, this, expression ); } @@ -716,10 +769,10 @@ public class ExpressionGenerator extends Generator { private String generateListOrMapVariableDeclaration(GrListOrMap listOrMap, PsiType type) { StringBuilder declaration = new StringBuilder(); - GenerationUtil.writeType(declaration, type); - final String varName = GenerationUtil.suggestVarName(type, listOrMap, this.context); + writeType(declaration, type); + final String varName = suggestVarName(type, listOrMap, this.context); declaration.append(" ").append(varName).append(" = new "); - GenerationUtil.writeType(declaration, type); + writeType(declaration, type); declaration.append("("); //insert count of elements in list or map diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java index 901c0c185492..237b6c058524 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java @@ -70,6 +70,16 @@ public class GenerationUtil { builder.replace(builder.length() - 2, builder.length(), ">"); } + static String suggestVarName(GrExpression expr, ExpressionContext expressionContext) { + final DefaultGroovyVariableNameValidator nameValidator = + new DefaultGroovyVariableNameValidator(expr, expressionContext.myUsedVarNames, true); + final String[] varNames = GroovyNameSuggestionUtil.suggestVariableNames(expr, nameValidator); + + LOG.assertTrue(varNames.length > 0); + expressionContext.myUsedVarNames.add(varNames[0]); + return varNames[0]; + } + static String suggestVarName(PsiType type, GroovyPsiElement context, ExpressionContext expressionContext) { final DefaultGroovyVariableNameValidator nameValidator = new DefaultGroovyVariableNameValidator(context, expressionContext.myUsedVarNames, true); @@ -85,7 +95,20 @@ public class GenerationUtil { } public static void writeCodeReferenceElement(StringBuilder builder, GrCodeReferenceElement referenceElement) { - builder.append(referenceElement.getText()); + final GroovyResolveResult resolveResult = referenceElement.advancedResolve(); + final PsiElement resolved = resolveResult.getElement(); + if (resolved == null) { + builder.append(referenceElement.getText()); + return; + } + LOG.assertTrue(resolved instanceof PsiClass || resolved instanceof PsiPackage); + if (resolved instanceof PsiClass) { + builder.append(((PsiClass)resolved).getQualifiedName()); + } + else { + builder.append(((PsiPackage)resolved).getQualifiedName()); + } + writeTypeParameters(builder, referenceElement.getTypeArguments()); } public static void invokeMethodByName(GrExpression caller, diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy index 532604d641b8..669155ccc9ed 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy @@ -88,4 +88,20 @@ public class CodeBlockGenerationTest extends LightCodeInsightFixtureTestCase { void _testWhile2() {doTest()} void _testWhile3() {doTest()} + void testRefExpr() { + myFixture.addFileToProject "Bar.groovy", """ +class Bar { + def foo = 2 + + def getBar() {3} +} +class MyCat { + static getAbc(Bar b) { + return 4 + } +} +""" + + doTest() + } } diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/refExpr.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/refExpr.groovy new file mode 100644 index 000000000000..44f74c60eddf --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/refExpr.groovy @@ -0,0 +1,10 @@ +print new Bar().foo +print new Bar().bar + +def bar = new Bar() + +print bar?.foo + +def file = new File("") +print file.text + diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/refExpr.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/refExpr.java new file mode 100644 index 000000000000..15b1127bbadb --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/refExpr.java @@ -0,0 +1,6 @@ +print(new Bar().getFoo()); +print(new Bar().getBar()); +Bar bar = new Bar(); +print(bar == null ? null : bar.getFoo()); +java.io.File file = new java.io.File(""); +print(org.codehaus.groovy.runtime.DefaultGroovyMethods.getText(file)); diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.java index ab6d5cf98598..b1f9dc5ded69 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.java @@ -1,9 +1,9 @@ -java.util.Date date = new Date(2011, 4, 9); -if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(new Date(20, 11, 23), date)) { +java.util.Date date = new java.util.Date(2011, 4, 9); +if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(new java.util.Date(20, 11, 23), date)) { print("aaa"); print("bbb"); } -else if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(new Date(45, 1, 2), date)) { +else if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(new java.util.Date(45, 1, 2), date)) { print("bbb"); } else print("ccc"); diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.java index feadc641f3e2..60b25a0e977d 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.java @@ -1,5 +1,5 @@ -java.util.Date date = new Date(2011, 4, 9); -if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(new Date(20, 11, 23), date)) { +java.util.Date date = new java.util.Date(2011, 4, 9); +if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(new java.util.Date(20, 11, 23), date)) { print("aaa"); print("bbb"); } From 639db359648b8246c23aa3ea0c49b9f1cecb775a Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 15 Apr 2011 16:07:16 +0400 Subject: [PATCH 099/100] convertLineSeparators --- .../platform-api/src/com/intellij/ide/diff/DiffElement.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/ide/diff/DiffElement.java b/platform/platform-api/src/com/intellij/ide/diff/DiffElement.java index 88a80da4c239..8ac5383a20bc 100644 --- a/platform/platform-api/src/com/intellij/ide/diff/DiffElement.java +++ b/platform/platform-api/src/com/intellij/ide/diff/DiffElement.java @@ -24,6 +24,7 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.encoding.EncodingManager; import org.jetbrains.annotations.NotNull; @@ -83,7 +84,7 @@ public abstract class DiffElement { final EditorFactory editorFactory = EditorFactory.getInstance(); final Document document = value instanceof VirtualFile ? FileDocumentManager.getInstance().getDocument((VirtualFile)value) - : editorFactory.createDocument(new String(content)); + : editorFactory.createDocument(StringUtil.convertLineSeparators(new String(content))); if (document != null && getFileType() != null) { myEditor = editorFactory.createEditor(document, project, getFileType(), true); myEditor.getSettings().setFoldingOutlineShown(false); From e45940a0eabd0b986f358554a1395e4c40bf2493 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 15 Apr 2011 16:08:37 +0400 Subject: [PATCH 100/100] set icon for elements --- .../openapi/diff/impl/dir/DirDiffTableCellRenderer.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableCellRenderer.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableCellRenderer.java index 127c952f1571..7eea4fc10f16 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableCellRenderer.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableCellRenderer.java @@ -76,14 +76,13 @@ public class DirDiffTableCellRenderer extends DefaultTableCellRenderer { if (hasFocus || isSelected) { label.setBorder(noFocusBorder); } + label.setIcon(null); final DirDiffOperation op = element.getOperation(); if (column == (table.getColumnCount() - 1) / 2) { label.setIcon(op.getIcon()); label.setHorizontalAlignment(CENTER); return label; - } else { - label.setIcon(element.getIcon()); } Color fg = isSelected ? UIUtil.getTableSelectionForeground() : getForegroundColor(op); @@ -96,7 +95,11 @@ public class DirDiffTableCellRenderer extends DefaultTableCellRenderer { label.setText(label.getText() + " "); } else { label.setHorizontalAlignment(LEFT); - label.setText(" " + label.getText()); + final String text = label.getText(); + label.setText(" " + text); + if (text != null && text.trim().length() > 0) { + label.setIcon(element.getIcon()); + } } } return c;