diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 9be9f12406dd..b3a7fb1ce535 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -959,10 +959,10 @@ public class CompileDriver { final TranslatorsOutputSink sink = new TranslatorsOutputSink(context, translators); final Set generatedTypes = new HashSet(); Collection chunkFiles = chunkMap.get(currentChunk); + final Set filesToRecompile = new HashSet(); + final Set allDependent = new HashSet(); try { int round = 0; - final Set filesToRecompile = new HashSet(); - final Set allDependent = new HashSet(); Collection dependentFiles = Collections.emptyList(); final Function>, Pair>> dependencyFilter = new DependentClassesCumulativeFilter(); @@ -1092,19 +1092,18 @@ public class CompileDriver { indicator.popState(); } } - - if (context.getMessageCount(CompilerMessageCategory.ERROR) != 0) { - filesToRecompile.addAll(allDependent); - } - if (filesToRecompile.size() > 0) { - sink.add(null, Collections.emptyList(), VfsUtil.toVirtualFileArray(filesToRecompile)); - } } catch (CacheCorruptedException e) { LOG.info(e); context.requestRebuildNextTime(e.getMessage()); } finally { + if (context.getMessageCount(CompilerMessageCategory.ERROR) != 0) { + filesToRecompile.addAll(allDependent); + } + if (filesToRecompile.size() > 0) { + sink.add(null, Collections.emptyList(), VfsUtil.toVirtualFileArray(filesToRecompile)); + } if (context.getMessageCount(CompilerMessageCategory.ERROR) == 0) { // perform update only if there were no errors, so it is guaranteed that the file was processd by all neccesary compilers sink.flushPostponedItems(); diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerCacheManager.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerCacheManager.java index 76082f3fbce2..4afce35c12ac 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerCacheManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerCacheManager.java @@ -171,6 +171,7 @@ public class CompilerCacheManager implements ProjectComponent { } } myCacheDisposables.clear(); + myNewCachesMap.clear(); myCompilerToCacheMap.clear(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/FramesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/FramesPanel.java index 1d6ac280bc4e..a2fd41de38e9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/FramesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/FramesPanel.java @@ -80,7 +80,7 @@ public class FramesPanel extends UpdatableDebuggerView { myThreadsListener = new ThreadsListener(); myThreadsCombo.addItemListener(myThreadsListener); - myFramesList = new FramesList(); + myFramesList = new FramesList(project); myFramesListener = new FramesListener(); myFramesList.addListSelectionListener(myFramesListener); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesList.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesList.java index 12d556c6f988..c279b01e7e10 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesList.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesList.java @@ -16,6 +16,7 @@ package com.intellij.debugger.ui.impl; import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.xdebugger.impl.frame.DebuggerFramesList; import com.sun.jdi.Method; @@ -29,6 +30,11 @@ import javax.swing.*; public class FramesList extends DebuggerFramesList { private volatile Method mySelectedMethod = null; + public FramesList(Project project) { + super(null); + doInit(); + } + protected FramesListRenderer createListRenderer() { return new FramesListRenderer(); } 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 6d60f732260b..7af0e0f32f16 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 @@ -15,18 +15,24 @@ */ package com.intellij.debugger.ui.impl; +import com.intellij.debugger.SourcePosition; import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; +import com.intellij.debugger.ui.tree.StackFrameDescriptor; import com.intellij.debugger.ui.tree.ValueMarkup; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.FileColorManager; import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.StringBuilderSpinAllocator; +import com.intellij.util.ui.UIUtil; import com.intellij.xdebugger.ui.DebuggerColors; import com.sun.jdi.Method; import javax.swing.*; +import java.awt.*; class FramesListRenderer extends ColoredListCellRenderer { private final EditorColorsScheme myColorScheme; @@ -52,10 +58,13 @@ class FramesListRenderer extends ColoredListCellRenderer { } if (selected) { - setBackground(com.intellij.util.ui.UIUtil.getListSelectionBackground()); + setBackground(UIUtil.getListSelectionBackground()); } else { - setBackground(shouldHighlightAsRecursive ? myColorScheme.getColor(DebuggerColors.RECURSIVE_CALL_ATTRIBUTES) : com.intellij.util.ui.UIUtil.getListBackground()); + Color bg = descriptor.getBackgroundColor(); + if (bg == null) bg = UIUtil.getListBackground(); + if (shouldHighlightAsRecursive) bg = myColorScheme.getColor(DebuggerColors.RECURSIVE_CALL_ATTRIBUTES); + setBackground(bg); } final String label = descriptor.getLabel(); 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 e3a82eaeecb1..8b84358a8172 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 @@ -33,12 +33,14 @@ import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; +import com.intellij.ui.FileColorManager; import com.intellij.util.StringBuilderSpinAllocator; import com.intellij.xdebugger.ui.DebuggerIcons; import com.sun.jdi.*; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.*; import java.util.Map; /** @@ -52,6 +54,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac private boolean myIsSynthetic; private boolean myIsInLibraryContent; private Long myObjectId; + private Color myBackgroundColor; private static final Icon myObsoleteFrameIcon = IconLoader.getIcon("/debugger/db_obsolete.png"); private Icon myIcon = DebuggerIcons.STACK_FRAME_ICON; @@ -72,6 +75,8 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac myIsInLibraryContent = true; } else { + myBackgroundColor = FileColorManager.getInstance(file.getProject()).getFileColor(file); + final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(getDebugProcess().getProject()).getFileIndex(); final VirtualFile vFile = file.getVirtualFile(); myIsInLibraryContent = vFile != null && (projectFileIndex.isInLibraryClasses(vFile) || projectFileIndex.isInLibrarySource(vFile)); @@ -102,6 +107,11 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac return myFrame.getVirtualMachine().getDebugProcess(); } + @Override + public Color getBackgroundColor() { + return myBackgroundColor; + } + @Nullable public Method getMethod() { return myMethodOccurrence.getMethod(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/StackFrameDescriptor.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/StackFrameDescriptor.java index 388c420ce0ff..7712b1583b9c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/StackFrameDescriptor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/StackFrameDescriptor.java @@ -16,6 +16,11 @@ package com.intellij.debugger.ui.tree; import com.intellij.debugger.engine.StackFrameContext; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; public interface StackFrameDescriptor extends NodeDescriptor, StackFrameContext { + @Nullable + Color getBackgroundColor(); } diff --git a/java/execution/impl/src/com/intellij/execution/testframework/JavaAwareTestConsoleProperties.java b/java/execution/impl/src/com/intellij/execution/testframework/JavaAwareTestConsoleProperties.java index 1c98de5ba1fa..6ca16855c893 100644 --- a/java/execution/impl/src/com/intellij/execution/testframework/JavaAwareTestConsoleProperties.java +++ b/java/execution/impl/src/com/intellij/execution/testframework/JavaAwareTestConsoleProperties.java @@ -22,6 +22,7 @@ package com.intellij.execution.testframework; import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.execution.Executor; import com.intellij.openapi.project.Project; import com.intellij.util.config.Storage; import org.jetbrains.annotations.Nullable; @@ -29,13 +30,8 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; public abstract class JavaAwareTestConsoleProperties extends TestConsoleProperties { - public JavaAwareTestConsoleProperties(final Storage storage, Project project) { - super(storage, project); - } - - @Override - public boolean isDebug() { - return getDebugSession() != null; + public JavaAwareTestConsoleProperties(final Storage storage, Project project, Executor executor) { + super(storage, project, executor); } @Override diff --git a/java/openapi/src/com/intellij/psi/util/PsiUtil.java b/java/openapi/src/com/intellij/psi/util/PsiUtil.java index ad9555b09ed8..cbb99a2868a2 100644 --- a/java/openapi/src/com/intellij/psi/util/PsiUtil.java +++ b/java/openapi/src/com/intellij/psi/util/PsiUtil.java @@ -796,10 +796,14 @@ public final class PsiUtil extends PsiUtilBase { } public static boolean hasDefaultConstructor(PsiClass clazz, boolean allowProtected) { + return hasDefaultConstructor(clazz, allowProtected, true); + } + + public static boolean hasDefaultConstructor(PsiClass clazz, boolean allowProtected, boolean checkModifiers) { final PsiMethod[] constructors = clazz.getConstructors(); if (constructors.length > 0) { for (PsiMethod cls: constructors) { - if ((cls.hasModifierProperty(PsiModifier.PUBLIC) || + if ((!checkModifiers || cls.hasModifierProperty(PsiModifier.PUBLIC) || allowProtected && cls.hasModifierProperty(PsiModifier.PROTECTED)) && cls.getParameterList().getParametersCount() == 0) { return true; @@ -807,7 +811,7 @@ public final class PsiUtil extends PsiUtilBase { } } else { final PsiClass superClass = clazz.getSuperClass(); - return superClass == null || hasDefaultConstructor(superClass, true); + return superClass == null || hasDefaultConstructor(superClass, true, true); } return false; } diff --git a/platform/lang-api/src/com/intellij/lang/injection/InjectedLanguageManager.java b/platform/lang-api/src/com/intellij/lang/injection/InjectedLanguageManager.java index e94dcfaa4bba..bf742113bc9f 100644 --- a/platform/lang-api/src/com/intellij/lang/injection/InjectedLanguageManager.java +++ b/platform/lang-api/src/com/intellij/lang/injection/InjectedLanguageManager.java @@ -23,6 +23,7 @@ package com.intellij.lang.injection; import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; @@ -41,7 +42,7 @@ public abstract class InjectedLanguageManager implements ProjectComponent { public static final ExtensionPointName MULTIHOST_INJECTOR_EP_NAME = MultiHostInjector.MULTIHOST_INJECTOR_EP_NAME; public static InjectedLanguageManager getInstance(Project project) { - return project.getComponent(InjectedLanguageManager.class); + return ServiceManager.getService(project, InjectedLanguageManager.class); } @Nullable diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoSymbolModel2.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoSymbolModel2.java index 376febce1227..f7244901207d 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoSymbolModel2.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoSymbolModel2.java @@ -70,11 +70,11 @@ public class GotoSymbolModel2 extends ContributorsBasedGotoByModel { @NotNull public String[] getSeparators() { - return new String[] {".", ":"}; + return new String[] {"."}; } @Override public String getHelpId() { return "procedures.navigating.goto.class"; } -} \ No newline at end of file +} diff --git a/platform/platform-api/src/com/intellij/ui/components/JBList.java b/platform/platform-api/src/com/intellij/ui/components/JBList.java index 7c57131fd977..0aade3bbc914 100644 --- a/platform/platform-api/src/com/intellij/ui/components/JBList.java +++ b/platform/platform-api/src/com/intellij/ui/components/JBList.java @@ -24,6 +24,7 @@ import com.intellij.util.ui.EmptyTextHelper; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import java.awt.*; import java.awt.event.ActionListener; import java.util.Collection; @@ -50,6 +51,12 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi init(); } + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + myEmptyTextHelper.paint(g); + } + private void init() { myEmptyTextHelper = new EmptyTextHelper(this) { @Override diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java index 69dfbbc7ee23..a3f4395aeb76 100644 --- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java +++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java @@ -82,6 +82,12 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component boolean marker = Patches.SUN_BUG_ID_4503845; // Don't remove. It's a marker for find usages } + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + myEmptyTextHelper.paint(g); + } + public static DefaultCellEditor createBooleanEditor() { return new DefaultCellEditor(new JCheckBox()) { { diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaTestApplication.java b/platform/platform-impl/src/com/intellij/idea/IdeaTestApplication.java index bab5a000ec17..bcbf41cbd1da 100644 --- a/platform/platform-impl/src/com/intellij/idea/IdeaTestApplication.java +++ b/platform/platform-impl/src/com/intellij/idea/IdeaTestApplication.java @@ -18,18 +18,14 @@ package com.intellij.idea; import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.ide.plugins.PluginManager; import com.intellij.openapi.actionSystem.DataProvider; -import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.application.impl.PluginsFacade; import com.intellij.openapi.extensions.PluginId; -import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.annotations.Nullable; -import java.io.File; - public class IdeaTestApplication extends CommandLineApplication { private DataProvider myDataContext; @@ -45,10 +41,6 @@ public class IdeaTestApplication extends CommandLineApplication { return PluginManager.getPlugins(); } }; - - final File system = new File(PathManager.getSystemPath()); - FileUtil.delete(system); - system.mkdirs(); } public void setDataProvider(DataProvider dataContext) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapChangeListener.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapChangeListener.java index 281334ff0b52..32c638e61410 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapChangeListener.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapChangeListener.java @@ -18,6 +18,8 @@ package com.intellij.openapi.editor.ex; import com.intellij.openapi.editor.TextChange; import org.jetbrains.annotations.NotNull; +import java.util.Collection; + /** * Defines a contract for the callbacks for soft wraps management notifications (addition/removal). * @@ -32,4 +34,9 @@ public interface SoftWrapChangeListener { * @param softWrap newly registered soft wrap */ void softWrapAdded(@NotNull TextChange softWrap); + + /** + * This method is assumed to be called every time soft wrap(s) is removed. + */ + void softWrapsRemoved(); } 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 5a6be1d663df..122d1f28fcca 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 @@ -334,6 +334,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi int softWrapLine = myDocument.getLineNumber(softWrap.getStart()); mySizeContainer.update(softWrapLine, softWrapLine, softWrapLine); } + + @Override + public void softWrapsRemoved() { + mySoftWrapsChanged = true; + mySizeContainer.reset(); + } }); EditorHighlighter highlighter = new EmptyEditorHighlighter(myScheme.getAttributes(HighlighterColors.TEXT)); @@ -1691,25 +1697,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (lIterator.getLineNumber() >= lastLineIndex && position.y <= clip.y + clip.height) { paintAfterFileEndBackground(iterationState, g, position, clip, lineHeight, defaultBackground); } - - // Perform additional activity if soft wrap is added or removed during repainting. - // Note: this code lives in this method in assumption that background repainting is the very first activity performed - // during whole editor component repaint. - if (mySoftWrapsChanged) { - mySoftWrapsChanged = false; - validateSize(); - - // Repaint editor to the bottom in order to ensure that its content is shown correctly after new soft wrap introduction. - repaintToScreenBottom(xyToLogicalPosition(position).line); - - // Repaint gutter at all space that is located after active clip in order to ensure that line numbers are correctly redrawn - // in accordance with the newly introduced soft wrap(s). - myGutterComponent.repaint(0, clip.y, myGutterComponent.getWidth(), myGutterComponent.getHeight() - clip.y); - - // Ask caret model to update visual caret position. - //TODO den implement - //getCaretModel().moveToOffset(getCaretModel().getOffset()); - } } private void paintRectangularSelection(Graphics g) { @@ -1908,6 +1895,22 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } flushCachedChars(g); + + // Perform additional activity if soft wrap is added or removed during repainting. + if (mySoftWrapsChanged) { + mySoftWrapsChanged = false; + validateSize(); + + // Repaint editor to the bottom in order to ensure that its content is shown correctly after new soft wrap introduction. + repaintToScreenBottom(xyToLogicalPosition(position).line); + + // Repaint gutter at all space that is located after active clip in order to ensure that line numbers are correctly redrawn + // in accordance with the newly introduced soft wrap(s). + myGutterComponent.repaint(0, clip.y, myGutterComponent.getWidth(), myGutterComponent.getHeight() - clip.y); + + // Ask caret model to update visual caret position. + getCaretModel().moveToOffset(getCaretModel().getOffset()); + } } private boolean paintSelection() { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapsStorage.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapsStorage.java index 627a5ed6ae4e..14a7def3ebe3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapsStorage.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapsStorage.java @@ -19,10 +19,7 @@ import com.intellij.openapi.editor.ex.SoftWrapChangeListener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.concurrent.CopyOnWriteArraySet; /** @@ -125,7 +122,9 @@ public class SoftWrapsStorage { if (index < 0 || index >= myWraps.size()) { return null; } - return myWraps.remove(index); + TextChangeImpl removed = myWraps.remove(index); + notifyListenersAboutRemoval(); + return removed; } /** @@ -133,6 +132,7 @@ public class SoftWrapsStorage { */ public void removeAll() { myWraps.clear(); + notifyListenersAboutRemoval(); } /** @@ -144,4 +144,10 @@ public class SoftWrapsStorage { public boolean addSoftWrapChangeListener(@NotNull SoftWrapChangeListener listener) { return myListeners.add(listener); } + + private void notifyListenersAboutRemoval() { + for (SoftWrapChangeListener listener : myListeners) { + listener.softWrapsRemoved(); + } + } } diff --git a/platform/platform-impl/testSrc/com/intellij/ide/util/treeView/AbstractTreeBuilderTest.java b/platform/platform-impl/testSrc/com/intellij/ide/util/treeView/AbstractTreeBuilderTest.java index b7e7346373cc..7dde8d515dc6 100644 --- a/platform/platform-impl/testSrc/com/intellij/ide/util/treeView/AbstractTreeBuilderTest.java +++ b/platform/platform-impl/testSrc/com/intellij/ide/util/treeView/AbstractTreeBuilderTest.java @@ -278,7 +278,7 @@ abstract class AbstractTreeBuilderTest extends BaseTreeTestCase + + diff --git a/platform/platform-resources/src/componentSets/Lang.xml b/platform/platform-resources/src/componentSets/Lang.xml index 7a2997d69b06..815293345032 100644 --- a/platform/platform-resources/src/componentSets/Lang.xml +++ b/platform/platform-resources/src/componentSets/Lang.xml @@ -189,11 +189,6 @@ - - com.intellij.lang.injection.InjectedLanguageManager - com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl - - com.intellij.pom.wrappers.PsiEventWrapperAspect com.intellij.pom.wrappers.PsiEventWrapperAspect diff --git a/platform/platform-resources/src/idea/PlatformLangActionManager.xml b/platform/platform-resources/src/idea/PlatformLangActionManager.xml index 029bc11e134b..48ce2e847d23 100644 --- a/platform/platform-resources/src/idea/PlatformLangActionManager.xml +++ b/platform/platform-resources/src/idea/PlatformLangActionManager.xml @@ -51,6 +51,7 @@ + diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java index 6a7f3ee1e1e2..77727073a0b2 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java @@ -16,6 +16,7 @@ package com.intellij.execution.testframework.sm; import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; import com.intellij.execution.configurations.CommandLineState; import com.intellij.execution.configurations.ConfigurationPerRunnerSettings; import com.intellij.execution.configurations.RunnerSettings; @@ -131,16 +132,18 @@ public class SMTestRunnerConnectionUtil { * @param processHandler Process handler * @param commandLineState Command line state * @param config User run configuration settings + * @param executor Executor * @return Console view * @throws ExecutionException If IDEA cannot execute process this Exception will * be caught and shown in error message box */ public static ConsoleView attachRunner(@NotNull final String testFrameworkName, @NotNull final ProcessHandler processHandler, @NotNull final CommandLineState commandLineState, - @NotNull final RuntimeConfiguration config + @NotNull final RuntimeConfiguration config, + @NotNull final Executor executor ) throws ExecutionException { // final String testFrameworkName - final TestConsoleProperties consoleProperties = new SMTRunnerConsoleProperties(config, testFrameworkName); + final TestConsoleProperties consoleProperties = new SMTRunnerConsoleProperties(config, testFrameworkName, executor); return attachRunner(testFrameworkName, processHandler, consoleProperties, commandLineState.getRunnerSettings(), diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java index 34f39808194b..cab20db48634 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java @@ -15,13 +15,11 @@ */ package com.intellij.execution.testframework.sm.runner; +import com.intellij.execution.Executor; import com.intellij.execution.configurations.RuntimeConfiguration; import com.intellij.execution.testframework.TestConsoleProperties; import com.intellij.ide.util.PropertiesComponent; import com.intellij.util.config.Storage; -import com.intellij.xdebugger.XDebugSession; -import com.intellij.xdebugger.XDebuggerManager; -import org.jetbrains.annotations.Nullable; /** * @author: Roman Chernyatchik @@ -32,40 +30,17 @@ public class SMTRunnerConsoleProperties extends TestConsoleProperties { /** * @param config * @param testFrameworkName Prefix for storage which keeps runner settings. E.g. "RubyTestUnit" + * @param executor */ public SMTRunnerConsoleProperties(final RuntimeConfiguration config, - final String testFrameworkName) + final String testFrameworkName, + Executor executor) { - super(new Storage.PropertiesComponentStorage(testFrameworkName + "Support.", PropertiesComponent.getInstance()), config.getProject()); + super(new Storage.PropertiesComponentStorage(testFrameworkName + "Support.", PropertiesComponent.getInstance()), config.getProject(), + executor); myConfiguration = config; } - @Override - public boolean isDebug() { - return getDebugSession() != null; - } - - @Override - public boolean isPaused() { - final XDebugSession debuggerSession = getDebugSession(); - return debuggerSession != null && debuggerSession.isPaused(); - } - - @Nullable - public XDebugSession getDebugSession() { - final XDebuggerManager debuggerManager = XDebuggerManager.getInstance(getProject()); - if (debuggerManager == null) { - return null; - } - final XDebugSession[] sessions = debuggerManager.getDebugSessions(); - for (final XDebugSession debuggerSession : sessions) { - if (getConsole() == debuggerSession.getRunContentDescriptor().getExecutionConsole()) { - return debuggerSession; - } - } - return null; - } - public RuntimeConfiguration getConfiguration() { return myConfiguration; } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/BaseSMTRunnerTestCase.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/BaseSMTRunnerTestCase.java index 607e32a8a2de..301986c39041 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/BaseSMTRunnerTestCase.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/BaseSMTRunnerTestCase.java @@ -16,6 +16,7 @@ package com.intellij.execution.testframework.sm.runner; import com.intellij.execution.configurations.RuntimeConfiguration; +import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.testframework.TestConsoleProperties; import com.intellij.testFramework.LightPlatformTestCase; import com.intellij.testFramework.PlatformTestCase; @@ -86,7 +87,7 @@ public abstract class BaseSMTRunnerTestCase extends LightPlatformTestCase { protected TestConsoleProperties createConsoleProperties() { final RuntimeConfiguration runConfiguration = createRunConfiguration(); - final TestConsoleProperties consoleProperties = new SMTRunnerConsoleProperties(runConfiguration, "SMRunnerTests"); + final TestConsoleProperties consoleProperties = new SMTRunnerConsoleProperties(runConfiguration, "SMRunnerTests", DefaultDebugExecutor.getDebugExecutorInstance()); TestConsoleProperties.HIDE_PASSED_TESTS.set(consoleProperties, false); return consoleProperties; diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java index efb7f16e7b76..df999debac32 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java @@ -15,6 +15,7 @@ */ package com.intellij.execution.testframework.sm.runner.ui; +import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.testframework.PoolOfTestIcons; import com.intellij.execution.testframework.sm.UITestUtil; import com.intellij.execution.testframework.sm.runner.BaseSMTRunnerTestCase; @@ -638,7 +639,7 @@ public class TestsPresentationUtilTest extends BaseSMTRunnerTestCase { public MyRenderer(final boolean isPaused, final UITestUtil.FragmentsContainer fragmentsContainer) { - super(new SMTRunnerConsoleProperties(createRunConfiguration(), "SMRunnerTests") { + super(new SMTRunnerConsoleProperties(createRunConfiguration(), "SMRunnerTests", DefaultDebugExecutor.getDebugExecutorInstance()) { @Override public boolean isPaused() { return isPaused; diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java b/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java index 74d432d106a7..81420f866b65 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java @@ -20,7 +20,9 @@ */ package com.intellij.execution.testframework; +import com.intellij.execution.Executor; import com.intellij.execution.configurations.RuntimeConfiguration; +import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ExecutionConsole; import com.intellij.execution.util.StoringPropertyContainer; @@ -31,6 +33,8 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.config.AbstractProperty; import com.intellij.util.config.BooleanProperty; import com.intellij.util.config.Storage; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XDebuggerManager; import java.util.ArrayList; import java.util.HashMap; @@ -46,14 +50,16 @@ public abstract class TestConsoleProperties extends StoringPropertyContainer imp public static final BooleanProperty SHOW_STATISTICS = new BooleanProperty("showStatistics", false); private final Project myProject; + private final Executor myExecutor; private ConsoleView myConsole; protected final HashMap> myListeners = new HashMap>(); - public TestConsoleProperties(final Storage storage, Project project) { + public TestConsoleProperties(final Storage storage, Project project, Executor executor) { super(storage); myProject = project; + myExecutor = executor; } public Project getProject() { @@ -92,9 +98,14 @@ public abstract class TestConsoleProperties extends StoringPropertyContainer imp } } - public abstract boolean isDebug(); + public boolean isDebug() { + return myExecutor.getId() == DefaultDebugExecutor.EXECUTOR_ID; + } - public abstract boolean isPaused(); + public boolean isPaused() { + final XDebugSession debuggerSession = XDebuggerManager.getInstance(myProject).getDebugSession(getConsole()); + return debuggerSession != null && debuggerSession.isPaused(); + } protected void onPropertyChanged(final AbstractProperty property, final T value) { final ArrayList listeners = myListeners.get(property); diff --git a/platform/testRunner/testRunner.iml b/platform/testRunner/testRunner.iml index 21d34cc6920b..5c2b923541d0 100644 --- a/platform/testRunner/testRunner.iml +++ b/platform/testRunner/testRunner.iml @@ -10,6 +10,7 @@ + diff --git a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java index bcc8d62e5524..05e1ac36c5f9 100644 --- a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java +++ b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java @@ -198,7 +198,7 @@ public class NameUtil { firstIdentifierLetter = true; } else { - if (prevIsUppercase) { + if (c == ':' || prevIsUppercase) { buffer.append("[A-Za-z\\s0-9\\$]*"); } diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManager.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManager.java index 0b26b83bdf76..53065283146b 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManager.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManager.java @@ -19,6 +19,7 @@ package com.intellij.xdebugger; import com.intellij.execution.ExecutionException; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ProgramRunner; +import com.intellij.execution.ui.ExecutionConsole; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.openapi.project.Project; import com.intellij.xdebugger.breakpoints.XBreakpointManager; @@ -43,6 +44,9 @@ public abstract class XDebuggerManager { @NotNull public abstract XDebugSession[] getDebugSessions(); + @Nullable + public abstract XDebugSession getDebugSession(@NotNull ExecutionConsole executionConsole); + @NotNull public abstract Collection getDebugProcesses(Class processClass); diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XStackFrame.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XStackFrame.java index 82b97af99f7c..d3167d40e7be 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XStackFrame.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XStackFrame.java @@ -16,6 +16,7 @@ package com.intellij.xdebugger.frame; +import com.intellij.ui.FileColorManager; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleTextAttributes; import com.intellij.xdebugger.XDebuggerBundle; @@ -66,6 +67,7 @@ public abstract class XStackFrame extends XValueContainer { public void customizePresentation(final SimpleColoredComponent component) { XSourcePosition position = getSourcePosition(); if (position != null) { + //FileColorManager.getInstance() component.append(position.getFile().getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); component.append(":" + (position.getLine()+1), SimpleTextAttributes.REGULAR_ATTRIBUTES); component.setIcon(DebuggerIcons.STACK_FRAME_ICON); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java index f6f498be98c9..28d5c23a7326 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java @@ -21,26 +21,27 @@ import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ProgramRunner; +import com.intellij.execution.ui.ExecutionConsole; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.ui.RunContentListener; import com.intellij.execution.ui.RunContentManager; +import com.intellij.openapi.Disposable; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.ProjectComponent; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileEditorManagerAdapter; +import com.intellij.openapi.fileEditor.FileEditorManagerListener; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.fileEditor.FileEditorManagerListener; -import com.intellij.openapi.fileEditor.FileEditorManagerAdapter; -import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.impl.http.HttpVirtualFile; -import com.intellij.openapi.Disposable; import com.intellij.util.containers.HashMap; -import com.intellij.util.xmlb.annotations.Property; import com.intellij.util.messages.MessageBus; +import com.intellij.util.xmlb.annotations.Property; import com.intellij.xdebugger.*; import com.intellij.xdebugger.impl.breakpoints.XBreakpointManagerImpl; import com.intellij.xdebugger.impl.ui.ExecutionPointHighlighter; @@ -208,6 +209,17 @@ public class XDebuggerManagerImpl extends XDebuggerManager return mySessions.toArray(new XDebugSession[mySessions.size()]); } + @Override + @Nullable + public XDebugSession getDebugSession(@NotNull ExecutionConsole executionConsole) { + for (final XDebugSession debuggerSession : getDebugSessions()) { + if (executionConsole == debuggerSession.getRunContentDescriptor().getExecutionConsole()) { + return debuggerSession; + } + } + return null; + } + @NotNull @Override public Collection getDebugProcesses(Class processClass) { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/DebuggerFramesList.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/DebuggerFramesList.java index 36bbf6d2c264..012b8b63b24e 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/DebuggerFramesList.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/DebuggerFramesList.java @@ -16,6 +16,7 @@ package com.intellij.xdebugger.impl.frame; import com.intellij.ide.OccurenceNavigator; +import com.intellij.openapi.project.Project; import com.intellij.ui.components.JBList; import com.intellij.xdebugger.XDebuggerBundle; @@ -27,8 +28,14 @@ import javax.swing.event.ListSelectionListener; * @author nik */ public abstract class DebuggerFramesList extends JBList implements OccurenceNavigator { - public DebuggerFramesList() { + protected final Project myProject; + + public DebuggerFramesList(Project project) { super(new DefaultListModel()); + myProject = project; + } + + protected void doInit() { getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); setCellRenderer(createListRenderer()); getSelectionModel().addListSelectionListener(new ListSelectionListener() { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebuggerFramesList.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebuggerFramesList.java index 6c71036bbb42..e13641291fb4 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebuggerFramesList.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebuggerFramesList.java @@ -15,12 +15,18 @@ */ package com.intellij.xdebugger.impl.frame; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.FileColorManager; import com.intellij.ui.SimpleTextAttributes; import com.intellij.xdebugger.XDebuggerBundle; +import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.frame.XStackFrame; import javax.swing.*; +import java.awt.*; /** * @author nik @@ -28,8 +34,13 @@ import javax.swing.*; public class XDebuggerFramesList extends DebuggerFramesList { private XStackFrame mySelectedFrame; + public XDebuggerFramesList(Project project) { + super(project); + doInit(); + } + protected ListCellRenderer createListRenderer() { - return new XDebuggerFrameListRenderer(); + return new XDebuggerFrameListRenderer(myProject); } protected void onFrameChanged(final Object selectedValue) { @@ -49,6 +60,14 @@ public class XDebuggerFramesList extends DebuggerFramesList { } private static class XDebuggerFrameListRenderer extends ColoredListCellRenderer { + private final FileColorManager myColorsManager; + private final PsiManager myPsiManager; + + public XDebuggerFrameListRenderer(Project project) { + myPsiManager = PsiManager.getInstance(project); + myColorsManager = FileColorManager.getInstance(project); + } + protected void customizeCellRenderer(final JList list, final Object value, final int index, @@ -64,6 +83,16 @@ public class XDebuggerFramesList extends DebuggerFramesList { } XStackFrame stackFrame = (XStackFrame)value; + if (!selected) { + XSourcePosition position = stackFrame.getSourcePosition(); + if (position != null) { + PsiFile f = myPsiManager.findFile(position.getFile()); + if (f != null) { + Color c = myColorsManager.getFileColor(f); + if (c != null) setBackground(c); + } + } + } stackFrame.customizePresentation(this); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java index 94bba97482e7..a4583932e9b1 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java @@ -59,7 +59,7 @@ public class XFramesView extends XDebugViewBase { myThreadComboBox.addItemListener(new MyItemListener()); myMainPanel.add(myThreadComboBox, BorderLayout.NORTH); - myFramesList = new XDebuggerFramesList(); + myFramesList = new XDebuggerFramesList(session.getProject()); myFramesList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(final ListSelectionEvent e) { if (e.getValueIsAdjusting()) return; diff --git a/plugins/groovy/resources/intentionDescriptions/CreateParameterForFieldIntention/after.groovy.template b/plugins/groovy/resources/intentionDescriptions/CreateParameterForFieldIntention/after.groovy.template new file mode 100644 index 000000000000..07896cc93878 --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/CreateParameterForFieldIntention/after.groovy.template @@ -0,0 +1,7 @@ + class Foo { + def field + + def Foo(def field) { + this.field = field + } + } diff --git a/plugins/groovy/resources/intentionDescriptions/CreateParameterForFieldIntention/before.groovy.template b/plugins/groovy/resources/intentionDescriptions/CreateParameterForFieldIntention/before.groovy.template new file mode 100644 index 000000000000..4e6acb3280a8 --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/CreateParameterForFieldIntention/before.groovy.template @@ -0,0 +1,6 @@ +class Foo { + def field + + def Foo() { + } +} diff --git a/plugins/groovy/resources/intentionDescriptions/CreateParameterForFieldIntention/description.html b/plugins/groovy/resources/intentionDescriptions/CreateParameterForFieldIntention/description.html new file mode 100644 index 000000000000..4d855e8801ab --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/CreateParameterForFieldIntention/description.html @@ -0,0 +1,5 @@ + + +This intention adds parameter to constructor for uninitialized field + + \ No newline at end of file diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index c072abb2eb76..2f285a10915c 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -85,6 +85,7 @@ + @@ -285,6 +286,11 @@ intention.category.groovy/intention.category.control.flow org.jetbrains.plugins.groovy.intentions.control.DemorgansLawIntention + + org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle + intention.category.groovy/intention.category.control.flow + org.jetbrains.plugins.groovy.intentions.control.CreateParameterForFieldIntention + org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle intention.category.groovy/intention.category.control.flow diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties index 371ffe7bb37a..e676d65bcdec 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties @@ -339,3 +339,5 @@ method.duplicate=Method with signature {0} is already defined in the class ''{1} ambiguous.code.block=Ambiguous code block cyclic.inheritance.involving.0=Cyclic inheritance involving ''{0}'' there.is.no.default.constructor.available.in.class.0=There is no default constructor available in class ''{0}'' +groovy.library.is.not.configured.for.module=Groovy SDK is not configured for module ''{0}'' +configure.groovy.library=Configure Groovy SDK... diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/ConfigureGroovyLibraryNotificationProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/ConfigureGroovyLibraryNotificationProvider.java new file mode 100644 index 000000000000..54580df92138 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/ConfigureGroovyLibraryNotificationProvider.java @@ -0,0 +1,83 @@ +/* + * 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 org.jetbrains.plugins.groovy.annotator; + +import com.intellij.ProjectTopics; +import com.intellij.ide.util.frameworkSupport.AddFrameworkSupportDialog; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootEvent; +import com.intellij.openapi.roots.ModuleRootListener; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.EditorNotificationPanel; +import com.intellij.ui.EditorNotifications; +import org.jetbrains.plugins.groovy.GroovyBundle; +import org.jetbrains.plugins.groovy.GroovyFileType; +import org.jetbrains.plugins.groovy.config.GroovyConfigUtils; + +/** + * @author Maxim.Medvedev + */ +public class ConfigureGroovyLibraryNotificationProvider implements EditorNotifications.Provider { + private static final Key KEY = Key.create("configure.groovy.library"); + + private final Project myProject; + + public ConfigureGroovyLibraryNotificationProvider(Project project, final EditorNotifications notifications) { + myProject = project; + project.getMessageBus().connect(project).subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() { + @Override + public void beforeRootsChange(ModuleRootEvent event) {} + + @Override + public void rootsChanged(ModuleRootEvent event) { + notifications.updateAllNotifications(); + } + }); + } + + @Override + public Key getKey() { + return KEY; + } + + @Override + public EditorNotificationPanel createNotificationPanel(VirtualFile file) { + if (file.getFileType() != GroovyFileType.GROOVY_FILE_TYPE) return null; + + final Module module = ModuleUtil.findModuleForFile(file, myProject); + if (module == null) return null; + + final Library[] libraries = GroovyConfigUtils.getInstance().getSDKLibrariesByModule(module); + if (libraries.length > 0) return null; + + final EditorNotificationPanel panel = new EditorNotificationPanel(); + panel.setText(GroovyBundle.message("groovy.library.is.not.configured.for.module", module.getName())); + panel.createActionLabel(GroovyBundle.message("configure.groovy.library"), new Runnable() { + @Override + public void run() { + AddFrameworkSupportDialog dialog = AddFrameworkSupportDialog.createDialog(module); + if (dialog != null) { + dialog.show(); + } + } + }); + return panel; + } +} 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 e174566e5aa2..816143bbacc7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -84,6 +84,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatem import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.types.*; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrVariableDeclarationOwner; +import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider; import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass; @@ -441,6 +442,22 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { @Override public void visitListOrMap(GrListOrMap listOrMap) { + for (PsiType type : GroovyExpectedTypesProvider.getDefaultExpectedTypes(listOrMap)) { + if (type instanceof PsiClassType && + !type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) && + !InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_LANG_ITERABLE) && + !InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) { + final PsiElement startToken = listOrMap.getFirstChild(); + if (startToken != null && startToken.getNode().getElementType() == GroovyTokenTypes.mLBRACK) { + myHolder.createInfoAnnotation(startToken, null).setTextAttributes(DefaultHighlighter.LITERAL_CONVERSION); + } + final PsiElement endToken = listOrMap.getLastChild(); + if (endToken != null && endToken.getNode().getElementType() == GroovyTokenTypes.mRBRACK) { + myHolder.createInfoAnnotation(endToken, null).setTextAttributes(DefaultHighlighter.LITERAL_CONVERSION); + } + } + } + MultiMap map = new MultiMap(); for (GrNamedArgument element : listOrMap.getNamedArguments()) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java index e1dca6a60a14..942416ef339d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java @@ -103,7 +103,6 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler { final JavaParameters parameters = new JavaParameters(); final PathsList classPathBuilder = parameters.getClassPath(); - classPathBuilder.add(PathUtil.getJarPathForClass(GroovycRunner.class)); final ModuleChunk chunk = createChunk(module, compileContext); @@ -119,6 +118,8 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler { appendOutputPath(module, classPathBuilder, true); } + classPathBuilder.add(PathUtil.getJarPathForClass(GroovycRunner.class)); + final List patchers = new SmartList(); for (final GroovyCompilerExtension extension : GroovyCompilerExtension.EP_NAME.getExtensions()) { extension.enhanceCompilationClassPath(chunk, classPathBuilder); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerLoader.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerLoader.java index a8ab5ded516e..87ff95e6a0ab 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerLoader.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerLoader.java @@ -48,7 +48,7 @@ public class GroovyCompilerLoader extends AbstractProjectComponent { compilerManager.addCompilableFileType(GroovyFileType.GROOVY_FILE_TYPE); compilerManager.addTranslatingCompiler(new GroovycStubGenerator(myProject), - new HashSet(Arrays.asList(GroovyFileType.GROOVY_FILE_TYPE)), + new HashSet(Arrays.asList(StdFileTypes.JAVA, GroovyFileType.GROOVY_FILE_TYPE)), new HashSet(Arrays.asList(StdFileTypes.JAVA))); compilerManager.addTranslatingCompiler(new GroovyCompiler(myProject), diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java index 11cd6b45302f..fd11d3e49540 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java @@ -589,17 +589,7 @@ public class GroovyToJavaGenerator { /************* parameters **********/ GrParameter[] parameterList = constructor.getParameters(); - text.append("("); - - for (int i = 0; i < parameterList.length; i++) { - if (i > 0) text.append(", "); - - GrParameter parameter = parameterList[i]; - - text.append(getTypeText(parameter.getTypeElementGroovy())).append(" ").append(parameter.getName()); - } - - text.append(") "); + writeParameterList(text, parameterList); final Set throwsTypes = collectThrowsTypes(constructor, new THashSet()); if (!throwsTypes.isEmpty()) { @@ -684,7 +674,8 @@ public class GroovyToJavaGenerator { } private static void writeVariableDeclarations(StringBuffer text, GrVariableDeclaration variableDeclaration) { - final String type = getTypeText(variableDeclaration.getTypeElementGroovy()); + GrTypeElement typeElement = variableDeclaration.getTypeElementGroovy(); + final String type = typeElement == null ? CommonClassNames.JAVA_LANG_OBJECT : getTypeText(typeElement.getType(), typeElement, false); final String initializer = getDefaultValueText(type); final GrModifierList modifierList = variableDeclaration.getModifierList(); @@ -728,11 +719,27 @@ public class GroovyToJavaGenerator { text.append(getTypeText(retType, method, false)); text.append(" "); - //append method name text.append(name); - /************* parameters **********/ + writeParameterList(text, parameters); + if (!isAbstract) { + /************* body **********/ + text.append("{\n"); + text.append(" return "); + + text.append(getDefaultValueText(getTypeText(retType, method, false))); + + text.append(";"); + + text.append("\n }"); + } else { + text.append(";"); + } + text.append("\n"); + } + + private static void writeParameterList(StringBuffer text, PsiParameter[] parameters) { text.append("("); //writes myParameters @@ -751,21 +758,6 @@ public class GroovyToJavaGenerator { } text.append(")"); text.append(" "); - - if (!isAbstract) { - /************* body **********/ - text.append("{\n"); - text.append(" return "); - - text.append(getDefaultValueText(getTypeText(retType, method, false))); - - text.append(";"); - - text.append("\n }"); - } else { - text.append(";"); - } - text.append("\n"); } private static boolean writeMethodModifiers(StringBuffer text, PsiModifierList modifierList, String[] modifiers) { @@ -813,14 +805,6 @@ public class GroovyToJavaGenerator { } } - private static String getTypeText(GrTypeElement typeElement) { - if (typeElement == null) { - return CommonClassNames.JAVA_LANG_OBJECT; - } - - return getTypeText(typeElement.getType(), typeElement, false); - } - private static String getTypeText(@Nullable PsiType type, @Nullable PsiElement context, boolean allowVarargs) { if (context != null && type instanceof PsiClassType) { final String accessible = findAccessibleSuperClass(context, ((PsiClassType)type).resolve()); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java index b0c87fa0078c..2571e658fd8e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java @@ -24,10 +24,10 @@ import com.intellij.openapi.compiler.CompileScope; import com.intellij.openapi.compiler.CompilerPaths; import com.intellij.openapi.compiler.ex.CompileContextEx; import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration; +import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; -import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -62,18 +62,21 @@ public class GroovycStubGenerator extends GroovyCompilerBase { @Override public void compile(CompileContext compileContext, Chunk moduleChunk, VirtualFile[] virtualFiles, OutputSink sink) { - final CompileScope scope = compileContext.getCompileScope(); - final VirtualFile[] javaFiles = scope.getFiles(StdFileTypes.JAVA, true); - if (javaFiles.length == 0) { - return; - } - boolean hasJava = false; - for (VirtualFile javaFile : javaFiles) { - final Module module = ModuleUtil.findModuleForFile(javaFile, myProject); - if (module != null && moduleChunk.containsNode(module)) { + + final ExcludedEntriesConfiguration excluded = GroovyCompilerConfiguration.getExcludeConfiguration(myProject); + + List total = new ArrayList(); + for (final VirtualFile virtualFile : virtualFiles) { + final FileType fileType = virtualFile.getFileType(); + if (fileType == StdFileTypes.JAVA) { hasJava = true; - break; + } + + if (!excluded.isExcluded(virtualFile)) { + if (fileType == GroovyFileType.GROOVY_FILE_TYPE) { + total.add(virtualFile); + } } } @@ -81,17 +84,6 @@ public class GroovycStubGenerator extends GroovyCompilerBase { return; } - final ExcludedEntriesConfiguration excluded = GroovyCompilerConfiguration.getExcludeConfiguration(myProject); - - List total = new ArrayList(); - for (final VirtualFile virtualFile : virtualFiles) { - if (!excluded.isExcluded(virtualFile)) { - if (virtualFile.getFileType() == GroovyFileType.GROOVY_FILE_TYPE) { - total.add(virtualFile); - } - } - } - if (total.isEmpty()) { return; } @@ -99,6 +91,11 @@ public class GroovycStubGenerator extends GroovyCompilerBase { super.compile(compileContext, moduleChunk, VfsUtil.toVirtualFileArray(total), sink); } + @Override + public boolean isCompilableFile(VirtualFile file, CompileContext context) { + return super.isCompilableFile(file, context) || StdFileTypes.JAVA.equals(file.getFileType()); + } + @Override protected void compileFiles(CompileContext compileContext, Module module, final List toCompile, OutputSink sink, boolean tests) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GrAliasedImportedElementSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GrAliasedImportedElementSearcher.java index d67bdbd5ff55..4712e91b1070 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GrAliasedImportedElementSearcher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GrAliasedImportedElementSearcher.java @@ -15,18 +15,13 @@ */ package org.jetbrains.plugins.groovy.findUsages; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.NullableComputable; +import com.intellij.openapi.application.QueryExecutorBase; import com.intellij.psi.*; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.search.SearchScope; -import com.intellij.psi.search.TextOccurenceProcessor; -import com.intellij.psi.search.UsageSearchContext; +import com.intellij.psi.search.*; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.util.Processor; -import com.intellij.util.QueryExecutor; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; @@ -34,125 +29,81 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; /** * @author Maxim.Medvedev */ -public class GrAliasedImportedElementSearcher implements QueryExecutor { - private static final ThreadLocal I_WAS_HERE = new ThreadLocal(); +public class GrAliasedImportedElementSearcher extends QueryExecutorBase { - public boolean execute(final ReferencesSearch.SearchParameters parameters, final Processor consumer) { - final PsiElement elementToSearch = parameters.getElementToSearch(); - if (!(elementToSearch instanceof PsiMember)) return true; - if (I_WAS_HERE.get() != null) return true; + public GrAliasedImportedElementSearcher() { + super(true); + } - try { - I_WAS_HERE.set(Boolean.TRUE); - final TextOccurenceProcessor processor = new MyTextOccurenceProcessor(elementToSearch, consumer); + @Override + public void processQuery(ReferencesSearch.SearchParameters parameters, Processor consumer) { + final PsiElement target = parameters.getElementToSearch(); + if (!(target instanceof PsiMember) || !(target instanceof PsiNamedElement)) return; - final SearchScope groovySearchScope = PsiUtil.restrictScopeToGroovyFiles(new Computable() { - public SearchScope compute() { - return parameters.getEffectiveSearchScope(); - } - }); + final String name = ((PsiNamedElement)target).getName(); + if (name == null) return; - if (!ReferencesSearch.search(elementToSearch, groovySearchScope).forEach(new MyProcessor(null, processor))) return false; + final SearchScope onlyGroovy = PsiUtil.restrictScopeToGroovyFiles(parameters.getEffectiveSearchScope()); - if (elementToSearch instanceof PsiMethod && isAccessor(elementToSearch)) { - final PsiField field = ApplicationManager.getApplication().runReadAction(new Computable() { - public PsiField compute() { - return GroovyPropertyUtils.findFieldForAccessor((PsiMethod)elementToSearch, true); - } - }); + if (target instanceof PsiMethod) { + final PsiMethod method = (PsiMethod)target; + if (GroovyPropertyUtils.isSimplePropertyAccessor(method)) { + final PsiField field = GroovyPropertyUtils.findFieldForAccessor(method, true); if (field != null) { - final String prefix = ApplicationManager.getApplication().runReadAction(new Computable() { - public String compute() { - return GroovyPropertyUtils.getAccessorPrefix((PsiMethod)elementToSearch); - } - }); - if (prefix == null) return true; - if (!ReferencesSearch.search(field, groovySearchScope).forEach(new MyProcessor(prefix, processor))) return false; + final String propertyName = field.getName(); + if (propertyName != null) { + final MyProcessor processor = new MyProcessor(method, GroovyPropertyUtils.getAccessorPrefix(method)); + parameters.getOptimizer().searchWord(propertyName, onlyGroovy, UsageSearchContext.IN_CODE, true, processor); + } } } - return true; - } - finally { - I_WAS_HERE.set(null); } + parameters.getOptimizer().searchWord(name, onlyGroovy, UsageSearchContext.IN_CODE, true, new MyProcessor(target, null)); + } - private static Boolean isAccessor(final PsiElement elementToSearch) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - public Boolean compute() { - return GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod)elementToSearch); - } - }); - } - - static class MyProcessor implements Processor { + private static class MyProcessor extends RequestResultProcessor { + private final PsiElement myTarget; private final String prefix; - private final TextOccurenceProcessor processor; - MyProcessor(@Nullable String prefix, TextOccurenceProcessor processor) { + MyProcessor(PsiElement target, @Nullable String prefix) { + myTarget = target; this.prefix = prefix; - this.processor = processor; } - public boolean process(PsiReference psiReference) { - final PsiElement element = psiReference.getElement(); - if (element == null) return true; - + @Override + public boolean processTextOccurrence(final PsiElement element, int offsetInElement, Processor consumer) { String alias = getAlias(element); if (alias == null) return true; - final PsiFile containingFile = ApplicationManager.getApplication().runReadAction(new Computable() { - public PsiFile compute() { - return element.getContainingFile(); - } - }); + final PsiReference reference = element.getReference(); + if (reference == null) { + return true; + } + if (!reference.isReferenceTo(myTarget instanceof GrAccessorMethod ? ((GrAccessorMethod)myTarget).getProperty() : myTarget)) { + return true; + } + final SearchRequestCollector collector = new SearchRequestCollector(); + final SearchScope fileScope = new LocalSearchScope(element.getContainingFile()); + collector.searchWord(alias, fileScope, UsageSearchContext.IN_CODE, true, myTarget); if (prefix != null) { - if (!PsiManager.getInstance(element.getProject()).getSearchHelper() - .processElementsWithWord(processor, GlobalSearchScope.fileScope(containingFile), prefix + GroovyPropertyUtils.capitalize(alias), - UsageSearchContext.IN_CODE, - false)) { - return false; - } + collector.searchWord(prefix + GroovyPropertyUtils.capitalize(alias), fileScope, UsageSearchContext.IN_CODE, true, myTarget); } - return PsiManager.getInstance(element.getProject()).getSearchHelper() - .processElementsWithWord(processor, GlobalSearchScope.fileScope(containingFile), alias, UsageSearchContext.IN_CODE, false); + + return element.getManager().getSearchHelper().processRequests(collector, consumer); } + @Nullable private static String getAlias(final PsiElement element) { - return ApplicationManager.getApplication().runReadAction(new NullableComputable() { - public String compute() { - if (!(element.getParent() instanceof GrImportStatement)) return null; - final GrImportStatement importStatement = (GrImportStatement)element.getParent(); - if (!importStatement.isAliasedImport()) return null; - return importStatement.getImportedName(); - } - }); + if (!(element.getParent() instanceof GrImportStatement)) return null; + final GrImportStatement importStatement = (GrImportStatement)element.getParent(); + if (!importStatement.isAliasedImport()) return null; + return importStatement.getImportedName(); } } -static class MyTextOccurenceProcessor implements TextOccurenceProcessor { - private final PsiElement elementToSearch; - private final Processor consumer; - - public MyTextOccurenceProcessor(PsiElement elementToSearch, Processor consumer) { - this.elementToSearch = elementToSearch; - this.consumer = consumer; - } - - public boolean execute(PsiElement element, int offsetInElement) { - final PsiReference[] refs = element.getParent().getReferences(); - for (PsiReference ref : refs) { - if (ReferenceRange.containsOffsetInElement(ref, offsetInElement)) { - if (ref.isReferenceTo(elementToSearch)) { - return consumer.process(ref); - } - } - } - return true; - } - } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearchHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearchHelper.java new file mode 100644 index 000000000000..c53a4c8d1f26 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearchHelper.java @@ -0,0 +1,199 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.plugins.groovy.findUsages; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadActionProcessor; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.NullableComputable; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.impl.light.LightMemberReference; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.SearchScope; +import com.intellij.psi.search.searches.DirectClassInheritorsSearch; +import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.util.Processor; +import org.jetbrains.plugins.groovy.GroovyFileType; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; + +/** + * @author Maxim.Medvedev + * Date: May 2, 2009 3:48:53 PM + */ +public class GroovyConstructorUsagesSearchHelper { + private GroovyConstructorUsagesSearchHelper() { + } + + public static boolean execute(final PsiMethod constructor, SearchScope searchScope, final Processor consumer) { + if (!constructor.isConstructor()) return true; + + if (searchScope instanceof GlobalSearchScope) { + searchScope = GlobalSearchScope.getScopeRestrictedByFileTypes((GlobalSearchScope)searchScope, GroovyFileType.GROOVY_FILE_TYPE); + } + + final PsiClass clazz = ApplicationManager.getApplication().runReadAction(new NullableComputable() { + public PsiClass compute() { + return constructor.getContainingClass(); + } + }); + if (clazz == null) return true; + + + //enum constants + if (!ApplicationManager.getApplication().runReadAction(new Computable() { + public Boolean compute() { + if (!clazz.isEnum()) return true; + if (!(clazz instanceof GroovyPsiElement)) return true; + final PsiField[] fields = clazz.getFields(); + for (PsiField field : fields) { + if (field instanceof GrEnumConstant) { + final PsiReference ref = field.getReference(); + if (ref.isReferenceTo(constructor)) { + if (!consumer.process(ref)) return false; + } + } + } + return true; + } + })) { + return false; + } + + + ReferencesSearch.search(clazz, searchScope, true).forEach(new ReadActionProcessor() { + @Override + public boolean processInReadAction(PsiReference ref) { + final PsiElement element = ref.getElement(); + if (element instanceof GrCodeReferenceElement) { + GrNewExpression newExpression = null; + if (element.getParent() instanceof GrNewExpression) { + newExpression = (GrNewExpression)element.getParent(); + } + else if (element.getParent() instanceof GrAnonymousClassDefinition) { + newExpression = (GrNewExpression)element.getParent().getParent(); + } + if (newExpression != null) { + final PsiMethod resolvedConstructor = newExpression.resolveConstructor(); + final PsiManager manager = constructor.getManager(); + if (manager.areElementsEquivalent(resolvedConstructor, constructor) && !consumer.process(ref)) return false; + } + } + return true; + } + }); + + //this() + if (clazz instanceof GrTypeDefinition) { + if (!processConstructors(constructor, consumer, clazz, true)) { + return false; + } + } + //super : does not work now, need to invent a way for it to work without repository + if (!DirectClassInheritorsSearch.search(clazz, searchScope).forEach(new Processor() { + public boolean process(PsiClass inheritor) { + if (inheritor instanceof GrTypeDefinition) { + if (!processConstructors(constructor, consumer, inheritor, false)) return false; + } + return true; + } + })) { + return false; + } + + return true; + } + + private static boolean processConstructors(final PsiMethod constructor, final Processor consumer, final PsiClass clazz, + final boolean processThisRefs) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + public Boolean compute() { + return processClassConstructors(clazz, constructor, consumer, processThisRefs); + } + }); + } + + private static boolean processClassConstructors(PsiClass clazz, + PsiMethod searchedConstructor, + Processor consumer, + boolean processThisRefs) { + final PsiMethod[] constructors = clazz.getConstructors(); + if (constructors.length == 0) { + processImplicitConstructorCall(clazz, consumer, searchedConstructor); + } + for (PsiMethod constructor : constructors) { + final GrOpenBlock block = ((GrMethod)constructor).getBlock(); + if (block != null) { + final GrStatement[] statements = block.getStatements(); + if (statements.length > 0 && statements[0] instanceof GrConstructorInvocation) { + final GrConstructorInvocation invocation = (GrConstructorInvocation)statements[0]; + if (invocation.isThisCall() == processThisRefs && + invocation.getManager().areElementsEquivalent(invocation.resolveConstructor(), searchedConstructor) && + !consumer.process(invocation.getThisOrSuperKeyword())) { + return false; + } + } + else { + processImplicitConstructorCall(constructor, consumer, searchedConstructor); + } + } + } + return true; + } + + private static void processImplicitConstructorCall(final PsiMember usage, + final Processor processor, + final PsiMethod constructor) { + if (constructor instanceof GrMethod) { + GrParameter[] grParameters = (GrParameter[])constructor.getParameterList().getParameters(); + if (grParameters.length > 0 && !grParameters[0].isOptional()) return; + } + else if (constructor.getParameterList().getParameters().length > 0) return; + + + PsiManager manager = constructor.getManager(); + if (manager.areElementsEquivalent(usage, constructor) || manager.areElementsEquivalent(constructor.getContainingClass(), usage.getContainingClass())) return; + processor.process(new LightMemberReference(manager, usage, PsiSubstitutor.EMPTY) { + public PsiElement getElement() { + return usage; + } + + public TextRange getRangeInElement() { + if (usage instanceof PsiClass) { + PsiIdentifier identifier = ((PsiClass)usage).getNameIdentifier(); + if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength()); + } + else if (usage instanceof PsiMethod) { + PsiIdentifier identifier = ((PsiMethod)usage).getNameIdentifier(); + if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength()); + } + return super.getRangeInElement(); + } + }); + + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java index 15642f8602ac..335641cf2a09 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java @@ -16,12 +16,10 @@ package org.jetbrains.plugins.groovy.findUsages; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.QueryExecutorBase; import com.intellij.openapi.application.ReadActionProcessor; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -49,7 +47,6 @@ import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; import org.jetbrains.plugins.groovy.gpp.GppTypeConverter; import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; 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.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; @@ -67,7 +64,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider; -import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.Arrays; @@ -90,10 +86,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase consumer, final SearchRequestCollector collector, final boolean searchGppCalls) { if (!constructor.isConstructor()) return; - SearchScope onlyGroovy = searchScope; - if (onlyGroovy instanceof GlobalSearchScope) { - onlyGroovy = GlobalSearchScope.getScopeRestrictedByFileTypes((GlobalSearchScope)onlyGroovy, GroovyFileType.GROOVY_FILE_TYPE); - } + SearchScope onlyGroovy = PsiUtil.restrictScopeToGroovyFiles(searchScope); final PsiClass clazz = constructor.getContainingClass(); if (clazz == null) return; @@ -110,27 +103,20 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase processedMethods = new ConcurrentHashSet(); + final LiteralConstructorSearcher literalProcessor = new LiteralConstructorSearcher(constructor, consumer); - ReferencesSearch.searchOptimized(clazz, searchScope, true, collector, true, new PairProcessor() { + final Processor newExpressionProcessor = new Processor() { @Override - public boolean process(PsiReference ref, SearchRequestCollector collector) { - final PsiElement element = ref.getElement(); - if (element instanceof GrCodeReferenceElement) { - if (!processGroovyConstructorUsages((GrCodeReferenceElement)element, constructor, consumer, ref, !searchGppCalls)) { - return false; - } - } - - if (searchGppCalls) { - final PsiMethod method = getMethodToSearchForCallsWithLiteralArguments(element, clazz); - if (method != null && processedMethods.add(method)) { - processGppMethodCalls(clazz, constructor, consumer, searchScope, collector, method); - } + public boolean process(GrNewExpression grNewExpression) { + final PsiMethod resolvedConstructor = grNewExpression.resolveConstructor(); + if (constructor.getManager().areElementsEquivalent(resolvedConstructor, constructor)) { + return consumer.process(grNewExpression.getReferenceElement()); } return true; } - }); + }; + + processGroovyClassUsages(clazz, searchScope, collector, searchGppCalls, newExpressionProcessor, literalProcessor); //this() if (clazz instanceof GrTypeDefinition) { @@ -139,8 +125,9 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase() { - public boolean process(PsiClass inheritor) { + DirectClassInheritorsSearch.search(clazz, onlyGroovy).forEach(new ReadActionProcessor() { + @Override + public boolean processInReadAction(PsiClass inheritor) { if (inheritor instanceof GrTypeDefinition) { if (!processConstructors(constructor, consumer, inheritor, false)) return false; } @@ -149,16 +136,53 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase newExpressionProcessor, + final LiteralConstructorSearcher literalProcessor) { + final Set processedMethods = new ConcurrentHashSet(); + + ReferencesSearch.searchOptimized(clazz, scope, true, collector, true, new PairProcessor() { + @Override + public boolean process(PsiReference ref, SearchRequestCollector collector) { + final PsiElement element = ref.getElement(); + + if (element instanceof GrCodeReferenceElement) { + if (!processGroovyConstructorUsages((GrCodeReferenceElement)element, !searchGppCalls, newExpressionProcessor, literalProcessor)) { + return false; + } + } + + if (searchGppCalls) { + final PsiMethod method = getMethodToSearchForCallsWithLiteralArguments(element, clazz); + if (method != null && processedMethods.add(method)) { + processGppMethodCalls(clazz, scope, collector, method, literalProcessor); + } + } + return true; + } + }); + } + @Nullable - static PsiMethod getMethodToSearchForCallsWithLiteralArguments(PsiElement element, PsiClass targetClass) { + private static PsiMethod getMethodToSearchForCallsWithLiteralArguments(PsiElement element, PsiClass targetClass) { final PsiParameter parameter = PsiTreeUtil.getParentOfType(element, PsiParameter.class); if (parameter != null) { final PsiMethod method = PsiTreeUtil.getParentOfType(parameter, PsiMethod.class); - if (method != null && Arrays.asList(method.getParameterList().getParameters()).contains(parameter)) { - final PsiType parameterType = parameter.getType(); - if (parameterType instanceof PsiClassType) { - if (method.getManager().areElementsEquivalent(targetClass, ((PsiClassType)parameterType).resolve())) { - return method; + if (method != null) { + final PsiParameter[] parameters = method.getParameterList().getParameters(); + final int idx = Arrays.asList(parameters).indexOf(parameter); + if (idx >= 0) { + PsiType parameterType = parameter.getType(); + if (parameterType instanceof PsiArrayType && idx == parameters.length - 1) { + parameterType = ((PsiArrayType)parameterType).getComponentType(); + } + if (parameterType instanceof PsiClassType) { + if (method.getManager().areElementsEquivalent(targetClass, ((PsiClassType)parameterType).resolve())) { + return method; + } } } } @@ -167,10 +191,9 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase originalProcessor, SearchScope scope, - SearchRequestCollector originalCollector, @NotNull PsiMethod currentTarget) { + SearchRequestCollector originalCollector, @NotNull PsiMethod currentTarget, + final LiteralConstructorSearcher literalProcessor) { final SearchScope gppScope = getGppScope(targetClass.getProject()).intersectWith(scope); final ReadActionProcessor gppCallProcessor = new ReadActionProcessor() { @Override @@ -183,7 +206,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase() { @Override public Result compute() { @@ -223,22 +246,24 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase consumer, - PsiReference ref, boolean usualCallsOnly) { + private static boolean processGroovyConstructorUsages(GrCodeReferenceElement element, + boolean usualCallsOnly, + final Processor newExpressionProcessor, + final LiteralConstructorSearcher literalProcessor) { PsiElement parent = element.getParent(); if (parent instanceof GrAnonymousClassDefinition) { parent = parent.getParent(); } if (parent instanceof GrNewExpression) { - final PsiMethod resolvedConstructor = ((GrNewExpression)parent).resolveConstructor(); - if (constructor.getManager().areElementsEquivalent(resolvedConstructor, constructor) && !consumer.process(ref)) { - return false; - } + return newExpressionProcessor.process((GrNewExpression)parent); } - else if (!usualCallsOnly && parent instanceof GrTypeElement) { + + if (usualCallsOnly) { + return true; + } + + if (parent instanceof GrTypeElement) { final GrTypeElement typeElement = (GrTypeElement)parent; final PsiElement grandpa = typeElement.getParent(); @@ -246,7 +271,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase consumer, - GrExpression expression, final GrTypeElement typeElement) { + private static boolean checkLiteralInstantiation(GrExpression expression, + final GrTypeElement typeElement, + final LiteralConstructorSearcher literalProcessor) { + if (expression instanceof GrListOrMap) { - final GrListOrMap list = (GrListOrMap)expression; - if (!list.isMap()) { - final PsiType expectedType = typeElement.getType(); - if (expectedType instanceof PsiClassType) { - return checkListInstantiation(constructor, consumer, list, (PsiClassType)expectedType); - } + final PsiType expectedType = typeElement.getType(); + if (expectedType instanceof PsiClassType) { + return literalProcessor.processLiteral((GrListOrMap)expression, (PsiClassType)expectedType); } } return true; } - static boolean checkListInstantiation(PsiMethod constructor, - Processor consumer, - GrListOrMap list, - PsiClassType expectedType) { - final PsiType listType = list.getType(); - if (listType instanceof GrTupleType) { - for (GroovyResolveResult candidate : PsiUtil.getConstructorCandidates(expectedType, ((GrTupleType)listType).getComponentTypes(), list)) { - if (constructor.getManager().areElementsEquivalent(candidate.getElement(), constructor)) { - if (!consumer.process(PsiReferenceBase.createSelfReference(list, TextRange.from(0, list.getTextLength()), constructor))) { - return false; - } - } - } - } - return true; - } - - static boolean processConstructors(final PsiMethod constructor, final Processor consumer, final PsiClass clazz, + private static boolean processConstructors(final PsiMethod searchedConstructor, final Processor consumer, final PsiClass clazz, final boolean processThisRefs) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - public Boolean compute() { - return processClassConstructors(clazz, constructor, consumer, processThisRefs); - } - }); - } - - static boolean processClassConstructors(PsiClass clazz, - PsiMethod searchedConstructor, - Processor consumer, - boolean processThisRefs) { final PsiMethod[] constructors = clazz.getConstructors(); if (constructors.length == 0) { processImplicitConstructorCall(clazz, consumer, searchedConstructor); @@ -367,7 +362,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase processor, final PsiMethod constructor) { if (constructor instanceof GrMethod) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/LiteralConstructorSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/LiteralConstructorSearcher.java new file mode 100644 index 000000000000..470b6a2625b2 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/LiteralConstructorSearcher.java @@ -0,0 +1,68 @@ +package org.jetbrains.plugins.groovy.findUsages; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.util.Processor; +import org.jetbrains.plugins.groovy.gpp.GppReferenceContributor; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; +import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType; +import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; + +/** +* @author peter +*/ +public class LiteralConstructorSearcher { + private final PsiMethod myConstructor; + private final Processor myConsumer; + + public LiteralConstructorSearcher(PsiMethod constructor, Processor consumer) { + myConstructor = constructor; + myConsumer = consumer; + } + + private static boolean checkLiteralInstantiation(PsiMethod constructor, + Processor consumer, + GrListOrMap literal, + PsiClassType expectedType) { + final PsiType listType = literal.getType(); + if (listType instanceof GrTupleType) { + if (GppReferenceContributor.isConstructorCall(expectedType, ((GrTupleType)listType).getComponentTypes(), constructor, literal)) { + return consumer.process(PsiReferenceBase.createSelfReference(literal, TextRange.from(0, literal.getTextLength()), constructor)); + } + } + else if (listType instanceof GrMapType) { + final PsiType constructorArgs = ((GrMapType)listType).getValueType("super"); + if (constructorArgs == null) { + if (constructor.getParameterList().getParametersCount() == 0) { + if (!consumer.process(PsiReferenceBase.createSelfReference(literal, TextRange.from(0, literal.getTextLength()), constructor))) { + return false; + } + } + return true; + } + + for (GrNamedArgument argument : literal.getNamedArguments()) { + final GrArgumentLabel label = argument.getLabel(); + if (label != null && "super".equals(label.getName())) { + final PsiReference reference = label.getReference(); + if (reference != null && reference.isReferenceTo(constructor)) { + return consumer.process(reference); + } + return true; + } + } + + //no 'super', only default constructor applicable + if (constructor.getParameterList().getParametersCount() == 0) { + return consumer.process(PsiReferenceBase.createSelfReference(literal, TextRange.from(0, literal.getTextLength()), constructor)); + } + } + return true; + } + + public boolean processLiteral(GrListOrMap list, PsiClassType expectedType) { + return checkLiteralInstantiation(myConstructor, myConsumer, list, expectedType); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppClosureParameterTypeProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppClosureParameterTypeProvider.java index 47e863de80d6..2e0a8e35d979 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppClosureParameterTypeProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppClosureParameterTypeProvider.java @@ -81,14 +81,20 @@ public class GppClosureParameterTypeProvider extends AbstractClosureParameterEnh @Nullable public static Pair getOverriddenMethod(GrNamedArgument namedArgument) { + return ContainerUtil.getFirstItem(getOverriddenMethodVariants(namedArgument), null); + } + + @NotNull + public static List> getOverriddenMethodVariants(GrNamedArgument namedArgument) { + final GrArgumentLabel label = namedArgument.getLabel(); if (label == null) { - return null; + return Collections.emptyList(); } final String methodName = label.getName(); if (methodName == null) { - return null; + return Collections.emptyList(); } final PsiElement map = namedArgument.getParent(); @@ -96,20 +102,16 @@ public class GppClosureParameterTypeProvider extends AbstractClosureParameterEnh for (PsiType expected : GroovyExpectedTypesProvider.getDefaultExpectedTypes((GrExpression)map)) { if (expected instanceof PsiClassType) { final List> pairs = getMethodsToOverrideImplementInInheritor((PsiClassType)expected, false); - final List> withName = - ContainerUtil.findAll(pairs, new Condition>() { + return ContainerUtil.findAll(pairs, new Condition>() { public boolean value(Pair pair) { return methodName.equals(pair.first.getName()); } }); - if (withName.size() == 1) { - return withName.get(0); - } } } } - return null; + return Collections.emptyList(); } @Nullable @@ -126,19 +128,22 @@ public class GppClosureParameterTypeProvider extends AbstractClosureParameterEnh if (type instanceof PsiClassType) { List> result = getMethodsToOverrideImplementInInheritor((PsiClassType)type, true); if (result.size() == 1) { - final Pair pair = result.get(0); - return ContainerUtil.map2Array(pair.first.getParameterList().getParameters(), PsiType.class, new Function() { - public PsiType fun(PsiParameter psiParameter) { - return pair.second.substitute(psiParameter.getType()); - } - }); + return getParameterTypes(result.get(0)); } } return null; } + public static PsiType[] getParameterTypes(final Pair pair) { + return ContainerUtil.map2Array(pair.first.getParameterList().getParameters(), PsiType.class, new Function() { + public PsiType fun(PsiParameter psiParameter) { + return pair.second.substitute(psiParameter.getType()); + } + }); + } + @NotNull - private static List> getMethodsToOverrideImplementInInheritor(PsiClassType classType, boolean toImplement) { + public static List> getMethodsToOverrideImplementInInheritor(PsiClassType classType, boolean toImplement) { final PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics(); final PsiClass psiClass = resolveResult.getElement(); if (psiClass == null) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppReferenceContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppReferenceContributor.java index 1e28a9471183..91e0f21bb3c4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppReferenceContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppReferenceContributor.java @@ -7,18 +7,58 @@ import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PropertyUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.ProcessingContext; +import com.intellij.util.containers.CollectionFactory; import org.jetbrains.annotations.NotNull; +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.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel; 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; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSafeCastExpression; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider; +import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType; +import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; + +import java.util.Collections; +import java.util.List; +import java.util.Set; /** * @author peter */ public class GppReferenceContributor extends PsiReferenceContributor { + public static boolean mayInvokeConstructor(PsiClassType expectedType, PsiMethod constructor, GrExpression args) { + if (args == null) { + return true; + } + + final PsiType type = args.getType(); + if (type == null) { + return true; + } + + if (type instanceof GrTupleType) { + return isConstructorCall(expectedType, ((GrTupleType)type).getComponentTypes(), constructor, args); + } + + return isConstructorCall(expectedType, new PsiType[]{type}, constructor, args); + } + + public static boolean isConstructorCall(PsiClassType expectedType, + PsiType[] argTypes, + PsiMethod constructor, + GroovyPsiElement context) { + for (GroovyResolveResult candidate : PsiUtil.getConstructorCandidates(expectedType, argTypes, context)) { + if (constructor.getManager().areElementsEquivalent(candidate.getElement(), constructor)) { + return true; + } + } + return false; + } + @Override public void registerReferenceProviders(PsiReferenceRegistrar registrar) { registrar.registerReferenceProvider(PlatformPatterns.psiElement(GrArgumentLabel.class), new PsiReferenceProvider() { @@ -34,7 +74,7 @@ public class GppReferenceContributor extends PsiReferenceContributor { }); } - private static class GppMapMemberReference extends PsiReferenceBase { + private static class GppMapMemberReference extends PsiReferenceBase.Poly { public GppMapMemberReference(PsiElement element) { super((GrArgumentLabel)element); @@ -45,30 +85,98 @@ public class GppReferenceContributor extends PsiReferenceContributor { return element instanceof PsiMethod && super.isReferenceTo(element); } - public PsiElement resolve() { - final GrNamedArgument namedArgument = (GrNamedArgument) getElement().getParent(); - for (PsiType type : GroovyExpectedTypesProvider.getDefaultExpectedTypes((GrExpression)namedArgument.getParent())) { + @NotNull + @Override + public ResolveResult[] multiResolve(boolean incompleteCode) { + final GrArgumentLabel context = getElement(); + final GrNamedArgument namedArgument = (GrNamedArgument) context.getParent(); + for (PsiType type : getTargetConversionTypes((GrExpression)namedArgument.getParent())) { if (type instanceof PsiClassType) { - final GrExpression value = namedArgument.getExpression(); - if (value != null && InheritanceUtil.isInheritor(value.getType(), GrClosableBlock.GROOVY_LANG_CLOSURE)) { - final Pair method = GppClosureParameterTypeProvider.getOverriddenMethod(namedArgument); - if (method != null) { - return method.first; + final PsiClassType classType = (PsiClassType)type; + final PsiClass psiClass = classType.resolve(); + if (psiClass != null) { + final GrExpression value = namedArgument.getExpression(); + + final List applicable = addMethodCandidates(classType, value); + + final String memberName = getValue(); + if ("super".equals(memberName) && GppTypeConverter.hasTypedContext(myElement)) { + applicable.addAll(addConstructorCandidates(classType, psiClass, value)); } - } else { - final PsiClass psiClass = ((PsiClassType)type).resolve(); - if (psiClass != null) { - final String propertyName = getValue(); - final PsiMethod setter = PropertyUtil.findPropertySetter(psiClass, propertyName, false, true); + + if (value == null || applicable.isEmpty()) { + final PsiMethod setter = PropertyUtil.findPropertySetter(psiClass, memberName, false, true); if (setter != null) { - return setter; + applicable.add(new PsiElementResolveResult(setter)); + } else { + final PsiField field = PropertyUtil.findPropertyField(psiClass.getProject(), psiClass, memberName, false); + if (field != null) { + applicable.add(new PsiElementResolveResult(field)); + } } - return PropertyUtil.findPropertyField(psiClass.getProject(), psiClass, propertyName, false); } + + return applicable.toArray(new ResolveResult[applicable.size()]); } } } - return null; + return ResolveResult.EMPTY_ARRAY; + } + + private static Set getTargetConversionTypes(GrExpression expression) { + //todo hack + if (expression.getParent() instanceof GrSafeCastExpression) { + final PsiType type = ((GrSafeCastExpression)expression.getParent()).getType(); + if (type != null) { + return Collections.singleton(type); + } + } + + return GroovyExpectedTypesProvider.getDefaultExpectedTypes(expression); + } + + + private static List addConstructorCandidates(PsiClassType classType, PsiClass psiClass, GrExpression value) { + List applicable = CollectionFactory.arrayList(); + final List byName = CollectionFactory.arrayList(); + for (PsiMethod constructor : psiClass.getConstructors()) { + final ResolveResult resolveResult = new PsiElementResolveResult(constructor); + byName.add(resolveResult); + if (mayInvokeConstructor(classType, constructor, value)) { + applicable.add(resolveResult); + } + } + if (applicable.isEmpty()) { + applicable.addAll(byName); + } + return applicable; + } + + private List addMethodCandidates(PsiClassType classType, GrExpression value) { + PsiType valueType = value == null ? null : value.getType(); + final List applicable = CollectionFactory.arrayList(); + + if (value == null || InheritanceUtil.isInheritor(valueType, GrClosableBlock.GROOVY_LANG_CLOSURE)) { + final List byName = CollectionFactory.arrayList(); + for (Pair variant : GppClosureParameterTypeProvider.getMethodsToOverrideImplementInInheritor(classType, false)) { + final PsiMethod method = variant.first; + if (getValue().equals(method.getName())) { + final ResolveResult resolveResult = new PsiElementResolveResult(method); + byName.add(resolveResult); + if (valueType instanceof GrClosureType) { + final PsiType[] psiTypes = GppClosureParameterTypeProvider.getParameterTypes(variant); + if (GppTypeConverter.isClosureOverride(psiTypes, (GrClosureType)valueType, myElement)) { + applicable.add(resolveResult); + } + } + } + } + + if (applicable.isEmpty()) { + return byName; + } + } + return applicable; } @NotNull diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java index ab44998ef803..e65c3e889a84 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java @@ -72,24 +72,29 @@ public class GppTypeConverter extends GrTypeConverter { return true; } - if (!isMethodCallConversion(context) && hasDefaultConstructor(lType)) { + if ((!isMethodCallConversion(context) || hasTypedContext(context)) && hasDefaultConstructor(lType)) { return true; } } else if (rType instanceof GrClosureType) { final PsiType[] methodParameters = GppClosureParameterTypeProvider.findSingleAbstractMethodSignature(lType); - final GrClosureSignature signature = ((GrClosureType)rType).getSignature(); - if (methodParameters != null && GrClosureSignatureUtil.isSignatureApplicable(signature, methodParameters, context)) { - return true; - } + if (isClosureOverride(methodParameters, (GrClosureType)rType, context)) return true; } return null; } + public static boolean isClosureOverride(PsiType[] methodParameters, GrClosureType closureType, GroovyPsiElement context) { + final GrClosureSignature signature = closureType.getSignature(); + if (methodParameters != null && GrClosureSignatureUtil.isSignatureApplicable(signature, methodParameters, context)) { + return true; + } + return false; + } + private static boolean hasDefaultConstructor(PsiType type) { final PsiClass psiClass = PsiUtil.resolveClassInType(type); - return psiClass != null && PsiUtil.hasDefaultConstructor(psiClass, true); + return psiClass != null && PsiUtil.hasDefaultConstructor(psiClass, true, false); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/DefaultHighlighter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/DefaultHighlighter.java index a3b5dd8321e9..282c86da459a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/DefaultHighlighter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/DefaultHighlighter.java @@ -76,6 +76,7 @@ public class DefaultHighlighter { @NonNls static final String UNRESOLVED_ACCESS_ID = "Unresolved reference access"; + static final String LITERAL_CONVERSION_ID = "List/map to object conversion"; public static TextAttributesKey LINE_COMMENT = TextAttributesKey.createTextAttributesKey(LINE_COMMENT_ID, @@ -148,7 +149,13 @@ public class DefaultHighlighter { UNRESOLVED_ACCESS_ATTRIBUTES.setEffectColor(Color.GRAY); UNRESOLVED_ACCESS_ATTRIBUTES.setEffectType(EffectType.LINE_UNDERSCORE); } + public static final TextAttributes LITERAL_CONVERSION_ATTRIBUTES = HighlighterColors.TEXT.getDefaultAttributes().clone(); + static{ + LITERAL_CONVERSION_ATTRIBUTES.setForegroundColor(Color.BLUE); + LITERAL_CONVERSION_ATTRIBUTES.setFontType(Font.BOLD); + } public static TextAttributesKey UNRESOLVED_ACCESS = TextAttributesKey.createTextAttributesKey(UNRESOLVED_ACCESS_ID, UNRESOLVED_ACCESS_ATTRIBUTES); + public static TextAttributesKey LITERAL_CONVERSION = TextAttributesKey.createTextAttributesKey(LITERAL_CONVERSION_ID, LITERAL_CONVERSION_ATTRIBUTES); private DefaultHighlighter() { } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyColorsAndFontsPage.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyColorsAndFontsPage.java index e9bab50b59a5..ca337285162d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyColorsAndFontsPage.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyColorsAndFontsPage.java @@ -64,6 +64,7 @@ public class GroovyColorsAndFontsPage implements ColorSettingsPage { new AttributesDescriptor(DefaultHighlighter.BAD_CHARACTER_ID, DefaultHighlighter.BAD_CHARACTER), new AttributesDescriptor(DefaultHighlighter.WRONG_STRING_ID, DefaultHighlighter.WRONG_STRING), new AttributesDescriptor(DefaultHighlighter.UNRESOLVED_ACCESS_ID, DefaultHighlighter.UNRESOLVED_ACCESS), + new AttributesDescriptor(DefaultHighlighter.LITERAL_CONVERSION_ID, DefaultHighlighter.LITERAL_CONVERSION), new AttributesDescriptor(DefaultHighlighter.ANNOTATION_ID, DefaultHighlighter.ANNOTATION), new AttributesDescriptor(DefaultHighlighter.STATIC_FIELD_ID, DefaultHighlighter.STATIC_FIELD), new AttributesDescriptor(DefaultHighlighter.STATIC_FIELD_ID, DefaultHighlighter.INSTANCE_FIELD), @@ -101,7 +102,9 @@ public class GroovyColorsAndFontsPage implements ColorSettingsPage { "Demo.panel.size = " + "Demo.foo(\"123${456}789\".toInteger()) \n" + "'JetBrains'.matches(/Jw+Bw+/) \n" + - "def x=1 + unresolved" + "def x=1 + unresolved\n" + + "def f1 = []\n" + + "File f=['path']" ; } @@ -116,6 +119,7 @@ public class GroovyColorsAndFontsPage implements ColorSettingsPage { map.put("doctag", DefaultHighlighter.DOC_COMMENT_TAG); map.put("unresolved", DefaultHighlighter.UNRESOLVED_ACCESS); map.put("classref", DefaultHighlighter.CLASS_REFERENCE); + map.put("literal", DefaultHighlighter.LITERAL_CONVERSION); return map; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties index dcdce8ab3c5b..0108a6fd38e9 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties @@ -85,4 +85,10 @@ map.param.name=Map parameter &name: convert.param.to.map.entry=Convert parameter to map entry convert.java.style.array.intention.name=Convert java-style array creation -convert.java.style.array.intention.family.name=Convert Java-Style Array Creation to Groovy Syntax \ No newline at end of file +convert.java.style.array.intention.family.name=Convert Java-Style Array Creation to Groovy Syntax + +create.parameter.for.field.intention.name = Add constructor parameter for field +create.parameter.for.field.intention.family.name = Add constructor parameter for field +cannot.suggest.parameter.name=Cannot suggest parameter name +create.parameter.for.field=Add parameter for field ''{0}'' +create.parameter.for.fields=Add parameter for field... \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/Intention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/Intention.java index bd28468c66eb..fb21940757b6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/Intention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/Intention.java @@ -19,15 +19,16 @@ import com.intellij.codeInsight.intention.IntentionAction; 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.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.annotator.intentions.QuickfixUtil; import org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle; import org.jetbrains.plugins.groovy.intentions.utils.BoolUtils; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; -import org.jetbrains.plugins.groovy.annotator.intentions.QuickfixUtil; public abstract class Intention implements IntentionAction { @@ -51,10 +52,10 @@ public abstract class Intention implements IntentionAction { return; } assert element.isValid() : element; - processIntention(element); + processIntention(element, project, editor); } - protected abstract void processIntention(@NotNull PsiElement element) + protected abstract void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException; @NotNull diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/ConvertClosureArgToItIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/ConvertClosureArgToItIntention.java index 11c5c4e46f7e..17409c93e2c5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/ConvertClosureArgToItIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/ConvertClosureArgToItIntention.java @@ -15,15 +15,19 @@ */ package org.jetbrains.plugins.groovy.intentions.closure; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.intentions.base.*; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; +import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList; -import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; import java.util.HashSet; import java.util.Set; @@ -36,7 +40,7 @@ public class ConvertClosureArgToItIntention extends Intention { return new SingleArgClosurePredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrClosableBlock closure = (GrClosableBlock) element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/EachToForIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/EachToForIntention.java index 02c7185a8daf..8684fcfe2147 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/EachToForIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/EachToForIntention.java @@ -23,7 +23,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -53,27 +52,8 @@ public class EachToForIntention extends Intention { return new EachToForPredicate(); } - private GrVariable var = null; - @Override - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - super.invoke(project, editor, file); - if (var == null) return; - - if (ApplicationManager.getApplication().isUnitTestMode()) return; - - final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); - final Document doc = documentManager.getDocument(file); - if (doc == null) return; - - - documentManager.doPostponedOperationsAndUnblockDocument(doc); - editor.getCaretModel().moveToOffset(var.getTextOffset()); - new VariableInplaceRenamer(var, editor).performInplaceRename(); - } - - @Override - protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrMethodCallExpression expression = (GrMethodCallExpression)element; final GrClosableBlock block = expression.getClosureArguments()[0]; final GrParameterList parameterList = block.getParameterList(); @@ -114,7 +94,19 @@ public class EachToForIntention extends Intention { final GrStatement statement = elementFactory.createStatementFromText(builder.toString()); final GrForStatement forStatement = (GrForStatement)expression.replaceWithStatement(statement); final GrForClause clause = forStatement.getClause(); - this.var = clause.getDeclaredVariables()[0]; + GrVariable variable = clause.getDeclaredVariables()[0]; + + if (variable == null) return; + + if (ApplicationManager.getApplication().isUnitTestMode()) return; + + final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); + final Document doc = documentManager.getDocument(element.getContainingFile()); + if (doc == null) return; + + documentManager.doPostponedOperationsAndUnblockDocument(doc); + editor.getCaretModel().moveToOffset(variable.getTextOffset()); + new VariableInplaceRenamer(variable, editor).performInplaceRename(); } private static class EachToForPredicate implements PsiElementPredicate { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/ForToEachIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/ForToEachIntention.java index 6950c1af528a..4af91b41ff6a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/ForToEachIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/ForToEachIntention.java @@ -15,6 +15,8 @@ */ package org.jetbrains.plugins.groovy.intentions.closure; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; @@ -39,7 +41,7 @@ public class ForToEachIntention extends Intention { return new ForToEachPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrForStatement parentStatement = (GrForStatement) element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallExplicitIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallExplicitIntention.java index ef5330790085..e1c4a3466ade 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallExplicitIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallExplicitIntention.java @@ -15,10 +15,14 @@ */ package org.jetbrains.plugins.groovy.intentions.closure; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.intentions.base.*; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -32,7 +36,7 @@ public class MakeClosureCallExplicitIntention extends Intention { return new ImplicitClosureCallPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrMethodCallExpression expression = (GrMethodCallExpression) element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallImplicitIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallImplicitIntention.java index 62f0823ec20b..7ad8807d756f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallImplicitIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallImplicitIntention.java @@ -15,10 +15,14 @@ */ package org.jetbrains.plugins.groovy.intentions.closure; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.intentions.base.*; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -33,7 +37,7 @@ public class MakeClosureCallImplicitIntention extends Intention { return new ExplicitClosureCallPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrMethodCallExpression expression = (GrMethodCallExpression) element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/comments/ChangeToCStyleCommentIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/comments/ChangeToCStyleCommentIntention.java index aeecd9f44ef9..8c29c0f087f4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/comments/ChangeToCStyleCommentIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/comments/ChangeToCStyleCommentIntention.java @@ -15,6 +15,8 @@ */ package org.jetbrains.plugins.groovy.intentions.comments; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; @@ -38,7 +40,7 @@ public class ChangeToCStyleCommentIntention extends Intention { return new EndOfLineCommentPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final PsiComment selectedComment = (PsiComment) element; PsiComment firstComment = selectedComment; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/comments/ChangeToEndOfLineCommentIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/comments/ChangeToEndOfLineCommentIntention.java index 8d046d80f8ce..f6326ad11c31 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/comments/ChangeToEndOfLineCommentIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/comments/ChangeToEndOfLineCommentIntention.java @@ -15,6 +15,8 @@ */ package org.jetbrains.plugins.groovy.intentions.comments; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; @@ -31,7 +33,7 @@ public class ChangeToEndOfLineCommentIntention extends Intention { return new CStyleCommentPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final PsiComment comment = (PsiComment) element; final JavaPsiFacade manager = JavaPsiFacade.getInstance(comment.getProject()); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ConditionalToElvisIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ConditionalToElvisIntention.java index 443c9666aea3..2b142d0f2eaa 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ConditionalToElvisIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ConditionalToElvisIntention.java @@ -16,6 +16,8 @@ package org.jetbrains.plugins.groovy.intentions.control; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -29,7 +31,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres * @author ilyas */ public class ConditionalToElvisIntention extends Intention { - protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrConditionalExpression expr = (GrConditionalExpression) element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/CreateParameterForFieldIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/CreateParameterForFieldIntention.java new file mode 100644 index 000000000000..f746dc76991c --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/CreateParameterForFieldIntention.java @@ -0,0 +1,317 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.intentions.control; + +import com.intellij.ide.util.DefaultPsiElementCellRenderer; +import com.intellij.ide.util.MethodCellRenderer; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.PopupChooserBuilder; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Ref; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.changeSignature.JavaThrownExceptionInfo; +import com.intellij.refactoring.changeSignature.ThrownExceptionInfo; +import com.intellij.ui.components.JBList; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; +import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; +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.blocks.GrOpenBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +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.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; +import org.jetbrains.plugins.groovy.refactoring.DefaultGroovyVariableNameValidator; +import org.jetbrains.plugins.groovy.refactoring.changeSignature.GrChangeInfoImpl; +import org.jetbrains.plugins.groovy.refactoring.changeSignature.GrChangeSignatureProcessor; +import org.jetbrains.plugins.groovy.refactoring.changeSignature.GrParameterInfo; + +import javax.swing.*; +import java.util.*; + +/** + * @author Maxim.Medvedev + */ +public class CreateParameterForFieldIntention extends Intention { + private static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.intentions.control.CreateParameterForFieldIntention"); + + @NotNull + @Override + public String getText() { + return super.getText(); + } + + @Override + protected void processIntention(@NotNull PsiElement element, final Project project, final Editor editor) + throws IncorrectOperationException { + final List candidates = findFieldCandidates(element); + if (candidates != null) { + performForConstructor(element, project, editor, candidates); + } + else { + final List constructors = findConstructorCandidates(element); + performForField(element, project, editor, constructors); + } + } + + private static void performForField(PsiElement element, final Project project, Editor editor, List constructors) { + final GrField field = PsiTreeUtil.getParentOfType(element, GrField.class); + if (constructors.size() == 0) return; + + if (ApplicationManager.getApplication().isUnitTestMode()) { + for (GrMethod constructor : constructors) { + addParameter(field, constructor, project); + } + return; + } + + final JList list = new JBList(constructors.toArray(new GrMethod[constructors.size()])); + list.setCellRenderer(new MethodCellRenderer(true)); + + new PopupChooserBuilder(list).setTitle(GroovyIntentionsBundle.message("create.parameter.for.field.intention.name")). + setMovable(true). + setItemChoosenCallback(new Runnable() { + public void run() { + final Object[] selectedValues = list.getSelectedValues(); + Arrays.sort(selectedValues, new Comparator() { + @Override + public int compare(Object o1, Object o2) { + return ((GrMethod)o2).getParameterList().getParametersCount() - ((GrMethod)o1).getParameterList().getParametersCount(); + } + }); + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + for (Object selectedValue : selectedValues) { + LOG.assertTrue(((GrMethod)selectedValue).isValid()); + addParameter(field, ((GrMethod)selectedValue), project); + } + } + }); + } + }, GroovyIntentionsBundle.message("create.parameter.for.field.intention.name"), null); + } + }).createPopup().showInBestPositionFor(editor); + + } + + private static void performForConstructor(PsiElement element, final Project project, Editor editor, List candidates) { + final GrMethod constructor = PsiTreeUtil.getParentOfType(element, GrMethod.class); + if (candidates.size() == 0) return; + if (ApplicationManager.getApplication().isUnitTestMode()) { + for (GrField candidate : candidates) { + addParameter(candidate, constructor, project); + } + return; + } + final JList list = new JBList(candidates.toArray(new GrField[candidates.size()])); + list.setCellRenderer(new DefaultPsiElementCellRenderer()); + + new PopupChooserBuilder(list).setTitle(GroovyIntentionsBundle.message("create.parameter.for.field.intention.name")). + setMovable(true). + setItemChoosenCallback(new Runnable() { + public void run() { + final Object[] selectedValues = list.getSelectedValues(); + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + for (Object selectedValue : selectedValues) { + LOG.assertTrue(((GrField)selectedValue).isValid()); + addParameter(((GrField)selectedValue), constructor, project); + } + } + }); + } + }, GroovyIntentionsBundle.message("create.parameter.for.field.intention.name"), null); + } + }).createPopup().showInBestPositionFor(editor); + } + + private static void addParameter(final GrField selectedValue, final GrMethod constructor, final Project project) { + List parameters = new ArrayList(); + GrParameter[] constructorParameters = constructor.getParameters(); + for (int i = 0; i < constructorParameters.length; i++) { + parameters.add(new GrParameterInfo(constructorParameters[i], i)); + } + final String[] suggestedNames = + JavaCodeStyleManager.getInstance(project).suggestVariableName(VariableKind.PARAMETER, selectedValue.getName(), null, null).names; + + final DefaultGroovyVariableNameValidator nameValidator = + new DefaultGroovyVariableNameValidator(constructor, Collections.emptyList(), false); + String parameterName = ContainerUtil.find(suggestedNames, new Condition() { + @Override + public boolean value(String name) { + return nameValidator.validateName(name, false).length() > 0; + } + }); + + if (parameterName == null) { + parameterName = nameValidator.validateName(suggestedNames[0], true); + } + parameters.add(new GrParameterInfo(parameterName, "null", "", selectedValue.getTypeGroovy(), -1)); + + PsiClassType[] exceptionTypes = constructor.getThrowsList().getReferencedTypes(); + ThrownExceptionInfo[] thrownExceptionInfos = new ThrownExceptionInfo[exceptionTypes.length]; + for (int i = 0; i < exceptionTypes.length; i++) { + new JavaThrownExceptionInfo(i, exceptionTypes[i]); + } + + final GrChangeInfoImpl grChangeInfo = + new GrChangeInfoImpl(constructor, null, null, constructor.getName(), parameters, thrownExceptionInfos, false); + final GrChangeSignatureProcessor processor = new GrChangeSignatureProcessor(project, grChangeInfo); + final Ref success = Ref.create(Boolean.FALSE); + processor.setPrepareSuccessfulSwingThreadCallback(new Runnable() { + @Override + public void run() { + success.set(Boolean.TRUE); + } + }); + processor.run(); + + if (success.get()) { + final GrOpenBlock block = constructor.getBlock(); + LOG.assertTrue(block != null); + final GrStatement statement = block.addStatementBefore( + GroovyPsiElementFactory.getInstance(project).createStatementFromText(selectedValue.getName() + " = " + parameterName), null); + final GrReferenceExpression ref = (GrReferenceExpression)((GrAssignmentExpression)statement).getLValue(); + if (!PsiManager.getInstance(project).areElementsEquivalent(ref.resolve(), selectedValue)) { + PsiUtil.qualifyMemberReference(ref, selectedValue, selectedValue.getName()); + } + } + } + + @NotNull + @Override + protected PsiElementPredicate getElementPredicate() { + return new MyPredicate(); + } + + static class MyPredicate implements PsiElementPredicate { + @Override + public boolean satisfiedBy(PsiElement element) { + final List candidates = findFieldCandidates(element); + if (candidates != null && candidates.size() > 0) return true; + final List constructors = findConstructorCandidates(element); + return constructors != null && constructors.size() > 0; + } + } + + @Nullable + private static List findFieldCandidates(PsiElement element) { + final GrMethod constructor = PsiTreeUtil.getParentOfType(element, GrMethod.class); + if (constructor == null || !constructor.isConstructor()) return null; + if (constructor.getBlock() == null) return null; + if (PsiTreeUtil.isAncestor(constructor.getBlock(), element, false)) { + return null; + } + final PsiClass clazz = constructor.getContainingClass(); + + if (!(clazz instanceof GrTypeDefinition)) return null; + return findCandidates(constructor, (GrTypeDefinition)clazz); + } + + private static List findCandidates(GrMethod constructor, final GrTypeDefinition clazz) { + final List usedFields = new ArrayList(); + //ContainerUtil.addAll(fields, clazz.getFields()); + final GrOpenBlock block = constructor.getBlock(); + LOG.assertTrue(block != null); + + final PsiManager manager = clazz.getManager(); + block.accept(new GroovyRecursiveElementVisitor() { + @Override + public void visitReferenceExpression(GrReferenceExpression referenceExpression) { + super.visitReferenceExpression(referenceExpression); + final PsiElement resolved = referenceExpression.resolve(); + if (resolved instanceof GrField && + manager.areElementsEquivalent(((GrField)resolved).getContainingClass(), clazz) && + PsiUtil.isAccessedForWriting(referenceExpression)) { + usedFields.add((GrField)resolved); + } + } + + @Override + public void visitTypeDefinition(GrTypeDefinition typeDefinition) { + } + + @Override + public void visitClosure(GrClosableBlock closure) { + } + }); + + List fields = new ArrayList(); + for (final GrField field : clazz.getFields()) { + if (field.getInitializerGroovy() != null) continue; + if (ContainerUtil.find(usedFields, new Condition() { + @Override + public boolean value(PsiField o) { + return manager.areElementsEquivalent(o, field); + } + }) == null) { + fields.add(field); + } + } + + return fields; + } + + @Nullable + private static List findConstructorCandidates(PsiElement element) { + final GrField field = PsiTreeUtil.getParentOfType(element, GrField.class); + if (field == null) return null; + return findConstructorCandidates(field, (GrTypeDefinition)field.getContainingClass()); + } + + private static List findConstructorCandidates(final GrField field, GrTypeDefinition psiClass) { + final List result = new ArrayList(); + final PsiMethod[] constructors = psiClass.getConstructors(); + final PsiManager manager = field.getManager(); + for (PsiMethod constructor : constructors) { + final List fields = findCandidates(((GrMethod)constructor), psiClass); + if (ContainerUtil.find(fields, new Condition() { + @Override + public boolean value(GrField grField) { + return manager.areElementsEquivalent(grField, field); + } + }) != null) { + result.add((GrMethod)constructor); + } + } + return result; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/DemorgansLawIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/DemorgansLawIntention.java index be7500e1b156..6adb2711a649 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/DemorgansLawIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/DemorgansLawIntention.java @@ -15,16 +15,18 @@ */ package org.jetbrains.plugins.groovy.intentions.control; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle; +import org.jetbrains.plugins.groovy.intentions.base.MutablyNamedIntention; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.intentions.utils.BoolUtils; import org.jetbrains.plugins.groovy.intentions.utils.ComparisonUtils; import org.jetbrains.plugins.groovy.intentions.utils.ParenthesesUtils; -import org.jetbrains.plugins.groovy.intentions.base.MutablyNamedIntention; -import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -47,7 +49,7 @@ public class DemorgansLawIntention extends MutablyNamedIntention { return new ConjunctionPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { GrBinaryExpression exp = (GrBinaryExpression) element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ExpandBooleanIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ExpandBooleanIntention.java index d07e3eaa1580..049f66254cbc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ExpandBooleanIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ExpandBooleanIntention.java @@ -15,11 +15,15 @@ */ package org.jetbrains.plugins.groovy.intentions.control; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.intentions.base.*; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression; @@ -33,7 +37,7 @@ public class ExpandBooleanIntention extends Intention { return new ExpandBooleanPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrStatement containingStatement = (GrStatement) element; if (ExpandBooleanPredicate.isBooleanAssignment(containingStatement)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/FlipComparisonIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/FlipComparisonIntention.java index b6fb61b55734..639c3db3b54e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/FlipComparisonIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/FlipComparisonIntention.java @@ -15,13 +15,17 @@ */ package org.jetbrains.plugins.groovy.intentions.control; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.MutablyNamedIntention; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.intentions.utils.ComparisonUtils; -import org.jetbrains.plugins.groovy.intentions.base.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -41,7 +45,7 @@ public class FlipComparisonIntention extends MutablyNamedIntention { return new ComparisonPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrBinaryExpression exp = (GrBinaryExpression) element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/FlipConditionalIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/FlipConditionalIntention.java index 4581f158dfbe..a7d86a96eda0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/FlipConditionalIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/FlipConditionalIntention.java @@ -15,11 +15,15 @@ */ package org.jetbrains.plugins.groovy.intentions.control; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.intentions.utils.BoolUtils; -import org.jetbrains.plugins.groovy.intentions.base.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrConditionalExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -31,7 +35,7 @@ public class FlipConditionalIntention extends Intention { return new ConditionalPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrConditionalExpression exp = (GrConditionalExpression) element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/FlipConjunctionIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/FlipConjunctionIntention.java index 85750395f256..78cba4b935b0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/FlipConjunctionIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/FlipConjunctionIntention.java @@ -15,12 +15,16 @@ */ package org.jetbrains.plugins.groovy.intentions.control; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle; -import org.jetbrains.plugins.groovy.intentions.base.*; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.MutablyNamedIntention; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -45,7 +49,7 @@ public class FlipConjunctionIntention extends MutablyNamedIntention { return new ConjunctionPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrBinaryExpression exp = (GrBinaryExpression) element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeElseIfIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeElseIfIntention.java index 16eb527880b7..d6d9f1c58c34 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeElseIfIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeElseIfIntention.java @@ -15,13 +15,17 @@ */ package org.jetbrains.plugins.groovy.intentions.control; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.intentions.base.*; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrBlockStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrBlockStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; public class MergeElseIfIntention extends Intention { @@ -31,7 +35,7 @@ public class MergeElseIfIntention extends Intention { return new MergeElseIfPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrIfStatement parentStatement = (GrIfStatement) element; GrBlockStatement elseBlockStatement = (GrBlockStatement) parentStatement.getElseBranch(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeIfAndIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeIfAndIntention.java index 0b888616baa7..83146f354a44 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeIfAndIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeIfAndIntention.java @@ -15,13 +15,17 @@ */ package org.jetbrains.plugins.groovy.intentions.control; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.intentions.utils.ConditionalUtils; import org.jetbrains.plugins.groovy.intentions.utils.ParenthesesUtils; -import org.jetbrains.plugins.groovy.intentions.base.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -34,7 +38,7 @@ public class MergeIfAndIntention extends Intention { return new MergeIfAndPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrIfStatement parentStatement = (GrIfStatement) element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/NegateComparisonIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/NegateComparisonIntention.java index f533fe268df4..16d1ddccca0f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/NegateComparisonIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/NegateComparisonIntention.java @@ -15,14 +15,16 @@ */ package org.jetbrains.plugins.groovy.intentions.control; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle; -import org.jetbrains.plugins.groovy.intentions.utils.ComparisonUtils; import org.jetbrains.plugins.groovy.intentions.base.MutablyNamedIntention; import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; +import org.jetbrains.plugins.groovy.intentions.utils.ComparisonUtils; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -42,7 +44,7 @@ public class NegateComparisonIntention extends MutablyNamedIntention { return new ComparisonPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrBinaryExpression exp = (GrBinaryExpression) element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitElseIfIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitElseIfIntention.java index fad62cd1ddbb..7bf1a4b1d1a8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitElseIfIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SplitElseIfIntention.java @@ -15,10 +15,14 @@ */ package org.jetbrains.plugins.groovy.intentions.control; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.intentions.base.*; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; @@ -29,7 +33,7 @@ public class SplitElseIfIntention extends Intention { return new SplitElseIfPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrIfStatement parentStatement = (GrIfStatement) element; assert parentStatement != null; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertClosureToMethodIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertClosureToMethodIntention.java index edabc9940fbb..c3ed59c7c061 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertClosureToMethodIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertClosureToMethodIntention.java @@ -16,6 +16,8 @@ package org.jetbrains.plugins.groovy.intentions.conversions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -40,7 +42,7 @@ public class ConvertClosureToMethodIntention extends Intention { } @Override - protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { element = element.getParent(); StringBuilder builder = new StringBuilder(element.getTextLength()); final GrField field = (GrField)element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertConcatenationToGstringIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertConcatenationToGstringIntention.java index 5e21af14a682..06fbe0e7217f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertConcatenationToGstringIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertConcatenationToGstringIntention.java @@ -16,6 +16,8 @@ package org.jetbrains.plugins.groovy.intentions.conversions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.MethodSignatureUtil; import com.intellij.psi.util.TypeConversionUtil; @@ -50,7 +52,7 @@ public class ConvertConcatenationToGstringIntention extends Intention { } @Override - protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { StringBuilder builder = new StringBuilder(element.getTextLength()); if (element instanceof GrBinaryExpression) { performIntention((GrBinaryExpression)element, builder); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertGStringToStringIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertGStringToStringIntention.java index e22e9c7d93dd..9927634ca468 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertGStringToStringIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertGStringToStringIntention.java @@ -15,6 +15,8 @@ */ package org.jetbrains.plugins.groovy.intentions.conversions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiType; @@ -44,7 +46,7 @@ public class ConvertGStringToStringIntention extends Intention { return new ConvertibleGStringLiteralPredicate(); } - public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrLiteral exp = (GrLiteral)element; IntentionUtils.replaceExpression(convertGStringLiteralToStringLiteral(exp), exp); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertIntegerToDecimalIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertIntegerToDecimalIntention.java index 982c182bc33c..cc3068dba5c2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertIntegerToDecimalIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertIntegerToDecimalIntention.java @@ -15,11 +15,15 @@ */ package org.jetbrains.plugins.groovy.intentions.conversions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.intentions.base.*; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import java.math.BigInteger; @@ -31,7 +35,7 @@ public class ConvertIntegerToDecimalIntention extends Intention { return new ConvertIntegerToDecimalPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrLiteral exp = (GrLiteral) element; @NonNls String textString = exp.getText(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertIntegerToHexIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertIntegerToHexIntention.java index 939d7b0d2b3e..fcdabe0042ae 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertIntegerToHexIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertIntegerToHexIntention.java @@ -15,11 +15,15 @@ */ package org.jetbrains.plugins.groovy.intentions.conversions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.intentions.base.*; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import java.math.BigInteger; @@ -32,7 +36,7 @@ public class ConvertIntegerToHexIntention extends Intention { return new ConvertIntegerToHexPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrLiteral exp = (GrLiteral) element; String textString = exp.getText(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertIntegerToOctalIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertIntegerToOctalIntention.java index c1cb92a1a6af..2f3e131041dc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertIntegerToOctalIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertIntegerToOctalIntention.java @@ -15,11 +15,15 @@ */ package org.jetbrains.plugins.groovy.intentions.conversions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.intentions.base.*; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import java.math.BigInteger; @@ -32,7 +36,7 @@ public class ConvertIntegerToOctalIntention extends Intention { return new ConvertIntegerToOctalPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrLiteral exp = (GrLiteral) element; @NonNls String textString = exp.getText(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertJavaStyleArrayIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertJavaStyleArrayIntention.java index f020043ac304..27f76089daae 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertJavaStyleArrayIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertJavaStyleArrayIntention.java @@ -15,6 +15,8 @@ */ package org.jetbrains.plugins.groovy.intentions.conversions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -31,7 +33,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrM */ public class ConvertJavaStyleArrayIntention extends Intention { @Override - protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrClosableBlock block = ((GrMethodCallExpression)element).getClosureArguments()[0]; final String text = block.getText(); int start = block.getLBrace().getStartOffsetInParent() + 1; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertMethodToClosureIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertMethodToClosureIntention.java index 5fb904c346c1..7823410e28b3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertMethodToClosureIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertMethodToClosureIntention.java @@ -16,6 +16,8 @@ package org.jetbrains.plugins.groovy.intentions.conversions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -40,7 +42,7 @@ public class ConvertMethodToClosureIntention extends Intention { } @Override - protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { element = element.getParent(); final GrMethod method = (GrMethod)element; StringBuilder builder = new StringBuilder(method.getTextLength()); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertStringToGStringIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertStringToGStringIntention.java index 3a91c51b61fc..28c20a003cc1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertStringToGStringIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertStringToGStringIntention.java @@ -15,10 +15,14 @@ */ package org.jetbrains.plugins.groovy.intentions.conversions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.intentions.base.*; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; public class ConvertStringToGStringIntention extends Intention { @@ -28,7 +32,7 @@ public class ConvertStringToGStringIntention extends Intention { return new StringLiteralPredicate(); } - public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrLiteral exp = (GrLiteral)element; final String textString = exp.getText(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/IndexedExpressionConversionIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/IndexedExpressionConversionIntention.java index a5350f0b5e48..82cac5901800 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/IndexedExpressionConversionIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/IndexedExpressionConversionIntention.java @@ -15,6 +15,8 @@ */ package org.jetbrains.plugins.groovy.intentions.conversions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -33,7 +35,7 @@ public class IndexedExpressionConversionIntention extends Intention { return new IndexedExpressionConversionPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrIndexProperty arrayIndexExpression = (GrIndexProperty) element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/IndexingMethodConversionIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/IndexingMethodConversionIntention.java index deb1f0f45462..54bd5373c3ac 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/IndexingMethodConversionIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/IndexingMethodConversionIntention.java @@ -15,15 +15,19 @@ */ package org.jetbrains.plugins.groovy.intentions.conversions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.intentions.base.*; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; +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.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; public class IndexingMethodConversionIntention extends Intention { @@ -32,7 +36,7 @@ public class IndexingMethodConversionIntention extends Intention { return new IndexingMethodConversionPredicate(); } - public void processIntention(@NotNull PsiElement element) + public void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrMethodCallExpression callExpression = (GrMethodCallExpression) element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveParenthesesFromMethodCallIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveParenthesesFromMethodCallIntention.java index 25b2c85536a3..5a403cd849a7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveParenthesesFromMethodCallIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveParenthesesFromMethodCallIntention.java @@ -15,6 +15,8 @@ */ package org.jetbrains.plugins.groovy.intentions.conversions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -39,7 +41,7 @@ public class RemoveParenthesesFromMethodCallIntention extends Intention { return element instanceof GrStatementOwner; } - protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrMethodCallExpression expression = (GrMethodCallExpression) element; final StringBuilder newStatementText = new StringBuilder(); newStatementText.append(expression.getInvokedExpression().getText()); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveUnnecessaryBracesInGStringIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveUnnecessaryBracesInGStringIntention.java index 697767a09aaa..ffb96c217245 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveUnnecessaryBracesInGStringIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveUnnecessaryBracesInGStringIntention.java @@ -16,6 +16,8 @@ package org.jetbrains.plugins.groovy.intentions.conversions; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -36,7 +38,7 @@ public class RemoveUnnecessaryBracesInGStringIntention extends Intention { } @Override - protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { GrStringUtil.removeUnnecessaryBracesInGString((GrString)element); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/JavaStylePropertiesInvocationIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/JavaStylePropertiesInvocationIntention.java index d905a09b5214..723d2d25ed34 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/JavaStylePropertiesInvocationIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/JavaStylePropertiesInvocationIntention.java @@ -16,6 +16,8 @@ package org.jetbrains.plugins.groovy.intentions.style; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; @@ -31,6 +33,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; + import static org.jetbrains.plugins.groovy.lang.psi.util.PsiElementUtil.*; /** @@ -42,7 +45,7 @@ public class JavaStylePropertiesInvocationIntention extends Intention { return super.isStopElement(element) || element instanceof GrClosableBlock; } - protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { assert element instanceof GrMethodCallExpression || element instanceof GrApplicationStatement; GrCall call = ((GrCall) element); GrExpression invoked = call instanceof GrMethodCallExpression ? diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java index 2404e622ad29..f89f4877b86b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java @@ -16,6 +16,7 @@ package org.jetbrains.plugins.groovy.intentions.style; +import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.infos.CandidateInfo; @@ -51,12 +52,12 @@ public class ReplaceAbstractClassInstanceByMapIntention extends Intention { } @Override - protected void processIntention(@NotNull PsiElement psiElement) throws IncorrectOperationException { - Project project = psiElement.getProject(); + protected void processIntention(@NotNull PsiElement psiElement, Project project, Editor editor) throws IncorrectOperationException { PsiDocumentManager.getInstance(project).commitAllDocuments(); final GrNewExpression newExpr = (GrNewExpression)psiElement; GrCodeReferenceElement ref = newExpr.getReferenceElement(); + assert ref != null; final PsiElement resolved = ref.resolve(); assert resolved instanceof PsiClass;// && ((PsiClass)resolved).isInterface(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ConvertParameterToMapEntryIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ConvertParameterToMapEntryIntention.java index 494bdb90eb55..9b69d187ace9 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ConvertParameterToMapEntryIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ConvertParameterToMapEntryIntention.java @@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.intentions.style.parameterToEntry; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; @@ -83,8 +84,7 @@ public class ConvertParameterToMapEntryIntention extends Intention { @NonNls private static final String MAP_TYPE_TEXT = "Map"; @NonNls private static final String[] MY_POSSIBLE_NAMES = new String[]{"attrs", "args", "params", "map"}; - protected void processIntention(@NotNull final PsiElement element) throws IncorrectOperationException { - final Project project = element.getProject(); + protected void processIntention(@NotNull final PsiElement element, final Project project, Editor editor) throws IncorrectOperationException { // Method or closure to be refactored final GrParametersOwner owner = PsiTreeUtil.getParentOfType(element, GrParametersOwner.class); final Collection occurrences = new ArrayList(); @@ -207,7 +207,7 @@ public class ConvertParameterToMapEntryIntention extends Intention { call instanceof GrCallExpression ? ((GrCallExpression)call).getClosureArguments() : GrClosableBlock.EMPTY_ARRAY; final GrClosureSignatureUtil.ArgInfo[] argInfos = - GrClosureSignatureUtil.mapParametersToArguments(signature, argumentList, closureArguments, owner.getResolveScope()); + GrClosureSignatureUtil.mapParametersToArguments(signature, argumentList, argumentList, closureArguments); if (argInfos == null) continue; final GrClosureSignatureUtil.ArgInfo argInfo = argInfos[index]; 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 8e6322a9648f..9d8fb3543879 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 @@ -264,7 +264,7 @@ public class GroovyCompletionContributor extends CompletionContributor { } else if (call instanceof GrCallExpression) { GrCallExpression constructorCall = (GrCallExpression)call; - ContainerUtil.addAll(results, constructorCall.getMethodVariants(null)); + ContainerUtil.addAll(results, constructorCall.getCallVariants(null)); final PsiType type = ((GrCallExpression)call).getType(); if (type instanceof PsiClassType) { final PsiClass psiClass = ((PsiClassType)type).resolve(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java index 415e55368dde..13820441edee 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java @@ -114,7 +114,7 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandler namedElements = ContainerUtil.findAll(variants, new Condition() { public boolean value(GroovyResolveResult groovyResolveResult) { final PsiElement element = groovyResolveResult.getElement(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java index 4163acc4c878..a6ff89d69721 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java @@ -65,8 +65,21 @@ public class ConstructorBody implements GroovyElementTypes { private static boolean parseExplicitConstructor(PsiBuilder builder, GroovyParser parser) { TypeArguments.parse(builder); + boolean result = false; + if (ParserUtils.lookAhead(builder, kTHIS, mLPAREN)) { + final PsiBuilder.Marker marker = builder.mark(); + ParserUtils.getToken(builder, kTHIS); + marker.done(THIS_REFERENCE_EXPRESSION); + result = true; + } + if (ParserUtils.lookAhead(builder, kSUPER, mLPAREN)) { + final PsiBuilder.Marker marker = builder.mark(); + ParserUtils.getToken(builder, kSUPER); + marker.done(SUPER_REFERENCE_EXPRESSION); + result = true; + } - if ((ParserUtils.getToken(builder, kTHIS) || ParserUtils.getToken(builder, kSUPER)) && ParserUtils.lookAhead(builder, mLPAREN)) { + if (result) { PsiBuilder.Marker marker = builder.mark(); ParserUtils.getToken(builder, mLPAREN); ArgumentList.parseArgumentList(builder, mRPAREN, parser); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/ClosureParameterEnhancer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/ClosureParameterEnhancer.java index 50ddc7147682..abec0085fbef 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/ClosureParameterEnhancer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/ClosureParameterEnhancer.java @@ -3,6 +3,8 @@ package org.jetbrains.plugins.groovy.lang.psi; import com.intellij.psi.*; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.util.containers.hash.HashMap; +import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; @@ -11,13 +13,67 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrParent import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.arithmetic.GrRangeExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; +import java.util.Map; +import java.util.Set; + /** * @author peter */ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer { + private final Map simpleTypes = new HashMap(); + private final Set iterations = new HashSet(); + + public ClosureParameterEnhancer() { + simpleTypes.put("times", "java.lang.Integer"); + simpleTypes.put("upto", "java.lang.Integer"); + simpleTypes.put("downto", "java.lang.Integer"); + simpleTypes.put("step", "java.lang.Integer"); + simpleTypes.put("withObjectOutputStream", "java.io.ObjectOutputStream");//todo + simpleTypes.put("withObjectInputStream", "java.io.ObjectInputStream"); + simpleTypes.put("withOutputStream", "java.io.OutputStream"); + simpleTypes.put("withInputStream", "java.io.InputStream"); + simpleTypes.put("withDataOutputStream", "java.io.DataOutputStream"); + simpleTypes.put("withDataInputStream", "java.io.DataInputStream"); + simpleTypes.put("eachLine", "java.lang.String"); + simpleTypes.put("eachFile", "java.io.File"); + simpleTypes.put("eachDir", "java.io.File"); + simpleTypes.put("eachFileRecurse", "java.io.File"); + simpleTypes.put("traverse", "java.io.File"); + simpleTypes.put("eachDirRecurse", "java.io.File"); + simpleTypes.put("eachFileMatch", "java.io.File"); + simpleTypes.put("eachDirMatch", "java.io.File"); + simpleTypes.put("withReader", "java.io.Reader"); + simpleTypes.put("withWriter", "java.io.Writer"); + simpleTypes.put("withWriterAppend", "java.io.Writer"); + simpleTypes.put("withPrintWriter", "java.io.PrintWriter"); + simpleTypes.put("eachByte", "byte"); + simpleTypes.put("transformChar", "String"); + simpleTypes.put("transformLine", "String"); + simpleTypes.put("filterLine", "String"); + simpleTypes.put("accept", "java.net.Socket"); + + iterations.add("each"); + iterations.add("any"); + iterations.add("every"); + iterations.add("reverseEach"); + iterations.add("collect"); + iterations.add("collectAll"); + iterations.add("find"); + iterations.add("findAll"); + iterations.add("retainAll"); + iterations.add("removeAll"); + iterations.add("split"); + iterations.add("groupBy"); + iterations.add("groupEntriesBy"); + iterations.add("findLastIndexOf"); + iterations.add("findIndexValues"); + iterations.add("findIndexOf"); + + } @Override @Nullable @@ -28,11 +84,11 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer { } PsiElementFactory factory = JavaPsiFacade.getInstance(closure.getProject()).getElementFactory(); String methodName = findMethodName((GrMethodCallExpression)parent); - //final GrExpression invokedExpression = methodCall.getInvokedExpression(); - //PsiType type = findQualifierType(methodCall); GrExpression expression = ((GrMethodCallExpression)parent).getInvokedExpression(); if (!(expression instanceof GrReferenceExpression)) return null; + final PsiElement resolved = ((GrReferenceExpression)expression).resolve(); + if (!(resolved instanceof GrGdkMethod)) return null; GrExpression qualifier = ((GrReferenceExpression)expression).getQualifierExpression(); if (qualifier == null) return null; @@ -42,74 +98,103 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer { return null; } - if ("each".equals(methodName) || - "every".equals(methodName) || - "collect".equals(methodName) || - "find".equals(methodName) || - "findAll".equals(methodName) || - "findIndexOf".equals(methodName)) { - PsiType res = findTypeForCollection(qualifier, factory, closure); - if (closure.getParameters().length <= 1 && res != null) { - return res; - } + final PsiParameter[] params = closure.getAllParameters(); - if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) { - if (closure.getParameters().length <= 1) { - return getEntryForMap(type, factory, closure); - } - if (closure.getParameters().length == 2) { - if (index == 0) { - return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 0, true); - } - return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 1, true); + if (params.length == 1 && simpleTypes.containsKey(methodName)) { + return factory.createTypeFromText(simpleTypes.get(methodName), closure); + } + + if (iterations.contains(methodName)) { + if (params.length == 1) { + return findTypeForIteration(qualifier, factory, closure); + } + if (params.length == 2 && InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) { + if (index == 0) { + return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 0, true); } + return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 1, true); } } - else if ("with".equals(methodName) && closure.getParameters().length <= 1) { + else if ("with".equals(methodName) && params.length == 1) { return type; } - else { - final PsiParameter[] paramCount = closure.getAllParameters(); - if ("eachWithIndex".equals(methodName)) { - PsiType res = findTypeForCollection(qualifier, factory, closure); - if (closure.getParameters().length == 2 && res != null) { + else if ("eachWithIndex".equals(methodName)) { + PsiType res = findTypeForIteration(qualifier, factory, closure); + if (params.length == 2 && res != null) { + if (index == 0) { + return res; + } + return factory.createTypeFromText(CommonClassNames.JAVA_LANG_INTEGER, closure); + } + if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) { + if (params.length == 2) { if (index == 0) { - return res; + return getEntryForMap(type, factory, closure); } return factory.createTypeFromText(CommonClassNames.JAVA_LANG_INTEGER, closure); } - if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) { - if (paramCount.length == 2) { - if (index == 0) { - return getEntryForMap(type, factory, closure); - } - return factory.createTypeFromText(CommonClassNames.JAVA_LANG_INTEGER, closure); + if (params.length == 3) { + if (index == 0) { + return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 0, true); } - if (paramCount.length == 3) { - if (index == 0) { - return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 0, true); - } - if (index == 1) { - return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 1, true); - } - return factory.createTypeFromText(CommonClassNames.JAVA_LANG_INTEGER, closure); + if (index == 1) { + return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 1, true); } + return factory.createTypeFromText(CommonClassNames.JAVA_LANG_INTEGER, closure); } } - else if ("inject".equals(methodName) && paramCount.length == 2) { - if (index == 0) { - return factory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, closure); - } + } + else if ("inject".equals(methodName) && params.length == 2) { + if (index == 0) { + return factory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, closure); + } - PsiType res = findTypeForCollection(qualifier, factory, closure); - if (res != null) { - return res; - } - if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) { - return getEntryForMap(type, factory, closure); + PsiType res = findTypeForIteration(qualifier, factory, closure); + if (res != null) { + return res; + } + if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) { + return getEntryForMap(type, factory, closure); + } + } + else if ("eachPermutation".equals(methodName) && params.length == 1) { + final PsiType itemType = findTypeForIteration(qualifier, factory, closure); + if (itemType != null) { + return factory.createTypeFromText("java.util.ArrayList<" + itemType.getCanonicalText() + ">", closure); + } + return factory.createTypeFromText("java.util.ArrayList", closure); + } + else if ("withDefault".equals(methodName)) { + if (params.length == 1 && InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) { + return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 0, true); + } + } + else if ("sort".equals(methodName)) { + if (params.length < 3) { + return findTypeForIteration(qualifier, factory, closure); + } + } + else if ("withStream".equals(methodName)) { + final PsiMethod method = ((GrMethodCallExpression)parent).resolveMethod(); + if (method != null) { + final PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameters.length > 0) { + return parameters[0].getType(); } } } + else if ("withStreams".equals(methodName)) { + if (index == 0) { + return factory.createTypeFromText("java.io.InputStream", closure); + } + else if (index == 1) return factory.createTypeFromText("java.io.OutputStream", closure); + } + else if ("withObjectStreams".equals(methodName)) { + if (index == 0) { + return factory.createTypeFromText("java.io.ObjectInputStream", closure); + } + else if (index == 1) return factory.createTypeFromText("java.io.ObjectOutputStream", closure); + } return null; } @@ -121,11 +206,11 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer { if (key != null && key != PsiType.NULL && value != null && value != PsiType.NULL) { return factory.createTypeFromText("java.util.Map.Entry<" + key.getCanonicalText() + ", " + value.getCanonicalText() + ">", context); } - return null; + return factory.createTypeFromText("java.util.Map.Entry", context); } @Nullable - public static PsiType findTypeForCollection(GrExpression qualifier, PsiElementFactory factory, PsiElement context) { + public static PsiType findTypeForIteration(GrExpression qualifier, PsiElementFactory factory, PsiElement context) { PsiType iterType = qualifier.getType(); if (iterType == null) return null; if (iterType instanceof PsiArrayType) { @@ -136,10 +221,10 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer { return types.length == 1 ? types[0] : null; } - if (factory.createTypeFromText("groovy.lang.IntRange", context).isAssignableFrom(iterType)) { + if (InheritanceUtil.isInheritor(iterType, "groovy.lang.IntRange")) { return factory.createTypeFromText(CommonClassNames.JAVA_LANG_INTEGER, context); } - if (factory.createTypeFromText("groovy.lang.ObjectRange", context).isAssignableFrom(iterType)) { + if (InheritanceUtil.isInheritor(iterType, "groovy.lang.ObjectRange")) { PsiElement element = qualifier; element = removeBrackets(element); if (element instanceof GrReferenceExpression) { @@ -160,6 +245,10 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer { if (iterType.equalsToText(CommonClassNames.JAVA_LANG_STRING) || iterType.equalsToText("java.io.File")) { return factory.createTypeFromText(CommonClassNames.JAVA_LANG_STRING, context); } + + if (InheritanceUtil.isInheritor(iterType, CommonClassNames.JAVA_UTIL_MAP)) { + return getEntryForMap(iterType, factory, context); + } return null; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrConstructorInvocation.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrConstructorInvocation.java index 5ed606681f5b..91aee9536d4a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrConstructorInvocation.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrConstructorInvocation.java @@ -16,18 +16,17 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements; import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiPolyVariantReference; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrConstructorCall; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression; /** * User: Dmitry.Krasilschikov * Date: 29.05.2007 */ -public interface GrConstructorInvocation extends GrStatement, GrConstructorCall, PsiPolyVariantReference { +public interface GrConstructorInvocation extends GrStatement, GrConstructorCall { boolean isSuperCall(); boolean isThisCall(); @@ -35,7 +34,7 @@ public interface GrConstructorInvocation extends GrStatement, GrConstructorCall, @NotNull GrArgumentList getArgumentList(); - PsiElement getThisOrSuperKeyword(); + GrThisSuperReferenceExpression getThisOrSuperKeyword(); @Nullable PsiClass getDelegatedClass(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSuperReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSuperReferenceExpression.java index b01e40a92a5d..d4400f8f1244 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSuperReferenceExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrSuperReferenceExpression.java @@ -4,12 +4,8 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions; -import org.jetbrains.annotations.Nullable; - /** * @author ilyas */ -public interface GrSuperReferenceExpression extends GrExpression { - @Nullable - GrReferenceExpression getQualifier(); +public interface GrSuperReferenceExpression extends GrThisSuperReferenceExpression { } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisReferenceExpression.java index ec6daf46be55..a8b0da352bfc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisReferenceExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisReferenceExpression.java @@ -4,12 +4,8 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions; -import org.jetbrains.annotations.Nullable; - /** * @author ilyas */ -public interface GrThisReferenceExpression extends GrExpression { - @Nullable - GrReferenceExpression getQualifier(); +public interface GrThisReferenceExpression extends GrThisSuperReferenceExpression { } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java new file mode 100644 index 000000000000..ac0c9ab00418 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java @@ -0,0 +1,27 @@ +/* + * 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 org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions; + +import com.intellij.psi.PsiPolyVariantReference; +import org.jetbrains.annotations.Nullable; + +/** + * @author Maxim.Medvedev + */ +public interface GrThisSuperReferenceExpression extends GrExpression, PsiPolyVariantReference { + @Nullable + GrReferenceExpression getQualifier(); +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/path/GrCallExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/path/GrCallExpression.java index 48aeb07117d5..65a6ae7ace1e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/path/GrCallExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/path/GrCallExpression.java @@ -43,7 +43,7 @@ public interface GrCallExpression extends GrExpression, GrCall { PsiMethod resolveMethod(); @NotNull - GroovyResolveResult[] getMethodVariants(@Nullable GrExpression upToArgument); + GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument); //PsiElement addNamedArgument(GrNamedArgument argument); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/types/GrClosureParameter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/types/GrClosureParameter.java index 17c8a2d0b33c..608c254fad8a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/types/GrClosureParameter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/types/GrClosureParameter.java @@ -15,7 +15,6 @@ */ package org.jetbrains.plugins.groovy.lang.psi.api.types; -import com.intellij.psi.PsiParameter; import com.intellij.psi.PsiType; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -24,7 +23,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres * @author Maxim.Medvedev */ public interface GrClosureParameter { - PsiParameter[] EMPTY_ARRAY = new PsiParameter[0]; @Nullable PsiType getType(); 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 a37a96beddbd..4e88b3b348ec 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 @@ -16,11 +16,11 @@ package org.jetbrains.plugins.groovy.lang.psi.expectedTypes; 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.util.*; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; @@ -38,6 +38,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrM import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; import java.util.*; @@ -127,14 +128,10 @@ public class GroovyExpectedTypesProvider { final int closureIndex = closureArgs.indexOf(myExpression); if (closureIndex >= 0) { List constraints = new ArrayList(); - for (GroovyResolveResult variant : ResolveUtil.getMethodVariants(myExpression)) { - PsiParameter[] parameters = getCallParameters(variant); - if (parameters == null || parameters.length == 0) continue; - - final int paramIndex = parameters.length - closureArgs.size() + closureIndex; - if (paramIndex >= 0) { - constraints.add(SubtypeConstraint.create(variant.getSubstitutor().substitute(parameters[paramIndex].getType()))); - } + for (GroovyResolveResult variant : ResolveUtil.getCallVariants(myExpression)) { + addConstraintsFromMap(constraints, + GrClosureSignatureUtil.mapArgumentsToParameters(variant, methodCall.getArgumentList(), methodCall, methodCall.getClosureArguments(), + true)); } if (!constraints.isEmpty()) { myResult = constraints.toArray(new TypeConstraint[constraints.size()]); @@ -175,30 +172,24 @@ public class GroovyExpectedTypesProvider { } public void visitArgumentList(GrArgumentList list) { - int idx = list.getExpressionArgumentIndex(myExpression); - List constraints = new ArrayList(); - for (GroovyResolveResult variant : ResolveUtil.getMethodVariants(list)) { - PsiParameter[] parameters = getCallParameters(variant); - if (parameters == null || parameters.length <= idx) continue; - PsiType parameterType = variant.getSubstitutor().substitute(parameters[idx].getType()); - constraints.add(SubtypeConstraint.create(parameterType)); + for (GroovyResolveResult variant : ResolveUtil.getCallVariants(list)) { + addConstraintsFromMap(constraints, + GrClosureSignatureUtil.mapArgumentsToParameters(variant, list, list, GrClosableBlock.EMPTY_ARRAY, true)); } if (!constraints.isEmpty()) { myResult = constraints.toArray(new TypeConstraint[constraints.size()]); } } - @Nullable - private static PsiParameter[] getCallParameters(GroovyResolveResult variant) { - PsiElement element = variant.getElement(); - if (element instanceof GrParametersOwner) { - return ((GrParametersOwner)element).getParameters(); + private void addConstraintsFromMap(List constraints, + Map> map) { + if (map != null) { + final Pair pair = map.get(myExpression); + if (pair != null) { + constraints.add(SubtypeConstraint.create(pair.second)); + } } - else if (element instanceof PsiMethod) { - return ((PsiMethod)element).getParameterList().getParameters(); - } - return null; } public void visitAssignmentExpression(GrAssignmentExpression expression) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java index f8460706203f..707c0012b9b4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java @@ -21,17 +21,17 @@ import com.intellij.psi.*; import com.intellij.psi.tree.TokenSet; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.TypeConversionUtil; -import com.intellij.util.ArrayUtil; 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.parser.GroovyElementTypes; 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.GrConstructorInvocation; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiElementImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; @@ -73,17 +73,18 @@ public class GrConstructorInvocationImpl extends GroovyPsiElementImpl implements } public boolean isSuperCall() { - return findChildByType(GroovyTokenTypes.kSUPER) != null; + return findChildByType(GroovyElementTypes.SUPER_REFERENCE_EXPRESSION) != null; } public boolean isThisCall() { - return findChildByType(GroovyTokenTypes.kTHIS) != null; + return findChildByType(GroovyElementTypes.THIS_REFERENCE_EXPRESSION) != null; } - private static final TokenSet THIS_OR_SUPER_SET = TokenSet.create(GroovyTokenTypes.kTHIS, GroovyTokenTypes.kSUPER); + private static final TokenSet THIS_OR_SUPER_SET = + TokenSet.create(GroovyElementTypes.THIS_REFERENCE_EXPRESSION, GroovyElementTypes.SUPER_REFERENCE_EXPRESSION); - public PsiElement getThisOrSuperKeyword() { - return findChildByType(THIS_OR_SUPER_SET); + public GrThisSuperReferenceExpression getThisOrSuperKeyword() { + return (GrThisSuperReferenceExpression)findChildByType(THIS_OR_SUPER_SET); } public GroovyResolveResult[] multiResolveConstructor() { @@ -156,36 +157,4 @@ public class GrConstructorInvocationImpl extends GroovyPsiElementImpl implements public String getCanonicalText() { return getText(); //TODO } - - public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { - return this; - } - - public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { - return this; - } - - public boolean isReferenceTo(PsiElement element) { - return element instanceof PsiMethod && ((PsiMethod)element).isConstructor() && getManager().areElementsEquivalent(element, resolve()); - - } - - @NotNull - public Object[] getVariants() { - return ArrayUtil.EMPTY_OBJECT_ARRAY; - } - - public boolean isSoft() { - return false; - } - - @Override - public PsiReference getReference() { - return this; - } - - @NotNull - public ResolveResult[] multiResolve(boolean incompleteCode) { - return multiResolveConstructor(); - } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelManipulator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelManipulator.java index 871666010481..b94e797b9c0a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelManipulator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelManipulator.java @@ -2,13 +2,27 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.arguments; import com.intellij.openapi.util.TextRange; import com.intellij.psi.AbstractElementManipulator; +import com.intellij.psi.PsiElement; +import com.intellij.psi.impl.source.tree.LeafPsiElement; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel; +import org.jetbrains.plugins.groovy.lang.resolve.GroovyStringLiteralManipulator; /** * @author peter */ public class GrArgumentLabelManipulator extends AbstractElementManipulator { + @Override + public TextRange getRangeInElement(GrArgumentLabel element) { + final PsiElement nameElement = element.getNameElement(); + if (nameElement instanceof LeafPsiElement && GroovyTokenTypes.STRING_LITERAL_SET.contains(((LeafPsiElement)nameElement).getElementType())) { + return GroovyStringLiteralManipulator.getLiteralRange(nameElement.getText()); + } + + return super.getRangeInElement(element); + } + public GrArgumentLabel handleContentChange(GrArgumentLabel element, TextRange range, String newContent) throws IncorrectOperationException { return (GrArgumentLabel)element.handleElementRename(newContent); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrBlockImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrBlockImpl.java index c85bdd2d8468..914f25279a05 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrBlockImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrBlockImpl.java @@ -105,8 +105,6 @@ public abstract class GrBlockImpl extends GroovyPsiElementImpl implements GrCode throw new IncorrectOperationException(); } - ASTNode elemNode = element.copy().getNode(); - assert elemNode != null; PsiElement actualAnchor = anchor == null ? getRBrace() : anchor; if (mayUseNewLinesAsSeparators()) { PsiElement prev = actualAnchor.getPrevSibling(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrNewExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrNewExpressionImpl.java index b79ecbde0668..22ff2fab9fc6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrNewExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrNewExpressionImpl.java @@ -182,7 +182,7 @@ public class GrNewExpressionImpl extends GrCallExpressionImpl implements GrNewEx } @NotNull - public GroovyResolveResult[] getMethodVariants(@Nullable GrExpression upToArgument) { + public GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument) { final GrCodeReferenceElement referenceElement = getReferenceElement(); if (referenceElement == null) return GroovyResolveResult.EMPTY_ARRAY; final GroovyResolveResult[] classResults = referenceElement.multiResolve(false); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java index 16311308b982..947db67a586f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java @@ -77,6 +77,120 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements super(node); } + public GroovyResolveResult[] resolveTypeOrProperty() { + String name = getReferenceName(); + if (name == null) return GroovyResolveResult.EMPTY_ARRAY; + + EnumSet kinds = getParent() instanceof GrReferenceExpression + ? EnumSet.of(ClassHint.ResolveKind.CLASS, ClassHint.ResolveKind.PACKAGE) + : EnumSet.of(ClassHint.ResolveKind.CLASS); + boolean hasAt = hasAt(); + GroovyResolveResult[] classCandidates = GroovyResolveResult.EMPTY_ARRAY; + if (!hasAt) { + ResolverProcessor classProcessor = new ClassResolverProcessor(getReferenceName(), this, kinds); + resolveImpl(classProcessor); + classCandidates = classProcessor.getCandidates(); + for (GroovyResolveResult classCandidate : classCandidates) { + final PsiElement element = classCandidate.getElement(); + if (element instanceof PsiClass && ((PsiClass)element).isEnum()) { + return classCandidates; + } + } + } + + ResolverProcessor processor = new PropertyResolverProcessor(name, this); + resolveImpl(processor); + final GroovyResolveResult[] fieldCandidates = processor.getCandidates(); + + if (hasAt) { + return fieldCandidates; + } + + //if reference expression is in class we need to return field instead of accessor method + for (GroovyResolveResult candidate : fieldCandidates) { + final PsiElement element = candidate.getElement(); + if (element instanceof PsiField) { + final PsiClass containingClass = ((PsiField)element).getContainingClass(); + if (containingClass != null && PsiTreeUtil.isAncestor(containingClass, this, true)) return fieldCandidates; + } else { + return fieldCandidates; + } + } + + final boolean isLValue = PsiUtil.isLValue(this); + String[] names; + names = isLValue ? GroovyPropertyUtils.suggestSettersName(name) : GroovyPropertyUtils.suggestGettersName(name); + List accessorResults = new ArrayList(); + for (String getterName : names) { + AccessorResolverProcessor accessorResolver = new AccessorResolverProcessor(getterName, this, !isLValue); + resolveImpl(accessorResolver); + final GroovyResolveResult[] candidates = accessorResolver.getCandidates(); //can be only one candidate + if (candidates.length == 1 && candidates[0].isStaticsOK()) { + return candidates; + } + else { + ContainerUtil.addAll(accessorResults, candidates); + } + } + if (fieldCandidates.length > 0) return fieldCandidates; + if (accessorResults.size() > 0) return new GroovyResolveResult[]{accessorResults.get(0)}; + + return classCandidates; + } + + public GroovyResolveResult[] resolveMethodOrProperty() { + return resolveMethodOrProperty(false, null); + } + + public GroovyResolveResult[] getCallVariants(GrExpression upToArgument) { + return resolveMethodOrProperty(true, upToArgument); + } + + private GroovyResolveResult[] resolveMethodOrProperty(boolean allVariants, GrExpression upToArgument) { + String name = getReferenceName(); + if (name == null) return GroovyResolveResult.EMPTY_ARRAY; + + final PsiType[] argTypes = PsiUtil.getArgumentTypes(this, false, upToArgument); + MethodResolverProcessor methodResolver = runMethodResolverProcessor(argTypes, allVariants); + assert methodResolver != null; + if (!allVariants && methodResolver.hasApplicableCandidates()) return methodResolver.getCandidates(); + + final String[] names = GroovyPropertyUtils.suggestGettersName(name); + List list = new ArrayList(); + for (String getterName : names) { + AccessorResolverProcessor getterResolver = new AccessorResolverProcessor(getterName, this, true); + resolveImpl(getterResolver); + final GroovyResolveResult[] candidates = getterResolver.getCandidates(); //can be only one candidate + if (!allVariants && candidates.length == 1 && candidates[0].isStaticsOK()) { + putUserData(IS_RESOLVED_TO_GETTER, true); + return candidates; + } + else { + ContainerUtil.addAll(list, candidates); + } + } + + PropertyResolverProcessor propertyResolver = new PropertyResolverProcessor(name, this); + resolveImpl(propertyResolver); + if (!allVariants && propertyResolver.hasCandidates()) return propertyResolver.getCandidates(); + + if (allVariants) { + if (list.isEmpty()) ContainerUtil.addAll(list, propertyResolver.getCandidates()); + ContainerUtil.addAll(list, methodResolver.getCandidates()); + return list.toArray(new GroovyResolveResult[list.size()]); + } + + if (methodResolver.hasCandidates()) { + return methodResolver.getCandidates(); + } + else if (list.size() > 0) { + putUserData(IS_RESOLVED_TO_GETTER, true); + return list.toArray(new GroovyResolveResult[list.size()]); + } + + return GroovyResolveResult.EMPTY_ARRAY; + } + public void accept(GroovyElementVisitor visitor) { visitor.visitReferenceExpression(this); } @@ -422,108 +536,13 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements switch (kind) { case METHOD_OR_PROPERTY: - return resolveMethodOrProperty(refExpr, name); + return refExpr.resolveMethodOrProperty(); case TYPE_OR_PROPERTY: - return resolveTypeOrProperty(refExpr, name); + return refExpr.resolveTypeOrProperty(); default: return GroovyResolveResult.EMPTY_ARRAY; } } - - private static GroovyResolveResult[] resolveTypeOrProperty(GrReferenceExpressionImpl refExpr, String name) { - EnumSet kinds = refExpr.getParent() instanceof GrReferenceExpression - ? EnumSet.of(ClassHint.ResolveKind.CLASS, ClassHint.ResolveKind.PACKAGE) - : EnumSet.of(ClassHint.ResolveKind.CLASS); - boolean hasAt = refExpr.hasAt(); - GroovyResolveResult[] classCandidates = GroovyResolveResult.EMPTY_ARRAY; - if (!hasAt) { - ResolverProcessor classProcessor = new ClassResolverProcessor(refExpr.getReferenceName(), refExpr, kinds); - refExpr.resolveImpl(classProcessor); - classCandidates = classProcessor.getCandidates(); - for (GroovyResolveResult classCandidate : classCandidates) { - final PsiElement element = classCandidate.getElement(); - if (element instanceof PsiClass && ((PsiClass)element).isEnum()) { - return classCandidates; - } - } - } - - ResolverProcessor processor = new PropertyResolverProcessor(name, refExpr); - refExpr.resolveImpl(processor); - final GroovyResolveResult[] fieldCandidates = processor.getCandidates(); - - if (refExpr.hasAt()) { - return fieldCandidates; - } - - //if reference expression is in class we need to return field instead of accessor method - for (GroovyResolveResult candidate : fieldCandidates) { - final PsiElement element = candidate.getElement(); - if (element instanceof PsiField) { - final PsiClass containingClass = ((PsiField)element).getContainingClass(); - if (containingClass != null && PsiTreeUtil.isAncestor(containingClass, refExpr, true)) return fieldCandidates; - } else { - return fieldCandidates; - } - } - - final boolean isLValue = PsiUtil.isLValue(refExpr); - String[] names; - names = isLValue ? GroovyPropertyUtils.suggestSettersName(name) : GroovyPropertyUtils.suggestGettersName(name); - List accessorResults = new ArrayList(); - for (String getterName : names) { - AccessorResolverProcessor accessorResolver = new AccessorResolverProcessor(getterName, refExpr, !isLValue); - refExpr.resolveImpl(accessorResolver); - final GroovyResolveResult[] candidates = accessorResolver.getCandidates(); //can be only one candidate - if (candidates.length == 1 && candidates[0].isStaticsOK()) { - return candidates; - } - else { - ContainerUtil.addAll(accessorResults, candidates); - } - } - if (fieldCandidates.length > 0) return fieldCandidates; - if (accessorResults.size() > 0) return new GroovyResolveResult[]{accessorResults.get(0)}; - - return classCandidates; - } - - private static GroovyResolveResult[] resolveMethodOrProperty(GrReferenceExpressionImpl refExpr, String name) { - final PsiType[] argTypes = PsiUtil.getArgumentTypes(refExpr, false); - MethodResolverProcessor methodResolver = refExpr.runMethodResolverProcessor(argTypes, false); - assert methodResolver != null; - if (methodResolver.hasApplicableCandidates()) return methodResolver.getCandidates(); - - final String[] names = GroovyPropertyUtils.suggestGettersName(name); - List list = new ArrayList(); - for (String getterName : names) { - AccessorResolverProcessor getterResolver = new AccessorResolverProcessor(getterName, refExpr, true); - refExpr.resolveImpl(getterResolver); - final GroovyResolveResult[] candidates = getterResolver.getCandidates(); //can be only one candidate - if (candidates.length == 1 && candidates[0].isStaticsOK()) { - refExpr.putUserData(IS_RESOLVED_TO_GETTER, true); - return candidates; - } - else { - ContainerUtil.addAll(list, candidates); - } - } - - PropertyResolverProcessor propertyResolver = new PropertyResolverProcessor(name, refExpr); - refExpr.resolveImpl(propertyResolver); - if (propertyResolver.hasCandidates()) return propertyResolver.getCandidates(); - - if (methodResolver.hasCandidates()) { - return methodResolver.getCandidates(); - } - else if (list.size() > 0) { - refExpr.putUserData(IS_RESOLVED_TO_GETTER, true); - return list.toArray(new GroovyResolveResult[list.size()]); - } - - return GroovyResolveResult.EMPTY_ARRAY; - } - } private void resolveImpl(ResolverProcessor processor) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java index 8d1f4dd657ce..fed5fc22d790 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java @@ -9,7 +9,6 @@ import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; @@ -22,7 +21,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini /** * @author ilyas */ -public class GrSuperReferenceExpressionImpl extends GrExpressionImpl implements GrSuperReferenceExpression { +public class GrSuperReferenceExpressionImpl extends GrThisSuperReferenceExpressionBase implements GrSuperReferenceExpression { public GrSuperReferenceExpressionImpl(@NotNull ASTNode node) { super(node); } @@ -60,11 +59,6 @@ public class GrSuperReferenceExpressionImpl extends GrExpressionImpl implements return null; } - @Nullable - public GrReferenceExpression getQualifier() { - return (GrReferenceExpression)findChildByType(GroovyElementTypes.REFERENCE_EXPRESSION); - } - @Nullable private PsiType getSuperType(PsiClass aClass) { if (aClass.isInterface()) { @@ -88,4 +82,10 @@ public class GrSuperReferenceExpressionImpl extends GrExpressionImpl implements return superTypes[0]; } + + @NotNull + @Override + public String getCanonicalText() { + return "super"; + } } 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 95f465b09902..f2d892c46aaf 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,8 +9,6 @@ import com.intellij.psi.*; 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.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; @@ -22,7 +20,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; /** * @author ilyas */ -public class GrThisReferenceExpressionImpl extends GrExpressionImpl implements GrThisReferenceExpression { +public class GrThisReferenceExpressionImpl extends GrThisSuperReferenceExpressionBase implements GrThisReferenceExpression { public GrThisReferenceExpressionImpl(@NotNull ASTNode node) { super(node); } @@ -73,8 +71,9 @@ public class GrThisReferenceExpressionImpl extends GrExpressionImpl implements G return elementFactory.createType(context); } - @Nullable - public GrReferenceExpression getQualifier() { - return (GrReferenceExpression)findChildByType(GroovyElementTypes.REFERENCE_EXPRESSION); + @NotNull + @Override + public String getCanonicalText() { + return "this"; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java new file mode 100644 index 000000000000..99604e3acc57 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java @@ -0,0 +1,82 @@ +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.ResolveResult; +import com.intellij.util.ArrayUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression; + +/** + * @author Maxim.Medvedev + */ +public abstract class GrThisSuperReferenceExpressionBase extends GrExpressionImpl implements GrThisSuperReferenceExpression { + public GrThisSuperReferenceExpressionBase(ASTNode node) { + super(node); + } + + @Nullable + public GrReferenceExpression getQualifier() { + return (GrReferenceExpression)findChildByType(GroovyElementTypes.REFERENCE_EXPRESSION); + } + + @Override + public PsiElement getElement() { + return this; + } + + @Override + public TextRange getRangeInElement() { + return new TextRange(0, getTextLength()); + } + + @Override + public PsiElement resolve() { + final PsiElement parent = getParent(); + if (parent instanceof GrConstructorInvocation)return ((GrConstructorInvocation)parent).resolveConstructor(); + return null; + } + + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + return this; + } + + public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { + return this; + } + + public boolean isReferenceTo(PsiElement element) { + return element instanceof PsiMethod && ((PsiMethod)element).isConstructor() && getManager().areElementsEquivalent(element, resolve()); + } + + @NotNull + public Object[] getVariants() { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + public boolean isSoft() { + return false; + } + + @Override + public PsiReference getReference() { + return this; + } + + @NotNull + public ResolveResult[] multiResolve(boolean incompleteCode) { + final PsiElement parent = getParent(); + if (parent instanceof GrConstructorInvocation) { + return ((GrConstructorInvocation)parent).multiResolveConstructor(); + } + return ResolveResult.EMPTY_ARRAY; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java index 26a0d6868e64..9b1707f9aa02 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java @@ -103,7 +103,8 @@ public class TypesUtil { if (candidates.length == 1) { final PsiElement element = candidates[0].getElement(); if (element instanceof PsiMethod) { - return candidates[0].getSubstitutor().substitute(PsiUtil.getSmartReturnType((PsiMethod)element)); + return boxPrimitiveType(candidates[0].getSubstitutor().substitute(PsiUtil.getSmartReturnType((PsiMethod)element)), + place.getManager(), place.getResolveScope()); } } return null; 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 e30d24327ee4..4e9f16abf393 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 @@ -19,18 +19,19 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path; import com.intellij.lang.ASTNode; import com.intellij.psi.*; import com.intellij.psi.util.InheritanceUtil; -import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; 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.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.api.statements.typedef.members.GrGdkMethod; import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrExpressionImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; +import static com.intellij.psi.util.PsiUtil.substituteTypeParameter; +import static org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.getSmartReturnType; + /** * @author ilyas */ @@ -74,38 +75,42 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp argTypes[i] = argType; } - if (thisType instanceof GrTupleType) { + if (thisType instanceof GrTupleType && + argTypes.length == 1 && + TypesUtil.isAssignable(PsiType.INT, argTypes[0], getManager(), getResolveScope())) { PsiType[] types = ((GrTupleType)thisType).getParameters(); return types.length == 1 ? types[0] : null; } PsiType overloadedOperatorType = null; - final GroovyResolveResult[] candidates = TypesUtil.getOverloadedOperatorCandidates(thisType, "getAt", this, argTypes); + GroovyResolveResult[] candidates = TypesUtil.getOverloadedOperatorCandidates(thisType, "getAt", this, argTypes); + if (candidates.length != 1) { + candidates = TypesUtil.getOverloadedOperatorCandidates(thisType, "getAt", this, new PsiType[]{ + new GrTupleType(argTypes, JavaPsiFacade.getInstance(getProject()), getResolveScope())}); + } if (candidates.length == 1) { final PsiElement element = candidates[0].getElement(); if (element instanceof PsiMethod) { - overloadedOperatorType = candidates[0].getSubstitutor().substitute(org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.getSmartReturnType((PsiMethod)element)); - if (overloadedOperatorType != null && !(element instanceof GrGdkMethod)) { //gdk 'getAt' methods don't have information about type parameters - return overloadedOperatorType; - } + overloadedOperatorType = candidates[0].getSubstitutor().substitute(getSmartReturnType((PsiMethod)element)); } } - if (thisType instanceof PsiArrayType) { - PsiType componentType = ((PsiArrayType)thisType).getComponentType(); - return TypesUtil.boxPrimitiveType(componentType, getManager(), getResolveScope()); + PsiType componentType = null; + if (thisType instanceof PsiArrayType && + argTypes.length == 1 && + TypesUtil.isAssignable(PsiType.INT, argTypes[0], getManager(), getResolveScope())) { + componentType = TypesUtil.boxPrimitiveType(((PsiArrayType)thisType).getComponentType(), getManager(), getResolveScope()); + } + else if (InheritanceUtil.isInheritor(thisType, CommonClassNames.JAVA_UTIL_MAP) && argTypes.length == 1) { + componentType = TypesUtil + .boxPrimitiveType(substituteTypeParameter(thisType, CommonClassNames.JAVA_UTIL_MAP, 1, true), getManager(), getResolveScope()); } - if (InheritanceUtil.isInheritor(thisType, CommonClassNames.JAVA_UTIL_LIST)) { - PsiType iterType = PsiUtil.extractIterableTypeParameter(thisType, true); - if (iterType != null) return iterType; + if (overloadedOperatorType != null && + (componentType == null || !TypesUtil.isAssignable(overloadedOperatorType, componentType, getManager(), getResolveScope()))) { + return TypesUtil.boxPrimitiveType(overloadedOperatorType, getManager(), getResolveScope()); } - - if (InheritanceUtil.isInheritor(thisType, CommonClassNames.JAVA_UTIL_MAP)) { - return PsiUtil.substituteTypeParameter(thisType, CommonClassNames.JAVA_UTIL_MAP, 1, true); - } - - return overloadedOperatorType; + return componentType; } } return null; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java index 5a7033e7aefc..240808ac9b5b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java @@ -41,7 +41,6 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrRefer 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 org.jetbrains.plugins.groovy.lang.resolve.processors.MethodResolverProcessor; import java.util.ArrayList; @@ -187,17 +186,11 @@ public class GrMethodCallExpressionImpl extends GrCallExpressionImpl implements } @NotNull - public GroovyResolveResult[] getMethodVariants(@Nullable GrExpression upToArgument) { + public GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument) { final GrExpression invoked = getInvokedExpression(); if (!(invoked instanceof GrReferenceExpressionImpl)) return GroovyResolveResult.EMPTY_ARRAY; - final PsiType[] partialArgs = PsiUtil.getArgumentTypes(invoked, false, upToArgument); - final MethodResolverProcessor processor = ((GrReferenceExpressionImpl)invoked).runMethodResolverProcessor(partialArgs, true); - if (processor != null) { - return processor.getCandidates(); - } - - return GroovyResolveResult.EMPTY_ARRAY; + return ((GrReferenceExpressionImpl)invoked).getCallVariants(upToArgument); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/params/GrParameterImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/params/GrParameterImpl.java index 1ee5b41f49b8..d3965f74fa6e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/params/GrParameterImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/params/GrParameterImpl.java @@ -84,7 +84,7 @@ public class GrParameterImpl extends GrVariableImpl implements GrParameter { return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_INTEGER, getResolveScope()); } else if (iteratedExpression != null) { - PsiType result = ClosureParameterEnhancer.findTypeForCollection(iteratedExpression, factory, this); + PsiType result = ClosureParameterEnhancer.findTypeForIteration(iteratedExpression, factory, this); if (result != null) { return result; } 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 c6fd2f5b186f..8adc70ef8db2 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 @@ -142,7 +142,7 @@ public class GrClosureSignatureImpl implements GrClosureSignature { private class DerivedClosureSignature extends GrClosureSignatureImpl { DerivedClosureSignature() { - super(GrClosureParameter.EMPTY_ARRAY, null); + super(PsiParameter.EMPTY_ARRAY, null); } DerivedClosureSignature(@NotNull GrClosureParameter[] params, @Nullable PsiType returnType, boolean isVarArgs) { 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 55a5b122a538..0a5a9598d68f 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 @@ -17,7 +17,6 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.types; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; -import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.MethodSignature; import com.intellij.psi.util.MethodSignatureUtil; @@ -40,10 +39,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.util.*; /** * @author Maxim.Medvedev @@ -139,7 +135,8 @@ public class GrClosureSignatureUtil { return false; } - public static ArgInfo[] mapArgTypesToParameters(GrClosureSignature signature, + @Nullable + public static ArgInfo[] mapArgTypesToParameters(@NotNull GrClosureSignature signature, PsiType[] args, GroovyPsiElement context, boolean partial) { @@ -147,10 +144,10 @@ public class GrClosureSignatureUtil { } @Nullable - private static ArgInfo[] mapParametersToArguments(GrClosureSignature signature, + private static ArgInfo[] mapParametersToArguments(@NotNull GrClosureSignature signature, Arg[] args, Function typeComputer, - GroovyPsiElement context, boolean partial) { + @NotNull GroovyPsiElement context, boolean partial) { GrClosureParameter[] params = signature.getParameters(); if (args.length > params.length && !signature.isVarargs()) return null; int optional = getOptionalParamCount(signature, false); @@ -158,11 +155,11 @@ public class GrClosureSignatureUtil { if (signature.isVarargs()) notOptional--; if (notOptional > args.length && !partial) return null; - final ArgInfo[] map = mapSimple(params, args, typeComputer, context); + final ArgInfo[] map = mapSimple(params, args, typeComputer, context, partial); if (map != null) return map; if (signature.isVarargs()) { - return new ParameterMapperForVararg(context, params, args, typeComputer).isApplicable(); + return new ParameterMapperForVararg(context, params, args, typeComputer).isApplicable(partial); } return null; } @@ -171,7 +168,7 @@ public class GrClosureSignatureUtil { private static ArgInfo[] mapSimple(GrClosureParameter[] params, Arg[] args, Function typeComputer, - GroovyPsiElement context) { + GroovyPsiElement context, boolean incompleteCode) { ArgInfo[] map = new ArgInfo[params.length]; int optional = getOptionalParamCount(params, false); int notOptional = params.length - optional; @@ -183,7 +180,7 @@ public class GrClosureSignatureUtil { } if (cur == params.length) return null; if (params[cur].isOptional()) optionalArgs--; - if (!TypesUtil.isAssignableByMethodCallConversion(params[cur].getType(), typeComputer.fun(args[i]), context)) return null; + if (!isAssibnableByConversion(params[cur].getType(), typeComputer.fun(args[i]), context, incompleteCode)) return null; map[cur] = new ArgInfo(args[i]); } for (int i = 0; i < map.length; i++) { @@ -192,6 +189,16 @@ public class GrClosureSignatureUtil { return map; } + private static boolean isAssibnableByConversion(PsiType paramType, + PsiType argType, + GroovyPsiElement context, + boolean incompleteCode) { + if (argType == null && incompleteCode) { + return true; + } + return TypesUtil.isAssignableByMethodCallConversion(paramType, argType, context); + } + private static class ParameterMapperForVararg { private GroovyPsiElement context; GrClosureParameter[] params; @@ -218,12 +225,12 @@ public class GrClosureSignatureUtil { } @Nullable - public ArgInfo[] isApplicable() { + public ArgInfo[] isApplicable(boolean incompleteCode) { int notOptionals = 0; for (int i = 0; i < paramLength; i++) { if (!params[i].isOptional()) notOptionals++; } - if (isApplicableInternal(0, 0, false, notOptionals)) { + if (isApplicableInternal(0, 0, false, notOptionals, incompleteCode)) { for (int i = 0; i < map.length; i++) { if (map[i] == null) map[i] = new ArgInfo(false); } @@ -234,7 +241,7 @@ public class GrClosureSignatureUtil { } } - private boolean isApplicableInternal(int curParam, int curArg, boolean skipOptionals, int notOptional) { + private boolean isApplicableInternal(int curParam, int curArg, boolean skipOptionals, int notOptional, boolean incompleteCode) { int startParam = curParam; if (notOptional > args.length - curArg) return false; if (notOptional == args.length - curArg) skipOptionals = true; @@ -247,15 +254,15 @@ public class GrClosureSignatureUtil { if (curParam == paramLength) break; if (params[curParam].isOptional()) { - if (TypesUtil.isAssignableByMethodCallConversion(params[curParam].getType(), types[curArg], context) && - isApplicableInternal(curParam + 1, curArg + 1, false, notOptional)) { + if (isAssibnableByConversion(params[curParam].getType(), types[curArg], context, incompleteCode) && + isApplicableInternal(curParam + 1, curArg + 1, false, notOptional, incompleteCode)) { map[curParam] = new ArgInfo(args[curArg]); return true; } skipOptionals = true; } else { - if (!TypesUtil.isAssignableByMethodCallConversion(params[curParam].getType(), types[curArg], context)) { + if (!isAssibnableByConversion(params[curParam].getType(), types[curArg], context, incompleteCode)) { for (int i = startParam; i < curParam; i++) map[i] = null; return false; } @@ -268,7 +275,7 @@ public class GrClosureSignatureUtil { List varargs = new ArrayList(); for (; curArg < args.length; curArg++) { - if (!TypesUtil.isAssignableByMethodCallConversion(vararg, types[curArg], context)) { + if (!isAssibnableByConversion(vararg, types[curArg], context, incompleteCode)) { for (int i = startParam; i < curParam; i++) map[i] = null; return false; } @@ -326,9 +333,8 @@ public class GrClosureSignatureUtil { */ @Nullable public static ArgInfo[] mapParametersToArguments(@NotNull GrClosureSignature signature, - @NotNull GrArgumentList list, - GlobalSearchScope scope) { - return mapParametersToArguments(signature, list, GrClosableBlock.EMPTY_ARRAY, scope); + @NotNull GrArgumentList list) { + return mapParametersToArguments(signature, list, list, GrClosableBlock.EMPTY_ARRAY); } private static class InnerArg { @@ -342,29 +348,83 @@ public class GrClosureSignatureUtil { } @Nullable - public static ArgInfo[] mapParametersToArguments(@NotNull GrClosureSignature signature, - @NotNull GrArgumentList list, - @NotNull GrClosableBlock[] closureArguments, - GlobalSearchScope scope) { - final GrNamedArgument[] namedArgs = list.getNamedArguments(); - boolean hasNamedArgs = namedArgs.length > 0; - GrClosureParameter[] params = signature.getParameters(); + public static Map> mapArgumentsToParameters(@NotNull GroovyResolveResult resolveResult, + @Nullable GrArgumentList list, + @NotNull GroovyPsiElement context, + @NotNull GrClosableBlock[] closureArguments, + final boolean partial) { + final GrClosureSignature signature; + final PsiParameter[] parameters; + final PsiElement element = resolveResult.getElement(); + final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); + if (element instanceof PsiMethod) { + signature = createSignature((PsiMethod)element, substitutor); + parameters = ((PsiMethod)element).getParameterList().getParameters(); + } else if (element instanceof GrClosableBlock) { + signature = createSignature((GrClosableBlock)element); + parameters = ((GrClosableBlock)element).getAllParameters(); + } else { + return null; + } - List innerArgs = new ArrayList(); + final ArgInfo[] argInfos = mapParametersToArguments(signature, list, context, closureArguments, partial); + if (argInfos == null) { + return null; + } - if (hasNamedArgs) { - if (params.length == 0) return null; - PsiType type = params[0].getType(); - if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) { - innerArgs.add(new InnerArg(PsiUtil.createMapType(scope), namedArgs)); - } - else { - return null; + final HashMap> result = new HashMap>(); + for (int i = 0; i < argInfos.length; i++) { + ArgInfo info = argInfos[i]; + for (PsiElement arg : info.args) { + final GrExpression expression = (GrExpression)arg; + PsiType type = parameters[i].getType(); + if (info.isMultiArg && type instanceof PsiArrayType) { + type = ((PsiArrayType)type).getComponentType(); + } + result.put(expression, Pair.create(parameters[i], substitutor.substitute(type))); } } - for (GrExpression expression : list.getExpressionArguments()) { - innerArgs.add(new InnerArg(expression.getType(), expression)); + return result; + } + + + @Nullable + public static ArgInfo[] mapParametersToArguments(@NotNull GrClosureSignature signature, + @Nullable GrArgumentList list, + @NotNull GroovyPsiElement context, + @NotNull GrClosableBlock[] closureArguments) { + return mapParametersToArguments(signature, list, context, closureArguments, false); + } + + @Nullable + public static ArgInfo[] mapParametersToArguments(@NotNull GrClosureSignature signature, + @Nullable GrArgumentList list, + @NotNull GroovyPsiElement context, + @NotNull GrClosableBlock[] closureArguments, final boolean partial) { + List innerArgs = new ArrayList(); + + boolean hasNamedArgs = false; + if (list != null) { + final GrNamedArgument[] namedArgs = list.getNamedArguments(); + hasNamedArgs = namedArgs.length > 0; + GrClosureParameter[] params = signature.getParameters(); + + + if (hasNamedArgs) { + if (params.length == 0) return null; + PsiType type = params[0].getType(); + if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) { + innerArgs.add(new InnerArg(PsiUtil.createMapType(list.getResolveScope()), namedArgs)); + } + else { + return null; + } + } + + for (GrExpression expression : list.getExpressionArguments()) { + innerArgs.add(new InnerArg(expression.getType(), expression)); + } } for (GrClosableBlock closureArgument : closureArguments) { @@ -377,7 +437,7 @@ public class GrClosureSignatureUtil { public PsiType fun(InnerArg o) { return o.type; } - }, list, false); + }, context, partial); if (innerMap == null) return null; ArgInfo[] map = new ArgInfo[innerMap.length]; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/patterns/GroovyExpressionPattern.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/patterns/GroovyExpressionPattern.java index 67b76bf82b5b..f2e50cb1d9a1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/patterns/GroovyExpressionPattern.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/patterns/GroovyExpressionPattern.java @@ -42,7 +42,7 @@ public class GroovyExpressionPattern method) { return new GroovyMethodCallPattern().and(this).with(new PatternCondition("methodCall") { public boolean accepts(@NotNull GrCallExpression callExpression, ProcessingContext context) { - final GroovyResolveResult[] results = callExpression.getMethodVariants(null); + final GroovyResolveResult[] results = callExpression.getCallVariants(null); for (GroovyResolveResult result : results) { if (method.getCondition().accepts(result.getElement(), context)) { return true; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java index 628b7350ce25..6e654b3db96f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java @@ -295,14 +295,6 @@ public class PsiUtil { return null; } - public static SearchScope restrictScopeToGroovyFiles(final Computable originalScopeComputation) { //important to compute originalSearchScope in read action! - return ApplicationManager.getApplication().runReadAction(new Computable() { - public SearchScope compute() { - return restrictScopeToGroovyFiles(originalScopeComputation.compute()); - } - }); - } - public static SearchScope restrictScopeToGroovyFiles(SearchScope originalScope) { if (originalScope instanceof GlobalSearchScope) { return GlobalSearchScope.getScopeRestrictedByFileTypes((GlobalSearchScope)originalScope, GroovyFileTypeLoader.getGroovyEnabledFileTypes()); @@ -632,7 +624,7 @@ public class PsiUtil { } public static boolean isRawMethodCall(GrMethodCallExpression call) { - final GroovyResolveResult[] resolveResults = call.getMethodVariants(null); + final GroovyResolveResult[] resolveResults = call.getCallVariants(null); if (resolveResults.length == 0) return false; final PsiElement element = resolveResults[0].getElement(); if (element instanceof PsiMethod) { @@ -857,7 +849,7 @@ public class PsiUtil { public static boolean isMethodUsage(PsiElement element) { if (element instanceof GrEnumConstant) return true; - if (!(element instanceof GrReferenceElement)) return false; + if (!(element instanceof GrReferenceElement || element instanceof GrThisSuperReferenceExpression)) return false; PsiElement parent = element.getParent(); if (parent instanceof GrCall) { return true; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyStringLiteralManipulator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyStringLiteralManipulator.java index 46273bf561c7..1055695db990 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyStringLiteralManipulator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyStringLiteralManipulator.java @@ -35,9 +35,13 @@ public class GroovyStringLiteralManipulator extends AbstractElementManipulator 6 && text.startsWith("\"\"\"") && text.endsWith("\"\"\"")) { - return new TextRange(3, element.getTextLength() - 3); + return new TextRange(3, text.length() - 3); } - return new TextRange(1, Math.max(1, element.getTextLength() - 1)); + return new TextRange(1, Math.max(1, text.length() - 1)); } } \ No newline at end of file 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 9659d975a867..47905ecaec05 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 @@ -439,11 +439,11 @@ public class ResolveUtil { return true; } - public static GroovyResolveResult[] getMethodVariants(GroovyPsiElement place) { + public static GroovyResolveResult[] getCallVariants(GroovyPsiElement place) { final PsiElement parent = place.getParent(); GroovyResolveResult[] variants = GroovyResolveResult.EMPTY_ARRAY; if (parent instanceof GrCallExpression) { - variants = ((GrCallExpression) parent).getMethodVariants(place instanceof GrExpression ? (GrExpression)place : null); + variants = ((GrCallExpression) parent).getCallVariants(place instanceof GrExpression ? (GrExpression)place : null); } else if (parent instanceof GrConstructorInvocation) { final PsiClass clazz = ((GrConstructorInvocation) parent).getDelegatedClass(); if (clazz != null) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/DefaultGroovyVariableNameValidator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/DefaultGroovyVariableNameValidator.java index 3c7b0b212b0d..0dc04319c953 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/DefaultGroovyVariableNameValidator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/DefaultGroovyVariableNameValidator.java @@ -17,9 +17,15 @@ package org.jetbrains.plugins.groovy.refactoring; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; import com.intellij.psi.PsiNamedElement; import com.intellij.util.containers.hash.HashSet; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +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.statements.GrVariable; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; import org.jetbrains.plugins.groovy.lang.resolve.processors.PropertyResolverProcessor; @@ -28,18 +34,21 @@ import java.util.Collections; import java.util.Set; /** - * checks for only upper declared names * @author Maxim.Medvedev */ public class DefaultGroovyVariableNameValidator implements NameValidator { private final PsiElement myContext; private final Set mySet = new HashSet(); - public DefaultGroovyVariableNameValidator(PsiElement context) { + public DefaultGroovyVariableNameValidator(GroovyPsiElement context) { this(context, Collections.emptyList()); } - public DefaultGroovyVariableNameValidator(PsiElement context, Collection restrictedNames) { + public DefaultGroovyVariableNameValidator(GroovyPsiElement context, Collection restrictedNames) { + this(context, restrictedNames, true); + } + + public DefaultGroovyVariableNameValidator(GroovyPsiElement context, Collection restrictedNames, boolean includeFields) { myContext = context; mySet.addAll(restrictedNames); PropertyResolverProcessor processor = new PropertyResolverProcessor(null, myContext); @@ -47,10 +56,23 @@ public class DefaultGroovyVariableNameValidator implements NameValidator { final GroovyResolveResult[] results = processor.getCandidates(); for (GroovyResolveResult result : results) { final PsiElement element = result.getElement(); - if (element instanceof PsiNamedElement) { + if (element instanceof PsiNamedElement && (includeFields || !(element instanceof PsiField))) { mySet.add(((PsiNamedElement)element).getName()); } } + + context.accept(new GroovyRecursiveElementVisitor(){ + @Override + public void visitVariable(GrVariable variable) { + mySet.add(variable.getName()); + } + + @Override + public void visitClosure(GrClosableBlock closure) {} + + @Override + public void visitTypeDefinition(GrTypeDefinition typeDefinition) {} + }); } public String validateName(String name, boolean increaseNumber) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionProvider.java index 79d2b7cc642c..0c69566ba662 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionProvider.java @@ -23,6 +23,7 @@ import com.intellij.psi.codeStyle.SuggestedNameInfo; import com.intellij.psi.statistics.JavaStatisticsManager; import com.intellij.refactoring.rename.NameSuggestionProvider; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import java.util.Arrays; @@ -36,11 +37,11 @@ public class GroovyNameSuggestionProvider implements NameSuggestionProvider { @Override public SuggestedNameInfo getSuggestedNames(final PsiElement element, @Nullable PsiElement nameSuggestionContext, Set result) { if (nameSuggestionContext == null) nameSuggestionContext = element; - if (element instanceof GrVariable) { + if (element instanceof GrVariable && nameSuggestionContext instanceof GroovyPsiElement) { final PsiType type = ((GrVariable)element).getTypeGroovy(); if (type != null) { - final String[] names = - GroovyNameSuggestionUtil.suggestVariableNameByType(type, new DefaultGroovyVariableNameValidator(nameSuggestionContext)); + final String[] names = GroovyNameSuggestionUtil + .suggestVariableNameByType(type, new DefaultGroovyVariableNameValidator((GroovyPsiElement)nameSuggestionContext)); result.addAll(Arrays.asList(names)); return new SuggestedNameInfo(names) { @Override diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringBundle.properties index 0e947a79f6eb..4a9e38fa2bdc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringBundle.properties @@ -121,4 +121,5 @@ changing.signature.of.0=Changing signature of {0} refactored.method.will.cover.closure.property=Refactored method will override closure property ''{0}'' in {1} changeSignature.not.throwable.type=Wrong type: ''{0}'' for exception, should extend java.lang.Throwable changeSignature.wrong.type.for.exception=Wrong type: ''{0}'' for exception -changeSignature.no.type.for.exception=Specify a type for exception \ No newline at end of file +changeSignature.no.type.for.exception=Specify a type for exception +no.occurences.found=No occurences found \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeInfoImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeInfoImpl.java index a7ab92d8f41a..2508abbbb7df 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeInfoImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeInfoImpl.java @@ -34,7 +34,7 @@ import java.util.List; /** * @author Maxim.Medvedev */ -class GrChangeInfoImpl implements JavaChangeInfo { +public class GrChangeInfoImpl implements JavaChangeInfo { GrMethod method; final String newName; @Nullable final CanonicalTypes.Type returnType; @@ -61,7 +61,7 @@ class GrChangeInfoImpl implements JavaChangeInfo { private String[] myOldParameterTypes; public GrChangeInfoImpl(GrMethod method, - String visibilityModifier, + @Nullable String visibilityModifier, @Nullable CanonicalTypes.Type returnType, String newName, List parameters, ThrownExceptionInfo[] exceptions, boolean generateDelegate) { @@ -77,7 +77,7 @@ class GrChangeInfoImpl implements JavaChangeInfo { myIsNameChanged = true; } - myIsVisibilityChanged = !method.hasModifierProperty(visibilityModifier); + myIsVisibilityChanged = visibilityModifier != null && !method.hasModifierProperty(visibilityModifier); if (!method.isConstructor()) { PsiType oldReturnType = null; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.java index 356be9639c63..e0652277fa30 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.java @@ -407,4 +407,8 @@ public class GrChangeSignatureDialog extends RefactoringDialog { return true; //Groovy accepts methods and parameters without explicit type } } + + public GrParameterTableModel getParameterModel() { + return myParameterModel; + } } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodCallUsageInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodCallUsageInfo.java index d5496e22307e..e00a97424b9c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodCallUsageInfo.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodCallUsageInfo.java @@ -17,7 +17,6 @@ package org.jetbrains.plugins.groovy.refactoring.changeSignature; import com.intellij.psi.*; import com.intellij.psi.impl.PsiSubstitutorImpl; -import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.MethodSignature; import com.intellij.psi.util.MethodSignatureUtil; @@ -87,7 +86,7 @@ public class GrMethodCallUsageInfo extends UsageInfo implements PossiblyIncorrec } else { myMapToArguments = - GrClosureSignatureUtil.mapParametersToArguments(signature, list, GlobalSearchScope.allScope(getProject())); + GrClosureSignatureUtil.mapParametersToArguments(signature, list); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterTableModel.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterTableModel.java index 81a4c9d08865..7a8fbfbdacdf 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterTableModel.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterTableModel.java @@ -50,8 +50,12 @@ public class GrParameterTableModel extends AbstractTableModel implements RowEdit } public void addRow() { + addRow(new GrTableParameterInfo(myProject, myMethod)); + } + + public void addRow(GrTableParameterInfo info) { final int row = infos.size(); - infos.add(new GrTableParameterInfo(myProject, myMethod)); + infos.add(info); fireTableRowsInserted(row, row); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrTableParameterInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrTableParameterInfo.java index ff5d2fe96b43..b9834cf3cd9d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrTableParameterInfo.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrTableParameterInfo.java @@ -65,6 +65,19 @@ public class GrTableParameterInfo { myDefaultInitializer = new GroovyCodeFragment(project, ""); } + public GrTableParameterInfo(Project project, + PsiElement context, + String name, + String type, + String defaultValue, + String defaultInitializer) { + this.myPosition = -1; + myName = new GroovyCodeFragment(project, name); + myDefaultValue = new GroovyCodeFragment(project, defaultValue); + myType = JavaPsiFacade.getElementFactory(project).createTypeCodeFragment(type, context, true, true); + myDefaultInitializer = new GroovyCodeFragment(project, defaultInitializer); + } + public GroovyCodeFragment getNameFragment() { return myName; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduceVariable/GroovyIntroduceVariableBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduceVariable/GroovyIntroduceVariableBase.java index 4b44eb03a117..ff90f6e44af1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduceVariable/GroovyIntroduceVariableBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduceVariable/GroovyIntroduceVariableBase.java @@ -38,6 +38,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlo import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; 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.GrStringInjection; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; @@ -90,8 +91,9 @@ public abstract class GroovyIntroduceVariableBase implements RefactoringActionHa private boolean invokeImpl(final Project project, final GrExpression selectedExpr, final Editor editor) { - if (selectedExpr == null) { - String message = RefactoringBundle.getCannotRefactorMessage(GroovyRefactoringBundle.message("selected.block.should.represent.an.expression")); + if (selectedExpr == null || (selectedExpr instanceof GrClosableBlock && selectedExpr.getParent() instanceof GrStringInjection)) { + String message = + RefactoringBundle.getCannotRefactorMessage(GroovyRefactoringBundle.message("selected.block.should.represent.an.expression")); showErrorMessage(project, editor, message); return false; } @@ -145,6 +147,12 @@ public abstract class GroovyIntroduceVariableBase implements RefactoringActionHa // Find occurrences final PsiElement[] occurrences = GroovyRefactoringUtil.getExpressionOccurrences(GroovyRefactoringUtil.getUnparenthesizedExpr(selectedExpr), tempContainer); + if (occurrences == null || occurrences.length == 0) { + String message = RefactoringBundle.getCannotRefactorMessage(GroovyRefactoringBundle.message("no.occurences.found")); + showErrorMessage(project, editor, message); + return false; + } + // Getting settings Validator validator = new GroovyVariableValidator(this, project, selectedExpr, occurrences, tempContainer); GroovyIntroduceVariableDialog dialog = getDialog(project, editor, selectedExpr, type, occurrences, false, validator); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/PropertyRenameHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/PropertyRenameHandler.java index 2737cdf8d74e..238d5dae2ffa 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/PropertyRenameHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/PropertyRenameHandler.java @@ -78,7 +78,7 @@ public class PropertyRenameHandler implements RenameHandler { private void doRename(String newName, boolean searchInComments) { final RenameRefactoring rename = new JavaRenameRefactoringImpl(myProperty.getProject(), myProperty, newName, searchInComments, false); - + rename.setPreviewUsages(isPreviewUsages()); final PsiMethod setter = myProperty.getSetter(); if (setter != null && !(setter instanceof GrAccessorMethod)) { final String setterName = PropertyUtil.suggestSetterName(newName); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/GrCompletionTestWithLibrary.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/GrCompletionTestWithLibrary.groovy index 967dcc8d2b23..5bffbbdfa5c9 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/GrCompletionTestWithLibrary.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/GrCompletionTestWithLibrary.groovy @@ -47,15 +47,26 @@ class GrCompletionTestWithLibrary extends GroovyCompletionTestBase { return GROOVY_17_PROJECT_DESCRIPTOR; } - @Override protected String getBasePath() { - return TestUtils.getTestDataPath() + "groovy/completionWithLibrary/"; + return TestUtils.getTestDataPath() + "groovy/completion/"; } - public void testCategoryMethod() {doBasicTest()} public void testCategoryProperty() {doBasicTest()} public void testMultipleCategories() {doBasicTest()} + public void testArrayLikeAccessForList() throws Throwable {doBasicTest(); } + public void testArrayLikeAccessForMap() throws Throwable {doBasicTest();} + + public void testEachMethodForList() throws Throwable {doBasicTest();} + public void testEachMethodForMapWithKeyValue() throws Throwable {doBasicTest();} + public void testEachMethodForMapWithEntry() throws Throwable {doBasicTest();} + public void testWithMethod() throws Throwable {doBasicTest();} + public void testInjectMethodForCollection() throws Throwable {doBasicTest();} + public void testInjectMethodForArray() throws Throwable {doBasicTest();} + public void testInjectMethodForMap() throws Throwable {doBasicTest();} + public void testClosureDefaultParameterInEachMethod() throws Throwable {doBasicTest();} + public void testEachMethodForRanges() throws Throwable {doBasicTest();} + public void testEachMethodForEnumRanges() throws Throwable {doBasicTest();} } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTest.java index cbcb20662b39..6f925ecd5edb 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTest.java @@ -64,54 +64,6 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase { doSmartTest(); } - public void testEachMethodForList() throws Throwable { - doBasicTest(); - } - - public void testEachMethodForMapWithKeyValue() throws Throwable { - doBasicTest(); - } - - public void testEachMethodForMapWithEntry() throws Throwable { - doBasicTest(); - } - - public void testWithMethod() throws Throwable { - doBasicTest(); - } - - public void testInjectMethodForCollection() throws Throwable { - doBasicTest(); - } - - public void testInjectMethodForArray() throws Throwable { - doBasicTest(); - } - - public void testInjectMethodForMap() throws Throwable { - doBasicTest(); - } - - public void testClosureDefaultParameterInEachMethod() throws Throwable { - doBasicTest(); - } - - public void testArrayLikeAccessForList() throws Throwable { - doBasicTest(); - } - - public void testArrayLikeAccessForMap() throws Throwable { - doBasicTest(); - } - - public void testEachMethodForRanges() throws Throwable { - doBasicTest(); - } - - public void testEachMethodForEnumRanges() throws Throwable { - doBasicTest(); - } - public void testNamedParametersForApplication() throws Throwable { doVariantableTest("abx", "aby"); } @@ -278,4 +230,7 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase { "}"); doSmartTest(); } -} + + public void testIntCompletionInPlusMethod() {doBasicTest();} + public void testIntCompletionInGenericParameter() {doBasicTest();} +} \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTestBase.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTestBase.java index 467fdaf3cde7..524a00ba742c 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTestBase.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTestBase.java @@ -31,7 +31,7 @@ abstract public class GroovyCompletionTestBase extends LightCodeInsightFixtureTe myFixture.checkResultByFile(getTestName(false) + "_after.groovy", true); } - protected void doBasicTest() throws Exception { + protected void doBasicTest() { myFixture.testCompletion(getTestName(false) + ".groovy", getTestName(false) + "_after.groovy"); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java index 466ae8733a0e..c89ce67f8bce 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java @@ -61,6 +61,7 @@ public void testArrayType1() throws Throwable { doTest(); } public void testVararg1() throws Throwable { doTest(); } public void testInaccessibleConstructor() throws Throwable { doTest(); } public void testSynchronizedProperty() throws Throwable { doTest(); } + public void testVarargs() throws Throwable { doTest(); } public void testCheckedExceptionInConstructorDelegate() throws Throwable { myFixture.addClass("package foo;" + diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/CreateParameterForFieldTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/CreateParameterForFieldTest.java new file mode 100644 index 000000000000..9301d51e333e --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/CreateParameterForFieldTest.java @@ -0,0 +1,35 @@ +/* + * 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 org.jetbrains.plugins.groovy.intentions; + +import org.jetbrains.plugins.groovy.util.TestUtils; + +/** + * @author Maxim.Medvedev + */ +public class CreateParameterForFieldTest extends GrIntentionTestCase { + @Override + protected String getBasePath() { + return TestUtils.getTestDataPath() + "intentions/createParameterForField/"; + } + + public void testFromConstructor() {doTest();} + public void testFromField() {doTest();} + + protected void doTest() { + doTest("Add constructor parameter for field", true); + } +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ParameterToMapEntryTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ParameterToMapEntryTest.java index 8fa073f22a6f..69e7adb07d4d 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ParameterToMapEntryTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ParameterToMapEntryTest.java @@ -109,7 +109,7 @@ public class ParameterToMapEntryTest extends GroovyFormatterTestCase { Assert.assertTrue(condition.satisfiedBy(element)); // Launch it! - intention.processIntention(element); + intention.processIntention(element, myFixture.getProject(), myFixture.getEditor()); PostprocessReformattingAspect.getInstance(getProject()).doPostponedFormatting(); final String result = file.getText(); //System.out.println(result); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy index f5d5fb58dfd0..57b08e4f9ec9 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy @@ -92,6 +92,9 @@ Foo f = [name: 'aaa', foo: { println 'hi' }, anotherProperty: 42 ] private PsiFile configureScript(String text) { return myFixture.configureByText("a.groovy", text) } + private PsiFile configureGppScript(String text) { + return myFixture.configureByText("a.gpp", text) + } public void testDeclaredVariableTypeIsMoreImportantThanTheInitializerOne() throws Exception { configureScript(""" @@ -345,12 +348,15 @@ r.apply { it.intVi } {} assertSameElements myFixture.getLookupElementStrings(), "intValue" } - public void testGotoDeclarationFromMapLiterals() throws Exception { + public void testGotoSuperMethodFromMapLiterals() throws Exception { PsiClass point = myFixture.addClass(""" class Point { + Point() {} + Point(int y) {} int y; void setX(int x) {} void move(int x, int y) {} + void move(int y) {} }""") configureScript "Point p = [y:2]" @@ -361,6 +367,34 @@ class Point { configureScript "Point p = [move: { x, y -> z }]" assertEquals point.findMethodsByName("move", false)[0], resolveReference() + + configureScript "Point p = [move: ]" + def resolveResults = multiResolveReference() + assertSameElements resolveResults.collect { it.element }, point.findMethodsByName("move", false) + } + + ResolveResult[] multiResolveReference() { + return ((PsiPolyVariantReference) myFixture.file.findReferenceAt(myFixture.editor.caretModel.offset)).multiResolve(true) + } + + public void testGotoSuperConstructorFromMapLiterals() throws Exception { + PsiClass point = myFixture.addClass(""" +class Point { + Point() {} + Point(int y) {} +}""") + + configureGppScript "Point p = [super: 2]" + assertEquals point.constructors[1], resolveReference() + + configureGppScript "Point p = [super: [2]]" + assertEquals point.constructors[1], resolveReference() + + configureGppScript "Point p = ['super': []]" + assertEquals point.constructors[0], resolveReference() + + configureGppScript "Point p = ['super': 'a']" + assertEquals 2, multiResolveReference().size() } public void testResolveTraitMethod() throws Exception { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/LiteralConstructorUsagesTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/LiteralConstructorUsagesTest.groovy index 00432a8cb4d0..4faa4cb1b0b3 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/LiteralConstructorUsagesTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/LiteralConstructorUsagesTest.groovy @@ -48,6 +48,26 @@ class LiteralConstructorUsagesTest extends LightCodeInsightFixtureTestCase { assertOneElement(ReferencesSearch.search(foo.constructors[0]).findAll()) } + public void testMap_AsCast() throws Exception { + def foo = myFixture.addClass("""class Foo { + Foo() {} + } +}""") + myFixture.addFileToProject "a.groovy", "def x = [:] as Foo" + assertOneElement(ReferencesSearch.search(foo.constructors[0]).findAll()) + } + + public void testMapSuper_AsCast() throws Exception { + def foo = myFixture.addClass("""class Foo { + Foo(int a) {} + } +}""") + myFixture.addFileToProject "a.gpp", "def x = ['super':[2]] as Foo" + myFixture.addFileToProject "c.gpp", "def x = [super:2] as Foo" + + assertEquals(2, ReferencesSearch.search(foo.constructors[0]).findAll().size()) + } + public void testList_GppMethodCall() throws Exception { //------------------------declarations def foo = myFixture.addClass(""" @@ -100,4 +120,44 @@ class LiteralConstructorUsagesTest extends LightCodeInsightFixtureTestCase { assertEquals(3, ReferencesSearch.search(foo.constructors[0]).findAll().size()) } + public void testMap_GppOverloads() throws Exception { + def foo = myFixture.addClass(""" + class Foo { + Foo() {} + Foo(int a) {} + } + """) + + myFixture.addClass(""" + class Bar { + static void foo(Foo f1, Foo f2) {} + } + """) + myFixture.addFileToProject "a.gpp", "Bar.foo([:], [super:2])" + assertEquals(1, ReferencesSearch.search(foo.constructors[0]).findAll().size()) + assertEquals(1, ReferencesSearch.search(foo.constructors[1]).findAll().size()) + } + + public void testGppCallVarargs() throws Exception { + def foo = myFixture.addClass(""" + class Foo { + Foo() {} + Foo(int a) {} + } + """) + + myFixture.addClass(""" + class Bar { + static void foo(Foo f1, Foo f2) {} + static void doo(int a, Foo f1, Foo f2) {} + } + """) + myFixture.addFileToProject "a.gpp", """ + Bar.foo([:], [super:2]) + Bar.doo 3, [:], [super:2] + """ + assertEquals(2, ReferencesSearch.search(foo.constructors[0]).findAll().size()) + assertEquals(2, ReferencesSearch.search(foo.constructors[1]).findAll().size()) + } + } 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 65d2d74e5b97..bfe4adfa098a 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 @@ -117,4 +117,9 @@ public class TypeInferenceTest extends GroovyResolveTestCase { final GrReferenceExpression ref = (GrReferenceExpression)configureByFile("genericWildcard/A.groovy").getElement(); assertEquals("A", ref.getType().getCanonicalText()); } + + public void testArrayLikeAccessWithIntSequence() { + final GrReferenceExpression ref = (GrReferenceExpression)configureByFile("arrayLikeAccessWithIntSequence/A.groovy").getElement(); + assertEquals("java.util.List", ref.getType().getCanonicalText()); + } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.java index 66a6b287c437..f4d84488722e 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureTest.java @@ -216,20 +216,24 @@ public class ChangeSignatureTest extends ChangeSignatureTestCase { doTest(new SimpleInfo[]{new SimpleInfo("l", 1, null, null, "Map[]"), new SimpleInfo(0)}); } + public void testConstructorCall() { + doTest(new SimpleInfo[]{new SimpleInfo(0), new SimpleInfo("a", -1, "1", null, PsiType.INT)}); + } + private PsiType createType(String typeText) { return JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName(typeText, GlobalSearchScope.allScope(getProject())); } - private void doTest(SimpleInfo[] parameterInfos) throws Exception { + private void doTest(SimpleInfo[] parameterInfos) { doTest("public", null, null, parameterInfos, new ThrownExceptionInfo[0], false); } - private void doTest(String newReturnType, SimpleInfo[] parameterInfos) throws Exception { + private void doTest(String newReturnType, SimpleInfo[] parameterInfos) { doTest("public", null, newReturnType, parameterInfos, new ThrownExceptionInfo[0], false); } - private void doTest(String newReturnType, SimpleInfo[] parameterInfos, final boolean generateDelegate) throws Exception { + private void doTest(String newReturnType, SimpleInfo[] parameterInfos, final boolean generateDelegate) { doTest("public", null, newReturnType, parameterInfos, new ThrownExceptionInfo[0], generateDelegate); } @@ -238,7 +242,7 @@ public class ChangeSignatureTest extends ChangeSignatureTestCase { String newReturnType, SimpleInfo[] parameterInfo, ThrownExceptionInfo[] exceptionInfo, - final boolean generateDelegate) throws Exception { + final boolean generateDelegate) { final File javaSrc = new File(getTestDataPath() + "/" + getTestName(false) + ".java"); if (javaSrc.exists()) { myFixture.copyFileToProject(getTestName(false) + ".java"); diff --git a/plugins/groovy/testdata/groovy/completionWithLibrary/CategoryMethod.groovy b/plugins/groovy/testdata/groovy/completion/CategoryMethod.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completionWithLibrary/CategoryMethod.groovy rename to plugins/groovy/testdata/groovy/completion/CategoryMethod.groovy diff --git a/plugins/groovy/testdata/groovy/completionWithLibrary/CategoryMethod_after.groovy b/plugins/groovy/testdata/groovy/completion/CategoryMethod_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completionWithLibrary/CategoryMethod_after.groovy rename to plugins/groovy/testdata/groovy/completion/CategoryMethod_after.groovy diff --git a/plugins/groovy/testdata/groovy/completionWithLibrary/CategoryProperty.groovy b/plugins/groovy/testdata/groovy/completion/CategoryProperty.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completionWithLibrary/CategoryProperty.groovy rename to plugins/groovy/testdata/groovy/completion/CategoryProperty.groovy diff --git a/plugins/groovy/testdata/groovy/completionWithLibrary/CategoryProperty_after.groovy b/plugins/groovy/testdata/groovy/completion/CategoryProperty_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completionWithLibrary/CategoryProperty_after.groovy rename to plugins/groovy/testdata/groovy/completion/CategoryProperty_after.groovy diff --git a/plugins/groovy/testdata/groovy/completion/IntCompletionInGenericParameter.groovy b/plugins/groovy/testdata/groovy/completion/IntCompletionInGenericParameter.groovy new file mode 100644 index 000000000000..bcc8971c1f4c --- /dev/null +++ b/plugins/groovy/testdata/groovy/completion/IntCompletionInGenericParameter.groovy @@ -0,0 +1,2 @@ +List list +list.get(0).intV \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/completion/IntCompletionInGenericParameter_after.groovy b/plugins/groovy/testdata/groovy/completion/IntCompletionInGenericParameter_after.groovy new file mode 100644 index 000000000000..eb07dd8424d9 --- /dev/null +++ b/plugins/groovy/testdata/groovy/completion/IntCompletionInGenericParameter_after.groovy @@ -0,0 +1,2 @@ +List list +list.get(0).intValue() \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/completion/IntCompletionInPlusMethod.groovy b/plugins/groovy/testdata/groovy/completion/IntCompletionInPlusMethod.groovy new file mode 100644 index 000000000000..e057df79f2e6 --- /dev/null +++ b/plugins/groovy/testdata/groovy/completion/IntCompletionInPlusMethod.groovy @@ -0,0 +1,5 @@ +class X { + int plus(X x) {} +} + +(new X()+new X()).intV \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/completion/IntCompletionInPlusMethod_after.groovy b/plugins/groovy/testdata/groovy/completion/IntCompletionInPlusMethod_after.groovy new file mode 100644 index 000000000000..d068bce94894 --- /dev/null +++ b/plugins/groovy/testdata/groovy/completion/IntCompletionInPlusMethod_after.groovy @@ -0,0 +1,5 @@ +class X { + int plus(X x) {} +} + +(new X()+new X()).intValue() \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/completionWithLibrary/MultipleCategories.groovy b/plugins/groovy/testdata/groovy/completion/MultipleCategories.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completionWithLibrary/MultipleCategories.groovy rename to plugins/groovy/testdata/groovy/completion/MultipleCategories.groovy diff --git a/plugins/groovy/testdata/groovy/completionWithLibrary/MultipleCategories_after.groovy b/plugins/groovy/testdata/groovy/completion/MultipleCategories_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completionWithLibrary/MultipleCategories_after.groovy rename to plugins/groovy/testdata/groovy/completion/MultipleCategories_after.groovy diff --git a/plugins/groovy/testdata/groovy/stubGenerator/grvy1376.test b/plugins/groovy/testdata/groovy/stubGenerator/grvy1376.test index e74375fc8805..c7b8c01f988c 100644 --- a/plugins/groovy/testdata/groovy/stubGenerator/grvy1376.test +++ b/plugins/groovy/testdata/groovy/stubGenerator/grvy1376.test @@ -5,7 +5,7 @@ class PerformanceLine extends HashMap { } ----- public class PerformanceLine extends java.util.HashMap implements groovy.lang.GroovyObject { - public PerformanceLine(java.lang.String data) { + public PerformanceLine(java.lang.String... data) { super((java.util.Map)null); } diff --git a/plugins/groovy/testdata/groovy/stubGenerator/varargs.test b/plugins/groovy/testdata/groovy/stubGenerator/varargs.test new file mode 100644 index 000000000000..bbd2895ee32c --- /dev/null +++ b/plugins/groovy/testdata/groovy/stubGenerator/varargs.test @@ -0,0 +1,67 @@ +class Foo { + def Foo(String... s) {} + def foo(String... s) {} +} + +class Derived { + def Derived(String... s) { + super(s) + } +} +----- +public class Foo implements groovy.lang.GroovyObject { + public Foo(java.lang.String... s) { + + } + + public java.lang.Object foo(java.lang.String... s) { + return null; + } + + public groovy.lang.MetaClass getMetaClass() { + return null; + } + + public void setMetaClass(groovy.lang.MetaClass mc) { + return ; + } + + public java.lang.Object invokeMethod(java.lang.String name, java.lang.Object args) { + return null; + } + + public java.lang.Object getProperty(java.lang.String propertyName) { + return null; + } + + public void setProperty(java.lang.String propertyName, java.lang.Object newValue) { + return ; + } +} +--- +public class Derived implements groovy.lang.GroovyObject { + public Derived(java.lang.String... s) { + super(); + } + + public groovy.lang.MetaClass getMetaClass() { + return null; + } + + public void setMetaClass(groovy.lang.MetaClass mc) { + return ; + } + + public java.lang.Object invokeMethod(java.lang.String name, java.lang.Object args) { + return null; + } + + public java.lang.Object getProperty(java.lang.String propertyName) { + return null; + } + + public void setProperty(java.lang.String propertyName, java.lang.Object newValue) { + return ; + } +} +--- \ No newline at end of file diff --git a/plugins/groovy/testdata/intentions/createParameterForField/FromConstructor.groovy b/plugins/groovy/testdata/intentions/createParameterForField/FromConstructor.groovy new file mode 100644 index 000000000000..873e4424819c --- /dev/null +++ b/plugins/groovy/testdata/intentions/createParameterForField/FromConstructor.groovy @@ -0,0 +1,6 @@ +class Foo { + def foo + def Foo() { + + } +} \ No newline at end of file diff --git a/plugins/groovy/testdata/intentions/createParameterForField/FromConstructor_after.groovy b/plugins/groovy/testdata/intentions/createParameterForField/FromConstructor_after.groovy new file mode 100644 index 000000000000..6f70aff9e9c8 --- /dev/null +++ b/plugins/groovy/testdata/intentions/createParameterForField/FromConstructor_after.groovy @@ -0,0 +1,7 @@ +class Foo { + def foo + def Foo(def foo) { + + this.foo = foo + } +} \ No newline at end of file diff --git a/plugins/groovy/testdata/intentions/createParameterForField/FromField.groovy b/plugins/groovy/testdata/intentions/createParameterForField/FromField.groovy new file mode 100644 index 000000000000..5d3848620d82 --- /dev/null +++ b/plugins/groovy/testdata/intentions/createParameterForField/FromField.groovy @@ -0,0 +1,7 @@ +class Foo { + def foo + + def Foo() { + + } +} \ No newline at end of file diff --git a/plugins/groovy/testdata/intentions/createParameterForField/FromField_after.groovy b/plugins/groovy/testdata/intentions/createParameterForField/FromField_after.groovy new file mode 100644 index 000000000000..c348f9751f6e --- /dev/null +++ b/plugins/groovy/testdata/intentions/createParameterForField/FromField_after.groovy @@ -0,0 +1,8 @@ +class Foo { + def foo + + def Foo(def foo) { + + this.foo = foo + } +} \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor1.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor1.test index 10667feddba0..17b392c66fb5 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor1.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor1.test @@ -32,7 +32,8 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - PsiElement(this)('this') + 'this' reference expression + PsiElement(this)('this') PsiWhiteSpace(' ') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor2.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor2.test index 7d69532a781f..0dccf897942e 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor2.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor2.test @@ -34,7 +34,8 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - PsiElement(super)('super') + 'super' reference expression + PsiElement(super)('super') Arguments PsiElement(()('(') PsiElement())(')') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor3.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor3.test index 543a792f9ebd..3a7d3dfa2214 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor3.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor3.test @@ -32,7 +32,8 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - PsiElement(this)('this') + 'this' reference expression + PsiElement(this)('this') Arguments PsiElement(()('(') PsiElement())(')') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor5.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor5.test index 78698c6f5561..72e3ca82f323 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor5.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor5.test @@ -39,7 +39,8 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - PsiElement(this)('this') + 'this' reference expression + PsiElement(this)('this') PsiWhiteSpace(' ') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor6.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor6.test index 7432dfea3d65..c711c17da9ca 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor6.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor6.test @@ -33,7 +33,8 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - PsiElement(this)('this') + 'this' reference expression + PsiElement(this)('this') Arguments PsiElement(()('(') PsiElement())(')') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor8.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor8.test index fe23f5bc045a..8ecd734e6fb3 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor8.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor8.test @@ -39,7 +39,8 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - PsiElement(this)('this') + 'this' reference expression + PsiElement(this)('this') PsiWhiteSpace(' ') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor9.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor9.test index 8cd7b5834167..eea22f6ef80a 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor9.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor9.test @@ -43,7 +43,8 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - PsiElement(this)('this') + 'this' reference expression + PsiElement(this)('this') PsiWhiteSpace(' ') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/interfaces/errors/interfaceerr1.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/interfaces/errors/interfaceerr1.test index da49e3c00fc1..f551a5148732 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/interfaces/errors/interfaceerr1.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/interfaces/errors/interfaceerr1.test @@ -52,7 +52,8 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - PsiElement(this)('this') + 'this' reference expression + PsiElement(this)('this') Arguments PsiElement(()('(') PsiElement())(')') diff --git a/plugins/groovy/testdata/refactoring/changeSignature/ConstructorCall.groovy b/plugins/groovy/testdata/refactoring/changeSignature/ConstructorCall.groovy new file mode 100644 index 000000000000..d90bc5a6c2ab --- /dev/null +++ b/plugins/groovy/testdata/refactoring/changeSignature/ConstructorCall.groovy @@ -0,0 +1,15 @@ +class Foo { + def Foo() { + this("a") + } + + def Foo(String s) { + + } +} + +class Bar extends Foo { + def Bar() { + super("d") + } +} \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/changeSignature/ConstructorCall_after.groovy b/plugins/groovy/testdata/refactoring/changeSignature/ConstructorCall_after.groovy new file mode 100644 index 000000000000..504fdcda027e --- /dev/null +++ b/plugins/groovy/testdata/refactoring/changeSignature/ConstructorCall_after.groovy @@ -0,0 +1,15 @@ +class Foo { + def Foo() { + this("a", 1) + } + + def Foo(String s, int a) { + + } +} + +class Bar extends Foo { + def Bar() { + super("d", 1) + } +} \ No newline at end of file diff --git a/plugins/groovy/testdata/resolve/inference/arrayLikeAccessWithIntSequence/A.groovy b/plugins/groovy/testdata/resolve/inference/arrayLikeAccessWithIntSequence/A.groovy new file mode 100644 index 000000000000..d176af95fc38 --- /dev/null +++ b/plugins/groovy/testdata/resolve/inference/arrayLikeAccessWithIntSequence/A.groovy @@ -0,0 +1,4 @@ +def foo = [1, 2, 5] +def list = foo[1, 2] + +print list \ No newline at end of file diff --git a/plugins/junit/src/com/intellij/execution/junit/TestObject.java b/plugins/junit/src/com/intellij/execution/junit/TestObject.java index dceaf3e1518d..a9232d65affa 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestObject.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestObject.java @@ -260,7 +260,7 @@ public abstract class TestObject implements JavaCommandLine { ext.handleStartProcess(myConfiguration, handler); } final TestProxy unboundOutputRoot = new TestProxy(new RootTestInfo()); - final JUnitConsoleProperties consoleProperties = new JUnitConsoleProperties(myConfiguration); + final JUnitConsoleProperties consoleProperties = new JUnitConsoleProperties(myConfiguration, executor); final JUnitTreeConsoleView consoleView = new JUnitTreeConsoleView(consoleProperties, getRunnerSettings(), getConfigurationSettings(), unboundOutputRoot); consoleView.initUI(); consoleView.attachToProcess(handler); diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/properties/JUnitConsoleProperties.java b/plugins/junit/src/com/intellij/execution/junit2/ui/properties/JUnitConsoleProperties.java index c5793c32088d..5698ddcf7aea 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/ui/properties/JUnitConsoleProperties.java +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/properties/JUnitConsoleProperties.java @@ -16,6 +16,7 @@ package com.intellij.execution.junit2.ui.properties; +import com.intellij.execution.Executor; import com.intellij.execution.junit.JUnitConfiguration; import com.intellij.execution.testframework.JavaAwareTestConsoleProperties; import com.intellij.ide.util.PropertiesComponent; @@ -29,12 +30,12 @@ public class JUnitConsoleProperties extends JavaAwareTestConsoleProperties { private final JUnitConfiguration myConfiguration; - public JUnitConsoleProperties(@NotNull JUnitConfiguration configuration) { - this(configuration, new Storage.PropertiesComponentStorage(GROUP_NAME, PropertiesComponent.getInstance())); + public JUnitConsoleProperties(@NotNull JUnitConfiguration configuration, Executor executor) { + this(configuration, new Storage.PropertiesComponentStorage(GROUP_NAME, PropertiesComponent.getInstance()), executor); } - public JUnitConsoleProperties(@NotNull JUnitConfiguration configuration, final Storage storage) { - super(storage, configuration.getProject()); + public JUnitConsoleProperties(@NotNull JUnitConfiguration configuration, final Storage storage, Executor executor) { + super(storage, configuration.getProject(), executor); myConfiguration = configuration; } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenTreeAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenTreeAction.java index 18a21ec70d08..a9a4c6d06a8b 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenTreeAction.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenTreeAction.java @@ -21,15 +21,17 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Shortcut; import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.project.DumbAware; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.utils.MavenDataKeys; +import org.jetbrains.idea.maven.utils.actions.MavenActionUtil; import javax.swing.*; /** * @author Konstantin Bulenkov */ -public abstract class MavenTreeAction extends AnAction { +public abstract class MavenTreeAction extends AnAction implements DumbAware { private boolean updated = false; @Override @@ -49,6 +51,8 @@ public abstract class MavenTreeAction extends AnAction { } updated = true; } + e.getPresentation().setEnabled(MavenActionUtil.hasProject(e.getDataContext()) + && MavenActionUtil.getProjectsManager(e.getDataContext()).isMavenizedProject()); } @Nullable diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml index deba1a0b35b3..b436d612e248 100644 --- a/plugins/maven/src/main/resources/META-INF/plugin.xml +++ b/plugins/maven/src/main/resources/META-INF/plugin.xml @@ -157,12 +157,12 @@ diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java index d9669df9ee23..7424fa25ae72 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java +++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java @@ -127,7 +127,8 @@ public class TestNGRunnableState extends JavaCommandLineState { throw e; } final TreeRootNode unboundOutputRoot = new TreeRootNode(); - final TestNGConsoleView console = new TestNGConsoleView(config, runnerSettings, myConfigurationPerRunnerSettings, unboundOutputRoot); + final TestNGConsoleView console = new TestNGConsoleView(config, runnerSettings, myConfigurationPerRunnerSettings, unboundOutputRoot, + executor); console.initUI(); unboundOutputRoot.setPrinter(console.getPrinter()); for (RunConfigurationExtension ext : Extensions.getExtensions(RunConfigurationExtension.EP_NAME)) { diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestNGConsoleProperties.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestNGConsoleProperties.java index ed87ce72230c..5ecc3b1e477f 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TestNGConsoleProperties.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestNGConsoleProperties.java @@ -15,6 +15,7 @@ */ package com.theoryinpractice.testng.model; +import com.intellij.execution.Executor; import com.intellij.execution.testframework.JavaAwareTestConsoleProperties; import com.intellij.ide.util.PropertiesComponent; import com.intellij.psi.search.GlobalSearchScope; @@ -26,9 +27,9 @@ public class TestNGConsoleProperties extends JavaAwareTestConsoleProperties { @NonNls private static final String PREFIX = "TestNGSupport."; private final TestNGConfiguration myConfiguration; - public TestNGConsoleProperties(TestNGConfiguration config) + public TestNGConsoleProperties(TestNGConfiguration config, Executor executor) { - super(new Storage.PropertiesComponentStorage(PREFIX, PropertiesComponent.getInstance()), config.getProject()); + super(new Storage.PropertiesComponentStorage(PREFIX, PropertiesComponent.getInstance()), config.getProject(), executor); myConfiguration = config; } diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java index 4d67bccc0add..2e628aca3bdd 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java @@ -22,9 +22,9 @@ */ package com.theoryinpractice.testng.ui; +import com.intellij.execution.Executor; import com.intellij.execution.configurations.ConfigurationPerRunnerSettings; import com.intellij.execution.configurations.RunnerSettings; -import com.intellij.execution.filters.HyperlinkInfo; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.testframework.Printable; import com.intellij.execution.testframework.Printer; @@ -32,9 +32,7 @@ import com.intellij.execution.testframework.TestTreeView; import com.intellij.execution.testframework.stacktrace.DiffHyperlink; import com.intellij.execution.testframework.ui.BaseTestsOutputConsoleView; import com.intellij.execution.testframework.ui.TestResultsPanel; -import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ConsoleViewContentType; -import com.intellij.openapi.application.ApplicationManager; import com.theoryinpractice.testng.configuration.TestNGConfiguration; import com.theoryinpractice.testng.model.TestNGConsoleProperties; import com.theoryinpractice.testng.model.TestProxy; @@ -42,7 +40,6 @@ import com.theoryinpractice.testng.model.TreeRootNode; import org.jetbrains.annotations.NonNls; import org.testng.remote.strprotocol.TestResultMessage; -import javax.swing.*; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import java.util.ArrayList; @@ -68,8 +65,9 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView { public TestNGConsoleView(TestNGConfiguration config, final RunnerSettings runnerSettings, final ConfigurationPerRunnerSettings configurationPerRunnerSettings, - final TreeRootNode unboundOutputRoot) { - super(new TestNGConsoleProperties(config), unboundOutputRoot); + final TreeRootNode unboundOutputRoot, + Executor executor) { + super(new TestNGConsoleProperties(config, executor), unboundOutputRoot); myConfiguration = config; myRunnerSettings = runnerSettings; myConfigurationPerRunnerSettings = configurationPerRunnerSettings; diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 9b3fcab5a73e..e0f068715d39 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -362,6 +362,9 @@ + + diff --git a/samples/comparingReferences/source/com/intellij/codeInspection/ComparingReferencesInspection.java b/samples/comparingReferences/source/com/intellij/codeInspection/ComparingReferencesInspection.java index 5532b0b6e44a..4c99465a2176 100644 --- a/samples/comparingReferences/source/com/intellij/codeInspection/ComparingReferencesInspection.java +++ b/samples/comparingReferences/source/com/intellij/codeInspection/ComparingReferencesInspection.java @@ -3,6 +3,7 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.daemon.GroupNames; 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.tree.IElementType; import com.intellij.ui.DocumentAdapter; @@ -78,7 +79,7 @@ public class ComparingReferencesInspection extends BaseJavaLocalInspectionTool { private ProblemDescriptor[] analyzeCode(PsiElement where, final InspectionManager manager) { if (where == null) return null; - final ArrayList[] problemList = new ArrayList[]{null}; + final Ref> problemList = new Ref>(); where.accept(new JavaRecursiveElementWalkingVisitor() { @Override public void visitMethod(PsiMethod method) {} @@ -96,18 +97,18 @@ public class ComparingReferencesInspection extends BaseJavaLocalInspectionTool { PsiType rType = rOperand.getType(); if (isCheckedType(lType) || isCheckedType(rType)) { - if (problemList[0] == null) problemList[0] = new ArrayList(); - problemList[0].add(manager.createProblemDescriptor(expression, DESCRIPTION_TEMPLATE, + if (problemList.get() == null) problemList.set(new ArrayList()); + problemList.get().add(manager.createProblemDescriptor(expression, DESCRIPTION_TEMPLATE, myQuickFix, - ProblemHighlightType.GENERIC_ERROR_OR_WARNING, onTheFly)); + ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); } } } }); - return problemList[0] == null + return problemList.get() == null ? null - : (ProblemDescriptor[])problemList[0].toArray(new ProblemDescriptor[problemList[0].size()]); + : problemList.get().toArray(new ProblemDescriptor[problemList.get().size()]); } private static boolean isNullLiteral(PsiExpression expr) { diff --git a/xml/impl/src/com/intellij/ide/browsers/firefox/FirefoxUtil.java b/xml/impl/src/com/intellij/ide/browsers/firefox/FirefoxUtil.java index 411c77b07b4b..9154de91ff5b 100644 --- a/xml/impl/src/com/intellij/ide/browsers/firefox/FirefoxUtil.java +++ b/xml/impl/src/com/intellij/ide/browsers/firefox/FirefoxUtil.java @@ -61,9 +61,8 @@ public class FirefoxUtil { FirefoxProfile profile = findProfileByNameOrDefault(settings.getProfile(), profiles); if (profile != null) { File profileDir = profile.getProfileDirectory(profilesFile); - File dir = new File(profileDir, "extensions"); - if (dir.isDirectory()) { - return dir; + if (profileDir.isDirectory()) { + return new File(profileDir, "extensions"); } } }