diff --git a/colorSchemes/src/colorSchemes/Railscasts.xml b/colorSchemes/src/colorSchemes/Railscasts.xml deleted file mode 100644 index 15ab83edf265..000000000000 --- a/colorSchemes/src/colorSchemes/Railscasts.xml +++ /dev/null @@ -1,2101 +0,0 @@ - - - - - diff --git a/colorSchemes/src/colorSchemes/all_hallows_eve.xml b/colorSchemes/src/colorSchemes/all_hallows_eve.xml new file mode 100644 index 000000000000..667867a556ca --- /dev/null +++ b/colorSchemes/src/colorSchemes/all_hallows_eve.xml @@ -0,0 +1,1554 @@ + + diff --git a/colorSchemes/src/colorSchemes/blackboard.xml b/colorSchemes/src/colorSchemes/blackboard.xml new file mode 100644 index 000000000000..32018be1399d --- /dev/null +++ b/colorSchemes/src/colorSchemes/blackboard.xml @@ -0,0 +1,1524 @@ + + diff --git a/colorSchemes/src/colorSchemes/cobalt.xml b/colorSchemes/src/colorSchemes/cobalt.xml index 2c7d36906835..58c10fe73530 100644 --- a/colorSchemes/src/colorSchemes/cobalt.xml +++ b/colorSchemes/src/colorSchemes/cobalt.xml @@ -1,866 +1,1687 @@ - - + - diff --git a/colorSchemes/src/colorSchemes/monokai.xml b/colorSchemes/src/colorSchemes/monokai.xml index c96e33a7f603..d80898857541 100644 --- a/colorSchemes/src/colorSchemes/monokai.xml +++ b/colorSchemes/src/colorSchemes/monokai.xml @@ -1,4 +1,4 @@ - + diff --git a/colorSchemes/src/colorSchemes/rails_casts.xml b/colorSchemes/src/colorSchemes/rails_casts.xml new file mode 100644 index 000000000000..bd9fdb48c809 --- /dev/null +++ b/colorSchemes/src/colorSchemes/rails_casts.xml @@ -0,0 +1,1582 @@ + + diff --git a/colorSchemes/src/colorSchemes/twilight.xml b/colorSchemes/src/colorSchemes/twilight.xml index e234343e600a..7cee3379f8ad 100644 --- a/colorSchemes/src/colorSchemes/twilight.xml +++ b/colorSchemes/src/colorSchemes/twilight.xml @@ -1,4 +1,4 @@ - + diff --git a/colorSchemes/src/colorSchemes/vibrantInk.xml b/colorSchemes/src/colorSchemes/vibrantInk.xml deleted file mode 100644 index 2839cfd8cf73..000000000000 --- a/colorSchemes/src/colorSchemes/vibrantInk.xml +++ /dev/null @@ -1,1904 +0,0 @@ - - - \ No newline at end of file diff --git a/colorSchemes/src/colorSchemes/vibrant_ink.xml b/colorSchemes/src/colorSchemes/vibrant_ink.xml new file mode 100644 index 000000000000..5adcecdc4cc8 --- /dev/null +++ b/colorSchemes/src/colorSchemes/vibrant_ink.xml @@ -0,0 +1,1569 @@ + + diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java index 8f88be86d8ee..4d7359ab4b49 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java @@ -50,6 +50,7 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.LibraryPro import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ModuleProjectStructureElement; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureDaemonAnalyzer; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement; +import com.intellij.openapi.ui.DialogBuilder; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.NamedConfigurable; @@ -64,6 +65,7 @@ import com.intellij.openapi.wm.WindowManager; import com.intellij.ui.navigation.Place; import com.intellij.util.Consumer; import com.intellij.util.Function; +import com.intellij.util.PathUtil; import com.intellij.util.PlatformIcons; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.tree.TreeUtil; @@ -783,27 +785,23 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple final NamedConfigurable namedConfigurable = getSelectedConfugurable(); if (namedConfigurable instanceof ModuleConfigurable) { try { + final ModuleEditor moduleEditor = ((ModuleConfigurable)namedConfigurable).getModuleEditor(); final String modulePresentation = IdeBundle.message("project.new.wizard.module.identification"); - final NamePathComponent component = new NamePathComponent(IdeBundle.message("label.project.name"), IdeBundle.message( - "label.component.file.location", StringUtil.capitalize(modulePresentation)), IdeBundle.message( - "title.select.project.file.directory", modulePresentation), IdeBundle.message("description.select.project.file.directory", - StringUtil.capitalize(modulePresentation)), true, false); - final DialogWrapper copyModuleDialog = new DialogWrapper(myTree, false) { - { - setTitle(ProjectBundle.message("copy.module.dialog.title")); - init(); - } + final NamePathComponent component = new NamePathComponent(IdeBundle.message("label.module.name"), IdeBundle.message("label.component.file.location", StringUtil.capitalize(modulePresentation)), IdeBundle.message("title.select.project.file.directory", modulePresentation), + IdeBundle.message("description.select.project.file.directory", StringUtil.capitalize(modulePresentation)), true, + false); + final Module originalModule = moduleEditor.getModule(); + if (originalModule != null) { + component.setPath(PathUtil.getParentPath(originalModule.getModuleFilePath())); + } - public JComponent getPreferredFocusedComponent() { - return component.getNameComponent(); - } - - @Nullable - protected JComponent createCenterPanel() { - return component; - } - - protected void doOKAction() { + final DialogBuilder dialogBuilder = new DialogBuilder(myTree); + dialogBuilder.setTitle(ProjectBundle.message("copy.module.dialog.title")); + dialogBuilder.setCenterPanel(component); + dialogBuilder.setPreferedFocusComponent(component.getNameComponent()); + dialogBuilder.setOkOperation(new Runnable() { + @Override + public void run() { if (component.getNameValue().length() == 0) { Messages.showErrorDialog(ProjectBundle.message("enter.module.copy.name.error.message"), CommonBundle.message("title.error")); return; @@ -815,16 +813,17 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple return; } if (!ProjectWizardUtil - .createDirectoryIfNotExists(IdeBundle.message("directory.project.file.directory", modulePresentation), component.getPath(), true)) { + .createDirectoryIfNotExists(IdeBundle.message("directory.project.file.directory", modulePresentation), component.getPath(), + true)) { Messages.showErrorDialog(ProjectBundle.message("path.0.is.invalid.error.message", component.getPath()), CommonBundle.message("title.error")); return; } - super.doOKAction(); + dialogBuilder.getDialogWrapper().close(DialogWrapper.OK_EXIT_CODE); } - }; - copyModuleDialog.show(); - if (!copyModuleDialog.isOK()) return; - final ModifiableRootModel rootModel = ((ModuleConfigurable)namedConfigurable).getModuleEditor().getModifiableRootModel(); + }); + if (dialogBuilder.show() != DialogWrapper.OK_EXIT_CODE) return; + + final ModifiableRootModel rootModel = moduleEditor.getModifiableRootModel(); final String path = component.getPath(); final ModuleBuilder builder = new ModuleBuilder() { public void setupRootModel(final ModifiableRootModel modifiableRootModel) throws ConfigurationException { diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/AbstractUnwrapper.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/AbstractUnwrapper.java new file mode 100644 index 000000000000..53f07e9ba579 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/AbstractUnwrapper.java @@ -0,0 +1,125 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.unwrap; + +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public abstract class AbstractUnwrapper implements Unwrapper { + private final String myDescription; + + public AbstractUnwrapper(String description) { + myDescription = description; + } + + public abstract boolean isApplicableTo(PsiElement e); + + public void collectElementsToIgnore(PsiElement element, Set result) { + } + + public String getDescription(PsiElement e) { + return myDescription; + } + + public PsiElement collectAffectedElements(PsiElement e, List toExtract) { + try { + C c = createContext(false); + doUnwrap(e, c); + toExtract.addAll(c.myElementsToExtract); + return e; + } + catch (IncorrectOperationException ex) { + throw new RuntimeException(ex); + } + } + + public List unwrap(Editor editor, PsiElement element) throws IncorrectOperationException { + C c = createContext(true); + doUnwrap(element, c); + return c.myElementsToExtract; + } + + protected abstract void doUnwrap(PsiElement element, C context) throws IncorrectOperationException; + + protected abstract C createContext(boolean isEffective); + + public abstract static class AbstractContext { + protected final List myElementsToExtract = new ArrayList(); + protected final boolean myIsEffective; + + public AbstractContext(boolean isEffective) { + myIsEffective = isEffective; + } + + public void addElementToExtract(PsiElement e) { + myElementsToExtract.add(e); + } + + public void extractElement(PsiElement element, PsiElement from) throws IncorrectOperationException { + extract(element, element, from); + } + + protected abstract boolean isWhiteSpace(PsiElement element); + + protected void extract(PsiElement first, PsiElement last, PsiElement from) throws IncorrectOperationException { + // trim leading empty spaces + while (first != last && isWhiteSpace(first)) { + //noinspection ConstantConditions + first = first.getNextSibling(); + } + + // trim trailing empty spaces + while (last != first && isWhiteSpace(last)) { + //noinspection ConstantConditions + last = last.getPrevSibling(); + } + + // nothing to extract + if (first == null || last == null || first == last && isWhiteSpace(last)) return; + + PsiElement toExtract = first; + if (myIsEffective) { + toExtract = from.getParent().addRangeBefore(first, last, from); + } + + do { + if (toExtract != null) { + addElementToExtract(toExtract); + toExtract = toExtract.getNextSibling(); + } + first = first.getNextSibling(); + } + while (first != null && first.getPrevSibling() != last); + } + + public void delete(PsiElement e) throws IncorrectOperationException { + if (myIsEffective) e.delete(); + } + + public void deleteExactly(PsiElement e) throws IncorrectOperationException { + if (myIsEffective) { + // have to use 'parent.deleteChildRange' since 'e.delete' is too smart: + // it attempts to remove not only the element but sometimes whole expression. + e.getParent().deleteChildRange(e, e); + } + } + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java index f1af90bc8db1..d9e87eadf59f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java +++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java @@ -29,19 +29,31 @@ import java.util.List; import java.util.Set; public class JavaUnwrapDescriptor implements UnwrapDescriptor { - private static final Unwrapper[] UNWRAPPERS = new Unwrapper[] { - new JavaMethodParameterUnwrapper(), - new JavaElseUnwrapper(), - new JavaElseRemover(), - new JavaIfUnwrapper(), - new JavaWhileUnwrapper(), - new JavaForUnwrapper(), - new JavaBracesUnwrapper(), - new JavaTryUnwrapper(), - new JavaCatchRemover(), - new JavaSynchronizedUnwrapper(), - new JavaAnonymousUnwrapper(), - }; + private Unwrapper[] myUnwrappers; + + public final Unwrapper[] getUnwrappers() { + if (myUnwrappers == null) { + myUnwrappers = createUnwrappers(); + } + + return myUnwrappers; + } + + protected Unwrapper[] createUnwrappers() { + return new Unwrapper[] { + new JavaMethodParameterUnwrapper(), + new JavaElseUnwrapper(), + new JavaElseRemover(), + new JavaIfUnwrapper(), + new JavaWhileUnwrapper(), + new JavaForUnwrapper(), + new JavaBracesUnwrapper(), + new JavaTryUnwrapper(), + new JavaCatchRemover(), + new JavaSynchronizedUnwrapper(), + new JavaAnonymousUnwrapper(), + }; + } public List> collectUnwrappers(Project project, Editor editor, PsiFile file) { PsiElement e = findTargetElement(editor, file); @@ -49,7 +61,7 @@ public class JavaUnwrapDescriptor implements UnwrapDescriptor { List> result = new ArrayList>(); Set ignored = new HashSet(); while (e != null) { - for (Unwrapper u : UNWRAPPERS) { + for (Unwrapper u : getUnwrappers()) { if (u.isApplicableTo(e) && !ignored.contains(e)) { result.add(new Pair(e, u)); u.collectElementsToIgnore(e, ignored); diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapper.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapper.java index dbec98c6a72d..ac6940f77517 100644 --- a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapper.java +++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapper.java @@ -15,60 +15,24 @@ */ package com.intellij.codeInsight.unwrap; -import com.intellij.openapi.editor.Editor; import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -public abstract class JavaUnwrapper implements Unwrapper { - private final String myDescription; +public abstract class JavaUnwrapper extends AbstractUnwrapper { public JavaUnwrapper(String description) { - myDescription = description; + super(description); } - public abstract boolean isApplicableTo(PsiElement e); - - public void collectElementsToIgnore(PsiElement element, Set result) { + @Override + protected Context createContext(boolean isEffective) { + return new Context(isEffective); } - public String getDescription(PsiElement e) { - return myDescription; - } - - public PsiElement collectAffectedElements(PsiElement e, List toExtract) { - try { - Context c = new Context(false); - doUnwrap(e, c); - toExtract.addAll(c.myElementsToExtract); - return e; - } - catch (IncorrectOperationException ex) { - throw new RuntimeException(ex); - } - } - - public List unwrap(Editor editor, PsiElement element) throws IncorrectOperationException { - Context c = new Context(true); - doUnwrap(element, c); - return c.myElementsToExtract; - } - - protected abstract void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException; - - protected static class Context { - private final List myElementsToExtract = new ArrayList(); - private final boolean myIsEffective; + protected static class Context extends AbstractUnwrapper.AbstractContext { public Context(boolean isEffective) { - myIsEffective = isEffective; - } - - public void addElementToExtract(PsiElement e) { - myElementsToExtract.add(e); + super(isEffective); } public void extractFromBlockOrSingleStatement(PsiStatement block, PsiElement from) throws IncorrectOperationException { @@ -85,51 +49,6 @@ public abstract class JavaUnwrapper implements Unwrapper { extract(block.getFirstBodyElement(), block.getLastBodyElement(), from); } - public void extractElement(PsiElement element, PsiElement from) throws IncorrectOperationException { - extract(element, element, from); - } - - private void extract(PsiElement first, PsiElement last, PsiElement from) throws IncorrectOperationException { - // trim leading empty spaces - while (first != last && first instanceof PsiWhiteSpace) { - first = first.getNextSibling(); - } - - // trim trailing empty spaces - while (last != first && last instanceof PsiWhiteSpace) { - last = last.getPrevSibling(); - } - - // nothing to extract - if (first == null || last == null || first == last && last instanceof PsiWhiteSpace) return; - - PsiElement toExtract = first; - if (myIsEffective) { - toExtract = from.getParent().addRangeBefore(first, last, from); - } - - do { - if (toExtract != null) { - addElementToExtract(toExtract); - toExtract = toExtract.getNextSibling(); - } - first = first.getNextSibling(); - } - while (first != null && first.getPrevSibling() != last); - } - - public void delete(PsiElement e) throws IncorrectOperationException { - if (myIsEffective) e.delete(); - } - - public void deleteExactly(PsiElement e) throws IncorrectOperationException { - if (myIsEffective) { - // have to use 'parent.deleteChildRange' since 'e.delete' is too smart: - // it attempts to remove not only the element but sometimes whole expression. - e.getParent().deleteChildRange(e, e); - } - } - public void setElseBranch(PsiIfStatement ifStatement, PsiStatement elseBranch) throws IncorrectOperationException { PsiStatement toExtract = elseBranch; if (myIsEffective) { @@ -139,6 +58,11 @@ public abstract class JavaUnwrapper implements Unwrapper { addElementToExtract(toExtract); } + @Override + protected boolean isWhiteSpace(PsiElement element) { + return element instanceof PsiWhiteSpace; + } + private static PsiStatement copyElement(PsiStatement e) throws IncorrectOperationException { // We cannot call el.copy() for 'else' since it sets context to parent 'if'. // This causes copy to be invalidated after parent 'if' is removed by setElseBranch method. diff --git a/java/java-impl/src/com/intellij/lang/java/JavaCommenter.java b/java/java-impl/src/com/intellij/lang/java/JavaCommenter.java index ea5118e52944..4d20c1a9b393 100644 --- a/java/java-impl/src/com/intellij/lang/java/JavaCommenter.java +++ b/java/java-impl/src/com/intellij/lang/java/JavaCommenter.java @@ -85,6 +85,6 @@ public class JavaCommenter implements CodeDocumentationAwareCommenterEx { public boolean isDocumentationCommentText(final PsiElement element) { if (element == null) return false; final ASTNode node = element.getNode(); - return node != null && node.getElementType() == JavaDocTokenType.DOC_COMMENT_DATA; + return node != null && (node.getElementType() == JavaDocTokenType.DOC_COMMENT_DATA || node.getElementType() == JavaDocTokenType.DOC_TAG_VALUE_TOKEN); } } diff --git a/platform/core-api/src/com/intellij/openapi/util/SimpleTimer.java b/platform/core-api/src/com/intellij/openapi/util/SimpleTimer.java index c04d74b0a3e1..68cc8f97a3d8 100644 --- a/platform/core-api/src/com/intellij/openapi/util/SimpleTimer.java +++ b/platform/core-api/src/com/intellij/openapi/util/SimpleTimer.java @@ -18,6 +18,7 @@ package com.intellij.openapi.util; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import java.util.*; @@ -30,21 +31,23 @@ public class SimpleTimer { private final Timer ourTimer; - private static final SimpleTimer ourInstance = new SimpleTimer(); - @NonNls private static final String THREAD_NAME = "SimpleTimer"; + private static final SimpleTimer ourInstance = newInstance("Shared SimpleTimer"); private long myNextScheduledTime = Long.MAX_VALUE; private TimerTask myNextProcessingTask; private final Map> myTime2Task = new TreeMap>(); + private String myThreadName; - private SimpleTimer() { + private SimpleTimer(@NotNull String threadName) { + myThreadName = threadName; + final Thread thread = Thread.currentThread(); final int currentPrio = thread.getPriority(); try { // need this becase the timer's thread will inherit the priority on creation thread.setPriority(Thread.MIN_PRIORITY + 1); - ourTimer = new Timer(THREAD_NAME, true); + ourTimer = new Timer(threadName, true); } finally { thread.setPriority(currentPrio); @@ -54,6 +57,10 @@ public class SimpleTimer { public static SimpleTimer getInstance() { return ourInstance; } + + public static SimpleTimer newInstance(@NotNull String name) { + return new SimpleTimer(name); + } public SimpleTimerTask setUp(final Runnable runnable, long delay) { synchronized (myTime2Task) { @@ -150,7 +157,7 @@ public class SimpleTimer { } public boolean isTimerThread(Thread thread) { - return THREAD_NAME.equals(thread.getName()); + return myThreadName.equals(thread.getName()); } void onCancelled(SimpleTimerTask task) { diff --git a/platform/funcTests/project1/module1/scripts/generateActions/_suite.ijs b/platform/funcTests/project1/module1/scripts/generateActions/_suite.ijs new file mode 100644 index 000000000000..4e3edad05246 --- /dev/null +++ b/platform/funcTests/project1/module1/scripts/generateActions/_suite.ijs @@ -0,0 +1,6 @@ +%startTest Generate actions + +%include extract_Superclass.ijs +%include newClass_projectView.ijs + +%endTest \ No newline at end of file diff --git a/platform/funcTests/project1/module1/scripts/generateActions/extract_Superclass.ijs b/platform/funcTests/project1/module1/scripts/generateActions/extract_Superclass.ijs index 7012ffb1e60a..c78f7c40a9db 100644 --- a/platform/funcTests/project1/module1/scripts/generateActions/extract_Superclass.ijs +++ b/platform/funcTests/project1/module1/scripts/generateActions/extract_Superclass.ijs @@ -1,12 +1,15 @@ -%startTest Create superclass +%startTest Create superclass from popup menu -%%include ../include/project1Init.ijs -%%action GotoClass -%%PsiManager\n - -%include ../include/init.ijs +%include ../include/project1Init.ijs +%action GotoClass +FileEditorManager\n +%call checkFocus(editorTab=FileEditorManager.java) %call contextMenu(Refactor|Extract Superclass) TestSuperclass\n -%call checkFocus(dialog=Analyze and Replace Usages) +%call waitForDialog(Analyze and Replace Usages) +%[space] +%call waitForDialog(Use Interface Where Possible) +%[space] +%call checkFocus(editorTab=FileEditorManager.java) %endTest \ No newline at end of file diff --git a/platform/funcTests/project1/module1/scripts/navbar/basicTest.ijs b/platform/funcTests/project1/module1/scripts/navbar/basicTest.ijs index ad5ac84c24ce..29ee97d49e8b 100644 --- a/platform/funcTests/project1/module1/scripts/navbar/basicTest.ijs +++ b/platform/funcTests/project1/module1/scripts/navbar/basicTest.ijs @@ -8,9 +8,9 @@ PsiManager\n %[left] %[left] %[down] -%call checkFocus(navBar=module1>src>com>intellij>[testProject]>idea>PsiManager|navBarPopup=[fabrique]>idea>mps) +%call checkFocus(navBar=module1>src>com>intellij>[testProject]>idea>PsiManager|navBarPopup=fabrique>[idea]>mps) \n %call flushUi() \n -%call checkFocus(editorTab=ActiveLibrary.java) +%call checkFocus(editorTab=FileEditorManager.java) diff --git a/platform/lang-api/src/com/intellij/psi/search/TodoAttributes.java b/platform/lang-api/src/com/intellij/psi/search/TodoAttributes.java index 08c9d17d9fa0..7f7b74f6d08c 100644 --- a/platform/lang-api/src/com/intellij/psi/search/TodoAttributes.java +++ b/platform/lang-api/src/com/intellij/psi/search/TodoAttributes.java @@ -79,7 +79,7 @@ public class TodoAttributes implements JDOMExternalizable, Cloneable { } private static TextAttributes getDefaultColorSchemeTextAttributes() { - return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.TODO_DEFAULT_ATTRIBUTES); + return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.TODO_DEFAULT_ATTRIBUTES).clone(); } public void readExternal(Element element) throws InvalidDataException { diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDialogBase.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDialogBase.java index af569088d49e..a8b269f15608 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDialogBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDialogBase.java @@ -30,7 +30,6 @@ import com.intellij.openapi.ui.VerticalFlowLayout; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; -import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.psi.PsiCodeFragment; @@ -47,7 +46,7 @@ import com.intellij.ui.treeStructure.Tree; import com.intellij.util.Alarm; import com.intellij.util.Consumer; import com.intellij.util.PlatformIcons; -import com.intellij.util.ui.MacUIUtil; +import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.table.JBListTable; import com.intellij.util.ui.table.JBTableRow; import com.intellij.util.ui.table.JBTableRowEditor; @@ -282,7 +281,13 @@ public abstract class ChangeSignatureDialogBase

() { @Override public Boolean compute() { - return CopyFilesOrDirectoriesHandler.checkFileExist(targetDirectory, choice, file, file.getName()); + return CopyFilesOrDirectoriesHandler.checkFileExist(targetDirectory, choice, file, file.getName(), "Move"); } }); if (fileExist) continue; diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java index 60cb7ac1dbeb..77cb4110667c 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java @@ -307,7 +307,7 @@ public class RenameProcessor extends BaseRefactoringProcessor { if (entry.getKey() instanceof PsiFile) { final PsiFile file = (PsiFile)entry.getKey(); final PsiDirectory containingDirectory = file.getContainingDirectory(); - if (CopyFilesOrDirectoriesHandler.checkFileExist(containingDirectory, choice, file, entry.getValue())) { + if (CopyFilesOrDirectoriesHandler.checkFileExist(containingDirectory, choice, file, entry.getValue(), "Rename")) { iterator.remove(); continue; } diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/Separator.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/Separator.java index 92e08842edfc..9bc7e8c1519a 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/Separator.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/Separator.java @@ -16,6 +16,7 @@ package com.intellij.openapi.actionSystem; import com.intellij.openapi.project.DumbAware; +import org.jetbrains.annotations.Nullable; /** * Represents a separator. @@ -28,7 +29,7 @@ public final class Separator extends AnAction implements DumbAware { public Separator() { } - public Separator(String text) { + public Separator(@Nullable final String text) { myText = text; } diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooser.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooser.java index db6d6546a8fc..863c1ec2387c 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooser.java +++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooser.java @@ -94,8 +94,29 @@ public class FileChooser { @Nullable final VirtualFile toSelect, @NotNull final Consumer onChosenCallback ) { - if (SystemInfo.isMac && isNativeMacChooserEnabled()) descriptor.putUserData(MacFileChooserDialog.NATIVE_MAC_FILE_CHOOSER_ENABLED, Boolean.TRUE); - final FileChooserDialog dialog = FileChooserFactory.getInstance().createFileChooser(descriptor, project); + chooseFilesWithSlideEffect(descriptor, project, null, toSelect, onChosenCallback); + } + + /** + * Shows file/folder open dialog, allows user to choose files/folders and then passes result to callback in EDT. + * On MacOS Open Dialog will be shown with slide effect if Macish UI is turned on. + * @param descriptor File chooser descriptor + * @param project project + * @param parent parent component + * @param toSelect file to preselect + * @param onChosenCallback Callback will be invoked after user have closed dialog + */ + public static void chooseFilesWithSlideEffect(@NotNull final FileChooserDescriptor descriptor, + @Nullable final Project project, + @Nullable final Component parent, + @Nullable final VirtualFile toSelect, + @NotNull final Consumer onChosenCallback + ) { + if (SystemInfo.isMac && isNativeMacChooserEnabled()) descriptor.putUserData(MacFileChooserDialog.NATIVE_MAC_FILE_CHOOSER_ENABLED, Boolean.TRUE); + final FileChooserFactory factory = FileChooserFactory.getInstance(); + final FileChooserDialog dialog = parent != null + ? factory.createFileChooser(descriptor, parent) + : factory.createFileChooser(descriptor, project); if (dialog instanceof MacFileChooserDialog) { ((MacFileChooserDialog)dialog).chooseWithSheet(toSelect, project, new MacFileChooserDialog.MacFileChooserCallback() { public void onChosen(@NotNull final VirtualFile[] files) { diff --git a/platform/platform-api/src/com/intellij/openapi/util/EdtRunnable.java b/platform/platform-api/src/com/intellij/openapi/util/EdtRunnable.java index 8e470f548a62..84f174706322 100644 --- a/platform/platform-api/src/com/intellij/openapi/util/EdtRunnable.java +++ b/platform/platform-api/src/com/intellij/openapi/util/EdtRunnable.java @@ -17,15 +17,28 @@ package com.intellij.openapi.util; import com.intellij.util.ui.UIUtil; -public abstract class EdtRunnable implements Runnable { +public abstract class EdtRunnable implements ExpirableRunnable { + + private boolean myExpired; public final void run() { UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { - runEdt(); + if (!isExpired()) { + runEdt(); + } } }); } + public void expire() { + myExpired = true; + } + + @Override + public boolean isExpired() { + return myExpired; + } + public abstract void runEdt(); } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java index df0256266971..d26dcdd0afc8 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java @@ -319,10 +319,8 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent myEventCount + "; current event count = " + currentEventCount ); */ - if (false) { LOG.error("cannot share data context between Swing events; initial event count = " + myEventCount + "; current event count = " + currentEventCount); - } } Component _component = myRef.get(); diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java index c1b6548b60ff..c9684dbc24cb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java @@ -247,19 +247,25 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa super.stop(); - if (myDialog != null) { - myDialog.hide(); - if (myDialog.wasShown()) { - myFocusTrackback.restoreFocus(); - } - else { - myFocusTrackback.consume(); - } - } - myStoppedAlready = true; + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + if (myDialog != null) { + myDialog.hide(); + if (myDialog.wasShown()) { + myFocusTrackback.restoreFocus(); + } + else { + myFocusTrackback.consume(); + } + } - Disposer.dispose(this); + myStoppedAlready = true; + + Disposer.dispose(ProgressWindow.this); + } + }); SwingUtilities.invokeLater(EmptyRunnable.INSTANCE); // Just to give blocking dispatching a chance to go out. } diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/playback/util/WindowSystemPlaybackCall.java b/platform/platform-impl/src/com/intellij/openapi/ui/playback/util/WindowSystemPlaybackCall.java index 84f2f0dfd96c..6f31ee622eeb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/playback/util/WindowSystemPlaybackCall.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/playback/util/WindowSystemPlaybackCall.java @@ -24,6 +24,9 @@ import com.intellij.openapi.ui.Queryable; import com.intellij.openapi.ui.playback.PlaybackContext; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.AsyncResult; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.SimpleTimer; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.IdeFrame; import com.intellij.openapi.wm.ToolWindow; @@ -34,8 +37,10 @@ import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; +import java.awt.event.AWTEventListener; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; +import java.awt.event.WindowEvent; import java.util.*; public class WindowSystemPlaybackCall { @@ -67,6 +72,46 @@ public class WindowSystemPlaybackCall { return result; } + + public static AsyncResult waitForDialog(final PlaybackContext context, final String title) { + final AsyncResult result = new AsyncResult(); + + final Ref listener = new Ref(); + listener.set(new AWTEventListener() { + @Override + public void eventDispatched(AWTEvent event) { + if (event.getID() == WindowEvent.WINDOW_ACTIVATED) { + final Window wnd = ((WindowEvent)event).getWindow(); + if (wnd instanceof JDialog) { + if (title.equals(((JDialog)wnd).getTitle())) { + Toolkit.getDefaultToolkit().removeAWTEventListener(listener.get()); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + getUiReady(context).notify(result); + } + }); + } + } + } + } + }); + + Toolkit.getDefaultToolkit().addAWTEventListener(listener.get(), WindowEvent.WINDOW_EVENT_MASK); + + SimpleTimer.getInstance().setUp(new Runnable() { + @Override + public void run() { + Toolkit.getDefaultToolkit().removeAWTEventListener(listener.get()); + if (!result.isProcessed()) { + result.setRejected("Timed out waiting for window: " + title); + } + } + }, Registry.intValue("actionSystem.commandProcessingTimeout")); + + return result; + } + public static AsyncResult checkFocus(final PlaybackContext context, String expected) { final AsyncResult result = new AsyncResult(); final Map expectedMap = new LinkedHashMap(); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java index 42c57c9dd791..0973b1662520 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java @@ -27,10 +27,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.ui.popup.JBPopup; -import com.intellij.openapi.util.ActionCallback; -import com.intellij.openapi.util.EdtRunnable; -import com.intellij.openapi.util.Expirable; -import com.intellij.openapi.util.ExpirableRunnable; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.*; import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; @@ -79,24 +76,11 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { final EdtAlarm myFocusedComponentAlaram; private final EdtAlarm myForcedFocusRequestsAlarm; + private SimpleTimer myTimer = SimpleTimer.newInstance("FocusManager timer"); + private final EdtAlarm myIdleAlarm; private final Set myIdleRequests = new LinkedHashSet(); - private final EdtRunnable myIdleRunnable = new EdtRunnable() { - public void runEdt() { - if (canFlushIdleRequests()) { - flushIdleRequests(); - } - else { - if (processFocusRevalidation()) { - if (isFocusTransferReady()) { - flushIdleRequests(); - } - } - - restartIdleAlarm(); - } - } - }; + private boolean myFlushWasDelayedToFixFocus; private ExpirableRunnable myFocusRevalidator; @@ -106,6 +90,24 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { private UiActivityMonitor myActivityMonitor; private boolean myTypeaheadEnabled = true; + + private class IdleRunnable extends EdtRunnable { + public void runEdt() { + if (canFlushIdleRequests()) { + flushIdleRequests(); + } + else { + if (processFocusRevalidation()) { + if (isFocusTransferReady()) { + flushIdleRequests(); + } + } + + restartIdleAlarm(); + } + } + } + private boolean canFlushIdleRequests() { Component focusOwner = getFocusOwner(); return isFocusTransferReady() @@ -128,9 +130,9 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { myQueue = IdeEventQueue.getInstance(); myActivityMonitor = UiActivityMonitor.getInstance(); - myFocusedComponentAlaram = new EdtAlarm(this); - myForcedFocusRequestsAlarm = new EdtAlarm(this); - myIdleAlarm = new EdtAlarm(this); + myFocusedComponentAlaram = new EdtAlarm(); + myForcedFocusRequestsAlarm = new EdtAlarm(); + myIdleAlarm = new EdtAlarm(); final AppListener myAppListener = new AppListener(); myApp.getMessageBus().connect().subscribe(ApplicationActivationListener.TOPIC, myAppListener); @@ -183,6 +185,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { @NotNull public ActionCallback requestFocus(@NotNull final FocusCommand command, final boolean forced) { + assertDispatchThread(); + if (isInternalMode) { recordCommand(command, new Throwable(), forced); } @@ -460,7 +464,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { private void restartIdleAlarm() { myIdleAlarm.cancelAllRequests(); - myIdleAlarm.addRequest(myIdleRunnable, Registry.intValue("actionSystem.focusIdleTimeout")); + myIdleAlarm.addRequest(new IdleRunnable(), Registry.intValue("actionSystem.focusIdleTimeout")); } private void flushIdleRequests() { @@ -602,6 +606,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } public boolean isFocusTransferReady() { + assertDispatchThread(); + if (myRunContext != null) return true; invalidateFocusRequestsQueue(); @@ -741,6 +747,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } public void suspendKeyProcessingUntil(@NotNull final ActionCallback done) { + assertDispatchThread(); + requestFocus(new FocusCommand(done) { public ActionCallback run() { return done; @@ -749,6 +757,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } public Expirable getTimestamp(final boolean trackOnlyForcedCommands) { + assertDispatchThread(); + return new Expirable() { long myOwnStamp = trackOnlyForcedCommands ? myForcedCmdTimestamp : myCmdTimestamp; @@ -760,6 +770,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { @Override public FocusRequestor getFurtherRequestor() { + assertDispatchThread(); + FurtherRequestor requestor = new FurtherRequestor(this, getTimestamp(true)); myValidFurtherRequestors.add(requestor); revalidateFurtherRequestors(); @@ -789,6 +801,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { @Override public Component getFocusOwner() { + assertDispatchThread(); + Component result = null; if (myRunContext != null) { result = (Component)myRunContext.getData(PlatformDataKeys.CONTEXT_COMPONENT.getName()); @@ -815,6 +829,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { @Override public void runOnOwnContext(DataContext context, Runnable runnable) { + assertDispatchThread(); + myRunContext = context; try { runnable.run(); @@ -825,12 +841,16 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { @Override public Component getLastFocusedFor(IdeFrame frame) { + assertDispatchThread(); + WeakReference ref = myLastFocused.get(frame); return ref != null ? ref.get() : null; } @Override public void toFront(JComponent c) { + assertDispatchThread(); + if (c == null) return; final Window window = UIUtil.getParentOfType(Window.class, c); @@ -877,19 +897,20 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } - static class EdtAlarm { - private final Alarm myAlarm; - - private EdtAlarm(Disposable parent) { - myAlarm = new Alarm(Alarm.ThreadToUse.OWN_THREAD, parent); - } + class EdtAlarm { + private Set myRequests = new HashSet(); + public void cancelAllRequests() { - myAlarm.cancelAllRequests(); + for (EdtRunnable each : myRequests) { + each.expire(); + } + myRequests.clear(); } public void addRequest(EdtRunnable runnable, int delay) { - myAlarm.addRequest(runnable, delay); + myRequests.add(runnable); + myTimer.setUp(runnable, delay); } } @@ -1018,4 +1039,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { public boolean isFocusTransferEnabled() { return myApp.isActive() || !Registry.is("actionSystem.suspendFocusTransferIfApplicationInactive"); } + + private void assertDispatchThread() { + ApplicationManager.getApplication().assertIsDispatchThread(); + } } diff --git a/platform/platform-impl/src/com/intellij/util/ui/table/JBListTable.java b/platform/platform-impl/src/com/intellij/util/ui/table/JBListTable.java index b9a95273df92..f1497fcedde4 100644 --- a/platform/platform-impl/src/com/intellij/util/ui/table/JBListTable.java +++ b/platform/platform-impl/src/com/intellij/util/ui/table/JBListTable.java @@ -56,11 +56,13 @@ public abstract class JBListTable extends JPanel { mainTable = new JBTable(model) { @Override protected void processKeyEvent(KeyEvent e) { + if (e.isAltDown()) return; if (e.getKeyCode() == KeyEvent.VK_ENTER && e.getModifiers() == 0) { if (!isEditing() && e.getID() == KeyEvent.KEY_PRESSED) { editCellAt(getSelectedRow(), getSelectedColumn()); } e.consume(); + return; } //todo[kb] JBTabsImpl breaks focus traversal policy. Need a workaround here else if (e.getKeyCode() == KeyEvent.VK_TAB) { @@ -73,10 +75,9 @@ public abstract class JBListTable extends JPanel { } } e.consume(); + return; } - else { - super.processKeyEvent(e); - } + super.processKeyEvent(e); } @Override diff --git a/platform/platform-resources-en/src/messages/SMTestsRunnerBundle.properties b/platform/platform-resources-en/src/messages/SMTestsRunnerBundle.properties index d519fe788278..c698828d276d 100644 --- a/platform/platform-resources-en/src/messages/SMTestsRunnerBundle.properties +++ b/platform/platform-resources-en/src/messages/SMTestsRunnerBundle.properties @@ -13,7 +13,7 @@ sm.test.runner.ui.tests.tree.presentation.labels.instantiating.tests=Instantiati sm.test.runner.ui.tests.tree.presentation.labels.not.test.results=No Test Results sm.test.runner.ui.tests.tree.presentation.labels.was.terminated=Terminated sm.test.runner.ui.tests.tree.presentation.labels.no.tests.were.found=No tests were found -sm.test.runner.ui.tests.tree.presentation.labels.test.reporter.not.attached=Unable to attach test reporter to test framework +sm.test.runner.ui.tests.tree.presentation.labels.test.reporter.not.attached=Unable to attach test reporter to test framework or test framework quit unexpectedly sm.test.runner.ui.tests.tree.presentation.labels.no.tests.were.found.with.errors=No tests were found. Errors occurred sm.test.runner.ui.tests.tree.presentation.labels.empty.test.suite=Empty test suite sm.test.runner.ui.tests.tree.presentation.labels.all.tests.passed=All Tests Passed diff --git a/platform/platform-resources/src/DefaultColorSchemesManager.xml b/platform/platform-resources/src/DefaultColorSchemesManager.xml index 1499d4e0b511..45616099a0c3 100644 --- a/platform/platform-resources/src/DefaultColorSchemesManager.xml +++ b/platform/platform-resources/src/DefaultColorSchemesManager.xml @@ -1175,6 +1175,76 @@ + + + + + + + diff --git a/platform/platform-resources/src/idea/Keymap_Mac.xml b/platform/platform-resources/src/idea/Keymap_Mac.xml index cc862b1e2b6e..2f82b8830f3a 100644 --- a/platform/platform-resources/src/idea/Keymap_Mac.xml +++ b/platform/platform-resources/src/idea/Keymap_Mac.xml @@ -218,7 +218,8 @@ - + + diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java index 33764f466176..a10a86bffcbc 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java @@ -19,6 +19,7 @@ import com.intellij.execution.Location; import com.intellij.execution.PsiLocation; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -36,7 +37,7 @@ import java.util.List; /** * @author Roman Chernyatchik */ -public class FileUrlProvider implements TestLocationProvider { +public class FileUrlProvider implements TestLocationProvider, DumbAware { private static final Logger LOG = Logger.getInstance(FileUrlProvider.class.getName()); @NonNls private static final String FILE_PROTOCOL_ID = "file"; diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java index 5a896c2db8d1..e6ecb19be407 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java @@ -28,6 +28,7 @@ import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.ide.util.EditSourceUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.pom.Navigatable; @@ -180,6 +181,8 @@ public class SMTestProxy extends AbstractTestProxy { final String protocolId = TestsLocationProviderUtil.extractProtocol(myLocationUrl); final String path = TestsLocationProviderUtil.extractPath(myLocationUrl); + final boolean isDumbMode = DumbService.isDumb(project); + if (protocolId != null && path != null) { if (myLocator != null) { List locations = myLocator.getLocation(protocolId, path, project); @@ -188,6 +191,9 @@ public class SMTestProxy extends AbstractTestProxy { } } for (TestLocationProvider provider : Extensions.getExtensions(TestLocationProvider.EP_NAME)) { + if (isDumbMode && !DumbService.isDumbAware(provider)) { + continue; + } final List locations = provider.getLocation(protocolId, path, project); if (!locations.isEmpty()) { return locations.iterator().next(); diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java index 81fe4ead2ffa..023eb3ee610a 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java @@ -547,7 +547,7 @@ public class TestsPresentationUtilTest extends BaseSMTRunnerTestCase { assertEquals(PoolOfTestIcons.NOT_RAN, myRenderer.getIcon()); assertOneElement(myFragContainer.getFragments()); - assertEquals("Unable to attach test reporter to test framework", myFragContainer.getTextAt(0)); + assertEquals("Unable to attach test reporter to test framework or test framework quit unexpectedly", myFragContainer.getTextAt(0)); assertEquals(SimpleTextAttributes.ERROR_ATTRIBUTES, myFragContainer.getAttribsAt(0)); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java index cca7926e64b0..6b2d4e650753 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -135,8 +135,8 @@ public class CommitHelper { if (failed > 0) { text += ", " + failed + " " + StringUtil.pluralize("change", failed) + " failed to commit"; } - String content = StringUtil.isEmpty(myCommitMessage) ? text : text + ": " + myCommitMessage; - VcsBalloonProblemNotifier.NOTIFICATION_GROUP.createNotification(content, NotificationType.INFORMATION).notify( myProject); + String content = StringUtil.isEmpty(myCommitMessage) ? text : text + ": " + StringUtil.escapeXml(myCommitMessage); + VcsBalloonProblemNotifier.NOTIFICATION_GROUP.createNotification(content, NotificationType.INFORMATION).notify(myProject); return new NotificationInfo("VCS Commit", "VCS Commit Finished", text, true); } }; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerHistoryManager.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerHistoryManager.java index e8557400aafe..71cd07f8e16e 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerHistoryManager.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerHistoryManager.java @@ -34,7 +34,8 @@ public class XDebuggerHistoryManager { } public void addRecentExpression(@NotNull @NonNls String id, @NotNull String expression) { - if (expression.trim().length() == 0) return; + final String trimmedExpression = expression.trim(); + if (trimmedExpression.length() == 0) return; LinkedList list = myRecentExpressions.get(id); if (list == null) { @@ -44,8 +45,8 @@ public class XDebuggerHistoryManager { if (list.size() == MAX_RECENT_EXPRESSIONS) { list.removeLast(); } - list.remove(expression); - list.addFirst(expression); + list.remove(trimmedExpression); + list.addFirst(trimmedExpression); } public List getRecentExpressions(@NonNls String id) { diff --git a/plugins/git4idea/src/git4idea/actions/GitQuickListContentProvider.java b/plugins/git4idea/src/git4idea/actions/GitQuickListContentProvider.java index 540c1f8dd7a0..2687a1a6a6db 100644 --- a/plugins/git4idea/src/git4idea/actions/GitQuickListContentProvider.java +++ b/plugins/git4idea/src/git4idea/actions/GitQuickListContentProvider.java @@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.actions.VcsQuickListContentProvider; import git4idea.GitVcs; +import git4idea.i18n.GitBundle; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -66,6 +67,14 @@ public class GitQuickListContentProvider implements VcsQuickListContentProvider add("Git.Stash", manager, actions); add("Git.Unstash", manager, actions); + // Github + addSeparator(actions); + final AnAction githubRebase = manager.getAction("Github.Rebase"); + if (githubRebase != null) { + actions.add(new Separator(GitBundle.message("vcs.popup.git.github.section"))); + actions.add(githubRebase); + } + return actions; } @@ -81,7 +90,7 @@ public class GitQuickListContentProvider implements VcsQuickListContentProvider return true; } - private void addSeparator(List actions) { + private void addSeparator(@NotNull final List actions) { actions.add(new Separator()); } diff --git a/plugins/git4idea/src/git4idea/i18n/GitBundle.properties b/plugins/git4idea/src/git4idea/i18n/GitBundle.properties index d4ce5b26e37b..215633bea117 100644 --- a/plugins/git4idea/src/git4idea/i18n/GitBundle.properties +++ b/plugins/git4idea/src/git4idea/i18n/GitBundle.properties @@ -516,3 +516,5 @@ branch.delete.not_fully_merged.description.not_on_branch=You are currently not o branch.delete.merged_to.many=The branch {0} is however fully merged to the following branches: {1}. branch.delete.merged_to.one=The branch {0} is however fully merged to the branch {1}. branch.delete.warning=You may still delete the branch {0}, but beware that it cannot be undone. + +vcs.popup.git.github.section=GitHub \ No newline at end of file diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubRebase.java b/plugins/github/src/org/jetbrains/plugins/github/GithubRebase.java index 8071d1faf418..6355e05006af 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubRebase.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubRebase.java @@ -31,7 +31,7 @@ import java.util.List; * @date 12/10/10 */ public class GithubRebase extends GitRebase { - private String myParent; + private String myOriginName; /** * {@inheritDoc} @@ -39,7 +39,7 @@ public class GithubRebase extends GitRebase { @Nullable protected GitLineHandler createHandler(final Project project, final List gitRoots, final VirtualFile defaultRoot) { final GithubRebaseDialog dialog = new GithubRebaseDialog(project, gitRoots, defaultRoot); - dialog.configure(myParent); + dialog.configure(myOriginName); dialog.show(); if (!dialog.isOK()) { return null; @@ -47,8 +47,8 @@ public class GithubRebase extends GitRebase { return dialog.handler(); } - public void setRebaseOrigin(final String parent) { - myParent = parent; + public void setRebaseOrigin(final String originName) { + myOriginName = originName; } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java index 9148996e28b3..bb09ef4ee4ef 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java @@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; @@ -124,15 +125,15 @@ public class GithubRebaseAction extends DumbAwareAction { final String parentRepoUrl = "git://github.com/" + parentRepoSuffix; // Check that corresponding remote branch is configured for the fork origin repo - boolean remoteForParentSeen = false; + final Ref remoteForForkParentRepo = new Ref(); for (GitRemote gitRemote : gitRemotes) { final String fetchUrl = gitRemote.fetchUrl(); if (fetchUrl.endsWith(parent + ".git")) { - remoteForParentSeen = true; + remoteForForkParentRepo.set(gitRemote.name()); break; } } - if (!remoteForParentSeen){ + if (remoteForForkParentRepo.isNull()){ final int result = Messages.showYesNoDialog(project, "It is necessary to have '" + parentRepoUrl + "' as a configured remote. Add remote?", "Github Rebase", @@ -149,8 +150,9 @@ public class GithubRebaseAction extends DumbAwareAction { final GitSimpleHandler addRemoteHandler = new GitSimpleHandler(project, root, GitCommand.REMOTE); addRemoteHandler.setNoSSH(true); addRemoteHandler.setSilent(true); - final String remoteName = parent.substring(0, parent.lastIndexOf('/')); - addRemoteHandler.addParameters("add", remoteName, parentRepoUrl); + + remoteForForkParentRepo.set("upstream"); + addRemoteHandler.addParameters("add", remoteForForkParentRepo.get(), parentRepoUrl); addRemoteHandler.run(); if (addRemoteHandler.getExitCode() != 0) { showErrorMessageInEDT(project, "Failed to add GitHub remote: '" + parentRepoUrl + "'"); @@ -180,7 +182,7 @@ public class GithubRebaseAction extends DumbAwareAction { BasicAction.saveAll(); final GithubRebase action = (GithubRebase) ActionManager.getInstance().getAction("Github.Rebase.Internal"); - action.setRebaseOrigin(parent); + action.setRebaseOrigin(remoteForForkParentRepo.get()); final AnActionEvent actionEvent = new AnActionEvent(e.getInputEvent(), e.getDataContext(), e.getPlace(), e.getPresentation(), e.getActionManager(), e.getModifiers()); action.actionPerformed(actionEvent); diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java index 6af7001bedca..a9382f961f1e 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java @@ -365,13 +365,20 @@ public class GithubUtil { @Nullable public static GitRemote findGitHubRemoteBranch(final Project project, final VirtualFile root) { + // i.e. find origin which points on my github repo try { // Check that given repository is properly configured git repository - final String host = GithubSettings.getInstance().getHost(); + final GithubSettings githubSettings = GithubSettings.getInstance(); + final String host = githubSettings.getHost(); + final String username = githubSettings.getLogin(); + + final String userRepoMarkerSSHProtocol = host + ":" + username + "/"; + final String userRepoMarkerOtherProtocols = host + "/" + username + "/"; + final List gitRemotes = GitRemote.list(project, root); for (GitRemote gitRemote : gitRemotes) { final String pushUrl = gitRemote.pushUrl(); - if (pushUrl.contains(host)) { + if (pushUrl.contains(userRepoMarkerSSHProtocol) || pushUrl.contains(userRepoMarkerOtherProtocols)) { return gitRemote; } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubRebaseDialog.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubRebaseDialog.java index 9f381d0ea1dd..9bce8d8ef355 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubRebaseDialog.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubRebaseDialog.java @@ -16,10 +16,13 @@ package org.jetbrains.plugins.github.ui; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; import git4idea.GitBranch; import git4idea.rebase.GitRebaseDialog; import git4idea.ui.GitUIUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -35,14 +38,13 @@ public class GithubRebaseDialog extends GitRebaseDialog { super(project, roots, defaultRoot); } - public void configure(final String parent) { + public void configure(final String originName) { setTitle("Rebase GitHub"); myShowRemoteBranchesCheckBox.setSelected(true); myShowRemoteBranchesCheckBox.getParent().remove(myShowRemoteBranchesCheckBox); myGitRootComboBox.setEnabled(false); myLocalBranches.clear(); - final String originName = parent.substring(0, parent.lastIndexOf('/')); final ArrayList remoteCopy = new ArrayList(); remoteCopy.addAll(myRemoteBranches); myRemoteBranches.clear(); @@ -55,14 +57,41 @@ public class GithubRebaseDialog extends GitRebaseDialog { updateOntoFrom(); // Preselect remote master - final String preselected = "/" + originName + "/master"; + GitBranch remoteBranch = null; + String currentLocalBranchName = null; + try { + final GitBranch currentBranch = GitBranch.current(myProject, gitRoot()); + if (currentBranch != null) { + currentLocalBranchName = currentBranch.getName(); + } + } + catch (VcsException e) { + // Do noting; + } + + if (currentLocalBranchName != null) { + // try to find corresponding remote branch + remoteBranch = findBranch("/" + originName + "/" + currentLocalBranchName); + } + if (remoteBranch == null) { + // else use master + remoteBranch = findBranch("/" + originName + "/master"); + } + + if (remoteBranch != null) { + myOntoComboBox.setSelectedItem(remoteBranch); + GitUIUtil.getTextField(myOntoComboBox).setText(remoteBranch.getFullName()); + } + } + + @Nullable + private GitBranch findBranch(@NotNull String preselected) { for (GitBranch remoteBranch : myRemoteBranches) { final String branchFullName = remoteBranch.getFullName(); if (branchFullName.endsWith(preselected)){ - myOntoComboBox.setSelectedItem(remoteBranch); - GitUIUtil.getTextField(myOntoComboBox).setText(branchFullName); - break; + return remoteBranch; } } + return null; } } diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index e04d3d1a8635..e11d5f10d3e9 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -255,6 +255,7 @@ + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyAnonymousUnwrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyAnonymousUnwrapper.java new file mode 100644 index 000000000000..0da4e87a5b7f --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyAnonymousUnwrapper.java @@ -0,0 +1,79 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.unwrap; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.unwrap.JavaUnwrapper; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition; + +import java.util.List; + +public class GroovyAnonymousUnwrapper extends GroovyUnwrapper { + public GroovyAnonymousUnwrapper() { + super(CodeInsightBundle.message("unwrap.anonymous")); + } + + public boolean isApplicableTo(PsiElement e) { + return e instanceof GrAnonymousClassDefinition + && ((GrAnonymousClassDefinition)e).getMethods().length <= 1; + } + + @Override + public PsiElement collectAffectedElements(PsiElement e, List toExtract) { + super.collectAffectedElements(e, toExtract); + return findElementToExtractFrom(e); + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + PsiElement from = findElementToExtractFrom(element); + + for (PsiMethod m : ((PsiAnonymousClass)element).getMethods()) { + //context.extractFromCodeBlock(m.getBody(), from); + } + + PsiElement next = from.getNextSibling(); + if (next instanceof PsiJavaToken && ((PsiJavaToken)next).getTokenType() == JavaTokenType.SEMICOLON) { + context.deleteExactly(from.getNextSibling()); + } + context.deleteExactly(from); + } + + private static PsiElement findElementToExtractFrom(PsiElement el) { + if (el.getParent() instanceof PsiNewExpression) el = el.getParent(); + el = findTopmostParentOfType(el, PsiMethodCallExpression.class); + el = findTopmostParentOfType(el, PsiAssignmentExpression.class); + el = findTopmostParentOfType(el, PsiDeclarationStatement.class); + + while (el.getParent() instanceof PsiExpressionStatement) { + el = el.getParent(); + } + + return el; + } + + private static PsiElement findTopmostParentOfType(PsiElement el, Class clazz) { + while (true) { + @SuppressWarnings({"unchecked"}) + PsiElement temp = PsiTreeUtil.getParentOfType(el, clazz, true, PsiAnonymousClass.class); + if (temp == null || temp instanceof PsiFile) return el; + el = temp; + } + } +} \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyBracesUnwrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyBracesUnwrapper.java new file mode 100644 index 000000000000..85970ef0c1f3 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyBracesUnwrapper.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.unwrap; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.unwrap.JavaUnwrapper; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.plugins.groovy.lang.psi.api.formatter.GrControlStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrBlockStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrCatchClause; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrTryCatchStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; + +public class GroovyBracesUnwrapper extends GroovyUnwrapper { + public GroovyBracesUnwrapper() { + super(CodeInsightBundle.message("unwrap.braces")); + } + + public boolean isApplicableTo(PsiElement e) { + if (e instanceof GrClosableBlock && !((GrClosableBlock)e).hasParametersSection()) { + PsiElement parent = e.getParent(); + return parent instanceof GrOpenBlock || parent instanceof GrClosableBlock; + } + return false; + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + context.extractFromCodeBlock(((GrClosableBlock)element), element); + context.delete(element); + } +} \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyCatchRemover.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyCatchRemover.java new file mode 100644 index 000000000000..5892563a3a51 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyCatchRemover.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.unwrap; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.unwrap.JavaUnwrapper; +import com.intellij.psi.PsiCatchSection; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiTryStatement; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrCatchClause; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrTryCatchStatement; + +public class GroovyCatchRemover extends GroovyUnwrapper { + public GroovyCatchRemover() { + super(CodeInsightBundle.message("remove.catch")); + } + + public boolean isApplicableTo(PsiElement e) { + return e instanceof GrCatchClause && tryHasSeveralCatches(e); + } + + private static boolean tryHasSeveralCatches(PsiElement el) { + return ((GrTryCatchStatement)el.getParent()).getCatchClauses().length > 1; + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + context.delete(element); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyForUnwrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyForUnwrapper.java new file mode 100644 index 000000000000..d376883f8ff4 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyForUnwrapper.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.unwrap; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.unwrap.JavaUnwrapper; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrForStatement; + +public class GroovyForUnwrapper extends GroovyUnwrapper { + public GroovyForUnwrapper() { + super(CodeInsightBundle.message("unwrap.for")); + } + + public boolean isApplicableTo(PsiElement e) { + return e instanceof GrForStatement; + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + if (element instanceof GrForStatement) { + context.extractFromBlockOrSingleStatement(((GrForStatement)element).getBody(), element); + } + + context.delete(element); + } +} \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyIfUnwrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyIfUnwrapper.java new file mode 100644 index 000000000000..ccc386ca7dd6 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyIfUnwrapper.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.unwrap; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.unwrap.JavaUnwrapper; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiIfStatement; +import com.intellij.psi.PsiStatement; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; + +public class GroovyIfUnwrapper extends GroovyUnwrapper { + public GroovyIfUnwrapper() { + super(CodeInsightBundle.message("unwrap.if")); + } + + public boolean isApplicableTo(PsiElement e) { + return e instanceof GrIfStatement && !isElseBlock(e); + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + GrStatement then = ((GrIfStatement)element).getThenBranch(); + context.extractFromBlockOrSingleStatement(then, element); + + context.delete(element); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyMethodParameterUnwrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyMethodParameterUnwrapper.java new file mode 100644 index 000000000000..287337f92a3b --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyMethodParameterUnwrapper.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.unwrap; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.psi.PsiElement; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; + +import java.util.List; + +public class GroovyMethodParameterUnwrapper extends GroovyUnwrapper { + public GroovyMethodParameterUnwrapper() { + super(""); + } + + @Override + public String getDescription(PsiElement e) { + String text = e.getText(); + if (text.length() > 20) text = text.substring(0, 17) + "..."; + return CodeInsightBundle.message("unwrap.method.parameter", text); + } + + public boolean isApplicableTo(PsiElement e) { + return (e instanceof GrExpression) && e.getParent() instanceof GrArgumentList; + } + + @Override + public PsiElement collectAffectedElements(PsiElement e, List toExtract) { + super.collectAffectedElements(e, toExtract); + return e.getParent().getParent(); + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + PsiElement methodCall = element.getParent().getParent(); + context.extractElement(element, methodCall); + if (methodCall.getParent() instanceof GrArgumentList) { + context.delete(methodCall); + } + else { + context.deleteExactly(methodCall); + } + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovySynchronizedUnwrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovySynchronizedUnwrapper.java new file mode 100644 index 000000000000..a61c3e352429 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovySynchronizedUnwrapper.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.unwrap; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.unwrap.JavaUnwrapper; +import com.intellij.psi.PsiCodeBlock; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSynchronizedStatement; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrSynchronizedStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; + +public class GroovySynchronizedUnwrapper extends GroovyUnwrapper { + public GroovySynchronizedUnwrapper() { + super(CodeInsightBundle.message("unwrap.synchronized")); + } + + public boolean isApplicableTo(PsiElement e) { + return e instanceof GrSynchronizedStatement; + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + GrOpenBlock body = ((GrSynchronizedStatement)element).getBody(); + context.extractFromCodeBlock(body, element); + + context.delete(element); + } +} \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyTryUnwrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyTryUnwrapper.java new file mode 100644 index 000000000000..1df5cc300ef1 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyTryUnwrapper.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.unwrap; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.unwrap.JavaUnwrapper; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiTryStatement; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrFinallyClause; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrTryCatchStatement; + +public class GroovyTryUnwrapper extends GroovyUnwrapper { + public GroovyTryUnwrapper() { + super(CodeInsightBundle.message("unwrap.try")); + } + + public boolean isApplicableTo(PsiElement e) { + return e instanceof GrTryCatchStatement; + } + + @Override + protected void doUnwrap(final PsiElement element, final Context context) throws IncorrectOperationException { + GrTryCatchStatement trySt = (GrTryCatchStatement)element; + + context.extractFromCodeBlock(trySt.getTryBlock(), trySt); + + GrFinallyClause finallyClause = trySt.getFinallyClause(); + if (finallyClause != null) { + context.extractFromCodeBlock(finallyClause.getBody(), trySt); + } + + context.delete(trySt); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyUnwrapDescriptor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyUnwrapDescriptor.java new file mode 100644 index 000000000000..d0ef0644e10a --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyUnwrapDescriptor.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.unwrap; + +import com.intellij.codeInsight.unwrap.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.SelectionModel; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class GroovyUnwrapDescriptor extends JavaUnwrapDescriptor { + + @Override + protected Unwrapper[] createUnwrappers() { + return new Unwrapper[]{ + new GroovyIfUnwrapper(), + new GroovyWhileUnwrapper(), + new GroovyTryUnwrapper(), + new GroovySynchronizedUnwrapper(), + new GroovyMethodParameterUnwrapper(), + new GroovyForUnwrapper(), + new GroovyCatchRemover(), + new GroovyBracesUnwrapper(), + }; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyUnwrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyUnwrapper.java new file mode 100644 index 000000000000..dfa011475155 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyUnwrapper.java @@ -0,0 +1,103 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.unwrap; + +import com.intellij.codeInsight.unwrap.AbstractUnwrapper; +import com.intellij.codeInsight.unwrap.Unwrapper; +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; +import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrBlockStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public abstract class GroovyUnwrapper extends AbstractUnwrapper { + public GroovyUnwrapper(String description) { + super(description); + } + + @Override + protected Context createContext(boolean isEffective) { + return new Context(isEffective); + } + + public static boolean isElseBlock(@Nullable final PsiElement element) { + if (element == null) return false; + final PsiElement parent = element.getParent(); + return parent instanceof GrIfStatement && element == ((GrIfStatement)parent).getElseBranch(); + } + + protected static class Context extends AbstractUnwrapper.AbstractContext { + + public Context(boolean isEffective) { + super(isEffective); + } + + public void extractFromBlockOrSingleStatement(GrStatement block, PsiElement from) throws IncorrectOperationException { + if (block instanceof GrBlockStatement) { + extractFromCodeBlock(((GrBlockStatement)block).getBlock(), from); + } + else if (block != null) { + extract(block, block, from); + } + } + + public void extractFromCodeBlock(GrCodeBlock block, PsiElement from) throws IncorrectOperationException { + if (block == null) return; + + PsiElement rBrace = block.getRBrace(); + PsiElement lBrace = block.getLBrace(); + + PsiElement firstBodyElement; + if (lBrace == null) { + firstBodyElement = null; + } + else { + firstBodyElement = lBrace.getNextSibling(); + if (firstBodyElement == rBrace) { + firstBodyElement = null; + } + } + + PsiElement lastBodyElement; + if (rBrace == null) { + lastBodyElement = null; + } + else { + lastBodyElement = rBrace.getPrevSibling(); + if (lastBodyElement == lBrace) { + lastBodyElement = null; + } + } + + extract(firstBodyElement, lastBodyElement, from); + } + + protected boolean isWhiteSpace(PsiElement element) { + return PsiUtil.isLeafElementOfType(element, TokenSets.WHITE_SPACES_SET); + } + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyWhileUnwrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyWhileUnwrapper.java new file mode 100644 index 000000000000..403d9089f9a9 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/unwrap/GroovyWhileUnwrapper.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.unwrap; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.psi.PsiDoWhileStatement; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLoopStatement; +import com.intellij.psi.PsiStatement; +import com.intellij.psi.impl.source.tree.java.PsiWhileStatementImpl; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrWhileStatement; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; + +public class GroovyWhileUnwrapper extends GroovyUnwrapper { + public GroovyWhileUnwrapper() { + super(CodeInsightBundle.message("unwrap.while")); + } + + public boolean isApplicableTo(PsiElement e) { + return e instanceof GrWhileStatement; + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + GrStatement body = ((GrWhileStatement)element).getBody(); + + context.extractFromBlockOrSingleStatement(body, element); + context.delete(element); + } +} \ No newline at end of file