diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/dependencyAnalysis/AnalyzeDependenciesComponent.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/dependencyAnalysis/AnalyzeDependenciesComponent.java index 56b11bd4709f..c2e2ad24d897 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/dependencyAnalysis/AnalyzeDependenciesComponent.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/dependencyAnalysis/AnalyzeDependenciesComponent.java @@ -111,7 +111,6 @@ public class AnalyzeDependenciesComponent extends MasterDetailsComponent { @Override public void disposeUIResources() { if (myMessageBusConnection != null) { - myMessageBusConnection.dispose(); myMessageBusConnection.disconnect(); } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java index 97bfa377a2b3..d83c937c1dd1 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java @@ -43,6 +43,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.tree.TreeCellRenderer; import java.awt.*; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; @@ -83,7 +84,23 @@ public class FacetStructureConfigurable extends BaseStructureConfigurable { super.initTree(); if (!myTreeWasInitialized) { myTreeWasInitialized = true; - myTree.setCellRenderer(new FacetsTreeCellRenderer()); + final FacetsTreeCellRenderer separatorRenderer = new FacetsTreeCellRenderer(); + final TreeCellRenderer oldRenderer = myTree.getCellRenderer(); + myTree.setCellRenderer(new TreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + if (value instanceof MyNode && ((MyNode)value).getConfigurable() instanceof FrameworkDetectionConfigurable) { + return separatorRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); + } + return oldRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); + } + }); myTree.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetsTreeCellRenderer.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetsTreeCellRenderer.java index 53ef207663eb..67b89765c300 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetsTreeCellRenderer.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetsTreeCellRenderer.java @@ -57,14 +57,15 @@ public class FacetsTreeCellRenderer extends GroupedElementsRenderer.Tree impleme final boolean showSeparator = configurable instanceof FrameworkDetectionConfigurable; int width = -1; if (showSeparator && tree.isVisible()) { - final int treeWidth = tree.getVisibleRect().width - 4; + final int treeWidth = tree.getVisibleRect().width; if (treeWidth > 0) { width = treeWidth; } } final JComponent component = configureComponent(node.getDisplayName(), null, icon, icon, selected, showSeparator, null, width); - myTextLabel.setOpaque(true); + + myTextLabel.setOpaque(selected); return component; } } diff --git a/java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityInspection.java b/java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityInspection.java index 4916e6c548b8..78a850d04e7b 100644 --- a/java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityInspection.java @@ -178,9 +178,10 @@ public class VisibilityInspection extends GlobalJavaInspectionTool { } @Modifier String access = getPossibleAccess(refElement); if (access != refElement.getAccessModifier() && access != null) { - final PsiElement psiElement = HighlightUsagesHandler.getNameIdentifier(refElement.getElement()); - if (psiElement != null) { - return new ProblemDescriptor[]{manager.createProblemDescriptor(psiElement, + final PsiElement element = refElement.getElement(); + final PsiElement nameIdentifier = element != null ? HighlightUsagesHandler.getNameIdentifier(element) : null; + if (nameIdentifier != null) { + return new ProblemDescriptor[]{manager.createProblemDescriptor(nameIdentifier, access.equals(PsiModifier.PRIVATE) ? CAN_BE_PRIVATE : access.equals(PsiModifier.PACKAGE_LOCAL) diff --git a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java index 164d43dce300..16768174d072 100644 --- a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java @@ -128,9 +128,7 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase { if (classes != null) { topLevelClasses = ArrayUtil.mergeArrays(classes, topLevelClasses, PsiClass.ARRAY_FACTORY); } - if (topLevelClasses != null) { - result.put(containingFile, topLevelClasses); - } + result.put(containingFile, topLevelClasses); } public void doCopy(PsiElement[] elements, PsiDirectory defaultTargetDirectory) { @@ -361,19 +359,26 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase { } private static PsiFile copy(@NotNull PsiFile file, PsiDirectory directory, String name, String relativePath) { - final String fileName; - if (name != null) { - fileName = file instanceof PsiClassOwner ? name + "." + file.getViewProvider().getVirtualFile().getExtension() : name; - } - else { - fileName = file.getName(); - } + final String fileName = getNewFileName(file, name); if (relativePath != null && !relativePath.isEmpty()) { return buildRelativeDir(directory, relativePath).findOrCreateTargetDirectory().copyFileFrom(fileName, file); } return directory.copyFileFrom(fileName, file); } + private static String getNewFileName(PsiFile file, String name) { + if (name != null) { + if (file instanceof PsiClassOwner) { + final PsiClass[] classes = ((PsiClassOwner)file).getClasses(); + if (classes.length > 0 && !(classes[0] instanceof SyntheticElement)) { + return name + "." + file.getViewProvider().getVirtualFile().getExtension(); + } + } + return name; + } + return file.getName(); + } + @NotNull private static MoveDirectoryWithClassesProcessor.TargetDirectoryWrapper buildRelativeDir(final @NotNull PsiDirectory directory, final @NotNull String relativePath) { diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java index 82e69525570c..b15a7aad1c87 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java @@ -128,6 +128,7 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton DirectoryChooser.ItemWrapper item = (DirectoryChooser.ItemWrapper)model.getElementAt(i); if (item != null && fileIndex.getSourceRootForFile(item.getDirectory().getVirtualFile()) == root) { getComboBox().setSelectedItem(item); + getComboBox().repaint(); return; } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java index a56df64c8367..df49e326cf5e 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java @@ -179,15 +179,16 @@ public class JavaResolveUtil { final ResolveState state, final PsiElement place, PsiManager manager) { + PsiPackage defaultPackage = JavaPsiFacade.getInstance(manager.getProject()).findPackage(""); + if (defaultPackage != null) { + if (!defaultPackage.processDeclarations(processor, state, null, place)) return false; + } + PsiPackage langPackage = JavaPsiFacade.getInstance(manager.getProject()).findPackage(CommonClassNames.DEFAULT_PACKAGE); if (langPackage != null) { if (!langPackage.processDeclarations(processor, state, null, place)) return false; } - PsiPackage defaultPackage = JavaPsiFacade.getInstance(manager.getProject()).findPackage(""); - if (defaultPackage != null) { - if (!defaultPackage.processDeclarations(processor, state, null, place)) return false; - } return true; } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/AnonymousProcess.java b/java/java-tests/testData/codeInsight/completion/normal/AnonymousProcess.java new file mode 100644 index 000000000000..9b5aa6caeb5d --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/AnonymousProcess.java @@ -0,0 +1,8 @@ +import java.util.*; + +public class Runner { + public static void main(String[] args) { + List src; + List dest = ListUtils.filter(src, new ); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/AnonymousProcess_after.java b/java/java-tests/testData/codeInsight/completion/normal/AnonymousProcess_after.java new file mode 100644 index 000000000000..b532bc1ff2cc --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/AnonymousProcess_after.java @@ -0,0 +1,13 @@ +import java.util.*; + +public class Runner { + public static void main(String[] args) { + List src; + List dest = ListUtils.filter(src, new Pred() { + @Override + public boolean predicate(Process elem) { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + }); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index d05310987c1a..a0aaf0d54b9a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -478,6 +478,21 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase { checkResult() } + public void testAnonymousProcess() { + myFixture.addClass 'package java.lang; public class Process {}' + myFixture.addClass ''' +import java.util.*; +public class Process {} +interface Pred { boolean predicate(A elem); } +public class ListUtils { + public static List filter(List list, Pred pred) {} +} +''' + configure() + type '\n' + checkResult() + } + public void testNoThisInComment() throws Throwable { doAntiTest() } public void testLastExpressionInFor() throws Throwable { doTest(); } diff --git a/platform/lang-impl/src/com/intellij/ide/actions/ViewStructureAction.java b/platform/lang-impl/src/com/intellij/ide/actions/ViewStructureAction.java index 07720a7c5028..931db8fa241a 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/ViewStructureAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/ViewStructureAction.java @@ -21,12 +21,14 @@ import com.intellij.ide.structureView.StructureView; import com.intellij.ide.structureView.StructureViewBuilder; import com.intellij.ide.structureView.StructureViewModel; import com.intellij.ide.util.FileStructureDialog; +import com.intellij.ide.util.FileStructurePopup; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.Navigatable; import com.intellij.psi.PsiDocumentManager; @@ -55,13 +57,24 @@ public class ViewStructureAction extends AnAction { FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.file.structure"); Navigatable navigatable = e.getData(PlatformDataKeys.NAVIGATABLE); - DialogWrapper dialog = createDialog(editor, project, navigatable, fileEditor); - if (dialog != null) { - final VirtualFile virtualFile = psiFile.getVirtualFile(); - if (virtualFile != null) { - dialog.setTitle(virtualFile.getName()); + if (Registry.is("file.structure.tree.mode")) { + FileStructurePopup popup = createPopup(editor, project, navigatable, fileEditor); + if (popup != null) { + final VirtualFile virtualFile = psiFile.getVirtualFile(); + if (virtualFile != null) { + popup.setTitle(virtualFile.getName()); + } + popup.show(); + } + } else { + DialogWrapper dialog = createDialog(editor, project, navigatable, fileEditor); + if (dialog != null) { + final VirtualFile virtualFile = psiFile.getVirtualFile(); + if (virtualFile != null) { + dialog.setTitle(virtualFile.getName()); + } + dialog.show(); } - dialog.show(); } } @@ -72,6 +85,14 @@ public class ViewStructureAction extends AnAction { StructureView structureView = structureViewBuilder.createStructureView(fileEditor, project); return createStructureViewBasedDialog(structureView.getTreeModel(), editor, project, navigatable, structureView); } + + @Nullable + private static FileStructurePopup createPopup(final Editor editor, Project project, Navigatable navigatable, final FileEditor fileEditor) { + final StructureViewBuilder structureViewBuilder = fileEditor.getStructureViewBuilder(); + if (structureViewBuilder == null) return null; + StructureView structureView = structureViewBuilder.createStructureView(fileEditor, project); + return createStructureViewPopup(structureView.getTreeModel(), editor, project, navigatable, structureView); + } public static FileStructureDialog createStructureViewBasedDialog(final StructureViewModel structureViewModel, final Editor editor, @@ -80,7 +101,14 @@ public class ViewStructureAction extends AnAction { final @NotNull Disposable alternativeDisposable) { return new FileStructureDialog(structureViewModel, editor, project, navigatable, alternativeDisposable, true); } - + public static FileStructurePopup createStructureViewPopup(final StructureViewModel structureViewModel, + final Editor editor, + final Project project, + final Navigatable navigatable, + final @NotNull Disposable alternativeDisposable) { + return new FileStructurePopup(structureViewModel, editor, project, navigatable, alternativeDisposable, true); + } + public void update(AnActionEvent event) { Presentation presentation = event.getPresentation(); DataContext dataContext = event.getDataContext(); diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java index ed83e7f47000..c15259f45760 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java @@ -373,39 +373,8 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis } public void installActions(final int index, final NavBarItem component) { - DnDSupport.createBuilder(component) - .setBeanProvider(new Function() { - @Override - public DnDDragStartBean fun(DnDActionInfo dnDActionInfo) { - return new DnDDragStartBean(new TransferableWrapper() { - @Override - public List asFileList() { - final Object o = myModel.get(index); - if (o instanceof PsiElement) { - final VirtualFile vf = o instanceof PsiDirectory ? ((PsiDirectory)o).getVirtualFile() - : ((PsiElement)o).getContainingFile().getVirtualFile(); - if (vf != null) { - return Arrays.asList(new File(vf.getPath()).getAbsoluteFile()); - } - } - return Collections.emptyList(); - } - - @Override - public TreeNode[] getTreeNodes() { - return null; - } - - @Override - public PsiElement[] getPsiElements() { - return null; - } - }); - } - }) - .setDisposableParent(component) - .install(); - + //suppress it for a while + //installDnD(index, component); ListenerUtil.addMouseListener(component, new MouseAdapter() { public void mouseReleased(final MouseEvent e) { @@ -446,6 +415,41 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis }); } + private void installDnD(final int index, NavBarItem component) { + DnDSupport.createBuilder(component) + .setBeanProvider(new Function() { + @Override + public DnDDragStartBean fun(DnDActionInfo dnDActionInfo) { + return new DnDDragStartBean(new TransferableWrapper() { + @Override + public List asFileList() { + final Object o = myModel.get(index); + if (o instanceof PsiElement) { + final VirtualFile vf = o instanceof PsiDirectory ? ((PsiDirectory)o).getVirtualFile() + : ((PsiElement)o).getContainingFile().getVirtualFile(); + if (vf != null) { + return Arrays.asList(new File(vf.getPath()).getAbsoluteFile()); + } + } + return Collections.emptyList(); + } + + @Override + public TreeNode[] getTreeNodes() { + return null; + } + + @Override + public PsiElement[] getPsiElements() { + return null; + } + }); + } + }) + .setDisposableParent(component) + .install(); + } + private void doubleClick(final int index) { doubleClick(myModel.getElement(index)); } diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureTreeBuilder.java b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureTreeBuilder.java index 17f9d5b83d1f..1e0f4a6c369d 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureTreeBuilder.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureTreeBuilder.java @@ -36,7 +36,7 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.tree.DefaultTreeModel; -class StructureTreeBuilder extends AbstractTreeBuilder { +public class StructureTreeBuilder extends AbstractTreeBuilder { private final Project myProject; private final StructureViewModel myStructureModel; diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java index 4edfba6bfad5..ce609a0c88c8 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java @@ -733,7 +733,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre } //todo [kirillk] dirty hack for discovering invalid psi elements, to delegate it to a proper place after 8.1 - private static boolean isValid(Object treeElement) { + public static boolean isValid(Object treeElement) { if (treeElement instanceof StructureViewTreeElementWrapper) { final StructureViewTreeElementWrapper wrapper = (StructureViewTreeElementWrapper)treeElement; if (wrapper.getValue() instanceof PsiTreeElementBase) { @@ -744,7 +744,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre return true; } - static class StructureViewTreeElementWrapper extends TreeElementWrapper implements NodeDescriptorProvidingKey { + public static class StructureViewTreeElementWrapper extends TreeElementWrapper implements NodeDescriptorProvidingKey { private long childrenStamp = -1; private long modificationCountForChildren = ourSettingsModificationCount; diff --git a/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooser.java b/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooser.java index da4b09be753c..ea8bac8d7fbf 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooser.java +++ b/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooser.java @@ -16,20 +16,28 @@ package com.intellij.ide.util; +import com.intellij.ide.util.gotoByName.ChooseByNamePanel; +import com.intellij.ide.util.gotoByName.ChooseByNamePopupComponent; +import com.intellij.ide.util.gotoByName.GotoClassModel2; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.refactoring.RefactoringBundle; import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TabbedPaneWrapper; import com.intellij.util.ArrayUtil; import com.intellij.util.PlatformIcons; import com.intellij.util.ui.UIUtil; @@ -51,6 +59,9 @@ public class DirectoryChooser extends DialogWrapper { private boolean myFilterExisting; private PsiDirectory myDefaultSelection; private List myItems = new ArrayList(); + private PsiElement mySelection; + private final TabbedPaneWrapper myTabbedPaneWrapper; + private final ChooseByNamePanel myChooseByNamePanel; public DirectoryChooser(Project project){ this(project, new DirectoryChooserModuleTreeView(project)); @@ -61,12 +72,40 @@ public class DirectoryChooser extends DialogWrapper { myView = view; final PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(); myFilterExisting = propertiesComponent.isValueSet(FILTER_NON_EXISTING) && propertiesComponent.isTrueValue(FILTER_NON_EXISTING); + myTabbedPaneWrapper = new TabbedPaneWrapper(getDisposable()); + myChooseByNamePanel = new ChooseByNamePanel(project, new GotoClassModel2(project){ + @Override + public String[] getNames(boolean checkBoxState) { + return super.getNames(false); + } + }, "", false, null) { + protected void showTextFieldPanel() { + } + + protected void close(boolean isOk) { + super.close(isOk); + if (isOk) { + final List elements = getChosenElements(); + if (elements != null && elements.size() > 0) { + myActionListener.elementChosen(elements.get(0)); + } + doOKAction(); + } + else { + doCancelAction(); + } + } + }; + Disposer.register(myDisposable, myChooseByNamePanel); init(); } @Override protected void doOKAction() { PropertiesComponent.getInstance().setValue(FILTER_NON_EXISTING, String.valueOf(myFilterExisting)); + if (myTabbedPaneWrapper.getSelectedIndex() == 1) { + setSelection(myChooseByNamePanel.getChosenElement()); + } super.doOKAction(); } @@ -93,7 +132,23 @@ public class DirectoryChooser extends DialogWrapper { installEnterAction(component); panel.add(jScrollPane, BorderLayout.CENTER); - return panel; + myTabbedPaneWrapper.addTab("Directory Structure", panel); + + myChooseByNamePanel.invoke(new ChooseByNamePopupComponent.Callback() { + @Override + public void elementChosen(Object element) { + setSelection(element); + } + }, ModalityState.stateForComponent(getRootPane()), false); + myTabbedPaneWrapper.addTab("Choose By Neighbor Class", myChooseByNamePanel.getPanel()); + + return myTabbedPaneWrapper.getComponent(); + } + + private void setSelection(Object element) { + if (element instanceof PsiElement) { + mySelection = (PsiElement)element; + } } private void installEnterAction(final JComponent component) { @@ -396,6 +451,12 @@ public class DirectoryChooser extends DialogWrapper { @Nullable public PsiDirectory getSelectedDirectory() { + if (mySelection != null) { + final PsiFile file = mySelection.getContainingFile(); + if (file != null){ + return file.getContainingDirectory(); + } + } ItemWrapper wrapper = myView.getSelectedItem(); if (wrapper == null) return null; return wrapper.myDirectory; diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java new file mode 100644 index 000000000000..1fd04f264364 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java @@ -0,0 +1,599 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.util; + +import com.intellij.ide.IdeBundle; +import com.intellij.ide.commander.CommanderPanel; +import com.intellij.ide.commander.ProjectListBuilder; +import com.intellij.ide.structureView.StructureViewBuilder; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.ide.structureView.TreeBasedStructureViewBuilder; +import com.intellij.ide.structureView.newStructureView.StructureTreeBuilder; +import com.intellij.ide.structureView.newStructureView.StructureViewComponent; +import com.intellij.ide.structureView.newStructureView.TreeActionsOwner; +import com.intellij.ide.structureView.newStructureView.TreeModelWrapper; +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.util.treeView.smartTree.*; +import com.intellij.lang.LanguageStructureViewBuilder; +import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.MnemonicHelper; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopup; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.ui.ListScrollingUtil; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.SpeedSearchBase; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.docking.DockManager; +import com.intellij.ui.speedSearch.SpeedSearchSupply; +import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.HashSet; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * @author Konstantin Bulenkov + */ +public class FileStructurePopup implements Disposable { + private final Editor myEditor; + private final Navigatable myNavigatable; + private final Project myProject; + private final StructureViewModel myTreeModel; + private final StructureViewModel myBaseTreeModel; + @NotNull private final Disposable myDisposable; + private final MyTreeActionsOwner myTreeActionsOwner; + private JBPopup myPopup; + + @NonNls private static final String ourPropertyKey = "FileStructure.narrowDown"; + private boolean myShouldNarrowDown = false; + private Tree myTree; + private AbstractTreeBuilder myAbstractTreeBuilder; + private String myTitle; + private TreeSpeedSearch mySpeedSearch; + private HashSet myVisibleElements = new HashSet(); + private Filter mySearchFilter = new Filter() { + @Override + public boolean isVisible(TreeElement treeNode) { + if (mySpeedSearch != null && myShouldNarrowDown && !StringUtil.isEmpty(mySpeedSearch.getEnteredPrefix())) { + + if (myVisibleElements.contains(treeNode)) return true; + ItemPresentation presentation = treeNode.getPresentation(); + if (presentation == null) return true; + String text = presentation.getPresentableText(); + if (text == null) return true; + Iterable ranges = mySpeedSearch.matchingFragments(text); + if (ranges == null) return true; + Iterator iterator = ranges.iterator(); + boolean contains = iterator.hasNext(); + if (contains) { + myVisibleElements.add(treeNode); + return true; + } + for (TreeElement child : treeNode.getChildren()) { + if (isVisible(child)) { + myVisibleElements.add(treeNode); + return true; + } + } + return false; + } + return true; + } + + @Override + public boolean isReverted() { + return false; + } + + @NotNull + @Override + public ActionPresentation getPresentation() { + return new ActionPresentationData("", "", null); + } + + @NotNull + @Override + public String getName() { + return "Narrow Down"; + } + }; + + public FileStructurePopup(StructureViewModel structureViewModel, + @Nullable Editor editor, + Project project, + Navigatable navigatable, + @NotNull final Disposable auxDisposable, + final boolean applySortAndFilter) { + myProject = project; + myEditor = editor; + myNavigatable = navigatable; + myBaseTreeModel = structureViewModel; + myDisposable = auxDisposable; + if (applySortAndFilter) { + myTreeActionsOwner = new MyTreeActionsOwner(); + myTreeModel = new TreeModelWrapper(structureViewModel, myTreeActionsOwner) { + @NotNull + @Override + public Filter[] getFilters() { + return ArrayUtil.append(super.getFilters(), mySearchFilter); + } + }; + } + else { + myTreeActionsOwner = null; + myTreeModel = structureViewModel; + } + + PsiFile psiFile = getPsiFile(project); + + final PsiElement psiElement = getCurrentElement(psiFile); + + //myDialog.setUndecorated(true); + + if (psiElement != null) { + if (structureViewModel.shouldEnterElement(psiElement)) { + //myCommanderPanel.getBuilder().enterElement(psiElement, PsiUtilBase.getVirtualFile(psiElement)); + } + else { + //myCommanderPanel.getBuilder().selectElement(psiElement, PsiUtilBase.getVirtualFile(psiElement)); + } + } + + SmartTreeStructure treeStructure = new SmartTreeStructure(project, myTreeModel){ + public void rebuildTree() { + if (!myPopup.isDisposed()) { + super.rebuildTree(); + } + } + + public boolean isToBuildChildrenInBackground(final Object element) { + return getRootElement() == element; + } + + protected TreeElementWrapper createTree() { + return new StructureViewComponent.StructureViewTreeElementWrapper(myProject, myModel.getRoot(), myModel); + } + + @Override + public String toString() { + return "structure view tree structure(model=" + myTreeModel + ")"; + } + }; + + final DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode(treeStructure.getRootElement())); + myTree = new Tree(model); + myTree.setRootVisible(false); + myTree.setShowsRootHandles(true); + + myAbstractTreeBuilder = new StructureTreeBuilder(project, myTree, + (DefaultTreeModel)myTree.getModel(),treeStructure, myTreeModel) { + @Override + protected boolean validateNode(Object child) { + return StructureViewComponent.isValid(child); + } + }; + } + + public void show() { + final JComponent panel = createCenterPanel(); + new MnemonicHelper().register(panel); + myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, null) + .setTitle(myTitle) + .setResizable(true) + .setFocusable(true) + .setMovable(true) + .setDimensionServiceKey(null, getDimensionServiceKey(), false) + .createPopup(); + Disposer.register(myPopup, myDisposable); + Disposer.register(myPopup, this); + Disposer.register(myPopup, myAbstractTreeBuilder); + myPopup.showInCenterOf(myEditor.getContentComponent()); + mySpeedSearch = new TreeSpeedSearch(myTree, TreeSpeedSearch.NODE_DESCRIPTOR_TOSTRING, true); + mySpeedSearch.addChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + myVisibleElements.clear(); + myAbstractTreeBuilder.queueUpdate(); + + } + }); + myAbstractTreeBuilder.expandAll(new Runnable() { + @Override + public void run() { + IdeFocusManager.getInstance(myProject).requestFocus(myTree, true); + myAbstractTreeBuilder.queueUpdate().doWhenDone(new Runnable() { + @Override + public void run() { + myAbstractTreeBuilder.expandAll(null); + } + }); + } + }); + + } + + protected PsiFile getPsiFile(final Project project) { + return PsiDocumentManager.getInstance(project).getPsiFile(myEditor.getDocument()); + } + + @Nullable + protected Border createContentPaneBorder() { + return null; + } + + public void dispose() { + } + + protected String getDimensionServiceKey() { + return DockManager.getInstance(myProject).getDimensionKeyForFocus("#com.intellij.ide.util.FileStructureDialog"); + } + + @Nullable + protected PsiElement getCurrentElement(@Nullable final PsiFile psiFile) { + if (psiFile == null) return null; + + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + + Object elementAtCursor = myTreeModel.getCurrentEditorElement(); + if (elementAtCursor instanceof PsiElement) { + return (PsiElement)elementAtCursor; + } + + return null; + } + + protected JComponent createCenterPanel() { + List fileStructureFilters = new ArrayList(); + List fileStructureNodeProviders = new ArrayList(); + if (myTreeActionsOwner != null) { + for(Filter filter: myBaseTreeModel.getFilters()) { + if (filter instanceof FileStructureFilter) { + final FileStructureFilter fsFilter = (FileStructureFilter)filter; + myTreeActionsOwner.setActionIncluded(fsFilter, true); + fileStructureFilters.add(fsFilter); + } + } + + if (myBaseTreeModel instanceof ProvidingTreeModel) { + for (NodeProvider provider : ((ProvidingTreeModel)myBaseTreeModel).getNodeProviders()) { + if (provider instanceof FileStructureNodeProvider) { + fileStructureNodeProviders.add((FileStructureNodeProvider)provider); + } + } + } + } + + //new AnAction() { + // public void actionPerformed(AnActionEvent e) { + // final boolean succeeded = myCommanderPanel.navigateSelectedElement(); + // if (succeeded) { + // unregisterCustomShortcutSet(myCommanderPanel); + // } + // } + //}.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getShortcutSet(), myCommanderPanel); + + //myCommanderPanel.setPreferredSize(new Dimension(400, 500)); + + JPanel panel = new JPanel(new BorderLayout()); + JPanel comboPanel = new JPanel(new GridLayout(0, 2, 0, 0)); + + addNarrowDownCheckbox(comboPanel); + + for(FileStructureFilter filter: fileStructureFilters) { + addCheckbox(comboPanel, filter); + } + + for (FileStructureNodeProvider provider : fileStructureNodeProviders) { + addCheckbox(comboPanel, provider); + } + + //myCommanderPanel.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP)); + panel.add(comboPanel, BorderLayout.NORTH); + panel.add(ScrollPaneFactory.createScrollPane(myAbstractTreeBuilder.getTree()), BorderLayout.CENTER); + //new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + + return panel; + } + + protected boolean isShowRoot(final PsiFile psiFile) { + StructureViewBuilder viewBuilder = LanguageStructureViewBuilder.INSTANCE.getStructureViewBuilder(psiFile); + return viewBuilder instanceof TreeBasedStructureViewBuilder && ((TreeBasedStructureViewBuilder)viewBuilder).isRootNodeShown(); + } + + private void addNarrowDownCheckbox(final JPanel panel) { + final JCheckBox checkBox = new JCheckBox(IdeBundle.message("checkbox.narrow.down.the.list.on.typing")); + checkBox.setSelected(PropertiesComponent.getInstance().isTrueValue(ourPropertyKey)); + checkBox.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + myShouldNarrowDown = checkBox.isSelected(); + PropertiesComponent.getInstance().setValue(ourPropertyKey, Boolean.toString(myShouldNarrowDown)); + + myAbstractTreeBuilder.queueUpdate(); + } + }); + + checkBox.setFocusable(false); + panel.add(checkBox); + //,new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0)); + } + + private void addCheckbox(final JPanel panel, final TreeAction action) { + String text = action instanceof FileStructureFilter ? ((FileStructureFilter)action).getCheckBoxText() : + action instanceof FileStructureNodeProvider ? ((FileStructureNodeProvider)action).getCheckBoxText() : null; + + if (text == null) return; + + Shortcut[] shortcuts = action instanceof FileStructureFilter ? + ((FileStructureFilter)action).getShortcut() : ((FileStructureNodeProvider)action).getShortcut(); + + + final JCheckBox chkFilter = new JCheckBox(); + chkFilter.addActionListener(new ActionListener() { + public void actionPerformed(final ActionEvent e) { + PsiElement currentParent = null; + final AbstractTreeNode parentNode = null;//todo myAbstractTreeBuilder.getUi().getRootNode().; + final Object value = null; //todo parentNode.getValue(); + if (value instanceof StructureViewTreeElement) { + final Object elementValue = ((StructureViewTreeElement)value).getValue(); + if (elementValue instanceof PsiElement) { + currentParent = (PsiElement) elementValue; + } + } + final boolean state = chkFilter.isSelected(); + myTreeActionsOwner.setActionIncluded(action, action instanceof FileStructureFilter ? !state : state); + myAbstractTreeBuilder.queueUpdate(); + if (currentParent != null) { + boolean oldNarrowDown = myShouldNarrowDown; + myShouldNarrowDown = false; + try { + //todo builder.enterElement(currentParent, PsiUtilBase.getVirtualFile(currentParent)); + } + finally { + myShouldNarrowDown = oldNarrowDown; + } + } + myAbstractTreeBuilder.queueUpdate(); + + if (SpeedSearchBase.hasActiveSpeedSearch(myTree)) { + final SpeedSearchSupply supply = SpeedSearchSupply.getSupply(myTree); + if (supply != null && supply.isPopupActive()) supply.refreshSelection(); + } + } + }); + chkFilter.setFocusable(false); + + if (shortcuts.length > 0) { + text += " (" + KeymapUtil.getShortcutText(shortcuts[0]) + ")"; + new AnAction() { + public void actionPerformed(final AnActionEvent e) { + chkFilter.doClick(); + } + }.registerCustomShortcutSet(new CustomShortcutSet(shortcuts), myTree); + } + chkFilter.setText(text); + panel.add(chkFilter); + //,new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0)); + } + + @Nullable + protected JComponent createSouthPanel() { + return null; + } + + public void setTitle(String title) { + myTitle = title; + } + + private class MyCommanderPanel extends CommanderPanel implements DataProvider { + @Override + protected boolean shouldDrillDownOnEmptyElement(final AbstractTreeNode node) { + return false; + } + + public MyCommanderPanel(Project _project) { + super(_project, false, true); + myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myListSpeedSearch.addChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + ProjectListBuilder builder = (ProjectListBuilder)getBuilder(); + if (builder == null) { + return; + } + builder.addUpdateRequest(hasPrefixShortened(evt)); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + int index = myList.getSelectedIndex(); + if (index != -1 && index < myList.getModel().getSize()) { + myList.clearSelection(); + ListScrollingUtil.selectItem(myList, index); + } + else { + ListScrollingUtil.ensureSelectionExists(myList); + } + } + }); + + myList.repaint(); // to update match highlighting + } + }); + myListSpeedSearch.setComparator(createSpeedSearchComparator()); + } + + private boolean hasPrefixShortened(final PropertyChangeEvent evt) { + return evt.getNewValue() != null && evt.getOldValue() != null && + ((String)evt.getNewValue()).length() < ((String)evt.getOldValue()).length(); + } + + public boolean navigateSelectedElement() { + final Ref succeeded = new Ref(); + final CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand(myProject, new Runnable() { + public void run() { + succeeded.set(MyCommanderPanel.super.navigateSelectedElement()); + IdeDocumentHistory.getInstance(myProject).includeCurrentCommandAsNavigation(); + } + }, "Navigate", null); + if (succeeded.get()) { + myPopup.cancel(); + } + return succeeded.get(); + } + + public Object getData(String dataId) { + Object selectedElement = ContainerUtil.getFirstItem(myAbstractTreeBuilder.getSelectedElements()); + + if (selectedElement instanceof TreeElement) selectedElement = ((StructureViewTreeElement)selectedElement).getValue(); + + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { + return selectedElement instanceof Navigatable ? selectedElement : myNavigatable; + } + + if (OpenFileDescriptor.NAVIGATE_IN_EDITOR.is(dataId)) return myEditor; + + return getDataImpl(dataId); + } + + public String getEnteredPrefix() { + return myListSpeedSearch.getEnteredPrefix(); + } + + public void updateSpeedSearch() { + myListSpeedSearch.refreshSelection(); + } + + public void scrollSelectionInView() { + int selectedIndex = myList.getSelectedIndex(); + if (selectedIndex >= 0) { + ListScrollingUtil.ensureIndexIsVisible(myList, selectedIndex, 0); + } + } + } + + private class MyStructureTreeStructure extends SmartTreeStructure { + public MyStructureTreeStructure(Project project) { + super(project, myTreeModel); + } + + public Object[] getChildElements(Object element) { + Object[] childElements = super.getChildElements(element); + + if (!myShouldNarrowDown) { + return childElements; + } + + String enteredPrefix = null;//todo myCommanderPanel.getEnteredPrefix(); + if (enteredPrefix == null) { + return childElements; + } + + ArrayList filteredElements = new ArrayList(childElements.length); + SpeedSearchBase.SpeedSearchComparator speedSearchComparator = createSpeedSearchComparator(); + + for (Object child : childElements) { + if (child instanceof AbstractTreeNode) { + Object value = ((AbstractTreeNode)child).getValue(); + if (value instanceof TreeElement) { + String name = ((TreeElement)value).getPresentation().getPresentableText(); + if (name == null) { + continue; + } + if (speedSearchComparator.matchingFragments(enteredPrefix, name) == null) { + continue; + } + } + } + filteredElements.add(child); + } + return ArrayUtil.toObjectArray(filteredElements); + } + + public void rebuildTree() { + getChildElements(getRootElement()); // for some reason necessary to rebuild tree correctly + super.rebuildTree(); + } + } + + private static SpeedSearchBase.SpeedSearchComparator createSpeedSearchComparator() { + return new SpeedSearchBase.SpeedSearchComparator(false); + } + + private class MyTreeActionsOwner implements TreeActionsOwner { + private final Set myActions = new HashSet(); + + public void setActionActive(String name, boolean state) { + } + + public boolean isActionActive(String name) { + for (final Sorter sorter : myBaseTreeModel.getSorters()) { + if (sorter.getName().equals(name)) { + if (!sorter.isVisible()) return true; + } + } + for(TreeAction action: myActions) { + if (action.getName().equals(name)) return true; + } + return Sorter.ALPHA_SORTER_ID.equals(name); + } + + public void setActionIncluded(final TreeAction filter, final boolean selected) { + if (selected) { + myActions.add(filter); + } + else { + myActions.remove(filter); + } + } + } + +} diff --git a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java index ab4f8908dcc3..ecbe04efce14 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java @@ -92,13 +92,13 @@ public abstract class AbstractInplaceIntroducer extends VariableInp myTitle = title; myOccurrences = occurrences; myExpr = expr; - myExprMarker = myExpr != null && myExpr.isPhysical() ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null; + myExprMarker = myExpr != null && myExpr.isPhysical() ? createMarker(myExpr) : null; initOccurrencesMarkers(); } @@ -127,10 +127,14 @@ public class InplaceVariableIntroducer extends VariableInp if (myOccurrenceMarkers != null) return; myOccurrenceMarkers = new ArrayList(); for (E occurrence : myOccurrences) { - myOccurrenceMarkers.add(myEditor.getDocument().createRangeMarker(occurrence.getTextRange())); + myOccurrenceMarkers.add(createMarker(occurrence)); } } + protected RangeMarker createMarker(PsiElement element) { + return myEditor.getDocument().createRangeMarker(element.getTextRange()); + } + public RangeMarker getExprMarker() { return myExprMarker; @@ -234,4 +238,8 @@ public class InplaceVariableIntroducer extends VariableInp //move logic to performRefactoring } + @Override + protected boolean performAutomaticRename() { + return false; + } } diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java index 183d0ac3dfdb..49507da0c699 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java @@ -338,7 +338,7 @@ public class VariableInplaceRenamer { performOnInvalidIdentifier(myNewName, nameSuggestions); return; } - if (snapshot != null && performAutomaticRename()) { + if (myNewName != null && snapshot != null && performAutomaticRename()) { if (LanguageNamesValidation.INSTANCE.forLanguage(scope1.getLanguage()).isIdentifier(myNewName, myProject)) { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { @@ -536,6 +536,7 @@ public class VariableInplaceRenamer { @Nullable protected String getNewName(String newName, ResolveSnapshotProvider.ResolveSnapshot snapshot) { + if (!performAutomaticRename()) return null; return snapshot != null ? newName : null; } diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java index c0079bafd7d6..655a4d1cf9ad 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java @@ -594,9 +594,9 @@ public class IdeEventQueue extends EventQueue { } boolean mouseEventsAhead = isMouseEventAhead(e); - boolean focusTransferred = IdeFocusManager.getGlobalInstance().isFocusBeingTransferred(); + boolean focusTransferredNow = IdeFocusManager.getGlobalInstance().isFocusBeingTransferred(); - boolean okToFixFocus = !mouseEventsAhead && focusTransferred; + boolean okToFixFocus = !mouseEventsAhead && !focusTransferredNow; if (okToFixFocus) { Window showingWindow = mgr.getActiveWindow(); diff --git a/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java b/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java index df752f1c2449..091162cb8a81 100644 --- a/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java +++ b/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java @@ -158,6 +158,9 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon final List paths = new ArrayList(); synchronized (myState) { outer: for (String recentPath : myState.recentPaths) { + if (recentPath == null) { + continue; + } for (Project openProject : openProjects) { final String path = getProjectPath(openProject); @@ -269,7 +272,7 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon } } - @Nullable + @NotNull private static String getProjectName(String path) { final File file = new File(path); if (file.isDirectory()) { @@ -294,14 +297,12 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon } } } - } else { - return file.getName(); } - } else { + return file.getName(); + } + else { return FileUtil.getNameWithoutExtension(file.getName()); } - - return null; } private class MyAppLifecycleListener extends AppLifecycleListener.Adapter { diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java index bce5ad94accd..fb605f852164 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java @@ -1105,7 +1105,9 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat } public Set getActionIds(){ - return new HashSet(myId2Action.keySet()); + synchronized (myLock) { + return new HashSet(myId2Action.keySet()); + } } private int myActionsPreloaded = 0; diff --git a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java index 15bb60eb6a82..5d42a065f141 100644 --- a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java @@ -1330,6 +1330,11 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { } public void _setBounds(Rectangle bounds) { + Rectangle currentBounds = getBounds(); + if (currentBounds.width != bounds.width || currentBounds.height != bounds.height) { + invalidateShadowImage(); + } + super.setBounds(bounds); if (myCloseRec.getParent() == null && getParent() != null) { myLayeredPane.add(myCloseRec); @@ -1357,6 +1362,11 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { } } + private void invalidateShadowImage() { + myImage = null; + myShadow = null; + } + public void repaintButton() { myCloseRec.repaint(); } diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 8e919fa85bad..9aa929eeb832 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -169,3 +169,4 @@ show.anonymous.in.structure.view.description=Enables Java anonymous classes in S enable.groovy.hotswap=true enable.groovy.hotswap.description=Whether IDEA should add a special java agent to the debugged process which allows to hot-swap Groovy changes in some cases +file.structure.tree.mode=false diff --git a/platform/util/src/com/intellij/openapi/ui/Splitter.java b/platform/util/src/com/intellij/openapi/ui/Splitter.java index bfd632013c1a..93e446a10bfa 100644 --- a/platform/util/src/com/intellij/openapi/ui/Splitter.java +++ b/platform/util/src/com/intellij/openapi/ui/Splitter.java @@ -432,7 +432,7 @@ public class Splitter extends JPanel { } /** - * Sets component which is located as the "secont" splitted area. The method doesn't validate and + * Sets component which is located as the "second" splitted area. The method doesn't validate and * repaint the splitter. * * @param component diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/ui/SearchFieldAction.java b/platform/vcs-api/src/com/intellij/openapi/vcs/ui/SearchFieldAction.java index db93a77b67ad..0443a3f03a90 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/ui/SearchFieldAction.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/ui/SearchFieldAction.java @@ -19,10 +19,13 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.actionSystem.ex.CustomComponentAction; import com.intellij.openapi.util.IconLoader; +import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.SearchTextField; import com.intellij.util.ui.UIUtil; import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.CompoundBorder; import java.awt.event.KeyEvent; /** @@ -56,6 +59,15 @@ public abstract class SearchFieldAction extends AnAction implements CustomCompon actionPerformed(null); } }; + Border border = myField.getBorder(); + Border emptyBorder = IdeBorderFactory.createEmptyBorder(3, 0, 2, 0); + if (border instanceof CompoundBorder) { + myField.setBorder(new CompoundBorder(emptyBorder, ((CompoundBorder)border).getInsideBorder())); + } + else { + myField.setBorder(emptyBorder); + } + myField.setSearchIcon(IconLoader.getIcon("/actions/filter_small.png")); myComponent = new JPanel(); final BoxLayout layout = new BoxLayout(myComponent, BoxLayout.X_AXIS); diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointType.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointType.java index b90c40fd39d4..ccded14b5c56 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointType.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointType.java @@ -118,11 +118,19 @@ public abstract class XBreakpointType, P extends XBreak return null; } + /** + * @deprecated override {@link #getEditorsProvider(XBreakpoint)} instead + */ @Nullable public XDebuggerEditorsProvider getEditorsProvider() { return null; } + @Nullable + public XDebuggerEditorsProvider getEditorsProvider(@NotNull B breakpoint) { + return getEditorsProvider(); + } + public List> getGroupingRules() { return Collections.emptyList(); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointPropertiesPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointPropertiesPanel.java index a4e6010f37cd..04dc11f69023 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointPropertiesPanel.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointPropertiesPanel.java @@ -63,7 +63,7 @@ public class XBreakpointPropertiesPanel> { mySuspendPolicyPanel.init(project, breakpointManager, breakpoint); - XDebuggerEditorsProvider debuggerEditorsProvider = breakpointType.getEditorsProvider(); + XDebuggerEditorsProvider debuggerEditorsProvider = breakpointType.getEditorsProvider(breakpoint); myBreakpointActionsPanel.init(project, breakpointManager, breakpoint, debuggerEditorsProvider); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java index e12a835764a0..ca5e69bb1372 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java @@ -105,7 +105,7 @@ public class XLightBreakpointPropertiesPanel> implement mySubPanels.add(mySuspendPolicyPanel); myMasterBreakpointPanel.init(project, breakpointManager, breakpoint); mySubPanels.add(myMasterBreakpointPanel); - XDebuggerEditorsProvider debuggerEditorsProvider = breakpointType.getEditorsProvider(); + XDebuggerEditorsProvider debuggerEditorsProvider = breakpointType.getEditorsProvider(breakpoint); myActionsPanel.init(project, breakpointManager, breakpoint, debuggerEditorsProvider); mySubPanels.add(myActionsPanel); diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EclipseClasspathReader.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EclipseClasspathReader.java index 0d11360e8661..b633502aefd5 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EclipseClasspathReader.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EclipseClasspathReader.java @@ -50,6 +50,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; +import java.util.regex.PatternSyntaxException; import static org.jetbrains.idea.eclipse.conversion.EPathUtil.*; @@ -150,7 +151,13 @@ public class EclipseClasspathReader { } else { String srcUrl = VfsUtil.pathToUrl(myRootPath + "/" + path); - final boolean isTestFolder = testPattern != null && testPattern.length() > 0 && path.matches(testPattern); + boolean isTestFolder = false; + try { + isTestFolder = testPattern != null && testPattern.length() > 0 && path.matches(testPattern); + } + catch (PatternSyntaxException e) { + isTestFolder = false; + } final EclipseProjectFinder.LinkedResource linkedResource = EclipseProjectFinder.findLinkedResource(myRootPath, path); if (linkedResource != null) { if (linkedResource.containsPathVariable()) { diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/GitLogSettings.java b/plugins/git4idea/src/git4idea/history/wholeTree/GitLogSettings.java index cd543450b116..7fbb80412a4e 100644 --- a/plugins/git4idea/src/git4idea/history/wholeTree/GitLogSettings.java +++ b/plugins/git4idea/src/git4idea/history/wholeTree/GitLogSettings.java @@ -64,6 +64,7 @@ public class GitLogSettings implements PersistentStateComponent myCommitsInRepositoryChangesBrowser; private boolean myDataBeingAdded; - private CardLayout myRepoLayout; - private JPanel myRepoPanel; private boolean myStarted; private String myPreviousFilter; private final CommentSearchContext myCommentSearchContext; @@ -134,6 +129,7 @@ public class GitLogUI implements Disposable { private MyRefreshAction myRefreshAction; private MyStructureFilter myStructureFilter; private StructureFilterAction myStructureFilterAction; + private ToggleAction myShowDetailsAction; private AnAction myCopyHashAction; // todo group somewhere?? private Consumer myDetailsLoaderImpl; @@ -153,6 +149,8 @@ public class GitLogUI implements Disposable { private JViewport myTableViewPort; private GitLogUI.MyGotoCommitAction myMyGotoCommitAction; private final Set myClearedHighlightingRoots; + private final Splitter myDetailsSplitter; + private JScrollPane myTableScrollPane; public GitLogUI(Project project, final Mediator mediator) { myProject = project; @@ -192,6 +190,8 @@ public class GitLogUI implements Disposable { reloadRequest(); } }; + myDetailsSplitter = new Splitter(true, 0.6f); + myDetailsSplitter.setShowDividerControls(true); } public void initFromSettings() { @@ -388,7 +388,6 @@ public class GitLogUI implements Disposable { public void createMe() { mySplitter = new Splitter(false, 0.7f); - mySplitter.setDividerWidth(4); final JPanel wrapper = createMainTable(); mySplitter.setFirstComponent(wrapper); @@ -487,10 +486,10 @@ public class GitLogUI implements Disposable { } private JComponent createRepositoryBrowserDetails() { - myRepoLayout = new CardLayout(); - myRepoPanel = new JPanel(myRepoLayout); myRepositoryChangesBrowser = new RepositoryChangesBrowser(myProject, Collections.emptyList(), Collections.emptyList(), null); myRepositoryChangesBrowser.getDiffAction().registerCustomShortcutSet(CommonShortcuts.getDiff(), myJBTable); + myRepositoryChangesBrowser.getViewer().setScrollPaneBorder(IdeBorderFactory.createBorder(SideBorder.LEFT | SideBorder.TOP | SideBorder.RIGHT)); + myRepositoryChangesBrowser.setBorder(IdeBorderFactory.createEmptyBorder(0, 0, 0, 4)); myJBTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { @@ -498,13 +497,7 @@ public class GitLogUI implements Disposable { mySelectionRequestsMerger.request(); } }); - myRepoPanel.add("main", myRepositoryChangesBrowser); - // todo loading circle - myRepoPanel.add("loading", panelWithCenteredText("Loading...")); - myRepoPanel.add("tooMuch", panelWithCenteredText("Too many rows selected")); - myRepoPanel.add("empty", panelWithCenteredText("Nothing selected")); - myRepoLayout.show(myRepoPanel, "empty"); - return myRepoPanel; + return myRepositoryChangesBrowser; } private void selectionChanged() { @@ -516,17 +509,14 @@ public class GitLogUI implements Disposable { selectionChangedForDetails(rows); if (rows.length == 0) { - myRepoLayout.show(myRepoPanel, "empty"); - myRepoPanel.repaint(); + myRepositoryChangesBrowser.getViewer().setEmptyText("Nothing selected"); return; } else if (rows.length >= 10) { - myRepoLayout.show(myRepoPanel, "tooMuch"); - myRepoPanel.repaint(); + myRepositoryChangesBrowser.getViewer().setEmptyText("Too many rows selected"); return; } if (! myDataBeingAdded && ! gatherNotLoadedData()) { - myRepoLayout.show(myRepoPanel, "loading"); - myRepoPanel.repaint(); + myRepositoryChangesBrowser.getViewer().setEmptyText("Loading..."); } } @@ -591,16 +581,6 @@ public class GitLogUI implements Disposable { return myDetailsCache.convert(commitAt.selectRepository(myRootsUnderVcs), commitAt.getHash()); } - private static JPanel panelWithCenteredText(final String text) { - final JPanel jPanel = new JPanel(new BorderLayout()); - jPanel.setBackground(UIUtil.getTableBackground()); - final JLabel label = new JLabel(text, JLabel.CENTER); - label.setUI(new MultiLineLabelUI()); - jPanel.add(label, BorderLayout.CENTER); - jPanel.setBorder(BorderFactory.createLineBorder(UIUtil.getBorderColor())); - return jPanel; - } - public void updateByScroll() { gatherNotLoadedData(); } @@ -638,8 +618,6 @@ public class GitLogUI implements Disposable { } final List zipped = CommittedChangesTreeBrowser.zipChanges(changes); myRepositoryChangesBrowser.setChangesToDisplay(zipped); - myRepoLayout.show(myRepoPanel, "main"); - myRepoPanel.repaint(); return true; } @@ -678,17 +656,18 @@ public class GitLogUI implements Disposable { }; myJBTable.addMouseListener(popupHandler); - final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myJBTable); + myTableScrollPane = ScrollPaneFactory.createScrollPane(myJBTable); + myTableScrollPane.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.RIGHT | SideBorder.BOTTOM)); myGraphGutter = new GraphGutter(myTableModel); myGraphGutter.setJBTable(myJBTable); - myTableViewPort = scrollPane.getViewport(); + myTableViewPort = myTableScrollPane.getViewport(); myGraphGutter.setTableViewPort(myTableViewPort); myGraphGutter.getComponent().addMouseListener(popupHandler); new AdjustComponentWhenShown() { @Override protected boolean init() { - return adjustColumnSizes(scrollPane); + return adjustColumnSizes(myTableScrollPane); } @Override @@ -711,7 +690,7 @@ public class GitLogUI implements Disposable { } } ); - scrollPane.getViewport().addChangeListener(myMyChangeListener); + myTableScrollPane.getViewport().addChangeListener(myMyChangeListener); final JPanel wrapper = new DataProviderPanel(new BorderLayout()); wrapper.add(actionToolbar.getComponent(), BorderLayout.NORTH); @@ -722,9 +701,10 @@ public class GitLogUI implements Disposable { wrapperGutter.add(myEqualToHeadr, BorderLayout.NORTH); wrapperGutter.add(myGraphGutter.getComponent(), BorderLayout.CENTER); mainBorderWrapper.add(wrapperGutter, BorderLayout.WEST); - mainBorderWrapper.add(scrollPane, BorderLayout.CENTER); + mainBorderWrapper.add(myTableScrollPane, BorderLayout.CENTER); //mainBorderWrapper.setBorder(BorderFactory.createLineBorder(UIUtil.getBorderColor())); wrapper.add(mainBorderWrapper, BorderLayout.CENTER); + myDetailsPanel = new GitLogDetailsPanel(myProject, myDetailsCache, new Convertor() { @Override public CachedRefs convert(VirtualFile o) { @@ -736,15 +716,12 @@ public class GitLogUI implements Disposable { return myMarked.contains(hash); } }); - final JPanel borderWrapper = new JPanel(new BorderLayout()); - borderWrapper.setBorder(BorderFactory.createLineBorder(UIUtil.getBorderColor())); - borderWrapper.add(myDetailsPanel.getComponent(), BorderLayout.CENTER); - final Splitter splitter = new Splitter(true, 0.6f); - splitter.setFirstComponent(wrapper); - splitter.setSecondComponent(borderWrapper); - splitter.setDividerWidth(4); - return splitter; + myDetailsSplitter.setFirstComponent(wrapper); + JPanel details = myDetailsPanel.getComponent(); + details.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.RIGHT)); + setupDetailsSplitter(GitLogSettings.getInstance(myProject).isShowDetails()); + return myDetailsSplitter; } private void createTreeUpperComponent() { @@ -888,6 +865,19 @@ public class GitLogUI implements Disposable { myRootsAction = new MyRootsAction(rootsGetter, myJBTable); group.add(myRootsAction); group.add(myMyShowTreeAction); + myShowDetailsAction = new ToggleAction("Show Details", "Display details panel", IconLoader.getIcon("/actions/showSource.png")) { + @Override + public boolean isSelected(AnActionEvent e) { + return GitLogSettings.getInstance(myProject).isShowDetails(); + } + + @Override + public void setSelected(AnActionEvent e, boolean state) { + setupDetailsSplitter(state); + GitLogSettings.getInstance(myProject).setShowDetails(state); + } + }; + group.add(myShowDetailsAction); myMyGotoCommitAction = new MyGotoCommitAction(); group.add(myMyGotoCommitAction); group.add(myRefreshAction); @@ -928,6 +918,16 @@ public class GitLogUI implements Disposable { return ActionManager.getInstance().createActionToolbar("Git log", group, true); } + private void setupDetailsSplitter(boolean state) { + myDetailsSplitter.setSecondComponent(state ? myDetailsPanel.getComponent() : null); + if (state) { + myTableScrollPane.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.RIGHT | SideBorder.BOTTOM)); + } + else { + myTableScrollPane.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.RIGHT)); + } + } + private class DataProviderPanel extends JPanel implements TypeSafeDataProvider { private DataProviderPanel(LayoutManager layout) { super(layout); @@ -1461,6 +1461,7 @@ public class GitLogUI implements Disposable { private class MyTextFieldAction extends SearchFieldAction { private MyTextFieldAction() { super("Filter:"); + } @Override @@ -1827,7 +1828,7 @@ public class GitLogUI implements Disposable { private final GitLogSettings myInstance; public MyShowTreeAction() { - super("Show graph", "Show graph", IconLoader.getIcon("/icons/branch.png")); + super("Show Graph", "Display commit graph", IconLoader.getIcon("/icons/branch.png")); myInstance = GitLogSettings.getInstance(myProject); myIsSelected = myInstance.isShowTree(); } diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java index 8560d9003258..88b079f1e040 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java @@ -58,7 +58,7 @@ public final class GitRepositoryManager extends AbstractProjectComponent impleme @Override public void initComponent() { - myProject.getMessageBus().connect(this).subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this); + myProject.getMessageBus().connect().subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this); Disposer.register(myProject, this); } diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 03f92e0930d7..fd3c5dc3a5c4 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -1077,6 +1077,10 @@ text="Change SDK version" description="Change Grails/Griffon SDK version"> + + + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties index 6d94d0a5290d..1fee7a5559a2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties @@ -295,7 +295,6 @@ default.initializers.are.not.allowed.in.abstract.method=Default initializers are groovy.does.not.support.constructor.type.arguments=Groovy does not support constructor type arguments illegal.escape.character.in.string.literal=Illegal escape character in string literal dollar.slash.end.expected=Dollar slash ending expected -regex.cannot.be.first.argument.of.command.method.call=Dollar-slashy strings cannot be the first argument of a command method call add.parentheses=Add parentheses add.parentheses.to.command.method.call=Add parentheses to command method call -dollar.slash.strings.are.not.allowed.in.0=Dollar-slash strings are not allowed in Groovy {0} \ No newline at end of file +dollar.slash.strings.are.not.allowed.in.0=Dollar slashy strings are not allowed in Groovy {0} 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 c4ad23b92f7b..44e73486e68c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -279,9 +279,14 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { private void checkStringNameIdentifier(GrReferenceExpression ref) { final PsiElement nameElement = ref.getReferenceNameElement(); if (nameElement == null) return; - if (!GroovyTokenTypes.mSTRING_LITERAL.equals(nameElement.getNode().getElementType())) return; - final String text = nameElement.getText(); - checkStringLiteral(nameElement, text); + + final IElementType elementType = nameElement.getNode().getElementType(); + if (elementType == GroovyTokenTypes.mSTRING_LITERAL || elementType == GroovyTokenTypes.mGSTRING_LITERAL) { + checkStringLiteral(nameElement, nameElement.getText()); + } + else if (elementType == GroovyTokenTypes.mREGEX_LITERAL || elementType == GroovyTokenTypes.mDOLLAR_SLASH_REGEX_LITERAL) { + checkRegexLiteral(nameElement); + } } /* @@ -856,19 +861,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { myHolder .createErrorAnnotation(regex, GroovyBundle.message("dollar.slash.strings.are.not.allowed.in.0", config.getSDKVersion(regex))); } - if (regex instanceof GrRegex && - regex.getParent() instanceof GrCommandArgumentList && - ((GrCommandArgumentList)regex.getParent()).getAllArguments()[0] == regex || - - !(regex instanceof GrRegex) && - regex.getParent().getParent() instanceof GrCommandArgumentList && - ((GrCommandArgumentList)regex.getParent().getParent()).getAllArguments()[0] == regex.getParent() - ) { - final Annotation annotation = - myHolder.createErrorAnnotation(regex, GroovyBundle.message("regex.cannot.be.first.argument.of.command.method.call")); - annotation.registerFix(new AddParenthesesFix()); - return; - } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java index 096776e53f78..b3482defa348 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java @@ -82,7 +82,7 @@ public class GeeseUtil { } @Nullable - static Alignment calculateRBraceAlignment(PsiElement rBrace, Map alignments, Map blocks) { + static Alignment calculateRBraceAlignment(PsiElement rBrace, Map alignments) { int leadingBraceCount = 0; PsiElement next; @@ -146,11 +146,7 @@ public class GeeseUtil { Alignment alignment = alignments.get(cur); if (alignment == null) { - final GroovyBlock block = blocks.get(cur); alignment = Alignment.createAlignment(true); - if (block != null) { - block.setAlignment(alignment); - } alignments.put(cur, alignment); } return alignment; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java index a0ad58d184f7..48d99924c203 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java @@ -55,7 +55,7 @@ import java.util.Map; * * @author ilyas */ -public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { +public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { final protected ASTNode myNode; protected Alignment myAlignment; final protected Indent myIndent; @@ -63,7 +63,6 @@ public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock final protected CommonCodeStyleSettings mySettings; final protected GroovyCodeStyleSettings myGroovySettings; final protected Map myInnerAlignments; - final protected Map myBlocks; protected List mySubBlocks = null; @@ -73,12 +72,10 @@ public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock @Nullable final Wrap wrap, final CommonCodeStyleSettings settings, GroovyCodeStyleSettings groovySettings, - @NotNull Map innerAlignments, Map blocks) { + @NotNull Map innerAlignments) { myNode = node; - myBlocks = blocks; if (groovySettings.USE_FLYING_GEESE_BRACES) { PsiElement psi = myNode.getPsi(); - myBlocks.put(psi, this); if (alignment == null) { alignment = innerAlignments.get(psi); } @@ -119,8 +116,12 @@ public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock } @NotNull + @Override public List getSubBlocks() { - return mySubBlocks; + if (mySubBlocks == null) { + mySubBlocks = new GroovyBlockGenerator(this).generateSubBlocks(); + } + return mySubBlocks; } @Nullable @@ -228,10 +229,6 @@ public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock return isIncomplete(myNode); } - public void setAlignment(Alignment alignment) { - myAlignment = alignment; - } - /** * @param node Tree node * @return true if node is incomplete diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java index d72d4a061660..dcc7e2719d92 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java @@ -82,7 +82,6 @@ public class GroovyBlockGenerator implements GroovyElementTypes { private final Wrap myWrap; private final CommonCodeStyleSettings mySettings; private final Map myInnerAlignments; - private final Map myBlocks; private final GroovyCodeStyleSettings myGroovySettings; public GroovyBlockGenerator(GroovyBlock block) { @@ -93,7 +92,6 @@ public class GroovyBlockGenerator implements GroovyElementTypes { mySettings = myBlock.getSettings(); myInnerAlignments = myBlock.getInnerAlignments(); myGroovySettings = myBlock.getGroovySettings(); - myBlocks = myBlock.myBlocks; } @@ -136,8 +134,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { for (ASTNode childNode : children) { if (childNode.getTextRange().getLength() > 0) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); - subBlocks.add(new GroovySimpleBlock(childNode, myAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks)); + subBlocks.add(new GroovyBlock(childNode, myAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } } return subBlocks; @@ -158,8 +155,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final Alignment newAlignment = mustAlign(blockPsi, astNodes) ? Alignment.createAlignment() : null; for (ASTNode childNode : astNodes) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); - subBlocks.add(new GroovySimpleBlock(childNode, isKeyword(childNode) ? null : newAlignment, indent, myWrap, mySettings, myGroovySettings, - myInnerAlignments, myBlocks)); + subBlocks.add(new GroovyBlock(childNode, isKeyword(childNode) ? null : newAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } return subBlocks; } @@ -172,8 +168,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { for (ASTNode childNode : children) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); Alignment alignmentToUse = classLevel ? myAlignment : myInnerAlignments.get(childNode.getPsi()); - subBlocks.add(new GroovySimpleBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks)); + subBlocks.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } return subBlocks; } @@ -182,8 +177,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final ArrayList subBlocks = new ArrayList(); for (ASTNode childNode : visibleChildren(myNode)) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); - subBlocks.add(new GroovySimpleBlock(childNode, myInnerAlignments.get(childNode.getPsi()), indent, myWrap, mySettings, myGroovySettings, - myInnerAlignments, myBlocks)); + subBlocks.add(new GroovyBlock(childNode, myInnerAlignments.get(childNode.getPsi()), indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } return subBlocks; } @@ -232,9 +226,9 @@ public class GroovyBlockGenerator implements GroovyElementTypes { } } } - else if (GeeseUtil.isClosureRBrace(psi) && myGroovySettings.USE_FLYING_GEESE_BRACES) { + /*else if (GeeseUtil.isClosureRBrace(psi) && myGroovySettings.USE_FLYING_GEESE_BRACES) { myInnerAlignments.put(psi, GeeseUtil.calculateRBraceAlignment(psi, myInnerAlignments, myBlocks)); - } + }*/ else { if (psi instanceof PsiComment) { PsiElement prev = psi.getPrevSibling(); @@ -325,22 +319,19 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final int start = myNode.getTextRange().getStartOffset(); final int end = myNode.getTextRange().getEndOffset(); - subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks) { + subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { @NotNull public TextRange getTextRange() { return new TextRange(start, start + 3); } }); - subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks) { + subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { @NotNull public TextRange getTextRange() { return new TextRange(start + 3, end - 3); } }); - subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks) { + subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { @NotNull public TextRange getTextRange() { return new TextRange(end - 3, end); @@ -354,15 +345,13 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final int start = myNode.getTextRange().getStartOffset(); final int end = myNode.getTextRange().getEndOffset(); - subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks) { + subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { @NotNull public TextRange getTextRange() { return new TextRange(start, start + 3); } }); - subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks) { + subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { @NotNull public TextRange getTextRange() { return new TextRange(start + 3, end); @@ -444,8 +433,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { PsiElement psi = childNode.getPsi(); if (!(psi instanceof GrBinaryExpression)) { Alignment alignmentToUse = op == psi ? myInnerAlignments.get(op) : alignment; - list.add(new GroovySimpleBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks)); + list.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } } if (myExpr.getRightOperand() instanceof GrBinaryExpression) { @@ -474,8 +462,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { } if (i < grandChildren.size()) { LOG.assertTrue(nameElement == grandChildren.get(i).getPsi()); - list.add(new MethodCallWithoutQualifierBlock(nameElement, null, myWrap, mySettings, myGroovySettings, topLevel, children, elem, - myInnerAlignments, myBlocks)); + list.add(new MethodCallWithoutQualifierBlock(nameElement, null, myWrap, mySettings, myGroovySettings, topLevel, children, elem, myInnerAlignments)); } return; } @@ -496,7 +483,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { else { Alignment alignmentToUse = myInnerAlignments.get(fst.getPsi()); Indent indent = Indent.getContinuationWithoutFirstIndent(); - list.add(new GroovySimpleBlock(fst, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments, myBlocks)); + list.add(new GroovyBlock(fst, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } addNestedChildrenSuffix(list, alignment, topLevel, children, limit); } @@ -510,7 +497,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { Indent.getContinuationWithoutFirstIndent() : Indent.getNoneIndent(); Alignment alignmentToUse = TokenSets.DOTS.contains(type) ? alignment : myInnerAlignments.get(childNode.getPsi()); - list.add(new GroovySimpleBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments, myBlocks)); + list.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java index c697f266a297..6fd00921d65f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java @@ -21,6 +21,7 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiRecursiveElementVisitor; import com.intellij.psi.TokenType; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; @@ -36,6 +37,8 @@ import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; +import java.util.Map; + /** * @author ilyas */ @@ -50,9 +53,24 @@ public class GroovyFormattingModelBuilder implements FormattingModelBuilder { assert astNode != null; CommonCodeStyleSettings groovySettings = settings.getCommonSettings(GroovyFileType.GROOVY_LANGUAGE); GroovyCodeStyleSettings customSettings = settings.getCustomSettings(GroovyCodeStyleSettings.class); - final GroovyBlock block = new GroovySimpleBlock(astNode, null, Indent.getAbsoluteNoneIndent(), null, groovySettings, customSettings, - CollectionFactory.hashMap(), - CollectionFactory.hashMap()); + + final Map innerAlignments = CollectionFactory.hashMap(); + if (customSettings.USE_FLYING_GEESE_BRACES) { + element.accept(new PsiRecursiveElementVisitor() { + @Override + public void visitElement(PsiElement element) { + if (GeeseUtil.isClosureRBrace(element)) { + final Alignment alignment = GeeseUtil.calculateRBraceAlignment(element, innerAlignments); + innerAlignments.put(element, alignment); + } + else { + super.visitElement(element); + } + } + }); + } + final GroovyBlock block = + new GroovyBlock(astNode, null, Indent.getAbsoluteNoneIndent(), null, groovySettings, customSettings, innerAlignments); return new GroovyFormattingModel(containingFile, block, FormattingDocumentModelImpl.createOn(containingFile)); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovySimpleBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovySimpleBlock.java deleted file mode 100644 index 960c12d8a0e8..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovySimpleBlock.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2000-2011 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.formatter; - -import com.intellij.formatting.Alignment; -import com.intellij.formatting.Indent; -import com.intellij.formatting.Wrap; -import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiElement; -import com.intellij.psi.codeStyle.CommonCodeStyleSettings; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Map; - -/** - * @author Max Medvedev - */ -public class GroovySimpleBlock extends GroovyBlock { - public GroovySimpleBlock(@NotNull ASTNode node, - @Nullable Alignment alignment, - @NotNull Indent indent, - @Nullable Wrap wrap, - CommonCodeStyleSettings settings, - GroovyCodeStyleSettings groovySettings, - @NotNull Map innerAlignments, Map blocks) { - super(node, alignment, indent, wrap, settings, groovySettings, innerAlignments, blocks); - mySubBlocks = new GroovyBlockGenerator(this).generateSubBlocks(); - } -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java index 51aa16d7887c..001814778e3a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java @@ -33,36 +33,48 @@ import java.util.Map; * @author peter */ public class MethodCallWithoutQualifierBlock extends GroovyBlock { - private final TextRange myRange; + private final PsiElement myNameElement; + private final boolean myTopLevel; + private final List myChildren; + private final PsiElement myElem; - protected MethodCallWithoutQualifierBlock(PsiElement nameElement, - Alignment alignment, - Wrap wrap, - CommonCodeStyleSettings settings, - GroovyCodeStyleSettings groovySettings, - boolean topLevel, - List children, - PsiElement elem, - Map innerAlignments, Map blocks) { - super(nameElement.getNode(), alignment, Indent.getContinuationWithoutFirstIndent(), wrap, settings, groovySettings, innerAlignments,blocks); - myRange = new TextRange(nameElement.getTextRange().getStartOffset(), elem.getTextRange().getEndOffset()); + public MethodCallWithoutQualifierBlock(PsiElement nameElement, + Alignment alignment, + Wrap wrap, + CommonCodeStyleSettings settings, + GroovyCodeStyleSettings groovySettings, + boolean topLevel, + List children, + PsiElement elem, + Map innerAlignments) { + super(nameElement.getNode(), alignment, Indent.getContinuationWithoutFirstIndent(), wrap, settings, groovySettings, innerAlignments); + myNameElement = nameElement; + myTopLevel = topLevel; + myChildren = children; + myElem = elem; + } - mySubBlocks = new ArrayList(); - final GroovySimpleBlock first = - new GroovySimpleBlock(nameElement.getNode(), myInnerAlignments.get(nameElement), Indent.getContinuationWithoutFirstIndent(), myWrap, - mySettings, myGroovySettings, myInnerAlignments, myBlocks); - mySubBlocks.add(first); - new GroovyBlockGenerator(this).addNestedChildrenSuffix(mySubBlocks, myAlignment, topLevel, children, children.size()); + @NotNull + @Override + public List getSubBlocks() { + if (mySubBlocks == null) { + mySubBlocks = new ArrayList(); + mySubBlocks.add( + new GroovyBlock(myNameElement.getNode(), myInnerAlignments.get(myNameElement), Indent.getContinuationWithoutFirstIndent(), myWrap, + mySettings, myGroovySettings, myInnerAlignments)); + new GroovyBlockGenerator(this).addNestedChildrenSuffix(mySubBlocks, myAlignment, myTopLevel, myChildren, myChildren.size()); + } + return mySubBlocks; } @NotNull @Override public TextRange getTextRange() { - return myRange; + return new TextRange(myNameElement.getTextRange().getStartOffset(), myElem.getTextRange().getEndOffset()); } @Override public boolean isLeaf() { return false; } -} +} \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/grape/GrabDependencies.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/grape/GrabDependencies.java index 609d1db536bc..3a066e1995a5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/grape/GrabDependencies.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/grape/GrabDependencies.java @@ -43,6 +43,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import com.intellij.util.PathUtil; +import com.intellij.util.containers.CollectionFactory; import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; @@ -234,15 +235,25 @@ public class GrabDependencies implements IntentionAction { for (VirtualFile jar : jars) { final VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(jar); if (jarRoot != null) { - final String libName = "Grab:" + jar.getName(); - - final Library existing = tableModel.getLibraryByName(libName); - if (existing != null) { - tableModel.removeLibrary(existing); + OrderRootType rootType = OrderRootType.CLASSES; + String libName = "Grab:" + jar.getName(); + for (String classifier : CollectionFactory.ar("sources", "source", "src")) { + if (libName.endsWith("-" + classifier + ".jar")) { + rootType = OrderRootType.SOURCES; + libName = StringUtil.trimEnd(libName, "-" + classifier + ".jar") + ".jar"; + } } - final Library.ModifiableModel libModel = tableModel.createLibrary(libName).getModifiableModel(); - libModel.addRoot(jarRoot, OrderRootType.CLASSES); + Library library = tableModel.getLibraryByName(libName); + if (library == null) { + library = tableModel.createLibrary(libName); + } + + final Library.ModifiableModel libModel = library.getModifiableModel(); + for (String url : libModel.getUrls(rootType)) { + libModel.removeRoot(url, rootType); + } + libModel.addRoot(jarRoot, rootType); libModel.commit(); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/UpdateGriffonSettingsAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/UpdateGriffonSettingsAction.java new file mode 100644 index 000000000000..ccce2f337ccd --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/UpdateGriffonSettingsAction.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2007 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.griffon; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.module.Module; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.mvc.MvcActionBase; +import org.jetbrains.plugins.groovy.mvc.MvcFramework; +import org.jetbrains.plugins.groovy.mvc.MvcIcons; + +/** + * @author peter + */ +public class UpdateGriffonSettingsAction extends MvcActionBase { + + @Override + protected boolean isFrameworkSupported(@NotNull MvcFramework framework) { + return framework == GriffonFramework.getInstance(); + } + + @Override + protected void actionPerformed(@NotNull AnActionEvent e, @NotNull final Module module, @NotNull MvcFramework framework) { + GriffonFramework.getInstance().updateProjectStructure(module); + } + + @Override + protected void updateView(AnActionEvent event, @NotNull MvcFramework framework, @NotNull Module module) { + event.getPresentation().setIcon(MvcIcons.PLUGINS_REFRESH); + } + +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/_GroovyLexer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/_GroovyLexer.java index cb36025f0ff9..b353f455515f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/_GroovyLexer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/_GroovyLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.3 on 12/18/11 8:26 PM */ +/* The following code was generated by JFlex 1.4.3 on 12/19/11 2:43 PM */ /* * Copyright 2000-2010 JetBrains s.r.o. @@ -27,7 +27,7 @@ import java.util.Stack; /** * This class is a scanner generated by * JFlex 1.4.3 - * on 12/18/11 8:26 PM from the specification file + * on 12/19/11 2:43 PM from the specification file * C:/Home/IDEA/tools/lexer/../../community/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/groovy.flex */ public class _GroovyLexer implements FlexLexer, GroovyTokenTypes, TokenType { @@ -1752,168 +1752,149 @@ public class _GroovyLexer implements FlexLexer, GroovyTokenTypes, TokenType { zzMarkedPos = zzMarkedPosL; switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { - case 70: - { yybegin(WAIT_FOR_REGEX); - return(mSPREAD_DOT); + case 58: + { yybegin(IN_DOLLAR_SLASH_REGEX_DOT); + return mIDENT; } case 173: break; - case 27: + case 5: { yybegin(WAIT_FOR_REGEX); - return(mMOD); + return(mSTAR); } case 174: break; - case 46: - { yybegin(NLS_AFTER_NLS); - afterComment = IN_TRIPLE_IDENT; - return mNLS; + case 73: + { yybegin(WAIT_FOR_REGEX); + return(mNOT_EQUAL); } case 175: break; - case 112: - { yybegin(WAIT_FOR_REGEX); - return(mSTAR_STAR_ASSIGN); + case 47: + { blockStack.push(mLCURLY); + braceCount.push(mLCURLY); + yybegin(NLS_AFTER_LBRACE); + return(mLCURLY); } case 176: break; case 133: { return( kTRUE ); } case 177: break; - case 122: - { yybegin(WAIT_FOR_REGEX); - return(mREGEX_MATCH); - } - case 178: break; - case 69: - { yybegin(WAIT_FOR_REGEX); - return(mSTAR_STAR); - } - case 179: break; case 135: { return( kNULL ); } - case 180: break; + case 178: break; + case 23: + { yybegin(WAIT_FOR_REGEX); + return(mCOMMA); + } + case 179: break; case 129: { return( kENUM ); } + case 180: break; + case 61: + { yybegin(IN_DOLLAR_SLASH_REGEX_DOLLAR); + return mDOLLAR; + } case 181: break; - case 53: - { blockStack.push(mDIV); - braceCount.push(mLCURLY); - yybegin(NLS_AFTER_LBRACE); - return mLCURLY; + case 83: + { yybegin(WAIT_FOR_REGEX); + return(mDEC); } case 182: break; - case 55: - { if (!gStringStack.isEmpty()) { - gStringStack.pop(); - } - if (blockStack.isEmpty()){ - yybegin(YYINITIAL); - } else { - yybegin(IN_INNER_BLOCK); - } - return mREGEX_END; - } - case 183: break; - case 62: - { yypushback(1); - yybegin(IN_DOLLAR_SLASH_REGEX); - } - case 184: break; case 80: { return( kDO ); } - case 185: break; - case 65: - { yypushback(1); - yybegin(NLS_AFTER_COMMENT); + case 183: break; + case 86: + { yybegin(WAIT_FOR_REGEX); + return(mRANGE_INCLUSIVE); } - case 186: break; + case 184: break; case 72: { return mSH_COMMENT; } + case 185: break; + case 125: + { yybegin(WAIT_FOR_REGEX); + return(mSR_ASSIGN); + } + case 186: break; + case 52: + { yybegin(IN_REGEX_DOT); + return mIDENT; + } case 187: break; - case 42: - { if (!gStringStack.isEmpty()) { - gStringStack.pop(); - } + case 105: + { yybegin(IN_DOLLAR_SLASH_REGEX); + gStringStack.push(mDOLLAR); + return mDOLLAR_SLASH_REGEX_BEGIN; + } + case 188: break; + case 49: + { yypushback(1); if (blockStack.isEmpty()){ yybegin(YYINITIAL); } else { yybegin(IN_INNER_BLOCK); } - return mGSTRING_END; } - case 188: break; + case 189: break; case 7: { return mIDENT; } - case 189: break; + case 190: break; + case 25: + { yybegin(WAIT_FOR_REGEX); + return(mGT); + } + case 191: break; case 144: { return( kSUPER ); } - case 190: break; - case 94: - { yybegin(WAIT_FOR_REGEX); - return(mREGEX_FIND); - } - case 191: break; - case 99: - { yybegin(WAIT_FOR_REGEX); - return(mBOR_ASSIGN); - } case 192: break; + case 119: + { yybegin(IN_TRIPLE_GSTRING); + gStringStack.push(mLBRACK); + return mGSTRING_BEGIN; + } + case 193: break; + case 68: + { yybegin(WAIT_FOR_REGEX); + return(mDIV_ASSIGN); + } + case 194: break; case 171: { return( kINSTANCEOF ); } - case 193: break; - case 35: - { blockStack.push(mLPAREN); - braceCount.push(mLCURLY); - yybegin(NLS_AFTER_LBRACE); - return mLCURLY; - } - case 194: break; - case 108: - { if (!gStringStack.isEmpty()) { - gStringStack.pop(); - } - if (blockStack.isEmpty()){ - yybegin(YYINITIAL); - } else { - yybegin(IN_INNER_BLOCK); - } - return mDOLLAR_SLASH_REGEX_END; - } case 195: break; - case 73: + case 93: { yybegin(WAIT_FOR_REGEX); - return(mNOT_EQUAL); + return(mEQUAL); } case 196: break; - case 103: - // lookahead expression with fixed base length - zzMarkedPos = zzStartRead + 1; - { yybegin(IN_SINGLE_IDENT); - return mDOT; + case 18: + { yybegin(WAIT_FOR_REGEX); + braceCount.push(mLPAREN); + return(mLPAREN); } case 197: break; + case 22: + { yybegin(WAIT_FOR_REGEX); + return(mCOLON); + } + case 198: break; case 152: { return( kSTATIC ); } - case 198: break; - case 100: - { yybegin(WAIT_FOR_REGEX); - return(mLOR); - } case 199: break; - case 57: - { yypushback(1); - yybegin(IN_REGEX); - } - case 200: break; case 143: { return( kCATCH ); } + case 200: break; + case 29: + { yybegin(WAIT_FOR_REGEX); + return(mBOR); + } case 201: break; case 54: { return mREGEX_CONTENT; @@ -1925,304 +1906,104 @@ public class _GroovyLexer implements FlexLexer, GroovyTokenTypes, TokenType { { return mREGEX_CONTENT; } case 203: break; - case 97: + case 27: { yybegin(WAIT_FOR_REGEX); - return(mMOD_ASSIGN); + return(mMOD); } case 204: break; - case 168: - { return( kPROTECTED ); + case 24: + { yybegin(WAIT_FOR_REGEX); + return(mLT); } case 205: break; - case 86: - { yybegin(WAIT_FOR_REGEX); - return(mRANGE_INCLUSIVE); + case 168: + { return( kPROTECTED ); } case 206: break; case 113: { return mNUM_BIG_DECIMAL; } case 207: break; - case 58: - { yybegin(IN_DOLLAR_SLASH_REGEX_DOT); - return mIDENT; + case 70: + { yybegin(WAIT_FOR_REGEX); + return(mSPREAD_DOT); } case 208: break; - case 25: - { yybegin(WAIT_FOR_REGEX); - return(mGT); - } - case 209: break; - case 33: - { yypushback(1); - yybegin(IN_SINGLE_GSTRING); - } - case 210: break; - case 125: - { yybegin(WAIT_FOR_REGEX); - return(mSR_ASSIGN); - } - case 211: break; case 149: { return( kDOUBLE ); } - case 212: break; - case 119: - { yybegin(IN_TRIPLE_GSTRING); - gStringStack.push(mLBRACK); - return mGSTRING_BEGIN; - } - case 213: break; - case 121: - { return( kNEW ); - } - case 214: break; - case 36: - { yypushback(1); - yybegin(IN_TRIPLE_GSTRING); - } - case 215: break; - case 17: - { yybegin(WAIT_FOR_REGEX); - return(mASSIGN); - } - case 216: break; - case 50: - { afterComment = YYINITIAL; - return(WHITE_SPACE); - } - case 217: break; - case 156: - { return( kNATIVE ); - } - case 218: break; - case 114: - { return( kFOR ); - } - case 219: break; - case 98: - { yybegin(WAIT_FOR_REGEX); - return(mBXOR_ASSIGN); - } - case 220: break; - case 132: - { return( kCHAR ); - } - case 221: break; - case 91: - { yybegin(WAIT_FOR_REGEX); - return(mOPTIONAL_DOT); - } - case 222: break; - case 24: - { yybegin(WAIT_FOR_REGEX); - return(mLT); - } - case 223: break; - case 148: - { return( kIMPORT ); - } - case 224: break; - case 159: - { return( kEXTENDS ); - } - case 225: break; - case 2: - { yybegin(NLS_AFTER_NLS); - afterComment = WAIT_FOR_REGEX; - return !braceCount.isEmpty() && - mLPAREN == braceCount.peek() ? WHITE_SPACE : mNLS; - } - case 226: break; - case 60: - { return mDOLLAR_SLASH_REGEX_CONTENT; - } - case 227: break; - case 109: - // lookahead expression with fixed lookahead length - yypushback(1); - { return mDOLLAR_SLASH_REGEX_CONTENT; - } - case 228: break; - case 63: - { yypushback(1); - yybegin(afterComment); - } - case 229: break; - case 157: - { return( kFINALLY ); - } - case 230: break; - case 82: - { yybegin(WAIT_FOR_REGEX); - return(mPLUS_ASSIGN); - } - case 231: break; - case 136: - { return( kVOID ); - } - case 232: break; - case 150: - { return( kPUBLIC ); - } - case 233: break; - case 128: - { return( kELSE ); - } - case 234: break; - case 12: - { return mSTRING_LITERAL; - } - case 235: break; - case 6: - { yybegin(WAIT_FOR_REGEX); - return(mLNOT); - } - case 236: break; - case 10: - { yybegin(WAIT_FOR_REGEX); - return(mMINUS); - } - case 237: break; - case 64: - { yypushback(1); - yybegin(WAIT_FOR_REGEX); - } - case 238: break; - case 59: - { blockStack.push(mDOLLAR); - braceCount.push(mLCURLY); - yybegin(NLS_AFTER_LBRACE); - return mLCURLY; - } - case 239: break; - case 30: - { yybegin(WAIT_FOR_REGEX); - return(mBAND); - } - case 240: break; - case 170: - { return( kIMPLEMENTS ); - } - case 241: break; - case 5: - { yybegin(WAIT_FOR_REGEX); - return(mSTAR); - } - case 242: break; - case 11: - { yybegin(WAIT_FOR_REGEX); - return(mDOT); - } - case 243: break; - case 8: - { return mNUM_INT; - } - case 244: break; - case 167: - { return( kINTERFACE ); - } - case 245: break; - case 81: - { yybegin(WAIT_FOR_REGEX); - return(mINC); - } - case 246: break; - case 161: - { return( kPACKAGE ); - } - case 247: break; - case 146: - { return( kTHROW ); - } - case 248: break; - case 92: - { yybegin(WAIT_FOR_REGEX); - return(mELVIS); - } - case 249: break; - case 79: - { return( kIN ); - } - case 250: break; - case 84: - { yybegin(WAIT_FOR_REGEX); - return(mMINUS_ASSIGN); - } - case 251: break; - case 66: - { return mSL_COMMENT; - } - case 252: break; + case 209: break; case 37: { yybegin(IN_TRIPLE_DOT); return mIDENT; } - case 253: break; - case 20: - { yybegin(WAIT_FOR_REGEX); - braceCount.push(mLPAREN); - return(mLBRACK); + case 210: break; + case 35: + { blockStack.push(mLPAREN); + braceCount.push(mLCURLY); + yybegin(NLS_AFTER_LBRACE); + return mLCURLY; } - case 254: break; - case 130: - { return( kBYTE ); - } - case 255: break; - case 137: - { yybegin(WAIT_FOR_REGEX); - return(mBSR_ASSIGN); - } - case 256: break; - case 52: - { yybegin(IN_REGEX_DOT); - return mIDENT; - } - case 257: break; - case 44: - { yybegin(IN_TRIPLE_GSTRING_DOLLAR); - return mDOLLAR; - } - case 258: break; - case 49: - { yypushback(1); + case 211: break; + case 126: + { if (!gStringStack.isEmpty()){ + gStringStack.pop(); + } if (blockStack.isEmpty()){ yybegin(YYINITIAL); } else { yybegin(IN_INNER_BLOCK); } + return mGSTRING_END; } - case 259: break; - case 172: - { return( kSYNCHRONIZED ); + case 212: break; + case 121: + { return( kNEW ); } - case 260: break; - case 117: - { yybegin(WAIT_FOR_REGEX); - return(mTRIPLE_DOT); + case 213: break; + case 156: + { return( kNATIVE ); } - case 261: break; - case 85: - { yybegin(WAIT_FOR_REGEX); - return(mCLOSABLE_BLOCK_OP); - } - case 262: break; + case 214: break; case 87: { yybegin(WAIT_FOR_REGEX); return(mMEMBER_POINTER); } - case 263: break; - case 120: - { return( kTRY ); - } - case 264: break; - case 21: + case 215: break; + case 19: { if (!braceCount.isEmpty() && mLPAREN == braceCount.peek()) { braceCount.pop(); } - return(mRBRACK); + return(mRPAREN); } - case 265: break; + case 216: break; + case 64: + { yypushback(1); + yybegin(WAIT_FOR_REGEX); + } + case 217: break; + case 114: + { return( kFOR ); + } + case 218: break; + case 132: + { return( kCHAR ); + } + case 219: break; + case 148: + { return( kIMPORT ); + } + case 220: break; + case 91: + { yybegin(WAIT_FOR_REGEX); + return(mOPTIONAL_DOT); + } + case 221: break; + case 101: + { yybegin(WAIT_FOR_REGEX); + return(mBAND_ASSIGN); + } + case 222: break; case 48: { if (!blockStack.isEmpty()) { IElementType br = blockStack.pop(); @@ -2239,21 +2020,117 @@ public class _GroovyLexer implements FlexLexer, GroovyTokenTypes, TokenType { } return mRCURLY; } - case 266: break; - case 131: - { return( kCASE ); + case 223: break; + case 159: + { return( kEXTENDS ); } - case 267: break; - case 77: - { return mNUM_DOUBLE; + case 224: break; + case 9: + { yybegin(WAIT_FOR_REGEX); + return(mPLUS); } - case 268: break; - case 158: - { return( kDEFAULT ); + case 225: break; + case 108: + { if (!gStringStack.isEmpty()) { + gStringStack.pop(); + } + if (blockStack.isEmpty()){ + yybegin(YYINITIAL); + } else { + yybegin(IN_INNER_BLOCK); + } + return mDOLLAR_SLASH_REGEX_END; } - case 269: break; - case 126: - { if (!gStringStack.isEmpty()){ + case 226: break; + case 94: + { yybegin(WAIT_FOR_REGEX); + return(mREGEX_FIND); + } + case 227: break; + case 26: + { yybegin(WAIT_FOR_REGEX); + return(mBNOT); + } + case 228: break; + case 60: + { return mDOLLAR_SLASH_REGEX_CONTENT; + } + case 229: break; + case 109: + // lookahead expression with fixed lookahead length + yypushback(1); + { return mDOLLAR_SLASH_REGEX_CONTENT; + } + case 230: break; + case 99: + { yybegin(WAIT_FOR_REGEX); + return(mBOR_ASSIGN); + } + case 231: break; + case 157: + { return( kFINALLY ); + } + case 232: break; + case 100: + { yybegin(WAIT_FOR_REGEX); + return(mLOR); + } + case 233: break; + case 71: + { yybegin(WAIT_FOR_REGEX); + return(mSTAR_ASSIGN); + } + case 234: break; + case 136: + { return( kVOID ); + } + case 235: break; + case 150: + { return( kPUBLIC ); + } + case 236: break; + case 128: + { return( kELSE ); + } + case 237: break; + case 38: + { blockStack.push(mLBRACK); + braceCount.push(mLCURLY); + yybegin(NLS_AFTER_LBRACE); + return mLCURLY; + } + case 238: break; + case 12: + { return mSTRING_LITERAL; + } + case 239: break; + case 88: + { if (zzStartRead == 0 || + zzBuffer.subSequence(0, zzStartRead).toString().trim().length() == 0) { + yypushback(2); + yybegin(WAIT_FOR_REGEX); + } else { + yypushback(1); + return(mDOLLAR); + } + } + case 240: break; + case 84: + { yybegin(WAIT_FOR_REGEX); + return(mMINUS_ASSIGN); + } + case 241: break; + case 85: + { yybegin(WAIT_FOR_REGEX); + return(mCLOSABLE_BLOCK_OP); + } + case 242: break; + case 170: + { return( kIMPLEMENTS ); + } + case 243: break; + case 42: + { if (!gStringStack.isEmpty()) { gStringStack.pop(); } if (blockStack.isEmpty()){ @@ -2263,321 +2140,451 @@ public class _GroovyLexer implements FlexLexer, GroovyTokenTypes, TokenType { } return mGSTRING_END; } - case 270: break; - case 169: - { return( kTRANSIENT ); + case 244: break; + case 97: + { yybegin(WAIT_FOR_REGEX); + return(mMOD_ASSIGN); } - case 271: break; - case 111: - { return GROOVY_DOC_COMMENT; - } - case 272: break; + case 245: break; case 16: { yybegin(WAIT_FOR_REGEX); return(mQUESTION); } + case 246: break; + case 8: + { return mNUM_INT; + } + case 247: break; + case 167: + { return( kINTERFACE ); + } + case 248: break; + case 31: + { yybegin(WAIT_FOR_REGEX); + return(mSEMI); + } + case 249: break; + case 161: + { return( kPACKAGE ); + } + case 250: break; + case 146: + { return( kTHROW ); + } + case 251: break; + case 17: + { yybegin(WAIT_FOR_REGEX); + return(mASSIGN); + } + case 252: break; + case 79: + { return( kIN ); + } + case 253: break; + case 66: + { return mSL_COMMENT; + } + case 254: break; + case 13: + { yybegin(IN_SINGLE_GSTRING); + gStringStack.push(mLPAREN); + return mGSTRING_BEGIN; + } + case 255: break; + case 130: + { return( kBYTE ); + } + case 256: break; + case 102: + { yybegin(WAIT_FOR_REGEX); + return(mLAND); + } + case 257: break; + case 33: + { yypushback(1); + yybegin(IN_SINGLE_GSTRING); + } + case 258: break; + case 28: + { yybegin(WAIT_FOR_REGEX); + return(mBXOR); + } + case 259: break; + case 57: + { yypushback(1); + yybegin(IN_REGEX); + } + case 260: break; + case 63: + { yypushback(1); + yybegin(afterComment); + } + case 261: break; + case 172: + { return( kSYNCHRONIZED ); + } + case 262: break; + case 124: + { yybegin(WAIT_FOR_REGEX); + return(mSL_ASSIGN); + } + case 263: break; + case 56: + { yybegin(IN_REGEX_DOLLAR); + return mDOLLAR; + } + case 264: break; + case 36: + { yypushback(1); + yybegin(IN_TRIPLE_GSTRING); + } + case 265: break; + case 120: + { return( kTRY ); + } + case 266: break; + case 10: + { yybegin(WAIT_FOR_REGEX); + return(mMINUS); + } + case 267: break; + case 11: + { yybegin(WAIT_FOR_REGEX); + return(mDOT); + } + case 268: break; + case 131: + { return( kCASE ); + } + case 269: break; + case 103: + // lookahead expression with fixed base length + zzMarkedPos = zzStartRead + 1; + { yybegin(IN_SINGLE_IDENT); + return mDOT; + } + case 270: break; + case 77: + { return mNUM_DOUBLE; + } + case 271: break; + case 158: + { return( kDEFAULT ); + } + case 272: break; + case 122: + { yybegin(WAIT_FOR_REGEX); + return(mREGEX_MATCH); + } case 273: break; + case 50: + { afterComment = YYINITIAL; + return(WHITE_SPACE); + } + case 274: break; + case 169: + { return( kTRANSIENT ); + } + case 275: break; + case 81: + { yybegin(WAIT_FOR_REGEX); + return(mINC); + } + case 276: break; + case 111: + { return GROOVY_DOC_COMMENT; + } + case 277: break; + case 2: + { yybegin(NLS_AFTER_NLS); + afterComment = WAIT_FOR_REGEX; + return !braceCount.isEmpty() && + mLPAREN == braceCount.peek() ? WHITE_SPACE : mNLS; + } + case 278: break; + case 59: + { blockStack.push(mDOLLAR); + braceCount.push(mLCURLY); + yybegin(NLS_AFTER_LBRACE); + return mLCURLY; + } + case 279: break; case 153: { return( kSWITCH ); } - case 274: break; + case 280: break; + case 15: + { while (!braceCount.isEmpty() && mLCURLY != braceCount.peek()) { + braceCount.pop(); + } + if (!braceCount.isEmpty() && mLCURLY == braceCount.peek()) { + braceCount.pop(); + } + return mRCURLY; + } + case 281: break; case 4: { if (zzStartRead == 0 || - zzBuffer.subSequence(0, zzStartRead).toString().trim().length() == 0) { - yypushback(1); - yybegin(WAIT_FOR_REGEX); + zzBuffer.subSequence(0, zzStartRead).toString().trim().length() == 0) { + yypushback(1); + yybegin(WAIT_FOR_REGEX); } else { return(mDIV); } } - case 275: break; + case 282: break; + case 89: + { return mGSTRING_LITERAL; + } + case 283: break; + case 20: + { yybegin(WAIT_FOR_REGEX); + braceCount.push(mLPAREN); + return(mLBRACK); + } + case 284: break; + case 45: + { yypushback(1); + yybegin(IN_TRIPLE_IDENT); + } + case 285: break; + case 138: + { return( kFLOAT ); + } + case 286: break; + case 137: + { yybegin(WAIT_FOR_REGEX); + return(mBSR_ASSIGN); + } + case 287: break; + case 78: + { return( kIF ); + } + case 288: break; + case 92: + { yybegin(WAIT_FOR_REGEX); + return(mELVIS); + } + case 289: break; + case 139: + { return( kFINAL ); + } + case 290: break; + case 34: + { yybegin(IN_SINGLE_DOT); + return mIDENT; + } + case 291: break; + case 96: + { yybegin(WAIT_FOR_REGEX); + return(mGE); + } + case 292: break; + case 154: + { return( kTHROWS ); + } + case 293: break; case 110: // lookahead expression with fixed base length zzMarkedPos = zzStartRead + 1; { yybegin(IN_DOLLAR_SLASH_REGEX_IDENT); return mDOT; } - case 276: break; - case 89: - { return mGSTRING_LITERAL; - } - case 277: break; - case 124: - { yybegin(WAIT_FOR_REGEX); - return(mSL_ASSIGN); - } - case 278: break; - case 138: - { return( kFLOAT ); - } - case 279: break; - case 105: - { yybegin(IN_DOLLAR_SLASH_REGEX); - gStringStack.push(mDOLLAR); - return mDOLLAR_SLASH_REGEX_BEGIN; - } - case 280: break; - case 45: - { yypushback(1); - yybegin(IN_TRIPLE_IDENT); - } - case 281: break; - case 34: - { yybegin(IN_SINGLE_DOT); - return mIDENT; - } - case 282: break; - case 123: - { yybegin(WAIT_FOR_REGEX); - return(mCOMPARE_TO); - } - case 283: break; - case 88: - { yypushback(2); - yybegin(WAIT_FOR_REGEX); - } - case 284: break; - case 78: - { return( kIF ); - } - case 285: break; - case 139: - { return( kFINAL ); - } - case 286: break; - case 101: - { yybegin(WAIT_FOR_REGEX); - return(mBAND_ASSIGN); - } - case 287: break; - case 154: - { return( kTHROWS ); - } - case 288: break; + case 294: break; case 75: { return mNUM_FLOAT; } - case 289: break; - case 38: - { blockStack.push(mLBRACK); - braceCount.push(mLCURLY); - yybegin(NLS_AFTER_LBRACE); - return mLCURLY; + case 295: break; + case 117: + { yybegin(WAIT_FOR_REGEX); + return(mTRIPLE_DOT); } - case 290: break; - case 47: - { blockStack.push(mLCURLY); - braceCount.push(mLCURLY); - yybegin(NLS_AFTER_LBRACE); - return(mLCURLY); - } - case 291: break; + case 296: break; case 115: { return( kINT ); } - case 292: break; + case 297: break; case 165: { return( kSTRICTFP ); } - case 293: break; - case 9: - { yybegin(WAIT_FOR_REGEX); - return(mPLUS); + case 298: break; + case 65: + { yypushback(1); + yybegin(NLS_AFTER_COMMENT); } - case 294: break; + case 299: break; case 163: { return( kABSTRACT ); } - case 295: break; + case 300: break; case 140: { return( kFALSE ); } - case 296: break; - case 41: - { yybegin(IN_SINGLE_GSTRING_DOLLAR); - return mDOLLAR; - } - case 297: break; - case 26: - { yybegin(WAIT_FOR_REGEX); - return(mBNOT); - } - case 298: break; - case 13: - { yybegin(IN_SINGLE_GSTRING); - gStringStack.push(mLPAREN); - return mGSTRING_BEGIN; - } - case 299: break; + case 301: break; case 90: { return( kAS ); } - case 300: break; - case 71: - { yybegin(WAIT_FOR_REGEX); - return(mSTAR_ASSIGN); - } - case 301: break; - case 164: - { return( kCONTINUE ); - } case 302: break; - case 40: - { clearStacks(); - yybegin(NLS_AFTER_NLS); - afterComment = YYINITIAL; + case 46: + { yybegin(NLS_AFTER_NLS); + afterComment = IN_TRIPLE_IDENT; return mNLS; } case 303: break; - case 127: - { return( kLONG ); - } - case 304: break; - case 76: - { return mNUM_LONG; - } - case 305: break; - case 141: - { return( kBREAK ); - } - case 306: break; - case 160: - { return( kBOOLEAN ); - } - case 307: break; - case 151: - { return( kASSERT ); - } - case 308: break; - case 96: - { yybegin(WAIT_FOR_REGEX); - return(mGE); - } - case 309: break; - case 23: - { yybegin(WAIT_FOR_REGEX); - return(mCOMMA); - } - case 310: break; - case 93: - { yybegin(WAIT_FOR_REGEX); - return(mEQUAL); - } - case 311: break; - case 3: - { return WHITE_SPACE; - } - case 312: break; - case 134: - { return( kTHIS ); - } - case 313: break; - case 162: - { return( kPRIVATE ); - } - case 314: break; - case 18: - { yybegin(WAIT_FOR_REGEX); - braceCount.push(mLPAREN); - return(mLPAREN); - } - case 315: break; - case 104: - // lookahead expression with fixed base length - zzMarkedPos = zzStartRead + 1; - { yybegin(IN_TRIPLE_NLS); - return mDOT; - } - case 316: break; - case 51: - { yybegin(IN_REGEX); - gStringStack.push(mDIV); - return mREGEX_BEGIN; - } - case 317: break; - case 145: - { return( kSHORT ); - } - case 318: break; - case 83: - { yybegin(WAIT_FOR_REGEX); - return(mDEC); - } - case 319: break; - case 31: - { yybegin(WAIT_FOR_REGEX); - return(mSEMI); - } - case 320: break; - case 61: - { yybegin(IN_DOLLAR_SLASH_REGEX_DOLLAR); - return mDOLLAR; - } - case 321: break; - case 166: - { return( kVOLATILE ); - } - case 322: break; - case 14: - { yybegin(NLS_AFTER_LBRACE); - braceCount.push(mLCURLY); - return(mLCURLY); - } - case 323: break; - case 32: - { yybegin(WAIT_FOR_REGEX); - return(mAT); - } - case 324: break; - case 74: - { return mNUM_BIG_INT; - } - case 325: break; case 118: { yybegin(WAIT_FOR_REGEX); return(mRANGE_EXCLUSIVE); } - case 326: break; - case 142: - { return( kCLASS ); + case 304: break; + case 164: + { return( kCONTINUE ); } - case 327: break; - case 68: + case 305: break; + case 32: { yybegin(WAIT_FOR_REGEX); - return(mDIV_ASSIGN); + return(mAT); } - case 328: break; + case 306: break; + case 127: + { return( kLONG ); + } + case 307: break; + case 76: + { return mNUM_LONG; + } + case 308: break; + case 141: + { return( kBREAK ); + } + case 309: break; case 95: { yybegin(WAIT_FOR_REGEX); return(mLE); } - case 329: break; - case 155: - { return( kRETURN ); + case 310: break; + case 160: + { return( kBOOLEAN ); } - case 330: break; - case 22: - { yybegin(WAIT_FOR_REGEX); - return(mCOLON); + case 311: break; + case 151: + { return( kASSERT ); } - case 331: break; + case 312: break; case 107: // lookahead expression with fixed base length zzMarkedPos = zzStartRead + 1; { yybegin(IN_REGEX_IDENT); return mDOT; } - case 332: break; - case 56: - { yybegin(IN_REGEX_DOLLAR); + case 313: break; + case 3: + { return WHITE_SPACE; + } + case 314: break; + case 134: + { return( kTHIS ); + } + case 315: break; + case 51: + { yybegin(IN_REGEX); + gStringStack.push(mDIV); + return mREGEX_BEGIN; + } + case 316: break; + case 162: + { return( kPRIVATE ); + } + case 317: break; + case 44: + { yybegin(IN_TRIPLE_GSTRING_DOLLAR); return mDOLLAR; } - case 333: break; - case 19: + case 318: break; + case 145: + { return( kSHORT ); + } + case 319: break; + case 21: { if (!braceCount.isEmpty() && mLPAREN == braceCount.peek()) { braceCount.pop(); } - return(mRPAREN); + return(mRBRACK); + } + case 320: break; + case 14: + { yybegin(NLS_AFTER_LBRACE); + braceCount.push(mLCURLY); + return(mLCURLY); + } + case 321: break; + case 166: + { return( kVOLATILE ); + } + case 322: break; + case 104: + // lookahead expression with fixed base length + zzMarkedPos = zzStartRead + 1; + { yybegin(IN_TRIPLE_NLS); + return mDOT; + } + case 323: break; + case 6: + { yybegin(WAIT_FOR_REGEX); + return(mLNOT); + } + case 324: break; + case 69: + { yybegin(WAIT_FOR_REGEX); + return(mSTAR_STAR); + } + case 325: break; + case 74: + { return mNUM_BIG_INT; + } + case 326: break; + case 55: + { if (!gStringStack.isEmpty()) { + gStringStack.pop(); + } + if (blockStack.isEmpty()){ + yybegin(YYINITIAL); + } else { + yybegin(IN_INNER_BLOCK); + } + return mREGEX_END; + } + case 327: break; + case 142: + { return( kCLASS ); + } + case 328: break; + case 82: + { yybegin(WAIT_FOR_REGEX); + return(mPLUS_ASSIGN); + } + case 329: break; + case 30: + { yybegin(WAIT_FOR_REGEX); + return(mBAND); + } + case 330: break; + case 62: + { yypushback(1); + yybegin(IN_DOLLAR_SLASH_REGEX); + } + case 331: break; + case 123: + { yybegin(WAIT_FOR_REGEX); + return(mCOMPARE_TO); + } + case 332: break; + case 98: + { yybegin(WAIT_FOR_REGEX); + return(mBXOR_ASSIGN); + } + case 333: break; + case 155: + { return( kRETURN ); } case 334: break; case 43: @@ -2608,33 +2615,32 @@ public class _GroovyLexer implements FlexLexer, GroovyTokenTypes, TokenType { { return mGSTRING_CONTENT; } case 336: break; - case 102: + case 112: { yybegin(WAIT_FOR_REGEX); - return(mLAND); + return(mSTAR_STAR_ASSIGN); } case 337: break; - case 29: - { yybegin(WAIT_FOR_REGEX); - return(mBOR); - } - case 338: break; case 116: { return( kDEF ); } + case 338: break; + case 41: + { yybegin(IN_SINGLE_GSTRING_DOLLAR); + return mDOLLAR; + } case 339: break; - case 28: - { yybegin(WAIT_FOR_REGEX); - return(mBXOR); + case 40: + { clearStacks(); + yybegin(NLS_AFTER_NLS); + afterComment = YYINITIAL; + return mNLS; } case 340: break; - case 15: - { while (!braceCount.isEmpty() && mLCURLY != braceCount.peek()) { - braceCount.pop(); - } - if (!braceCount.isEmpty() && mLCURLY == braceCount.peek()) { - braceCount.pop(); - } - return mRCURLY; + case 53: + { blockStack.push(mDIV); + braceCount.push(mLCURLY); + yybegin(NLS_AFTER_LBRACE); + return mLCURLY; } case 341: break; case 147: diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/groovy.flex b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/groovy.flex index a119cb61949a..8a13b7731be8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/groovy.flex +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/groovy.flex @@ -663,9 +663,6 @@ mGSTRING_LITERAL = \"\" {mGSTRING_LITERAL} { return mGSTRING_LITERAL; } -"$""/" { yypushback(2); - yybegin(WAIT_FOR_REGEX); } - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////// keywords ///////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -738,13 +735,22 @@ mGSTRING_LITERAL = \"\" "?" { yybegin(WAIT_FOR_REGEX); return(mQUESTION); } "/" { if (zzStartRead == 0 || - zzBuffer.subSequence(0, zzStartRead).toString().trim().length() == 0) { - yypushback(1); - yybegin(WAIT_FOR_REGEX); + zzBuffer.subSequence(0, zzStartRead).toString().trim().length() == 0) { + yypushback(1); + yybegin(WAIT_FOR_REGEX); } else { return(mDIV); } } +"$""/" { if (zzStartRead == 0 || + zzBuffer.subSequence(0, zzStartRead).toString().trim().length() == 0) { + yypushback(2); + yybegin(WAIT_FOR_REGEX); + } else { + yypushback(1); + return(mDOLLAR); + } + } "/=" { yybegin(WAIT_FOR_REGEX); return(mDIV_ASSIGN); } "(" { yybegin(WAIT_FOR_REGEX); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java index 4a9779ffa51b..68037fe17eef 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java @@ -35,6 +35,70 @@ public class GrStringUtil { private GrStringUtil() { } + public static String escapeForSlashyStrings(String str) { + final StringBuilder buffer = new StringBuilder(str.length()); + escapeSymbolsForSlashyStrings(buffer, str); + return buffer.toString(); + } + + public static void escapeSymbolsForSlashyStrings(StringBuilder buffer, String str) { + final int length = str.length(); + for (int idx = 0; idx < length; idx++) { + char ch = str.charAt(idx); + switch (ch) { + case '/': + buffer.append("\\/"); + break; + default: + if (Character.isISOControl(ch) || ch == '$') { + appendUnicode(buffer, ch); + } + else { + buffer.append(ch); + } + } + } + } + + public static String escapeSymbolsForDollarSlashyStrings(String str) { + final StringBuilder buffer = new StringBuilder(str.length()); + escapeSymbolsForDollarSlashyStrings(buffer, str); + return buffer.toString(); + } + + public static void escapeSymbolsForDollarSlashyStrings(StringBuilder buffer, String str) { + final int length = str.length(); + for (int idx = 0; idx < length; idx++) { + char ch = str.charAt(idx); + switch (ch) { + case '/': + if (idx + 1 < length && str.charAt(idx + 1) == '$') { + appendUnicode(buffer, '/'); + appendUnicode(buffer, '$'); + break; + } + default: + if (Character.isISOControl(ch)) { + appendUnicode(buffer, ch); + } + else { + buffer.append(ch); + } + } + } + } + + private static void appendUnicode(StringBuilder buffer, char ch) { + String hexCode = Integer.toHexString(ch).toUpperCase(); + buffer.append("\\u"); + int paddingCount = 4 - hexCode.length(); + while (paddingCount-- > 0) { + buffer.append(0); + } + buffer.append(hexCode); + } + + public static String escapeSymbolsForGString(String s, boolean escapeDoubleQuotes) { return escapeSymbolsForGString(s, escapeDoubleQuotes, false); } @@ -115,13 +179,7 @@ public class GrStringUtil { buffer.append("\\").append(ch); } else if (Character.isISOControl(ch)) { - String hexCode = Integer.toHexString(ch).toUpperCase(); - buffer.append("\\u"); - int paddingCount = 4 - hexCode.length(); - while (paddingCount-- > 0) { - buffer.append(0); - } - buffer.append(hexCode); + appendUnicode(buffer, ch); } else { buffer.append(ch); 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 94da17e17241..55a5a5bb3963 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 @@ -15,56 +15,45 @@ */ package org.jetbrains.plugins.groovy.lang.resolve; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.AbstractElementManipulator; -import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.literals.GrLiteralImpl; import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil; public class GroovyStringLiteralManipulator extends AbstractElementManipulator { - public GrLiteral handleContentChange(GrLiteral expr, TextRange range, String newContent) throws IncorrectOperationException { + private static final Logger LOG = Logger.getInstance(GroovyStringLiteralManipulator.class); + + public GrLiteralImpl handleContentChange(GrLiteral expr, TextRange range, String newContent) throws IncorrectOperationException { if (!(expr.getValue() instanceof String)) throw new IncorrectOperationException("cannot handle content change"); + LOG.assertTrue(expr instanceof GrLiteralImpl); + String oldText = expr.getText(); - if (oldText.startsWith("'")) { - newContent = GrStringUtil.escapeSymbolsForString(newContent, !oldText.startsWith("'''"), true); - } - else if (oldText.startsWith("\"")) { - newContent = GrStringUtil.escapeSymbolsForGString(newContent, !oldText.startsWith("\"\"\""), true); - } - else if (oldText.startsWith("/")) { - newContent = StringUtil.escapeSlashes(newContent); - } - //if there is $/-string we don't need to escape something + final String quote = GrStringUtil.getStartQuote(oldText); - String newText; - if (range.getStartOffset() == 1 && (newContent.indexOf('\n') >= 0 || newContent.indexOf('\r') >= 0)) { - String corner = oldText.substring(0, 1) + oldText.substring(0, 1) + oldText.substring(0, 1); - newText = corner + newContent + corner; + if (quote.startsWith("'")) { + newContent = GrStringUtil.escapeSymbolsForString(newContent, !quote.equals("'''"), false); } - else { - newText = oldText.substring(0, range.getStartOffset()) + newContent + oldText.substring(range.getEndOffset()); + else if (quote.startsWith("\"")) { + newContent = GrStringUtil.escapeSymbolsForGString(newContent, !quote.equals("\"\"\""), true); + } + else if ("/".equals(quote)) { + newContent = GrStringUtil.escapeForSlashyStrings(newContent); + } + else if ("$/".equals(quote)) { + newContent = GrStringUtil.escapeSymbolsForDollarSlashyStrings(newContent); } - final GrExpression newExpr = GroovyPsiElementFactory.getInstance(expr.getProject()).createExpressionFromText(newText); - PsiElement firstChild = expr.getFirstChild(); - assert firstChild != null && firstChild.getNextSibling() == null; - - PsiElement newElement = newExpr.getFirstChild(); - assert newElement != null; - firstChild.replace(newElement); - - return expr; + String newText = oldText.substring(0, range.getStartOffset()) + newContent + oldText.substring(range.getEndOffset()); + return ((GrLiteralImpl)expr).updateText(newText); } public TextRange getRangeInElement(final GrLiteral element) { final String text = element.getText(); - if (element instanceof GrLiteralImpl && !(element.getValue() instanceof String)) { + if (!(element.getValue() instanceof String)) { return super.getRangeInElement(element); } return getLiteralRange(text); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcActionBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcActionBase.java index 51bd4b9bdf84..50fdc45d20d5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcActionBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcActionBase.java @@ -18,12 +18,12 @@ public abstract class MvcActionBase extends DumbAwareAction { @Override public final void actionPerformed(AnActionEvent e) { Pair pair = guessFramework(e); - if (pair != null && isSupportFramework(pair.getFirst())) { + if (pair != null && isFrameworkSupported(pair.getFirst())) { actionPerformed(e, pair.getSecond(), pair.getFirst()); } } - protected boolean isSupportFramework(@NotNull MvcFramework framework) { + protected boolean isFrameworkSupported(@NotNull MvcFramework framework) { return true; } @@ -73,7 +73,7 @@ public abstract class MvcActionBase extends DumbAwareAction { public final void update(AnActionEvent event) { Pair pair = guessFramework(event); - if (pair != null && isSupportFramework(pair.getFirst())) { + if (pair != null && isFrameworkSupported(pair.getFirst())) { event.getPresentation().setVisible(true); updateView(event, pair.getFirst(), pair.getSecond()); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcConsole.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcConsole.java index a0af4d23a3d1..d04d0a3d5fba 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcConsole.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcConsole.java @@ -323,6 +323,8 @@ public class MvcConsole implements Disposable { ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { + if (myProject.isDisposed()) return; + module.putUserData(UPDATING_BY_CONSOLE_PROCESS, true); LocalFileSystem.getInstance().refresh(false); module.putUserData(UPDATING_BY_CONSOLE_PROCESS, null); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java index 2013139497d6..5c1586c3c06e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java @@ -265,12 +265,14 @@ public class GrIntroduceFieldHandler extends GrIntroduceHandlerBase$/abc/$ -print $/a$bc/$ \ No newline at end of file +print $/abc/$ +print $/a$bc/$ \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashy6.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashy6.test new file mode 100644 index 000000000000..b1f4b878dc0f --- /dev/null +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashy6.test @@ -0,0 +1,8 @@ +$/abc/$ +----- +Groovy script + Literal + GroovyASTPsiElementImpl($/ regex literal) + PsiElement($/ regex begin)('$/') + PsiElement($/ regex content)('abc') + PsiElement($/ regex end)('/$') \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashy7.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashy7.test new file mode 100644 index 000000000000..9f0a4fde6e3a --- /dev/null +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashy7.test @@ -0,0 +1,12 @@ +print $/abc/$ +----- +Groovy script + Reference expression + PsiElement(identifier)('print') + PsiWhiteSpace(' ') + PsiErrorElement:';' or new line expected + PsiElement($)('$') + PsiElement(/)('/') + PsiElement(identifier)('abc') + PsiElement(/)('/') + PsiElement(identifier)('$') \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashy8.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashy8.test new file mode 100644 index 000000000000..0d98996de5e3 --- /dev/null +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashy8.test @@ -0,0 +1,14 @@ +print($/abc/$) +----- +Groovy script + Method call + Reference expression + PsiElement(identifier)('print') + Arguments + PsiElement(()('(') + Literal + GroovyASTPsiElementImpl($/ regex literal) + PsiElement($/ regex begin)('$/') + PsiElement($/ regex content)('abc') + PsiElement($/ regex end)('/$') + PsiElement())(')') \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashy9.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashy9.test new file mode 100644 index 000000000000..38abff2a6366 --- /dev/null +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/dollarSlashy9.test @@ -0,0 +1,17 @@ +print a, $/a/$ +----- +Groovy script + Call expression + Reference expression + PsiElement(identifier)('print') + PsiWhiteSpace(' ') + Command arguments + Reference expression + PsiElement(identifier)('a') + PsiElement(,)(',') + PsiWhiteSpace(' ') + Literal + GroovyASTPsiElementImpl($/ regex literal) + PsiElement($/ regex begin)('$/') + PsiElement($/ regex content)('a') + PsiElement($/ regex end)('/$') \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/introduceField/AnonymousClass.groovy b/plugins/groovy/testdata/refactoring/introduceField/AnonymousClass.groovy new file mode 100644 index 000000000000..0dfeba0375ac --- /dev/null +++ b/plugins/groovy/testdata/refactoring/introduceField/AnonymousClass.groovy @@ -0,0 +1,10 @@ +interface A { + void m1() +} + +def a = new A() { + @Override + void m1() { + println 123 + } +} \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/introduceField/AnonymousClass_after.groovy b/plugins/groovy/testdata/refactoring/introduceField/AnonymousClass_after.groovy new file mode 100644 index 000000000000..fcdcbb9a6f79 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/introduceField/AnonymousClass_after.groovy @@ -0,0 +1,13 @@ +interface A { + void m1() +} + +def a = new A() { + def f + + @Override + void m1() { + f = 123 + println f + } +} \ No newline at end of file diff --git a/xml/impl/src/com/intellij/xml/DefaultXmlExtension.java b/xml/impl/src/com/intellij/xml/DefaultXmlExtension.java index 95137042f893..d204ac54e55c 100644 --- a/xml/impl/src/com/intellij/xml/DefaultXmlExtension.java +++ b/xml/impl/src/com/intellij/xml/DefaultXmlExtension.java @@ -184,13 +184,11 @@ public class DefaultXmlExtension extends XmlExtension { } final List providers = XmlSchemaProvider.getAvailableProviders(file); - XmlSchemaProvider prefixProvider = null; String prefix = nsPrefix; if (prefix == null) { for (XmlSchemaProvider provider : providers) { prefix = provider.getDefaultPrefix(namespace, file); if (prefix != null) { - prefixProvider = provider; break; } } @@ -210,10 +208,10 @@ public class DefaultXmlExtension extends XmlExtension { String location = null; if (namespace.length() > 0) { - if (prefixProvider != null) { - final Set strings = prefixProvider.getLocations(namespace, file); - if (strings != null && strings.size() > 0) { - location = strings.iterator().next(); + for (XmlSchemaProvider provider : providers) { + Set locations = provider.getLocations(namespace, file); + if (locations != null && !locations.isEmpty()) { + location = locations.iterator().next(); } } }