diff --git a/platform/lang-impl/src/com/intellij/codeInsight/codeFragment/CannotCreateCodeFragmentException.java b/platform/lang-impl/src/com/intellij/codeInsight/codeFragment/CannotCreateCodeFragmentException.java new file mode 100644 index 000000000000..706e71c3ccd8 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/codeFragment/CannotCreateCodeFragmentException.java @@ -0,0 +1,10 @@ +package com.intellij.codeInsight.codeFragment; + +/** +* @author oleg +*/ +public class CannotCreateCodeFragmentException extends RuntimeException { + public CannotCreateCodeFragmentException(final String reason) { + super(reason); + } + } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/codeFragment/CodeFragment.java b/platform/lang-impl/src/com/intellij/codeInsight/codeFragment/CodeFragment.java new file mode 100644 index 000000000000..3d394c8fed55 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/codeFragment/CodeFragment.java @@ -0,0 +1,30 @@ +package com.intellij.codeInsight.codeFragment; + +import java.util.Set; + +/** + * @author oleg + */ +public class CodeFragment { + private final Set inputVariables; + private final Set outputVariables; + private final boolean returnInstructonInside; + + public CodeFragment(final Set input, final Set output, final boolean returnInside) { + inputVariables = input; + outputVariables = output; + returnInstructonInside = returnInside; + } + + public Set getInputVariables() { + return inputVariables; + } + + public Set getOutputVariables() { + return outputVariables; + } + + public boolean isReturnInstructonInside() { + return returnInstructonInside; + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/codeFragment/CodeFragmentUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/codeFragment/CodeFragmentUtil.java new file mode 100644 index 000000000000..f6ac9466ef5f --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/codeFragment/CodeFragmentUtil.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.codeFragment; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +/** + * @author oleg + */ +public class CodeFragmentUtil { + public static Position getPosition(@NotNull final PsiElement element, final int startOffset, final int endOffset) { + final int offset = element.getTextOffset(); + if (offset < startOffset) { + return Position.BEFORE; + } + if (element.getTextOffset() < endOffset) { + return Position.INSIDE; + } + return Position.AFTER; + } + + public static boolean elementFit(final PsiElement element, final int start, final int end) { + return element != null && start <= element.getTextOffset() && element.getTextOffset() + element.getTextLength() <= end; + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/codeFragment/Position.java b/platform/lang-impl/src/com/intellij/codeInsight/codeFragment/Position.java new file mode 100644 index 000000000000..28435de10275 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/codeFragment/Position.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.codeFragment; + +/** + * @author oleg + */ +public enum Position { + BEFORE, + INSIDE, + AFTER +} diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java index 037ad0f67981..ae12700b4086 100644 --- a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java +++ b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -43,6 +43,7 @@ import com.intellij.openapi.util.DimensionService; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -101,7 +102,8 @@ public class PsiViewerDialog extends DialogWrapper { private Map handlers = new HashMap(); private DefaultActionGroup myGroup; private Language[] myLanguageDialects; - private final Color SELECTION_BG_COLOR = new Color(0, 51, 51); + private final Color SELECTION_BG_COLOR = Registry.getColor("psi.viewer.selection.color", new Color(255, 204, 204)); + private static final Comparator DIALECTS_COMPARATOR = new Comparator() { public int compare(final Language o1, final Language o2) { if (o1 == null) return o2 == null ? 0 : -1; diff --git a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java index aa9f254a73da..164620b24502 100644 --- a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java +++ b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -27,6 +27,8 @@ import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.ShadowAction; import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.ColorChooser; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.TitledBorder; @@ -38,9 +40,17 @@ import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import java.awt.*; import java.awt.event.ActionEvent; +import java.awt.image.BufferedImage; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +/** + * @author Kirill Kalishev + * @author Konstantin Bulenkov + */ public class RegistryUi implements Disposable { private JTable myTable; @@ -48,10 +58,9 @@ public class RegistryUi implements Disposable { private JPanel myContent = new JPanel(); - private DialogWrapper myDialog; private static final Icon RESTART_ICON = IconLoader.getIcon("/gutter/check.png"); private RestoreDefaultsAction myRestoreDefaultsAction; - private RegistryUi.MyTableModel myModel; + private MyTableModel myModel; public RegistryUi() { myContent.setLayout(new BorderLayout()); @@ -175,9 +184,9 @@ public class RegistryUi implements Disposable { }); } - private class MyTableModel extends AbstractTableModel { + private static class MyTableModel extends AbstractTableModel { - private java.util.List myAll; + private List myAll; private MyTableModel() { myAll = Registry.getInstance().getAll(); @@ -211,8 +220,7 @@ public class RegistryUi implements Disposable { } public void show() { - myDialog = new DialogWrapper(true) { - + DialogWrapper dialog = new DialogWrapper(true) { { setTitle("Registry"); setModal(true); @@ -243,19 +251,17 @@ public class RegistryUi implements Disposable { @Override protected Action[] createActions() { - return new Action[]{ - myRestoreDefaultsAction, new AbstractAction("Close") { - public void actionPerformed(ActionEvent e) { - processClose(); - doOKAction(); - } - } - }; + return new Action[]{myRestoreDefaultsAction, new AbstractAction("Close") { + public void actionPerformed(ActionEvent e) { + processClose(); + doOKAction(); + } + }}; } }; - myDialog.show(); + dialog.show(); } private void processClose() { @@ -299,7 +305,7 @@ public class RegistryUi implements Disposable { public void dispose() { } - private class MyRenderer implements TableCellRenderer { + private static class MyRenderer implements TableCellRenderer { private JLabel myLabel = new JLabel(); @@ -319,7 +325,11 @@ public class RegistryUi implements Disposable { myLabel.setText(v.getKey()); break; case 2: - myLabel.setText(v.asString()); + if (v.asColor(null) == null) { + myLabel.setText(v.asString()); + } else { + myLabel.setIcon(createColoredIcon(v.asColor(null))); + } } myLabel.setOpaque(true); @@ -333,17 +343,42 @@ public class RegistryUi implements Disposable { } } + private static final Map icons_cache = new HashMap(); + private static Icon createColoredIcon(Color color) { + Icon icon = icons_cache.get(color); + if (icon != null) return icon; + final BufferedImage image = GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice().getDefaultConfiguration() + .createCompatibleImage(16, 16, Color.TRANSLUCENT); + final Graphics g = image.getGraphics(); + g.setColor(color); + g.fillRect(0, 0, 16, 16); + g.dispose(); + icon = new ImageIcon(image); + icons_cache.put(color, icon); + return icon; + } + private class MyEditor extends AbstractCellEditor implements TableCellEditor { private JTextField myField = new JTextField(); private RegistryValue myValue; + @Nullable public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { myValue = (RegistryValue) value; - myField.setText(myValue.asString()); - myField.selectAll(); - myField.setBorder(null); - return myField; + if (myValue.asColor(null) == null) { + myField.setText(myValue.asString()); + myField.selectAll(); + myField.setBorder(null); + return myField; + } else { + final Color color = ColorChooser.chooseColor(table, "Chose color", ((RegistryValue)value).asColor(Color.WHITE)); + if (color != null) { + myValue.setValue(color.getRed() + "," + color.getGreen() + "," + color.getBlue()); + } + return null; + } } @Override diff --git a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java index 961b9fd36f8e..de118d9d2108 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java +++ b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java @@ -22,17 +22,18 @@ import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.ui.*; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.refactoring.RefactoringBundle; import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.EditorComboWithBrowseButton; import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.RecentsManager; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NonNls; import javax.swing.*; import javax.swing.event.DocumentEvent; @@ -42,13 +43,14 @@ import java.io.File; class CopyFilesOrDirectoriesDialog extends DialogWrapper{ private JLabel myInformationLabel; - private TextFieldWithBrowseButton myTargetDirectoryField; + private EditorComboWithBrowseButton myTargetDirectoryField; private JTextField myNewNameField; private final Project myProject; private final boolean myShowDirectoryField; private final boolean myShowNewNameField; private PsiDirectory myTargetDirectory; + @NonNls private static final String RECENT_KEYS = "CopyFile.RECENT_KEYS"; public CopyFilesOrDirectoriesDialog(PsiElement[] elements, PsiDirectory defaultTargetDirectory, Project project, boolean doClone) { super(project, true); @@ -88,7 +90,7 @@ class CopyFilesOrDirectoriesDialog extends DialogWrapper{ } if (myShowDirectoryField) { - myTargetDirectoryField.setText(defaultTargetDirectory == null ? "" : defaultTargetDirectory.getVirtualFile().getPresentableUrl()); + myTargetDirectoryField.prependItem(defaultTargetDirectory == null ? "" : defaultTargetDirectory.getVirtualFile().getPresentableUrl()); } validateOKButton(); } @@ -120,7 +122,7 @@ class CopyFilesOrDirectoriesDialog extends DialogWrapper{ } public JComponent getPreferredFocusedComponent() { - return myShowDirectoryField ? myTargetDirectoryField.getTextField() : myNewNameField; + return myShowDirectoryField ? myTargetDirectoryField.getChildComponent() : myNewNameField; } protected JComponent createCenterPanel() { @@ -145,15 +147,22 @@ class CopyFilesOrDirectoriesDialog extends DialogWrapper{ if (myShowDirectoryField) { panel.add(new JLabel(RefactoringBundle.message("copy.files.to.directory.label")), new GridBagConstraints(0,1,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,8,4,8),0,0)); - myTargetDirectoryField = new TextFieldWithBrowseButton(); - myTargetDirectoryField.addBrowseFolderListener(RefactoringBundle.message("select.target.directory"), - RefactoringBundle.message("the.file.will.be.copied.to.this.directory"), - null, - FileChooserDescriptorFactory.createSingleFolderDescriptor()); + final ComponentWithBrowseButton.BrowseFolderActionListener browseActionListener = + new ComponentWithBrowseButton.BrowseFolderActionListener(RefactoringBundle.message("select.target.directory"), + RefactoringBundle.message("the.file.will.be.copied.to.this.directory"), + null, myProject, FileChooserDescriptorFactory.createSingleFolderDescriptor(), + TextComponentAccessor.STRING_COMBOBOX_WHOLE_TEXT); + myTargetDirectoryField = new EditorComboWithBrowseButton(browseActionListener, "", myProject, + RECENT_KEYS); myTargetDirectoryField.setTextFieldPreferredWidth(60); panel.add(myTargetDirectoryField, new GridBagConstraints(1,1,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,0,4,8),0,0)); - myTargetDirectoryField.getTextField().getDocument().addDocumentListener(documentListener); + myTargetDirectoryField.getChildComponent().getDocument().addDocumentListener(new com.intellij.openapi.editor.event.DocumentAdapter() { + @Override + public void documentChanged(com.intellij.openapi.editor.event.DocumentEvent e) { + validateOKButton(); + } + }); } if (myShowNewNameField) { @@ -199,6 +208,8 @@ class CopyFilesOrDirectoriesDialog extends DialogWrapper{ return; } + RecentsManager.getInstance(myProject).registerRecentEntry(RECENT_KEYS, targetDirectoryName); + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { public void run() { ApplicationManager.getApplication().runWriteAction(new Runnable() { diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesDialog.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesDialog.java index 8a031f678f97..3fe59552f956 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesDialog.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesDialog.java @@ -19,11 +19,14 @@ package com.intellij.refactoring.move.moveFilesOrDirectories; import com.intellij.ide.util.DirectoryUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComponentWithBrowseButton; import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.ui.TextComponentAccessor; import com.intellij.openapi.util.Disposer; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; @@ -31,23 +34,25 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.util.CommonRefactoringUtil; -import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.EditorComboWithBrowseButton; import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.RecentsManager; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import javax.swing.*; -import javax.swing.event.DocumentEvent; import java.awt.*; import java.io.File; public class MoveFilesOrDirectoriesDialog extends DialogWrapper{ + @NonNls private static final String RECENT_KEYS = "MoveFile.RECENT_KEYS"; + public interface Callback { void run(MoveFilesOrDirectoriesDialog dialog); } private JLabel myNameLabel; - private TextFieldWithBrowseButton myTargetDirectoryField; + private EditorComboWithBrowseButton myTargetDirectoryField; private String myHelpID; private final Project myProject; private final Callback myCallback; @@ -66,7 +71,7 @@ public class MoveFilesOrDirectoriesDialog extends DialogWrapper{ } public JComponent getPreferredFocusedComponent() { - return myTargetDirectoryField.getTextField(); + return myTargetDirectoryField.getChildComponent(); } protected JComponent createCenterPanel() { @@ -85,15 +90,18 @@ public class MoveFilesOrDirectoriesDialog extends DialogWrapper{ panel.add(new JLabel(RefactoringBundle.message("move.files.to.directory.label")), new GridBagConstraints(0,1,1,1,0,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,8,4,8),0,0)); - myTargetDirectoryField = new TextFieldWithBrowseButton(); - myTargetDirectoryField.addBrowseFolderListener(RefactoringBundle.message("select.target.directory"), - RefactoringBundle.message("the.file.will.be.moved.to.this.directory"), - null, FileChooserDescriptorFactory.createSingleFolderDescriptor()); + final ComponentWithBrowseButton.BrowseFolderActionListener browseActionListener = + new ComponentWithBrowseButton.BrowseFolderActionListener(RefactoringBundle.message("select.target.directory"), + RefactoringBundle.message("the.file.will.be.moved.to.this.directory"), null, + myProject, FileChooserDescriptorFactory.createSingleFolderDescriptor(), + TextComponentAccessor.STRING_COMBOBOX_WHOLE_TEXT); + myTargetDirectoryField = new EditorComboWithBrowseButton(browseActionListener, "", myProject, RECENT_KEYS); myTargetDirectoryField.setTextFieldPreferredWidth(60); panel.add(myTargetDirectoryField, new GridBagConstraints(1,1,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(4,0,4,8),0,0)); - myTargetDirectoryField.getTextField().getDocument().addDocumentListener(new DocumentAdapter() { - public void textChanged(DocumentEvent event) { + myTargetDirectoryField.getChildComponent().getDocument().addDocumentListener(new DocumentAdapter() { + @Override + public void documentChanged(DocumentEvent e) { validateOKButton(); } }); @@ -128,7 +136,7 @@ public class MoveFilesOrDirectoriesDialog extends DialogWrapper{ RefactoringBundle.message("move.specified.directories") : RefactoringBundle.message("move.specified.elements")); } - myTargetDirectoryField.setText(initialTargetDirectory == null ? "" : initialTargetDirectory.getVirtualFile().getPresentableUrl()); + myTargetDirectoryField.prependItem(initialTargetDirectory == null ? "" : initialTargetDirectory.getVirtualFile().getPresentableUrl()); validateOKButton(); myHelpID = helpID; @@ -143,6 +151,7 @@ public class MoveFilesOrDirectoriesDialog extends DialogWrapper{ } protected void doOKAction() { + RecentsManager.getInstance(myProject).registerRecentEntry(RECENT_KEYS, myTargetDirectoryField.getText()); CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { public void run() { final Runnable action = new Runnable() { diff --git a/platform/lang-impl/src/com/intellij/ui/EditorComboWithBrowseButton.java b/platform/lang-impl/src/com/intellij/ui/EditorComboWithBrowseButton.java new file mode 100644 index 000000000000..f55e55aea575 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ui/EditorComboWithBrowseButton.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ui; + +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComponentWithBrowseButton; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; + +import java.awt.event.ActionListener; +import java.util.List; + +/** + * @author ven + */ +public class EditorComboWithBrowseButton extends ComponentWithBrowseButton implements TextAccessor { + public EditorComboWithBrowseButton(final ActionListener browseActionListener, + final String text, + @NotNull final Project project, + final String recentsKey) { + super(new EditorComboBox(text, project, StdFileTypes.PLAIN_TEXT), browseActionListener); + final List recentEntries = RecentsManager.getInstance(project).getRecentEntries(recentsKey); + if (recentEntries != null) { + setHistory(ArrayUtil.toStringArray(recentEntries)); + } + if (text != null && text.length() > 0) { + prependItem(text); + } + } + + public String getText() { + return getChildComponent().getText().trim(); + } + + public void setText(final String text) { + getChildComponent().setText(text); + } + + public boolean isEditable() { + return !getChildComponent().getEditorEx().isViewer(); + } + + public void setHistory(String[] history) { + getChildComponent().setHistory(history); + } + + public void prependItem(String item) { + getChildComponent().prependItem(item); + } +} \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/openapi/project/DumbService.java b/platform/platform-api/src/com/intellij/openapi/project/DumbService.java index ac4b8d551428..a7eee8dda576 100644 --- a/platform/platform-api/src/com/intellij/openapi/project/DumbService.java +++ b/platform/platform-api/src/com/intellij/openapi/project/DumbService.java @@ -41,6 +41,10 @@ import java.util.List; * @author peter */ public abstract class DumbService { + + /** + * @see com.intellij.openapi.project.Project#getMessageBus() + */ public static final Topic DUMB_MODE = new Topic("dumb mode", DumbModeListener.class); /** @@ -118,11 +122,26 @@ public abstract class DumbService { return wrapper; } + public void makeDumbAware(@NotNull final JComponent component, @NotNull Disposable disposable) { + component.setEnabled(!isDumb()); + getProject().getMessageBus().connect(disposable).subscribe(DUMB_MODE, new DumbModeListener() { + public void enteredDumbMode() { + component.setEnabled(false); + } + + public void exitDumbMode() { + component.setEnabled(true); + } + }); + } + public abstract BalloonHandler showDumbModeNotification(String message); public abstract Project getProject(); - + /** + * @see #DUMB_MODE + */ public interface DumbModeListener { /** diff --git a/platform/platform-api/src/com/intellij/openapi/util/registry/Registry.java b/platform/platform-api/src/com/intellij/openapi/util/registry/Registry.java index cf0d446483b6..6d82076ba8b7 100644 --- a/platform/platform-api/src/com/intellij/openapi/util/registry/Registry.java +++ b/platform/platform-api/src/com/intellij/openapi/util/registry/Registry.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -20,9 +20,11 @@ import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.PropertyKey; +import java.awt.*; import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.util.*; +import java.util.List; public class Registry { @@ -62,6 +64,10 @@ public class Registry { return get(key).asString(); } + public static Color getColor(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) String key, Color defaultValue) { + return get(key).asColor(defaultValue); + } + ResourceBundle getBundle() { ResourceBundle bundle = null; if (ourBundle != null) bundle = ourBundle.get(); diff --git a/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryValue.java b/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryValue.java index 633330d9be7a..333551b05cae 100644 --- a/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryValue.java +++ b/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryValue.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -15,12 +15,17 @@ */ package com.intellij.openapi.util.registry; -import com.intellij.openapi.util.Disposer; import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; -import java.util.concurrent.CopyOnWriteArraySet; +import java.awt.*; import java.util.MissingResourceException; +import java.util.concurrent.CopyOnWriteArraySet; +/** + * @author Kirill Kalishev + * @author Konstantin Bulenkov + */ public class RegistryValue { private Registry myRegistry; @@ -66,6 +71,20 @@ public class RegistryValue { return myIntCachedValue.intValue(); } + public Color asColor(Color defaultValue) { + final String s = get(myKey, null, true); + if (s != null) { + final String[] rgb = s.split(","); + if (rgb.length == 3) { + try { + return new Color(Integer.parseInt(rgb[0]), Integer.parseInt(rgb[1]), Integer.parseInt(rgb[2])); + } catch (Exception e) {// + } + } + } + return defaultValue; + } + public String getDescription() { return get(myKey + ".description", "", false); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/OpenRemoteFileAction.java b/platform/platform-impl/src/com/intellij/ide/actions/OpenRemoteFileAction.java deleted file mode 100644 index d6f851c3a167..000000000000 --- a/platform/platform-impl/src/com/intellij/ide/actions/OpenRemoteFileAction.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.ide.actions; - -import com.intellij.CommonBundle; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.vfs.VirtualFileManager; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.fileEditor.FileEditorManager; - -/** - * @author nik - * internal action - */ -public class OpenRemoteFileAction extends AnAction implements DumbAware { - @Override - public void update(final AnActionEvent e) { - e.getPresentation().setEnabled(e.getData(PlatformDataKeys.PROJECT)!=null); - } - - @Override - public void actionPerformed(final AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); - String defaultUrl = "http://"; - String url = Messages.showInputDialog(project, "URL:", "Open Remote File", null, defaultUrl, null); - if (url != null) { - VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url); - if (file == null) { - Messages.showErrorDialog(project, "Cannot find file '" + url + "'", CommonBundle.getErrorTitle()); - } - else { - FileEditorManager.getInstance(project).openFile(file, true); - } - } - } -} diff --git a/platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.java b/platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.java index 9fb117055ce1..7ab71dad9980 100644 --- a/platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.java +++ b/platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.java @@ -64,7 +64,7 @@ public class ToggleDumbModeAction extends AnAction implements DumbAware { public void canceled() { } }; - DumbServiceImpl.getInstance(project).queueCacheUpdate(Arrays.asList(updater)); + DumbServiceImpl.getInstance(project).queueCacheUpdateInDumbMode(Arrays.asList(updater)); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditorProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditorProvider.java index cfd3626b6830..58a2f905f374 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditorProvider.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditorProvider.java @@ -20,6 +20,7 @@ import com.intellij.openapi.fileEditor.FileEditorPolicy; import com.intellij.openapi.fileEditor.FileEditorProvider; import com.intellij.openapi.fileEditor.FileEditorState; import com.intellij.openapi.fileEditor.impl.text.TextEditorState; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; @@ -30,7 +31,7 @@ import org.jetbrains.annotations.NotNull; /** * @author nik */ -public class HttpFileEditorProvider implements FileEditorProvider { +public class HttpFileEditorProvider implements FileEditorProvider, DumbAware { public boolean accept(@NotNull final Project project, @NotNull final VirtualFile file) { return file instanceof HttpVirtualFile && !file.isDirectory(); } diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 2ff32c6d3f2c..114dfdbf81ef 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -50,3 +50,4 @@ compiler.perform.outputs.refresh.on.start=true compiler.perform.outputs.refresh.on.start.description=Whether to perform initial FS refresh before compilation starts. Need this to detect external changes to output dirs compiler.perform.outputs.refresh.on.start.restartRequired=false vcs.show.colored.annotations=true +psi.viewer.selection.color=0,153,153 diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index fbed7287a140..4c93e96a74e4 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -99,7 +99,6 @@ - diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java index d145b61aef72..937c8d7cacc8 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -232,7 +232,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { */ void checkResultByFile(@NonNls String filePath, @TestDataFile @NonNls String expectedFile, boolean ignoreTrailingWhitespaces) throws Exception; - void testCompletion(@NonNls String[] filesBefore, @NonNls String fileAfter) throws Exception; + void testCompletion(@NonNls String[] filesBefore, @TestDataFile @NonNls String fileAfter) throws Exception; /** * Runs basic completion in caret position in fileBefore. diff --git a/platform/util/src/com/intellij/util/io/zip/JBZipFile.java b/platform/util/src/com/intellij/util/io/zip/JBZipFile.java index a369f70f553f..2ce37c4672aa 100644 --- a/platform/util/src/com/intellij/util/io/zip/JBZipFile.java +++ b/platform/util/src/com/intellij/util/io/zip/JBZipFile.java @@ -313,7 +313,12 @@ public class JBZipFile { ze.setInternalAttributes(internalAttributes); ze.setExternalAttributes(externalAttributes); ze.setExtra(extra); - ze.setComment(comment); + try { + ze.setComment(comment); + } + catch (IllegalArgumentException e) { + ze.setComment(comment.substring(0, 0xffff / 3)); + } nameMap.put(ze.getName(), ze); entries.add(ze); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GroovyLineMarkerProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GroovyLineMarkerProvider.java index 155056efd2af..6f971199a731 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GroovyLineMarkerProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GroovyLineMarkerProvider.java @@ -77,7 +77,7 @@ public class GroovyLineMarkerProvider extends JavaLineMarkerProvider { if (drawSeparator) { GrDocComment comment = null; if (element1 instanceof GrDocCommentOwner) { - comment = ((GrDocCommentOwner)element1).getGrDocComment(); + comment = ((GrDocCommentOwner)element1).getDocComment(); } LineMarkerInfo info = new LineMarkerInfo(element, comment != null ? comment.getTextRange() : element.getTextRange(), null, diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/documentation/GroovyDocumentationProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/documentation/GroovyDocumentationProvider.java index 5ccb187c18f8..4be79cfd4aa0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/documentation/GroovyDocumentationProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/documentation/GroovyDocumentationProvider.java @@ -15,28 +15,55 @@ */ package org.jetbrains.plugins.groovy.lang.documentation; -import com.intellij.lang.documentation.DocumentationProvider; +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.editorActions.CodeDocumentationUtil; +import com.intellij.codeInsight.javadoc.JavaDocUtil; +import com.intellij.lang.CodeDocumentationAwareCommenter; +import com.intellij.lang.LanguageCommenters; +import com.intellij.lang.documentation.CodeDocumentationProvider; +import com.intellij.lang.java.JavaDocumentationProvider; +import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.impl.source.javadoc.PsiDocParamRef; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.StringBuilderSpinAllocator; +import com.intellij.util.containers.HashMap; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocCommentOwner; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.impl.GrDocCommentUtil; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +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.typedef.GrTypeDefinition; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; -import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import java.util.List; +import java.util.Map; /** * @author ven */ -public class GroovyDocumentationProvider implements DocumentationProvider { +public class GroovyDocumentationProvider implements CodeDocumentationProvider { + private static final String LINE_SEPARATOR = "\n"; + + @NonNls private static final String PARAM_TAG = "@param"; + @NonNls private static final String RETURN_TAG = "@return"; + @NonNls private static final String THROWS_TAG = "@throws"; + @Nullable public String getQuickNavigateInfo(PsiElement element) { if (element instanceof GrVariable) { - GrVariable variable = (GrVariable) element; + GrVariable variable = (GrVariable)element; StringBuffer buffer = new StringBuffer(); final PsiType type = variable.getDeclaredType(); appendTypeString(buffer, type); @@ -45,11 +72,11 @@ public class GroovyDocumentationProvider implements DocumentationProvider { return buffer.toString(); } else if (element instanceof GrReferenceExpression) { - GrReferenceExpression refExpr = (GrReferenceExpression) element; + GrReferenceExpression refExpr = (GrReferenceExpression)element; StringBuffer buffer = new StringBuffer(); PsiType type = null; if (refExpr.getParent() instanceof GrAssignmentExpression) { - GrAssignmentExpression assignment = (GrAssignmentExpression) refExpr.getParent(); + GrAssignmentExpression assignment = (GrAssignmentExpression)refExpr.getParent(); if (refExpr.equals(assignment.getLValue())) { GrExpression rvalue = assignment.getRValue(); if (rvalue != null) { @@ -61,12 +88,14 @@ public class GroovyDocumentationProvider implements DocumentationProvider { buffer.append(" "); buffer.append(refExpr.getReferenceName()); return buffer.toString(); - } else if (element instanceof PsiMethod) { + } + else if (element instanceof PsiMethod) { StringBuffer buffer = new StringBuffer(); - PsiMethod method = (PsiMethod) element; + PsiMethod method = (PsiMethod)element; if (method instanceof GrGdkMethod) { buffer.append("[GDK] "); - } else { + } + else { PsiClass hisClass = method.getContainingClass(); if (hisClass != null) { String qName = hisClass.getQualifiedName(); @@ -87,8 +116,9 @@ public class GroovyDocumentationProvider implements DocumentationProvider { PsiParameter parameter = parameters[i]; if (i > 0) buffer.append(", "); if (parameter instanceof GrParameter) { - buffer.append(GroovyPresentationUtil.getParameterPresentation((GrParameter) parameter, PsiSubstitutor.EMPTY)); - } else { + buffer.append(GroovyPresentationUtil.getParameterPresentation((GrParameter)parameter, PsiSubstitutor.EMPTY)); + } + else { PsiType type = parameter.getType(); appendTypeString(buffer, type); buffer.append(" "); @@ -97,7 +127,8 @@ public class GroovyDocumentationProvider implements DocumentationProvider { } buffer.append(")"); return buffer.toString(); - } else if (element instanceof GrTypeDefinition) { + } + else if (element instanceof GrTypeDefinition) { return generateClassInfo((GrTypeDefinition)element); } @@ -106,9 +137,9 @@ public class GroovyDocumentationProvider implements DocumentationProvider { } @SuppressWarnings({"HardCodedStringLiteral"}) - private String generateClassInfo(PsiClass aClass) { + private static String generateClassInfo(PsiClass aClass) { StringBuffer buffer = new StringBuffer(); - GroovyFile file = (GroovyFile) aClass.getContainingFile(); + GroovyFile file = (GroovyFile)aClass.getContainingFile(); String packageName = file.getPackageName(); if (packageName.length() > 0) { @@ -116,9 +147,7 @@ public class GroovyDocumentationProvider implements DocumentationProvider { } final String classString = - aClass.isInterface() ? "interface" : - aClass instanceof PsiTypeParameter ? "type parameter" : - aClass.isEnum() ? "enum" : "class"; + aClass.isInterface() ? "interface" : aClass instanceof PsiTypeParameter ? "type parameter" : aClass.isEnum() ? "enum" : "class"; buffer.append(classString).append(" "); buffer.append(aClass.getName()); @@ -155,7 +184,8 @@ public class GroovyDocumentationProvider implements DocumentationProvider { buffer.append(" extends "); if (refs.length == 0) { buffer.append("Object"); - } else { + } + else { for (int i = 0; i < refs.length; i++) { if (i > 0) buffer.append(", "); appendTypeString(buffer, refs[i]); @@ -177,23 +207,65 @@ public class GroovyDocumentationProvider implements DocumentationProvider { } - private void appendTypeString(StringBuffer buffer, PsiType type) { + private static void appendTypeString(StringBuffer buffer, PsiType type) { if (type != null) { buffer.append(type.getCanonicalText()); - } else { + } + else { buffer.append("def"); } } @Nullable public List getUrlFor(PsiElement element, PsiElement originalElement) { - return null; + return JavaDocumentationProvider.getExternalJavaDocUrl(element); } @Nullable public String generateDoc(PsiElement element, PsiElement originalElement) { - //todo - return null; + if (element instanceof GrReferenceExpression) { + return getMethodCandidateInfo((GrReferenceExpression)element); + } + + if (element instanceof GrGdkMethod) { + element = ((GrGdkMethod)element).getStaticMethod(); + } + + final GrDocComment doc = PsiTreeUtil.getParentOfType(originalElement, GrDocComment.class); + if (doc != null) { + element = GrDocCommentUtil.findDocOwner(doc); + } + + return JavaDocumentationProvider.generateExternalJavadoc(element); + } + + private static String getMethodCandidateInfo(GrReferenceExpression expr) { + final GroovyResolveResult[] candidates = expr.multiResolve(false); + final String text = expr.getText(); + if (candidates.length > 0) { + @NonNls final StringBuffer sb = new StringBuffer(); + for (final GroovyResolveResult candidate : candidates) { + final PsiElement element = candidate.getElement(); + if (!(element instanceof PsiMethod)) { + continue; + } + final String str = PsiFormatUtil.formatMethod((PsiMethod)element, candidate.getSubstitutor(), + PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_PARAMETERS, + PsiFormatUtil.SHOW_TYPE); + createElementLink(sb, element, str); + } + return CodeInsightBundle.message("javadoc.candiates", text, sb); + } + return CodeInsightBundle.message("javadoc.candidates.not.found", text); + } + + private static void createElementLink(@NonNls final StringBuffer sb, final PsiElement element, final String str) { + sb.append("  "); + sb.append(str); + sb.append(""); + sb.append("
"); } @Nullable @@ -203,6 +275,111 @@ public class GroovyDocumentationProvider implements DocumentationProvider { @Nullable public PsiElement getDocumentationElementForLink(PsiManager psiManager, String link, PsiElement context) { + return JavaDocUtil.findReferenceTarget(psiManager, link, context); + } + + public PsiComment findExistingDocComment(PsiComment contextElement) { + if (contextElement instanceof GrDocComment) { + final GrDocCommentOwner owner = GrDocCommentUtil.findDocOwner((GrDocComment)contextElement); + if (owner != null) { + return owner.getDocComment(); + } + } return null; } + + public String generateDocumentationContentStub(PsiComment contextComment) { + if (!(contextComment instanceof GrDocComment)) { + return null; + } + + final GrDocCommentOwner owner = GrDocCommentUtil.findDocOwner((GrDocComment)contextComment); + if (owner == null) return null; + + Project project = contextComment.getProject(); + final CodeDocumentationAwareCommenter commenter = + (CodeDocumentationAwareCommenter)LanguageCommenters.INSTANCE.forLanguage(owner.getLanguage()); + + + StringBuilder builder = StringBuilderSpinAllocator.alloc(); + try { + if (owner instanceof GrMethod) { + final GrMethod method = (GrMethod)owner; + final GrParameter[] parameters = method.getParameters(); + final Map param2Description = new HashMap(); + final PsiMethod[] superMethods = method.findSuperMethods(); + + for (PsiMethod superMethod : superMethods) { + final PsiDocComment comment = superMethod.getDocComment(); + if (comment != null) { + final PsiDocTag[] params = comment.findTagsByName("param"); + for (PsiDocTag param : params) { + final PsiElement[] dataElements = param.getDataElements(); + if (dataElements != null) { + String paramName = null; + for (PsiElement dataElement : dataElements) { + if (dataElement instanceof PsiDocParamRef) { + paramName = dataElement.getReference().getCanonicalText(); + break; + } + } + if (paramName != null) { + param2Description.put(paramName, param.getText()); + } + } + } + } + } + for (PsiParameter parameter : parameters) { + String description = param2Description.get(parameter.getName()); + if (description != null) { + builder.append(CodeDocumentationUtil.createDocCommentLine("", project, commenter)); + if (description.indexOf('\n') > -1) description = description.substring(0, description.lastIndexOf('\n')); + builder.append(description); + } + else { + builder.append(CodeDocumentationUtil.createDocCommentLine(PARAM_TAG, project, commenter)); + builder.append(parameter.getName()); + } + builder.append(LINE_SEPARATOR); + } + + if ((method.getReturnType() != null || method.getModifierList().hasModifierProperty("def")) && + method.getReturnType() != PsiType.VOID) { + builder.append(CodeDocumentationUtil.createDocCommentLine(RETURN_TAG, project, commenter)); + builder.append(LINE_SEPARATOR); + } + + final PsiClassType[] references = method.getThrowsList().getReferencedTypes(); + for (PsiClassType reference : references) { + builder.append(CodeDocumentationUtil.createDocCommentLine(THROWS_TAG, project, commenter)); + builder.append(reference.getClassName()); + builder.append(LINE_SEPARATOR); + } + } + else if (owner instanceof GrTypeDefinition) { + final PsiTypeParameterList typeParameterList = ((PsiClass)owner).getTypeParameterList(); + if (typeParameterList != null) { + createTypeParamsListComment(builder, project, commenter, typeParameterList); + } + } + return builder.length() > 0 ? builder.toString() : null; + } + finally { + StringBuilderSpinAllocator.dispose(builder); + } + } + + private static void createTypeParamsListComment(final StringBuilder buffer, + final Project project, + final CodeDocumentationAwareCommenter commenter, + final PsiTypeParameterList typeParameterList) { + final PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters(); + for (PsiTypeParameter typeParameter : typeParameters) { + buffer.append(CodeDocumentationUtil.createDocCommentLine(PARAM_TAG, project, commenter)); + buffer.append("<").append(typeParameter.getName()).append(">"); + buffer.append(LINE_SEPARATOR); + } + } + } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/moveUpDown/DeclarationMover.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/moveUpDown/DeclarationMover.java index 0425c2356fed..608b37341b9f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/moveUpDown/DeclarationMover.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/moveUpDown/DeclarationMover.java @@ -148,7 +148,7 @@ public class DeclarationMover extends LineMover { if (!isInsideDeclaration(member, startLine, endLine, lineRange, editor)) return null; if (member instanceof GrDocCommentOwner) { - final GrDocComment comment = ((GrDocCommentOwner)member).getGrDocComment(); + final GrDocComment comment = ((GrDocCommentOwner)member).getDocComment(); if (comment != null) { final int docStart = editor.offsetToLogicalPosition(comment.getTextRange().getStartOffset()).line; return new LineRange(docStart, endLine); @@ -174,7 +174,7 @@ public class DeclarationMover extends LineMover { ContainerUtil.addIfNotNull(((GrMember) member).getModifierList(), memberSuspects); } if (member instanceof GrDocCommentOwner) { - ContainerUtil.addIfNotNull(((GrDocCommentOwner)member).getGrDocComment(), memberSuspects); + ContainerUtil.addIfNotNull(((GrDocCommentOwner)member).getDocComment(), memberSuspects); } if (member instanceof GrMethod) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocComment.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocComment.java index 8ce3f0570346..c00362428e17 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocComment.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocComment.java @@ -16,15 +16,25 @@ package org.jetbrains.plugins.groovy.lang.groovydoc.psi.api; -import com.intellij.psi.PsiComment; +import com.intellij.psi.javadoc.PsiDocComment; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * @author ilyas */ -public interface GrDocComment extends PsiComment, GroovyDocPsiElement{ +public interface GrDocComment extends PsiDocComment, GroovyDocPsiElement { @Nullable GrDocCommentOwner getOwner(); + @NotNull + GrDocTag[] getTags(); + + @Nullable + GrDocTag findTagByName(@NonNls String name); + + @NotNull + GrDocTag[] findTagsByName(@NonNls String name); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocCommentOwner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocCommentOwner.java index 9c74e3ce0739..39466c40dacc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocCommentOwner.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocCommentOwner.java @@ -16,15 +16,16 @@ package org.jetbrains.plugins.groovy.lang.groovydoc.psi.api; +import com.intellij.psi.PsiDocCommentOwner; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; /** * @author Maxim.Medvedev */ -public interface GrDocCommentOwner extends GroovyPsiElement{ +public interface GrDocCommentOwner extends GroovyPsiElement, PsiDocCommentOwner { @Nullable - GrDocComment getGrDocComment(); + GrDocComment getDocComment(); boolean isDeprecated(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocTag.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocTag.java index 3082cd200409..f29835938b3c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocTag.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocTag.java @@ -16,15 +16,17 @@ package org.jetbrains.plugins.groovy.lang.groovydoc.psi.api; -import org.jetbrains.annotations.NotNull; -import com.intellij.psi.PsiElement; +import com.intellij.psi.javadoc.PsiDocTag; +import org.jetbrains.annotations.Nullable; /** * @author ilyas */ -public interface GrDocTag extends GroovyDocPsiElement { - @NotNull - PsiElement getNameIdentifier(); +public interface GrDocTag extends GroovyDocPsiElement, PsiDocTag { + GrDocTag[] EMPTY_ARRAY = new GrDocTag[0]; - String getName(); + GrDocComment getContainingComment(); + + @Nullable + GrDocTagValueToken getValueElement(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocTagValueToken.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocTagValueToken.java index 37770ee37437..6ae2fa92b79b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocTagValueToken.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/api/GrDocTagValueToken.java @@ -16,8 +16,10 @@ package org.jetbrains.plugins.groovy.lang.groovydoc.psi.api; +import com.intellij.psi.javadoc.PsiDocTagValue; + /** * @author ilyas */ -public interface GrDocTagValueToken extends GroovyDocPsiElement{ +public interface GrDocTagValueToken extends GroovyDocPsiElement, PsiDocTagValue { } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocCommentImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocCommentImpl.java index f885e0f19700..a71b2b1342b0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocCommentImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocCommentImpl.java @@ -16,15 +16,24 @@ package org.jetbrains.plugins.groovy.lang.groovydoc.psi.impl; +import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; import com.intellij.psi.impl.source.tree.LazyParseablePsiElement; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.text.CharArrayUtil; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.groovydoc.parser.GroovyDocElementTypes; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocCommentOwner; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocTag; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import java.util.ArrayList; + /** * @author ilyas */ @@ -49,7 +58,7 @@ public class GrDocCommentImpl extends LazyParseablePsiElement implements GroovyD PsiElement child = getFirstChild(); while (child != null) { if (child instanceof GroovyPsiElement) { - ((GroovyPsiElement) child).accept(visitor); + ((GroovyPsiElement)child).accept(visitor); } child = child.getNextSibling(); @@ -59,4 +68,47 @@ public class GrDocCommentImpl extends LazyParseablePsiElement implements GroovyD public GrDocCommentOwner getOwner() { return GrDocCommentUtil.findDocOwner(this); } + + @NotNull + public GrDocTag[] getTags() { + final GrDocTag[] tags = PsiTreeUtil.getChildrenOfType(this, GrDocTag.class); + return tags == null ? GrDocTag.EMPTY_ARRAY : tags; + } + + @Nullable + public GrDocTag findTagByName(@NonNls String name) { + if (!getText().contains(name)) return null; + for (PsiElement e = getFirstChild(); e != null; e = e.getNextSibling()) { + if (e instanceof GrDocTag && ((GrDocTag)e).getName().equals(name)) { + return (GrDocTag)e; + } + } + return null; + } + + @NotNull + public GrDocTag[] findTagsByName(@NonNls String name) { + if (!getText().contains(name)) return GrDocTag.EMPTY_ARRAY; + ArrayList list = new ArrayList(); + for (PsiElement e = getFirstChild(); e != null; e = e.getNextSibling()) { + if (e instanceof GrDocTag && CharArrayUtil.regionMatches(((GrDocTag)e).getName(), 1, name)) { + list.add((GrDocTag)e); + } + } + return list.toArray(new GrDocTag[list.size()]); + } + + public PsiElement[] getDescriptionElements() { + ArrayList array = new ArrayList(); + for (PsiElement child = getFirstChild(); child != null; child = child.getNextSibling()) { + final ASTNode node = child.getNode(); + if (node == null) continue; + final IElementType i = node.getElementType(); + if (i == GDOC_TAG) break; + if (i != mGDOC_COMMENT_START && i != mGDOC_COMMENT_END && i != mGDOC_ASTERISKS) { + array.add(child); + } + } + return array.toArray(new PsiElement[array.size()]); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocInlinedTagImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocInlinedTagImpl.java index 7bbe9711896b..d64d54787176 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocInlinedTagImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocInlinedTagImpl.java @@ -18,15 +18,29 @@ package org.jetbrains.plugins.groovy.lang.groovydoc.psi.impl; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; -import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocInlinedTag; -import org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes; -import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; +import com.intellij.psi.tree.TokenSet; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocInlinedTag; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocTagValueToken; +import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; + +import java.util.List; + +import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_COMMENT_DATA; +import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_TAG_VALUE_TOKEN; +import static org.jetbrains.plugins.groovy.lang.groovydoc.parser.GroovyDocElementTypes.*; /** * @author ilyas */ public class GrDocInlinedTagImpl extends GroovyDocPsiElementImpl implements GrDocInlinedTag { + private static final TokenSet VALUE_BIT_SET = TokenSet + .create(mGDOC_TAG_VALUE_TOKEN, GDOC_METHOD_REF, GDOC_FIELD_REF, GDOC_PARAM_REF, GDOC_REFERENCE_ELEMENT, mGDOC_COMMENT_DATA, + GDOC_INLINED_TAG); public GrDocInlinedTagImpl(@NotNull ASTNode node) { super(node); @@ -40,15 +54,37 @@ public class GrDocInlinedTagImpl extends GroovyDocPsiElementImpl implements GrDo return "GrDocInlinedTag"; } + @NotNull public String getName() { - return getNameIdentifier().getText(); + return getNameElement().getText(); } @NotNull - public PsiElement getNameIdentifier() { - PsiElement element = findChildByType(GroovyDocTokenTypes.mGDOC_TAG_NAME); + public PsiElement getNameElement() { + PsiElement element = findChildByType(mGDOC_TAG_NAME); assert element != null; return element; } + + public GrDocComment getContainingComment() { + return (GrDocComment)getParent(); + } + + public GrDocTagValueToken getValueElement() { + return findChildByClass(GrDocTagValueToken.class); + } + + public PsiElement[] getDataElements() { + final List list = findChildrenByType(VALUE_BIT_SET); + return list.toArray(new PsiElement[list.size()]); + } + + public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { + final PsiElement nameElement = getNameElement(); + final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(getProject()); + final GrDocComment comment = factory.createDocCommentFromText("/** {@" + name + "}*/"); + nameElement.replace(comment.getTags()[0].getNameElement()); + return this; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocTagImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocTagImpl.java index 222e8d3e268b..51108d27cdb8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocTagImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/groovydoc/psi/impl/GrDocTagImpl.java @@ -18,15 +18,31 @@ package org.jetbrains.plugins.groovy.lang.groovydoc.psi.impl; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; +import com.intellij.psi.tree.TokenSet; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocParameterReference; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocTag; -import org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocTagValueToken; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; + +import java.util.List; + +import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_COMMENT_DATA; +import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_TAG_NAME; +import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_TAG_VALUE_TOKEN; +import static org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes.*; /** * @author ilyas */ public class GrDocTagImpl extends GroovyDocPsiElementImpl implements GrDocTag { + private static final TokenSet VALUE_BIT_SET = TokenSet + .create(mGDOC_TAG_VALUE_TOKEN, GDOC_METHOD_REF, GDOC_FIELD_REF, GDOC_PARAM_REF, GDOC_REFERENCE_ELEMENT, mGDOC_COMMENT_DATA, + GDOC_INLINED_TAG); public GrDocTagImpl(@NotNull ASTNode node) { super(node); @@ -40,15 +56,39 @@ public class GrDocTagImpl extends GroovyDocPsiElementImpl implements GrDocTag { return "GroovyDocTag"; } + @NotNull public String getName() { - return getNameIdentifier().getText(); + return getNameElement().getText(); } @NotNull - public PsiElement getNameIdentifier() { - PsiElement element = findChildByType(GroovyDocTokenTypes.mGDOC_TAG_NAME); + public PsiElement getNameElement() { + PsiElement element = findChildByType(mGDOC_TAG_NAME); assert element != null; return element; } + + public GrDocComment getContainingComment() { + return (GrDocComment)getParent(); + } + + public GrDocTagValueToken getValueElement() { + final GrDocParameterReference reference = findChildByClass(GrDocParameterReference.class); + if (reference == null) return null; + return reference.getReferenceNameElement(); + } + + public PsiElement[] getDataElements() { + final List list = findChildrenByType(VALUE_BIT_SET); + return list.toArray(new PsiElement[list.size()]); + } + + public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { + final PsiElement nameElement = getNameElement(); + final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(getProject()); + final GrDocComment comment = factory.createDocCommentFromText("/** @" + name + "*/"); + nameElement.replace(comment.getTags()[0].getNameElement()); + return this; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java index 0f68f3da4f0e..4b6c600d5a28 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java @@ -23,6 +23,7 @@ import com.intellij.psi.PsiType; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrLabel; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrBlockStatement; @@ -138,5 +139,7 @@ public abstract class GroovyPsiElementFactory { public abstract GrMethod createConstructorFromText(@NotNull String constructorName, String[] paramTypes, String[] paramNames, String body); - public abstract GrLabel createLabel(@NotNull String name); + public abstract GrLabel createLabel(@NotNull String name); + + public abstract GrDocComment createDocCommentFromText(String text) ; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java index 8c2be5cfd3e8..e674c3d483b1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java @@ -160,7 +160,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory { public GrEnumConstant createEnumConstantFromText(String text) { GroovyFile file = (GroovyFile)createGroovyFile("enum E{" + text + "}"); final GrEnumTypeDefinition enumClass = (GrEnumTypeDefinition)file.getClasses()[0]; - return enumClass.getEnumConstants()[0]; + return enumClass.getEnumConstants()[0]; } public GrVariableDeclaration createFieldDeclaration(String[] modifiers, String identifier, GrExpression initializer, PsiType type) { @@ -517,4 +517,11 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory { return createMethodFromText(modifier, name, type, paramTypes, QuickfixUtil.getMethodArgumentsNames(myProject, res.toArray(PsiType.EMPTY_ARRAY)), null); } + + public GrDocComment createDocCommentFromText(String text) { + StringBuilder builder = new StringBuilder(); + builder.append(text); + builder.append(" def foo(){}"); + return (GrDocComment)createGroovyFile(text+"def foo(){}").getFirstChild(); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrFieldImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrFieldImpl.java index c59be1a3d797..aeb24c615d3a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrFieldImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrFieldImpl.java @@ -20,7 +20,6 @@ import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.psi.*; import com.intellij.psi.impl.PsiImplUtil; -import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.search.SearchScope; import com.intellij.psi.stubs.IStubElementType; import com.intellij.psi.util.CachedValue; @@ -307,11 +306,7 @@ public class GrFieldImpl extends GrVariableBaseImpl implements GrFi return namedParameters.toArray(new HashSet[namedParameters.size()]); } - public GrDocComment getGrDocComment() { + public GrDocComment getDocComment() { return GrDocCommentUtil.findDocComment(this); } - - public PsiDocComment getDocComment() { - return null; - } } 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 acc00f45dbb5..81884a569f1a 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 @@ -346,7 +346,7 @@ public class GrParameterImpl extends GrVariableImpl implements GrParameter { final PsiElement scope = getDeclarationScope(); if (scope instanceof GrDocCommentOwner) { GrDocCommentOwner owner = (GrDocCommentOwner)scope; - final GrDocComment comment = owner.getGrDocComment(); + final GrDocComment comment = owner.getDocComment(); if (comment != null) { return new LocalSearchScope(new PsiElement[]{scope, comment}); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java index 118ff640db9e..2ca9f5fef13e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java @@ -19,7 +19,6 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef; import com.intellij.lang.ASTNode; import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.editor.colors.TextAttributesKey; -import com.intellij.openapi.util.Iconable; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -28,7 +27,6 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.impl.*; import com.intellij.psi.impl.source.tree.LeafPsiElement; import com.intellij.psi.impl.source.tree.java.ClassElement; -import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.stubs.IStubElementType; import com.intellij.ui.RowIcon; @@ -120,6 +118,7 @@ public abstract class GrTypeDefinitionImpl extends GroovyBaseElementImpl extends GroovyBaseEl } @Nullable - public PsiDocComment getDocComment() { - return null; - } - - @Nullable - public GrDocComment getGrDocComment() { + public GrDocComment getDocComment() { return GrDocCommentUtil.findDocComment(this); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/ClosureSyntheticParameter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/ClosureSyntheticParameter.java index 3dfc0993c654..605b4752ae92 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/ClosureSyntheticParameter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/ClosureSyntheticParameter.java @@ -88,4 +88,9 @@ public class ClosureSyntheticParameter extends LightParameter implements Navigat } return typeGroovy != null ? typeGroovy : super.getType(); } + + @Override + public PsiElement getContext() { + return myClosure; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrAccessorMethodImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrAccessorMethodImpl.java index e1ed222db812..58194467e21c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrAccessorMethodImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrAccessorMethodImpl.java @@ -18,10 +18,10 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.synthetic; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import java.util.LinkedHashSet; import java.util.Set; @@ -125,4 +125,9 @@ public class GrAccessorMethodImpl extends GrSyntheticMethod implements GrAccesso public GrField getProperty() { return myProperty; } + + @Override + public PsiElement getContext() { + return myProperty; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitMethod.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitMethod.java index 0f9ae5cfc633..96ae75ca2ace 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitMethod.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitMethod.java @@ -27,11 +27,11 @@ import com.intellij.psi.search.ProjectScope; import com.intellij.psi.search.SearchScope; import com.intellij.psi.util.MethodSignature; import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; +import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns; +import com.intellij.ui.treeStructure.treetable.TreeTable; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.ui.tree.TreeUtil; -import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns; -import com.intellij.ui.treeStructure.treetable.TreeTable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; @@ -41,10 +41,10 @@ import org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicToolWind import org.jetbrains.plugins.groovy.annotator.intentions.dynamic.elements.DClassElement; import org.jetbrains.plugins.groovy.annotator.intentions.dynamic.elements.DMethodElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; -import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; 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.util.PsiUtil; import javax.swing.*; @@ -369,4 +369,9 @@ public class GrDynamicImplicitMethod extends LightElement implements PsiMethod, public PsiType getReturnTypeNoResolve() { return getReturnType(); } + + @Override + public PsiElement getContext() { + return myMethod; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrSyntheticMethodImplementation.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrSyntheticMethodImplementation.java index 8e45499d3e6c..d54ff37ee91d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrSyntheticMethodImplementation.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrSyntheticMethodImplementation.java @@ -81,4 +81,8 @@ public class GrSyntheticMethodImplementation extends GrSyntheticMethod { return "SyntheticMethodImplementation"; } + @Override + public PsiElement getContext() { + return myInterfaceMethod; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java index 5bcb9af931f0..2bfb2b289f1f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java @@ -153,7 +153,13 @@ public class GroovyScriptClass extends LightElement implements GrMemberOwner, Sy @NotNull public PsiClass[] getSupers() { - return new PsiClass[]{getSuperClass()}; + final PsiClass superClass = getSuperClass(); + if (superClass != null) { + return new PsiClass[]{superClass}; + } + else { + return PsiClass.EMPTY_ARRAY; + } } @NotNull @@ -343,6 +349,11 @@ public class GroovyScriptClass extends LightElement implements GrMemberOwner, Sy return true; } + @Override + public PsiElement getContext() { + return myFile; + } + //default implementations of methods from NavigationItem public ItemPresentation getPresentation() { return new ItemPresentation() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptMethod.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptMethod.java index 98b0ce59f007..f55b21465e13 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptMethod.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptMethod.java @@ -202,4 +202,9 @@ public class GroovyScriptMethod extends LightElement implements PsiMethod { public PsiType getReturnTypeNoResolve() { return getReturnType(); } + + @Override + public PsiElement getContext() { + return myScriptClass; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrTypeParameterImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrTypeParameterImpl.java index 81fe6dd57af3..64e87babacba 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrTypeParameterImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrTypeParameterImpl.java @@ -20,7 +20,6 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; import com.intellij.psi.impl.InheritanceImplUtil; -import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; @@ -333,11 +332,7 @@ public class GrTypeParameterImpl extends GroovyPsiElementImpl implements GrTypeP } @Nullable - public PsiDocComment getDocComment() { - return null; - } - - public GrDocComment getGrDocComment() { + public GrDocComment getDocComment() { return null; } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/EnterActionTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/EnterActionTest.java index fe5babab46bd..c09edd81c451 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/EnterActionTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/EnterActionTest.java @@ -56,6 +56,8 @@ public class EnterActionTest extends GroovyFormatterTestCase { public void testGdoc7() throws Throwable { doTest(); } public void testGdoc8() throws Throwable { doTest(); } public void testGdoc9() throws Throwable { doTest(); } + public void testGdoc10() throws Throwable { doTest(); } + public void testGdoc11() throws Throwable { doTest(); } public void testGRVY_953() throws Throwable { doTest(); } public void testGstring1() throws Throwable { doTest(); } public void testGstring10() throws Throwable { doTest(); } diff --git a/plugins/groovy/testdata/groovy/enterAction/gdoc10.test b/plugins/groovy/testdata/groovy/enterAction/gdoc10.test new file mode 100644 index 000000000000..d94133ca199f --- /dev/null +++ b/plugins/groovy/testdata/groovy/enterAction/gdoc10.test @@ -0,0 +1,10 @@ +/** +def foo(int x, int y){} +----- +/** + * + * @param x + * @param y + * @return + */ +def foo(int x, int y){} \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/enterAction/gdoc11.test b/plugins/groovy/testdata/groovy/enterAction/gdoc11.test new file mode 100644 index 000000000000..018419abb4ce --- /dev/null +++ b/plugins/groovy/testdata/groovy/enterAction/gdoc11.test @@ -0,0 +1,9 @@ +/** +void foo(int x, int y){} +----- +/** + * + * @param x + * @param y + */ +void foo(int x, int y){} \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/enterAction/gdoc6.test b/plugins/groovy/testdata/groovy/enterAction/gdoc6.test index 13440fd15aba..75f346cccd93 100644 --- a/plugins/groovy/testdata/groovy/enterAction/gdoc6.test +++ b/plugins/groovy/testdata/groovy/enterAction/gdoc6.test @@ -3,6 +3,7 @@ ----- /** * + * @return */ def foo() { } \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/enterAction/gdoc7.test b/plugins/groovy/testdata/groovy/enterAction/gdoc7.test index 5a082f0f96d1..93d1901b8040 100644 --- a/plugins/groovy/testdata/groovy/enterAction/gdoc7.test +++ b/plugins/groovy/testdata/groovy/enterAction/gdoc7.test @@ -4,6 +4,7 @@ def foo() { ----- /** * + * @return */ def foo() {