diff --git a/build/scripts/dist.gant b/build/scripts/dist.gant index 49bebb6899da..dab08a968c34 100644 --- a/build/scripts/dist.gant +++ b/build/scripts/dist.gant @@ -143,6 +143,9 @@ private def layoutMac(Map args, String home, Paths paths) { """ args["idea.properties.path"] = "$home/bin/idea.properties" + if (!isEap()) { + args["idea.properties"] = ["idea.fatal.error.notification":"disabled"]; + } def system_selector = args.system_selector // TODO remove the next line when system_selector for Mac and other OS will be unified system_selector = args.system_selector_mac diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java index 6176e0fee201..a7637185dc21 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java @@ -102,7 +102,9 @@ public class CompilerUtil { * @param files */ public static void refreshIOFiles(@NotNull final Collection files) { - LocalFileSystem.getInstance().refreshIoFiles(files); + if (!files.isEmpty()) { + LocalFileSystem.getInstance().refreshIoFiles(files); + } } public static void refreshIODirectories(@NotNull final Collection files) { @@ -114,7 +116,9 @@ public class CompilerUtil { filesToRefresh.add(virtualFile); } } - RefreshQueue.getInstance().refresh(false, true, null, VfsUtil.toVirtualFileArray(filesToRefresh)); + if (!filesToRefresh.isEmpty()) { + RefreshQueue.getInstance().refresh(false, true, null, VfsUtil.toVirtualFileArray(filesToRefresh)); + } } public static void refreshIOFile(final File file) { diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java index 5a66b0f9c6a3..85133995723e 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java @@ -274,11 +274,12 @@ public class JavacCompiler extends ExternalCompiler { } public static List addAdditionalSettings(List commandLine, JavacSettings javacSettings, boolean isAnnotationProcessing, - JavaSdkVersion version, Project project, final boolean annotationProcessorsEnabled) { + JavaSdkVersion version, Project project, boolean annotationProcessorsEnabled) { final List additionalOptions = new ArrayList(); StringTokenizer tokenizer = new StringTokenizer(javacSettings.getOptionsString(project), " "); if (!version.isAtLeast(JavaSdkVersion.JDK_1_6)) { isAnnotationProcessing = false; // makes no sense for these versions + annotationProcessorsEnabled = false; } if (isAnnotationProcessing) { final CompilerConfiguration config = CompilerConfiguration.getInstance(project); @@ -311,7 +312,7 @@ public class JavacCompiler extends ExternalCompiler { } } else { - if (version.isAtLeast(JavaSdkVersion.JDK_1_6) && annotationProcessorsEnabled) { + if (annotationProcessorsEnabled) { // Unless explicitly specified by user, disable annotation processing by default for 'java compilation' mode // This is needed to suppress unwanted side-effects from auto-discovered processors from compilation classpath additionalOptions.add("-proc:none"); @@ -326,14 +327,22 @@ public class JavacCompiler extends ExternalCompiler { if (!version.isAtLeast(JavaSdkVersion.JDK_1_5) && "-Xlint".equals(token)) { continue; // not supported in these versions } - if (token.startsWith("-proc:")) { - continue; - } if (isAnnotationProcessing) { + if (token.startsWith("-proc:")) { + continue; + } if (token.startsWith("-implicit:")) { continue; } } + else { // compiling java + if (annotationProcessorsEnabled) { + // in this mode we have -proc:none already added above, so user's settings should be ignored + if (token.startsWith("-proc:")) { + continue; + } + } + } if (token.startsWith("-J-")) { commandLine.add(token.substring("-J".length())); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java index da7c37b380b7..a994be84e76c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java @@ -41,6 +41,7 @@ import com.intellij.psi.util.PsiTypesUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.IncorrectOperationException; import com.sun.jdi.Value; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -321,7 +322,10 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { if (rType == null) { throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", expression.getText())); } - PsiType typeForBinOp = TypeConversionUtil.calcTypeForBinaryExpression(lType, rType, opType, true); + final PsiType typeForBinOp = TypeConversionUtil.calcTypeForBinaryExpression(lType, rType, opType, true); + if (typeForBinOp == null) { + throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", wideExpression.getText())); + } myResult = createBinaryEvaluator(result, lType, rResult, rType, opType, typeForBinOp); lType = typeForBinOp; result = myResult; @@ -330,7 +334,7 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { // constructs binary evaluator handling unboxing and numeric promotion issues private static BinaryExpressionEvaluator createBinaryEvaluator( - Evaluator lResult, final PsiType lType, Evaluator rResult, final PsiType rType, final IElementType operation, final PsiType expressionExpectedType) { + Evaluator lResult, final PsiType lType, Evaluator rResult, final PsiType rType, final IElementType operation, final @NotNull PsiType expressionExpectedType) { // handle unboxing if neccesary if (isUnboxingInBinaryExpressionApplicable(lType, rType, operation)) { if (rType instanceof PsiClassType && UnBoxingEvaluator.isTypeUnboxable(rType.getCanonicalText())) { @@ -394,7 +398,7 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { } } - return new BinaryExpressionEvaluator(lResult, rResult, operation, expressionExpectedType == null ? null : expressionExpectedType.getCanonicalText()); + return new BinaryExpressionEvaluator(lResult, rResult, operation, expressionExpectedType.getCanonicalText()); } private static boolean isBinaryNumericPromotionApplicable(PsiType lType, PsiType rType, IElementType opType) { diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java index f068f11df306..4a08f8867bc6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java @@ -176,7 +176,8 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable{ private void updateContext(final String qName) { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { - final PsiClass psiClass = DebuggerUtils.findClass(qName, myProject, GlobalSearchScope.allScope(myProject)); + final Project project = myProject; + final PsiClass psiClass = project != null? DebuggerUtils.findClass(qName, project, GlobalSearchScope.allScope(project)) : null; myLabelEditor.setContext(psiClass); myChildrenEditor.setContext(psiClass); myChildrenExpandedEditor.setContext(psiClass); diff --git a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java index f725208093ba..41ce665cc145 100644 --- a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java +++ b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java @@ -192,15 +192,16 @@ public class NewProjectUtil { } public static void applyJdkToProject(@NotNull Project project, @NotNull Sdk jdk) { - JavaSdkVersion version = JavaSdk.getInstance().getVersion(jdk); - if (version == null) return; - ProjectRootManagerEx rootManager = ProjectRootManagerEx.getInstanceEx(project); rootManager.setProjectSdk(jdk); - LanguageLevel level = version.getMaxLanguageLevel(); - LanguageLevelProjectExtension ext = LanguageLevelProjectExtension.getInstance(project); - if (level.compareTo(ext.getLanguageLevel()) < 0) { - ext.setLanguageLevel(level); + + JavaSdkVersion version = JavaSdk.getInstance().getVersion(jdk); + if (version != null) { + LanguageLevel level = version.getMaxLanguageLevel(); + LanguageLevelProjectExtension ext = LanguageLevelProjectExtension.getInstance(project); + if (level.compareTo(ext.getLanguageLevel()) < 0) { + ext.setLanguageLevel(level); + } } } diff --git a/java/idea-ui/src/com/intellij/ide/util/importProject/LibrariesLayoutPanel.java b/java/idea-ui/src/com/intellij/ide/util/importProject/LibrariesLayoutPanel.java index 65d287d4e337..3f556fbc2788 100644 --- a/java/idea-ui/src/com/intellij/ide/util/importProject/LibrariesLayoutPanel.java +++ b/java/idea-ui/src/com/intellij/ide/util/importProject/LibrariesLayoutPanel.java @@ -84,7 +84,7 @@ public class LibrariesLayoutPanel extends ProjectLayoutPanel{ } protected String getSplitDialogChooseFilesPrompt() { - return "Select jars to extract to the new library:"; + return "&Select jars to extract to the new library:"; } protected String getNameAlreadyUsedMessage(final String name) { diff --git a/java/idea-ui/src/com/intellij/ide/util/importProject/ModulesLayoutPanel.java b/java/idea-ui/src/com/intellij/ide/util/importProject/ModulesLayoutPanel.java index b24fe9eabf72..c77a7e08c45c 100644 --- a/java/idea-ui/src/com/intellij/ide/util/importProject/ModulesLayoutPanel.java +++ b/java/idea-ui/src/com/intellij/ide/util/importProject/ModulesLayoutPanel.java @@ -100,7 +100,7 @@ public class ModulesLayoutPanel extends ProjectLayoutPanel{ } protected String getSplitDialogChooseFilesPrompt() { - return "Select content roots to extract to the new module:"; + return "&Select content roots to extract to the new module:"; } protected String getNameAlreadyUsedMessage(final String name) { diff --git a/java/idea-ui/src/com/intellij/ide/util/importProject/ProjectLayoutPanel.java b/java/idea-ui/src/com/intellij/ide/util/importProject/ProjectLayoutPanel.java index be7e9fec14a4..f1d7449494a7 100644 --- a/java/idea-ui/src/com/intellij/ide/util/importProject/ProjectLayoutPanel.java +++ b/java/idea-ui/src/com/intellij/ide/util/importProject/ProjectLayoutPanel.java @@ -25,15 +25,19 @@ import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.ui.ex.MultiLineLabel; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.DocumentAdapter; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.components.JBList; import com.intellij.util.PlatformIcons; import com.intellij.util.StringBuilderSpinAllocator; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.FormBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.DocumentEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; @@ -81,9 +85,8 @@ abstract class ProjectLayoutPanel extends JPanel { final Splitter splitter = new Splitter(false); - final JScrollPane entriesPane = ScrollPaneFactory.createScrollPane(myEntriesChooser); final JPanel entriesPanel = new JPanel(new BorderLayout()); - entriesPanel.add(entriesPane, BorderLayout.CENTER); + entriesPanel.add(myEntriesChooser, BorderLayout.CENTER); entriesPanel.setBorder(IdeBorderFactory.createTitledBorder(StringUtil.capitalize(StringUtil.pluralize(getElementTypeName())), false, false, true)); splitter.setFirstComponent(entriesPanel); @@ -483,7 +486,26 @@ abstract class ProjectLayoutPanel extends JPanel { } }); } + myChooser.selectElements(ContainerUtil.createMaybeSingletonList(ContainerUtil.getFirstItem(files))); + myChooser.addElementsMarkListener(new ElementsChooser.ElementsMarkListener() { + @Override + public void elementMarkChanged(File element, boolean isMarked) { + updateOkButton(); + } + }); + myNameField.getDocument().addDocumentListener(new DocumentAdapter() { + @Override + protected void textChanged(DocumentEvent e) { + updateOkButton(); + } + }); + init(); + updateOkButton(); + } + + private void updateOkButton() { + setOKActionEnabled(!getName().isEmpty() && !getChosenFiles().isEmpty()); } protected void doOKAction() { @@ -497,22 +519,11 @@ abstract class ProjectLayoutPanel extends JPanel { @Nullable protected JComponent createCenterPanel() { - final JPanel panel = new JPanel(new BorderLayout()); - - final JPanel labelNameField = new JPanel(new BorderLayout()); - labelNameField.add(new JLabel("Name:"), BorderLayout.NORTH); - labelNameField.add(myNameField, BorderLayout.CENTER); - labelNameField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - - final JPanel labelChooser = new JPanel(new BorderLayout()); - labelChooser.add(new JLabel(getSplitDialogChooseFilesPrompt()), BorderLayout.NORTH); - labelChooser.add(ScrollPaneFactory.createScrollPane(myChooser), BorderLayout.CENTER); - labelChooser.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - - panel.add(labelNameField, BorderLayout.NORTH); - panel.add(labelChooser, BorderLayout.CENTER); - panel.setPreferredSize(new Dimension(450, 300)); - return panel; + FormBuilder builder = new FormBuilder(true); + builder.addLabeledComponent("&Name:", myNameField); + builder.addLabeledComponent(getSplitDialogChooseFilesPrompt(), myChooser); + myChooser.setPreferredSize(new Dimension(450, 300)); + return builder.getPanel(); } public JComponent getPreferredFocusedComponent() { diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java index d7f56497e4f6..1ed00b0c054a 100644 --- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java +++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java @@ -35,7 +35,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.*; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.JavaSdk; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; @@ -55,6 +54,7 @@ import com.intellij.util.containers.MultiMap; import org.jdom.Element; import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; @@ -357,20 +357,31 @@ public class ProjectFromSourcesBuilderImpl extends ProjectBuilder implements Pro for (ProjectDescriptor projectDescriptor : getSelectedDescriptors()) { for (ModuleDescriptor moduleDescriptor : projectDescriptor.getModules()) { try { - final File file = new File(moduleDescriptor.computeModuleFilePath()); - if (file.exists()) { - final Element rootElement = JDOMUtil.loadDocument(file).getRootElement(); - final String type = rootElement.getAttributeValue("type"); - if (type != null) { - final ModuleType moduleType = ModuleTypeManager.getInstance().findByID(type); - if (moduleType != null && !moduleType.createModuleBuilder().isSuitableSdk(sdk)) return false; - } - } + final ModuleType moduleType = getModuleType(moduleDescriptor); + if (moduleType != null && !moduleType.createModuleBuilder().isSuitableSdk(sdk)) return false; } catch (Exception ignore) { } } } - return sdk.getSdkType() == JavaSdk.getInstance(); + return true; + } + + @Nullable + private static ModuleType getModuleType(ModuleDescriptor moduleDescriptor) throws InvalidDataException, JDOMException, IOException { + if (moduleDescriptor.isReuseExistingElement()) { + final File file = new File(moduleDescriptor.computeModuleFilePath()); + if (file.exists()) { + final Element rootElement = JDOMUtil.loadDocument(file).getRootElement(); + final String type = rootElement.getAttributeValue("type"); + if (type != null) { + return ModuleTypeManager.getInstance().findByID(type); + } + } + return null; + } + else { + return moduleDescriptor.getModuleType(); + } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateConstructorHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateConstructorHandler.java index a3c5b5c68a15..116da27861d4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateConstructorHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateConstructorHandler.java @@ -134,6 +134,32 @@ public class GenerateConstructorHandler extends GenerateMembersHandlerBase { return members; } + @Override + protected MemberChooser createMembersChooser(ClassMember[] members, + boolean allowEmptySelection, + boolean copyJavadocCheckbox, + Project project) { + final MemberChooser chooser = super.createMembersChooser(members, allowEmptySelection, copyJavadocCheckbox, project); + final List preselection = preselect(members); + if (!preselection.isEmpty()) { + chooser.selectElements(preselection.toArray(new ClassMember[preselection.size()])); + } + return chooser; + } + + protected static List preselect(ClassMember[] members) { + final List preselection = new ArrayList(); + for (ClassMember member : members) { + if (member instanceof PsiFieldMember) { + final PsiField psiField = ((PsiFieldMember)member).getElement(); + if (psiField != null && psiField.hasModifierProperty(PsiModifier.FINAL)) { + preselection.add(member); + } + } + } + return preselection; + } + @NotNull protected List generateMemberPrototypes(PsiClass aClass, ClassMember[] members) throws IncorrectOperationException { List baseConstructors = new ArrayList(); diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java index 79cbfe47eef0..a42018e62eb8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java @@ -183,15 +183,23 @@ public abstract class GenerateMembersHandlerBase implements CodeInsightActionHan @Nullable protected ClassMember[] chooseMembers(ClassMember[] members, boolean allowEmptySelection, boolean copyJavadocCheckbox, Project project) { - MemberChooser chooser = new MemberChooser(members, allowEmptySelection, true, project); - chooser.setTitle(myChooserTitle); - chooser.setCopyJavadocVisible(copyJavadocCheckbox); + MemberChooser chooser = createMembersChooser(members, allowEmptySelection, copyJavadocCheckbox, project); chooser.show(); myToCopyJavaDoc = chooser.isCopyJavadoc(); final List list = chooser.getSelectedElements(); return list == null ? null : list.toArray(new ClassMember[list.size()]); } + protected MemberChooser createMembersChooser(ClassMember[] members, + boolean allowEmptySelection, + boolean copyJavadocCheckbox, + Project project) { + MemberChooser chooser = new MemberChooser(members, allowEmptySelection, true, project); + chooser.setTitle(myChooserTitle); + chooser.setCopyJavadocVisible(copyJavadocCheckbox); + return chooser; + } + @NotNull protected List generateMemberPrototypes(PsiClass aClass, ClassMember[] members) throws IncorrectOperationException { ArrayList array = new ArrayList(); 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 20f222c4e3a5..b4eea0e90ce1 100644 --- a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java @@ -91,6 +91,7 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase { } continue; } + if (!(element instanceof PsiFileSystemItem)) return null; } fillResultsMap(result, containingFile, topLevelClasses); if (relativeMap != null) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/AbstractLightClass.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/AbstractLightClass.java new file mode 100644 index 000000000000..c6b10b2623c4 --- /dev/null +++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/AbstractLightClass.java @@ -0,0 +1,360 @@ +/* + * 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. + */ + +/* + * @author max + */ +package com.intellij.psi.impl.light; + +import com.intellij.lang.Language; +import com.intellij.lang.java.JavaLanguage; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiClassImplUtil; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.List; + +public abstract class AbstractLightClass extends LightElement implements PsiClass { + protected AbstractLightClass(PsiManager manager, Language language) { + super(manager, language); + } + + protected AbstractLightClass(PsiManager manager) { + super(manager, JavaLanguage.INSTANCE); + } + + public abstract PsiClass getDelegate(); + public abstract PsiElement copy(); + + @Override + @NonNls + @Nullable + public String getName() { + return getDelegate().getName(); + } + + @Override + @Nullable + public PsiModifierList getModifierList() { + return getDelegate().getModifierList(); + } + + @Override + public boolean hasModifierProperty(@Modifier @NonNls @NotNull String name) { + return getDelegate().hasModifierProperty(name); + } + + @Override + @Nullable + public PsiDocComment getDocComment() { + return null; + } + + @Override + public boolean isDeprecated() { + return getDelegate().isDeprecated(); + } + + @Override + public boolean hasTypeParameters() { + return PsiImplUtil.hasTypeParameters(this); + } + + @Override + @Nullable + public PsiTypeParameterList getTypeParameterList() { + return getDelegate().getTypeParameterList(); + } + + @Override + @NotNull + public PsiTypeParameter[] getTypeParameters() { + return getDelegate().getTypeParameters(); + } + + @Override + @NonNls + @Nullable + public String getQualifiedName() { + return getDelegate().getQualifiedName(); + } + + @Override + public boolean isInterface() { + return getDelegate().isInterface(); + } + + @Override + public boolean isAnnotationType() { + return getDelegate().isAnnotationType(); + } + + @Override + public boolean isEnum() { + return getDelegate().isEnum(); + } + + @Override + @Nullable + public PsiReferenceList getExtendsList() { + return getDelegate().getExtendsList(); + } + + @Override + @Nullable + public PsiReferenceList getImplementsList() { + return getDelegate().getImplementsList(); + } + + @Override + @NotNull + public PsiClassType[] getExtendsListTypes() { + return PsiClassImplUtil.getExtendsListTypes(this); + } + + @Override + @NotNull + public PsiClassType[] getImplementsListTypes() { + return PsiClassImplUtil.getImplementsListTypes(this); + } + + @Override + @Nullable + public PsiClass getSuperClass() { + return getDelegate().getSuperClass(); + } + + @Override + public PsiClass[] getInterfaces() { + return getDelegate().getInterfaces(); + } + + @NotNull + @Override + public PsiElement getNavigationElement() { + return getDelegate().getNavigationElement(); + } + + @Override + @NotNull + public PsiClass[] getSupers() { + return getDelegate().getSupers(); + } + + @Override + @NotNull + public PsiClassType[] getSuperTypes() { + return getDelegate().getSuperTypes(); + } + + @Override + @NotNull + public PsiField[] getFields() { + return getDelegate().getFields(); + } + + @Override + @NotNull + public PsiMethod[] getMethods() { + return getDelegate().getMethods(); + } + + @Override + @NotNull + public PsiMethod[] getConstructors() { + return getDelegate().getConstructors(); + } + + @Override + @NotNull + public PsiClass[] getInnerClasses() { + return getDelegate().getInnerClasses(); + } + + @Override + @NotNull + public PsiClassInitializer[] getInitializers() { + return getDelegate().getInitializers(); + } + + @Override + public boolean processDeclarations(@NotNull PsiScopeProcessor processor, + @NotNull ResolveState state, + PsiElement lastParent, + @NotNull PsiElement place) { + return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, false); + } + + @Override + @NotNull + public PsiField[] getAllFields() { + return getDelegate().getAllFields(); + } + + @Override + @NotNull + public PsiMethod[] getAllMethods() { + return getDelegate().getAllMethods(); + } + + @Override + @NotNull + public PsiClass[] getAllInnerClasses() { + return getDelegate().getAllInnerClasses(); + } + + @Override + @Nullable + public PsiField findFieldByName(@NonNls String name, boolean checkBases) { + return PsiClassImplUtil.findFieldByName(this, name, checkBases); + } + + @Override + @Nullable + public PsiMethod findMethodBySignature(PsiMethod patternMethod, boolean checkBases) { + return PsiClassImplUtil.findMethodBySignature(this, patternMethod, checkBases); + } + + @Override + @NotNull + public PsiMethod[] findMethodsBySignature(PsiMethod patternMethod, boolean checkBases) { + return PsiClassImplUtil.findMethodsBySignature(this, patternMethod, checkBases); + } + + @Override + @NotNull + public PsiMethod[] findMethodsByName(@NonNls String name, boolean checkBases) { + return PsiClassImplUtil.findMethodsByName(this, name, checkBases); + } + + @Override + @NotNull + public List> findMethodsAndTheirSubstitutorsByName(@NonNls String name, boolean checkBases) { + return PsiClassImplUtil.findMethodsAndTheirSubstitutorsByName(this, name, checkBases); + } + + @Override + @NotNull + public List> getAllMethodsAndTheirSubstitutors() { + return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiMethod.class); + } + + @Override + @Nullable + public PsiClass findInnerClassByName(@NonNls String name, boolean checkBases) { + return getDelegate().findInnerClassByName(name, checkBases); + } + + @Override + @Nullable + public PsiElement getLBrace() { + return getDelegate().getLBrace(); + } + + @Override + @Nullable + public PsiElement getRBrace() { + return getDelegate().getRBrace(); + } + + @Override + @Nullable + public PsiIdentifier getNameIdentifier() { + return getDelegate().getNameIdentifier(); + } + + @Override + public PsiElement getScope() { + return getDelegate().getScope(); + } + + @Override + public boolean isInheritor(@NotNull PsiClass baseClass, boolean checkDeep) { + return getDelegate().isInheritor(baseClass, checkDeep); + } + + @Override + public boolean isInheritorDeep(PsiClass baseClass, @Nullable PsiClass classToByPass) { + return getDelegate().isInheritorDeep(baseClass, classToByPass); + } + + @Override + @Nullable + public PsiClass getContainingClass() { + return getDelegate().getContainingClass(); + } + + @Override + @NotNull + public Collection getVisibleSignatures() { + return getDelegate().getVisibleSignatures(); + } + + @Override + public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { + return getDelegate().setName(name); + } + + @Override + public String toString() { + return "PsiClass:" + getName(); + } + + @Override + public String getText() { + return getDelegate().getText(); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof JavaElementVisitor) { + ((JavaElementVisitor)visitor).visitClass(this); + } else { + visitor.visitElement(this); + } + } + + @Override + public PsiFile getContainingFile() { + return getDelegate().getContainingFile(); + } + + @Override + public PsiElement getContext() { + return getDelegate(); + } + + @Override + public boolean isValid() { + return getDelegate().isValid(); + } + + @Override + public boolean isEquivalentTo(PsiElement another) { + return this == another || + (another instanceof AbstractLightClass && getDelegate().isEquivalentTo(((AbstractLightClass)another).getDelegate())) || + getDelegate().isEquivalentTo(another); + } + +} diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightClass.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightClass.java index 1c1707bc3e3e..91f6e7c822d4 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightClass.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightClass.java @@ -34,8 +34,8 @@ import java.util.List; /** * @author peter */ -public class LightClass extends LightElement implements PsiClass { - protected final PsiClass myDelegate; +public class LightClass extends AbstractLightClass { + private final PsiClass myDelegate; public LightClass(PsiClass delegate) { this(delegate, JavaLanguage.INSTANCE); @@ -47,291 +47,8 @@ public class LightClass extends LightElement implements PsiClass { } @Override - @NonNls - @Nullable - public String getName() { - return myDelegate.getName(); - } - - @Override - @Nullable - public PsiModifierList getModifierList() { - return myDelegate.getModifierList(); - } - - @Override - public boolean hasModifierProperty(@Modifier @NonNls @NotNull String name) { - return myDelegate.hasModifierProperty(name); - } - - @Override - @Nullable - public PsiDocComment getDocComment() { - return null; - } - - @Override - public boolean isDeprecated() { - return myDelegate.isDeprecated(); - } - - @Override - public boolean hasTypeParameters() { - return PsiImplUtil.hasTypeParameters(this); - } - - @Override - @Nullable - public PsiTypeParameterList getTypeParameterList() { - return myDelegate.getTypeParameterList(); - } - - @Override - @NotNull - public PsiTypeParameter[] getTypeParameters() { - return myDelegate.getTypeParameters(); - } - - @Override - @NonNls - @Nullable - public String getQualifiedName() { - return myDelegate.getQualifiedName(); - } - - @Override - public boolean isInterface() { - return myDelegate.isInterface(); - } - - @Override - public boolean isAnnotationType() { - return myDelegate.isAnnotationType(); - } - - @Override - public boolean isEnum() { - return myDelegate.isEnum(); - } - - @Override - @Nullable - public PsiReferenceList getExtendsList() { - return myDelegate.getExtendsList(); - } - - @Override - @Nullable - public PsiReferenceList getImplementsList() { - return myDelegate.getImplementsList(); - } - - @Override - @NotNull - public PsiClassType[] getExtendsListTypes() { - return PsiClassImplUtil.getExtendsListTypes(this); - } - - @Override - @NotNull - public PsiClassType[] getImplementsListTypes() { - return PsiClassImplUtil.getImplementsListTypes(this); - } - - @Override - @Nullable - public PsiClass getSuperClass() { - return myDelegate.getSuperClass(); - } - - @Override - public PsiClass[] getInterfaces() { - return myDelegate.getInterfaces(); - } - - @NotNull - @Override - public PsiElement getNavigationElement() { - return myDelegate.getNavigationElement(); - } - - @Override - @NotNull - public PsiClass[] getSupers() { - return myDelegate.getSupers(); - } - - @Override - @NotNull - public PsiClassType[] getSuperTypes() { - return myDelegate.getSuperTypes(); - } - - @Override - @NotNull - public PsiField[] getFields() { - return myDelegate.getFields(); - } - - @Override - @NotNull - public PsiMethod[] getMethods() { - return myDelegate.getMethods(); - } - - @Override - @NotNull - public PsiMethod[] getConstructors() { - return myDelegate.getConstructors(); - } - - @Override - @NotNull - public PsiClass[] getInnerClasses() { - return myDelegate.getInnerClasses(); - } - - @Override - @NotNull - public PsiClassInitializer[] getInitializers() { - return myDelegate.getInitializers(); - } - - @Override - public boolean processDeclarations(@NotNull PsiScopeProcessor processor, - @NotNull ResolveState state, - PsiElement lastParent, - @NotNull PsiElement place) { - return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, false); - } - - @Override - @NotNull - public PsiField[] getAllFields() { - return myDelegate.getAllFields(); - } - - @Override - @NotNull - public PsiMethod[] getAllMethods() { - return myDelegate.getAllMethods(); - } - - @Override - @NotNull - public PsiClass[] getAllInnerClasses() { - return myDelegate.getAllInnerClasses(); - } - - @Override - @Nullable - public PsiField findFieldByName(@NonNls String name, boolean checkBases) { - return PsiClassImplUtil.findFieldByName(this, name, checkBases); - } - - @Override - @Nullable - public PsiMethod findMethodBySignature(PsiMethod patternMethod, boolean checkBases) { - return PsiClassImplUtil.findMethodBySignature(this, patternMethod, checkBases); - } - - @Override - @NotNull - public PsiMethod[] findMethodsBySignature(PsiMethod patternMethod, boolean checkBases) { - return PsiClassImplUtil.findMethodsBySignature(this, patternMethod, checkBases); - } - - @Override - @NotNull - public PsiMethod[] findMethodsByName(@NonNls String name, boolean checkBases) { - return PsiClassImplUtil.findMethodsByName(this, name, checkBases); - } - - @Override - @NotNull - public List> findMethodsAndTheirSubstitutorsByName(@NonNls String name, boolean checkBases) { - return PsiClassImplUtil.findMethodsAndTheirSubstitutorsByName(this, name, checkBases); - } - - @Override - @NotNull - public List> getAllMethodsAndTheirSubstitutors() { - return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiMethod.class); - } - - @Override - @Nullable - public PsiClass findInnerClassByName(@NonNls String name, boolean checkBases) { - return myDelegate.findInnerClassByName(name, checkBases); - } - - @Override - @Nullable - public PsiElement getLBrace() { - return myDelegate.getLBrace(); - } - - @Override - @Nullable - public PsiElement getRBrace() { - return myDelegate.getRBrace(); - } - - @Override - @Nullable - public PsiIdentifier getNameIdentifier() { - return myDelegate.getNameIdentifier(); - } - - @Override - public PsiElement getScope() { - return myDelegate.getScope(); - } - - @Override - public boolean isInheritor(@NotNull PsiClass baseClass, boolean checkDeep) { - return myDelegate.isInheritor(baseClass, checkDeep); - } - - @Override - public boolean isInheritorDeep(PsiClass baseClass, @Nullable PsiClass classToByPass) { - return myDelegate.isInheritorDeep(baseClass, classToByPass); - } - - @Override - @Nullable - public PsiClass getContainingClass() { - return myDelegate.getContainingClass(); - } - - @Override - @NotNull - public Collection getVisibleSignatures() { - return myDelegate.getVisibleSignatures(); - } - - @Override - public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { - return myDelegate.setName(name); - } - - @Override - public String toString() { - return "PsiClass:" + getName(); - } - - @Override - public String getText() { - return myDelegate.getText(); - } - - @Override - public void accept(@NotNull PsiElementVisitor visitor) { - if (visitor instanceof JavaElementVisitor) { - ((JavaElementVisitor)visitor).visitClass(this); - } else { - visitor.visitElement(this); - } + public PsiClass getDelegate() { + return myDelegate; } @Override @@ -339,29 +56,4 @@ public class LightClass extends LightElement implements PsiClass { return new LightClass(this); } - @Override - public PsiFile getContainingFile() { - return myDelegate.getContainingFile(); - } - - public PsiClass getDelegate() { - return myDelegate; - } - - @Override - public PsiElement getContext() { - return myDelegate; - } - - @Override - public boolean isValid() { - return myDelegate.isValid(); - } - - @Override - public boolean isEquivalentTo(PsiElement another) { - return this == another || - (another instanceof LightClass && getDelegate().isEquivalentTo(((LightClass)another).getDelegate())) || - getDelegate().isEquivalentTo(another); - } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightTypeParameter.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightTypeParameter.java index 9eef9a6fb8d8..54e5d84da927 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightTypeParameter.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightTypeParameter.java @@ -26,7 +26,7 @@ public class LightTypeParameter extends LightClass implements PsiTypeParameter { @Override public PsiTypeParameter getDelegate() { - return (PsiTypeParameter)myDelegate; + return (PsiTypeParameter)super.getDelegate(); } @Override diff --git a/java/java-tests/testData/codeInsight/generateConstructor/afterFinalFieldPreselection.java b/java/java-tests/testData/codeInsight/generateConstructor/afterFinalFieldPreselection.java new file mode 100644 index 000000000000..bd402a9b28b7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateConstructor/afterFinalFieldPreselection.java @@ -0,0 +1,11 @@ +class Test { + private int a; + private final int b; + private int c; + private final int d; + + Test(int b, int d) { + this.b = b; + this.d = d; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateConstructor/beforeFinalFieldPreselection.java b/java/java-tests/testData/codeInsight/generateConstructor/beforeFinalFieldPreselection.java new file mode 100644 index 000000000000..57459a5e4b37 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateConstructor/beforeFinalFieldPreselection.java @@ -0,0 +1,6 @@ +class Test { + private int a; + private final int b; + private int c; + private final int d; +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/GenerateConstructorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateConstructorTest.java index 21efe1f59f4a..c04ab6a28d4c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/GenerateConstructorTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateConstructorTest.java @@ -10,6 +10,8 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.testFramework.LightCodeInsightTestCase; +import java.util.List; + public class GenerateConstructorTest extends LightCodeInsightTestCase { public void testAbstractClass() throws Exception { doTest(); } public void testPackageLocalClass() throws Exception { doTest(); } @@ -38,6 +40,22 @@ public class GenerateConstructorTest extends LightCodeInsightTestCase { doTest(); } + public void testFinalFieldPreselection() throws Exception { + String name = getTestName(false); + configureByFile("/codeInsight/generateConstructor/before" + name + ".java"); + new GenerateConstructorHandler() { + @Override + protected ClassMember[] chooseMembers(ClassMember[] members, + boolean allowEmptySelection, + boolean copyJavadocCheckbox, + Project project) { + final List preselection = GenerateConstructorHandler.preselect(members); + return preselection.toArray(new ClassMember[preselection.size()]); + } + }.invoke(getProject(), getEditor(), getFile()); + checkResultByFile("/codeInsight/generateConstructor/after" + name +".java"); + } + private void doTest() throws Exception { String name = getTestName(false); configureByFile("/codeInsight/generateConstructor/before" + diff --git a/platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java b/platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java index aa68f383aebb..3e723b6d87e2 100644 --- a/platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java +++ b/platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java @@ -314,6 +314,16 @@ public class StubBasedPsiElementBase extends ASTDelegateP return PsiTreeUtil.getParentOfType(this, parentClass); } + @Nullable + protected PsiElement getStubOrPsiParent() { + T stub = myStub; + if (stub != null) { + //noinspection unchecked + return stub.getParentStub().getPsi(); + } + return getParent(); + } + @Override protected Object clone() { final StubBasedPsiElementBase stubbless = (StubBasedPsiElementBase)super.clone(); diff --git a/platform/lang-api/src/com/intellij/codeInsight/daemon/LineMarkerInfo.java b/platform/lang-api/src/com/intellij/codeInsight/daemon/LineMarkerInfo.java index e993113a46ae..c944eec2ffb4 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/daemon/LineMarkerInfo.java +++ b/platform/lang-api/src/com/intellij/codeInsight/daemon/LineMarkerInfo.java @@ -48,22 +48,14 @@ public class LineMarkerInfo { private final GutterIconRenderer.Alignment myIconAlignment; @Nullable private final GutterIconNavigationHandler myNavigationHandler; - - public LineMarkerInfo(T element, + public LineMarkerInfo(@NotNull T element, int startOffset, Icon icon, int updatePass, @Nullable Function tooltipProvider, @Nullable GutterIconNavigationHandler navHandler, GutterIconRenderer.Alignment alignment) { - myIcon = icon; - myTooltipProvider = tooltipProvider; - myIconAlignment = alignment; - elementRef = new WeakReference(element); - myNavigationHandler = navHandler; - this.startOffset = startOffset; - this.updatePass = updatePass; - endOffset = startOffset; + this(element, new TextRange(startOffset, startOffset), icon, updatePass, tooltipProvider, navHandler, alignment); } public LineMarkerInfo(@NotNull T element, @NotNull TextRange range, diff --git a/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java b/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java index a3b4ba723c13..e7816ffcbc94 100644 --- a/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java +++ b/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java @@ -228,7 +228,9 @@ public class InitialConfigurationDialog extends DialogWrapper { @Override public void dispose() { - myPreviewEditor.disposeUIResources(); + if (myPreviewEditor != null) { + myPreviewEditor.disposeUIResources(); + } myPreviewOptions.disposeUIResources(); } @@ -282,8 +284,12 @@ public class InitialConfigurationDialog extends DialogWrapper { super.doOKAction(); - myPreviewEditor.disposeUIResources(); - myPreviewOptions.disposeUIResources(); + if (myPreviewEditor != null) { + myPreviewEditor.disposeUIResources(); + } + if (myPreviewOptions != null) { + myPreviewOptions.disposeUIResources(); + } // set keymap ((KeymapManagerImpl)KeymapManager.getInstance()).setActiveKeymap((Keymap)myKeymapComboBox.getSelectedItem()); // set color scheme diff --git a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java index 1d6084f48763..ff8f2b8913e0 100644 --- a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java +++ b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java @@ -226,7 +226,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec myProject = project; myEditor = editor; - mySearchResults = new SearchResults(myEditor); + mySearchResults = new SearchResults(myEditor, myProject); myDefaultBackground = new JTextField().getBackground(); diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java index b4f147d91239..6bf025589d68 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java +++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java @@ -58,6 +58,7 @@ public class SearchResults implements DocumentListener { private Set myExcluded = new HashSet(); private Editor myEditor; + private Project myProject; private FindModel myFindModel; private int myMatchesLimit = 100; @@ -72,8 +73,9 @@ public class SearchResults implements DocumentListener { private Stack> myCursorPositions = new Stack>(); - public SearchResults(Editor editor) { + public SearchResults(Editor editor, Project project) { myEditor = editor; + myProject = project; myEditor.getDocument().addDocumentListener(this); } @@ -161,7 +163,7 @@ public class SearchResults implements DocumentListener { @Nullable public Project getProject() { - return myEditor.getProject(); + return myProject; } public synchronized void setEditor(Editor editor) { @@ -328,7 +330,7 @@ public class SearchResults implements DocumentListener { int offset = r.getStartOffset(); while (true) { - FindManager findManager = FindManager.getInstance(editor.getProject()); + FindManager findManager = FindManager.getInstance(getProject()); FindResult result; try { BombedCharSequence diff --git a/platform/lang-impl/src/com/intellij/ide/macro/FilePromptMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/FilePromptMacro.java index a6096602a02e..7346a6865e00 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/FilePromptMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/FilePromptMacro.java @@ -29,7 +29,7 @@ import com.intellij.openapi.vfs.VirtualFile; /** * @author yole */ -public class FilePromptMacro extends Macro implements SecondQueueExpandMacro { +public class FilePromptMacro extends PromptingMacro implements SecondQueueExpandMacro { @Override public String getName() { return "FilePrompt"; @@ -40,16 +40,12 @@ public class FilePromptMacro extends Macro implements SecondQueueExpandMacro { return "Shows a file chooser dialog"; } - @Override - public String expand(DataContext dataContext) throws ExecutionCancelledException { + protected String promptUser(DataContext dataContext) { Project project = PlatformDataKeys.PROJECT.getData(dataContext); final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleLocalFileDescriptor(); final FileChooserDialog fileChooser = FileChooserFactory.getInstance().createFileChooser(descriptor, project); final VirtualFile[] result = fileChooser.choose(null, project); - if (result.length != 1) { - throw new ExecutionCancelledException(); - } - return FileUtil.toSystemDependentName(result [0].getPath()); + return result.length == 1? FileUtil.toSystemDependentName(result[0].getPath()) : null; } @Override diff --git a/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java b/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java index 1cfccc09c07d..378ad9777bc3 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java @@ -158,14 +158,17 @@ public final class MacroManager { } public String expandSilentMarcos(String str, boolean firstQueueExpand, DataContext dataContext) throws Macro.ExecutionCancelledException { - return expandMacroSet(str, firstQueueExpand, dataContext, - ConvertingIterator.create(getMacros().iterator(), new Convertor() { - public Macro convert(Macro macro) { - if (macro instanceof PromptMacro) - return new Macro.Silent(macro, ""); - return macro; - } - })); + final Convertor convertor = new Convertor() { + public Macro convert(Macro macro) { + if (macro instanceof PromptingMacro) { + return new Macro.Silent(macro, ""); + } + return macro; + } + }; + return expandMacroSet( + str, firstQueueExpand, dataContext, ConvertingIterator.create(getMacros().iterator(), convertor) + ); } } diff --git a/platform/lang-impl/src/com/intellij/ide/macro/PromptMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/PromptMacro.java index 5aa4eec96baa..4d3caab3f275 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/PromptMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/PromptMacro.java @@ -19,8 +19,9 @@ package com.intellij.ide.macro; import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.ui.Messages; +import org.jetbrains.annotations.Nullable; -public final class PromptMacro extends Macro implements SecondQueueExpandMacro { +public final class PromptMacro extends PromptingMacro implements SecondQueueExpandMacro { public String getName() { return "Prompt"; } @@ -29,11 +30,9 @@ public final class PromptMacro extends Macro implements SecondQueueExpandMacro { return IdeBundle.message("macro.prompt"); } - public String expand(DataContext dataContext) throws ExecutionCancelledException { - String userInput = Messages.showInputDialog(IdeBundle.message("prompt.enter.parameters"), - IdeBundle.message("title.input"), Messages.getQuestionIcon()); - if (userInput == null) throw new ExecutionCancelledException(); - return userInput; + @Nullable + protected String promptUser(DataContext dataContext) { + return Messages.showInputDialog(IdeBundle.message("prompt.enter.parameters"), IdeBundle.message("title.input"), Messages.getQuestionIcon()); } public void cachePreview(DataContext dataContext) { diff --git a/platform/lang-impl/src/com/intellij/ide/macro/PromptingMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/PromptingMacro.java new file mode 100644 index 000000000000..41453dedcf68 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/macro/PromptingMacro.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import org.jetbrains.annotations.Nullable; + +/** + * @author Eugene Zhuravlev + * Date: 12/9/11 + */ +public abstract class PromptingMacro extends Macro{ + + public final String expand(DataContext dataContext) throws ExecutionCancelledException { + final String userInput = promptUser(dataContext); + if (userInput == null) { + throw new ExecutionCancelledException(); + } + return userInput; + } + + + /** + * Called from expand() method + * + * @param dataContext + * @return user input. If null is returned, ExecutionCancelledException is thrown by expand() method + */ + @Nullable + protected abstract String promptUser(DataContext dataContext); +} 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 68cdb0468c71..bc0f6718c494 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooser.java +++ b/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooser.java @@ -18,7 +18,6 @@ package com.intellij.ide.util; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectUtil; import com.intellij.openapi.roots.FileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.DialogWrapper; @@ -33,14 +32,13 @@ import com.intellij.refactoring.RefactoringBundle; import com.intellij.ui.ScrollPaneFactory; import com.intellij.util.ArrayUtil; import com.intellij.util.PlatformIcons; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.tree.DefaultTreeModel; import java.awt.*; import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayList; @@ -77,7 +75,7 @@ public class DirectoryChooser extends DialogWrapper { final JPanel panel = new JPanel(new BorderLayout()); final DefaultActionGroup actionGroup = new DefaultActionGroup(); actionGroup.add(new ToggleAction(RefactoringBundle.message("directory.chooser.hide.non.existent.checkBox.text"), - RefactoringBundle.message("directory.chooser.hide.non.existent.checkBox.text"), + UIUtil.removeMnemonic(RefactoringBundle.message("directory.chooser.hide.non.existent.checkBox.text")), IconLoader.getIcon("/ant/filter.png")) { @Override public boolean isSelected(AnActionEvent e) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java index 5031f3986d35..7533c674ee76 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java @@ -18,6 +18,7 @@ package com.intellij.psi.impl; import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; @@ -53,7 +54,6 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.Processor; import com.intellij.util.SmartList; import com.intellij.util.containers.Queue; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -156,6 +156,7 @@ public class DocumentCommitThread implements Runnable, Disposable { Object[] documentTasks = documentsToCommit.toArray(); for (Object o : documentTasks) { + assert o != null : "Null element in:" + documentsToCommit; CommitTask task = (CommitTask)o; if (task.document == document) { ProgressIndicator current = document.getUserData(COMMIT_PROGRESS); @@ -316,7 +317,8 @@ public class DocumentCommitThread implements Runnable, Disposable { success = false; } if (success) { - UIUtil.invokeLaterIfNeeded(finishRunnable); + assert !ApplicationManager.getApplication().isDispatchThread(); + ApplicationManager.getApplication().invokeLater(finishRunnable, ModalityState.NON_MODAL); // do not commit while modal progress is running log("Invoked later finishRunnable", document, false, success, finishRunnable, indicator); } } @@ -422,6 +424,7 @@ public class DocumentCommitThread implements Runnable, Disposable { @NotNull final Object reason) { final List> finishRunnables = new SmartList>(); Runnable runnable = new Runnable() { + @Override public void run() { if (project.isDisposed()) return; final PsiDocumentManagerImpl documentManager = (PsiDocumentManagerImpl)PsiDocumentManager.getInstance(project); @@ -672,6 +675,7 @@ public class DocumentCommitThread implements Runnable, Disposable { final PomModel model = PomManager.getModel(fileImpl.getProject()); model.runTransaction(new PomTransactionBase(fileImpl, model.getModelAspect(TreeAspect.class)) { + @Override public PomModelEvent runInner() { return new TreeAspectEvent(model, diffLog.performActualPsiChange(file)); } 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 4d145a50c43d..ab4f8908dcc3 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 @@ -417,6 +417,11 @@ public abstract class AbstractInplaceIntroducer> ourIndexIdToCreationStamp = new TObjectLongHashMap>(); private static final boolean ourUnitTestMode = ApplicationManager.getApplication().isUnitTestMode(); diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java index 5cacf273efe6..b5a4913b32a6 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java @@ -16,6 +16,7 @@ package com.intellij.util.indexing; +import com.intellij.openapi.diagnostic.Logger; import gnu.trove.TIntHashSet; import gnu.trove.TIntIterator; @@ -26,6 +27,8 @@ import java.util.*; * Date: Dec 20, 2007 */ class ValueContainerImpl extends UpdatableValueContainer implements Cloneable{ + private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.ValueContainerImpl"); + private HashMap myInputIdMapping; public ValueContainerImpl() { @@ -60,17 +63,19 @@ class ValueContainerImpl extends UpdatableValueContainer implement @Override public void removeAssociatedValue(int inputId) { - Value toRemove = null; + final List toRemove = new ArrayList(1); for (final Iterator valueIterator = getValueIterator(); valueIterator.hasNext();) { final Value value = valueIterator.next(); if (isAssociated(value, inputId)) { - assert toRemove == null; - toRemove = value; + LOG.assertTrue(toRemove.isEmpty(), "Expected only one value per-inputId"); + toRemove.add(value); } } - if (toRemove != null) { - removeValue(inputId, toRemove); + if (!toRemove.isEmpty()) { + for (Value value : toRemove) { + removeValue(inputId, value); + } } } diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileTypeDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileTypeDescriptor.java index 95941fac6b78..dab5da47eec7 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileTypeDescriptor.java +++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileTypeDescriptor.java @@ -35,7 +35,15 @@ public class FileTypeDescriptor extends FileChooserDescriptor { } @Override - public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) { + public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) { + if (!showHiddenFiles && FileElement.isFileHidden(file)) { + return false; + } + + if (file.isDirectory()) { + return true; + } + final String ex = file.getExtension(); return file.isDirectory() || (ex != null && ext.contains(ex.toLowerCase())); } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java index ffbc169b464f..4b9139ed5d51 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java @@ -21,7 +21,6 @@ import com.intellij.openapi.actionSystem.ex.ComboBoxAction; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.updateSettings.impl.UpdateSettings; -import com.intellij.openapi.util.IconLoader; import com.intellij.ui.ScrollPaneFactory; import com.intellij.util.net.HTTPProxySettingsDialog; import com.intellij.util.ui.update.UiNotifyConnector; @@ -105,7 +104,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain { actionGroup.add(new RefreshAction()); actionGroup.add(new ActionInstallPlugin(this, installed)); if (inToolbar) { - actionGroup.add(new SortByStatusAction()); + actionGroup.add(new SortByStatusAction("Sort installed first")); actionGroup.add(new MyFilterRepositoryAction()); actionGroup.add(new MyFilterCategoryAction()); } @@ -188,21 +187,4 @@ public class AvailablePluginsManagerMain extends PluginManagerMain { }; } } - - private class SortByStatusAction extends ToggleAction { - private SortByStatusAction() { - super("Sort installed first", "Sort installed first", IconLoader.getIcon("/objectBrowser/sortByType.png")); - } - - @Override - public boolean isSelected(AnActionEvent e) { - return pluginsModel.isSortByStatus(); - } - - @Override - public void setSelected(AnActionEvent e, boolean state) { - pluginsModel.setSortByStatus(state); - pluginsModel.sort(); - } - } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java index 3bb9aebc9941..5abc980f9788 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java @@ -158,6 +158,7 @@ public class InstalledPluginsManagerMain extends PluginManagerMain { actionGroup.add(new ActionInstallPlugin(this, this)); actionGroup.add(new ActionUninstallPlugin(this, pluginTable)); if (inToolbar) { + actionGroup.add(new SortByStatusAction("Sort by status")); actionGroup.add(new MyFilterEnabledAction()); //actionGroup.add(new MyFilterBundleAction()); } @@ -256,8 +257,12 @@ public class InstalledPluginsManagerMain extends PluginManagerMain { gr.add(new AnAction(enabledValue) { @Override public void actionPerformed(AnActionEvent e) { + final IdeaPluginDescriptor[] selection = pluginTable.getSelectedObjects(); final String filter = myFilter.getFilter().toLowerCase(); ((InstalledPluginsTableModel)pluginsModel).setEnabledFilter(enabledValue, filter); + if (selection != null) { + select(selection); + } } }); } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java index 2559f56f8d17..4b57faa754d6 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java @@ -241,7 +241,7 @@ public class InstalledPluginsTableModel extends PluginTableModel { final PluginId pluginId = existing.getPluginId(); final String idString = pluginId.getIdString(); final JDOMExternalizableStringList installedPlugins = PluginManagerUISettings.getInstance().myInstalledPlugins; - if (!installedPlugins.contains(idString)){ + if (!installedPlugins.contains(idString) && !((IdeaPluginDescriptorImpl)existing).isDeleted()){ installedPlugins.add(idString); } final PluginManagerUISettings updateSettings = PluginManagerUISettings.getInstance(); @@ -609,25 +609,49 @@ public class InstalledPluginsTableModel extends PluginTableModel { return true; } - /*@Override + @Override public Comparator getComparator() { - final Comparator comparator = super.getComparator(); - return new Comparator() { - @Override - public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) { - if (o1.isBundled() && o2.isBundled()) return comparator.compare(o1, o2); - if (o1.isBundled()) return -1; - if (o2.isBundled()) return 1; - final String host1 = myPlugin2host.get(o1.getPluginId().getIdString()); - final String host2 = myPlugin2host.get(o2.getPluginId().getIdString()); - if (host1 == null && host2 == null) return comparator.compare(o1, o2); - if (host1 == null) return 1; - if (host2 == null) return -1; - if (host1.equals(host2)) return comparator.compare(o1, o2); - return host1.compareToIgnoreCase(host2); - } - }; + final Comparator comparator = super.getColumnComparator(); + return new Comparator() { + @Override + public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) { + if (isSortByStatus()) { + final boolean hasNewerVersion1 = hasNewerVersion(o1.getPluginId()); + final boolean hasNewerVersion2 = hasNewerVersion(o2.getPluginId()); + if (hasNewerVersion1) { + if (hasNewerVersion2) return comparator.compare(o1, o2); + return -1; + } + if (hasNewerVersion2) return 1; - }*/ + + final boolean wasUpdated1 = wasUpdated(o1.getPluginId()); + final boolean wasUpdated2 = wasUpdated(o2.getPluginId()); + if (wasUpdated1) { + if (wasUpdated2) return comparator.compare(o1, o2); + return -1; + } + if (wasUpdated2) return 1; + + + if (o1 instanceof PluginNode) { + if (o2 instanceof PluginNode) return comparator.compare(o1, o2); + return -1; + } + if (o2 instanceof PluginNode) return 1; + + + final boolean deleted1 = o1 instanceof IdeaPluginDescriptorImpl && ((IdeaPluginDescriptorImpl)o1).isDeleted(); + final boolean deleted2 = o2 instanceof IdeaPluginDescriptorImpl && ((IdeaPluginDescriptorImpl)o2).isDeleted(); + if (deleted1) { + if (deleted2) return comparator.compare(o1, o2); + return -1; + } + if (deleted2) return 1; + } + return comparator.compare(o1, o2); + } + }; + } } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java index c53aa37430c9..10ba954a4e0f 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java @@ -908,11 +908,26 @@ public class PluginManager { if (descriptor != null && !descriptor.getOptionalConfigs().isEmpty()) { final Map descriptors = new HashMap(descriptor.getOptionalConfigs().size()); for (Map.Entry entry: descriptor.getOptionalConfigs().entrySet()) { - assert !Comparing.equal(fileName, entry.getValue()) : "recursive dependency: "+fileName; - final IdeaPluginDescriptorImpl optionalDescriptor = loadDescriptor(file, entry.getValue()); + String optionalDescriptorName = entry.getValue(); + assert !Comparing.equal(fileName, optionalDescriptorName) : "recursive dependency: "+ fileName; + + IdeaPluginDescriptorImpl optionalDescriptor = loadDescriptor(file, optionalDescriptorName); + if (optionalDescriptor == null && !ClassloaderUtil.isJarOrZip(file)) { + for (URL url : getClassLoaderUrls()) { + if ("file".equals(url.getProtocol())) { + optionalDescriptor = loadDescriptor(new File(URLDecoder.decode(url.getFile())), optionalDescriptorName); + if (optionalDescriptor != null) { + break; + } + } + } + } if (optionalDescriptor != null) { descriptors.put(entry.getKey(), optionalDescriptor); } + else { + getLogger().info("Cannot find optional descriptor " + optionalDescriptorName); + } } descriptor.setOptionalDescriptors(descriptors); } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerColumnInfo.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerColumnInfo.java index cdf73b4a1bd5..3f2c2566c9cf 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerColumnInfo.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerColumnInfo.java @@ -165,7 +165,7 @@ class PluginManagerColumnInfo extends ColumnInfo { return comparator; } - private Comparator getColumnComparator() { + protected Comparator getColumnComparator() { if (isSortByName()) { return new Comparator() { public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java index 6a8603b1876b..ccbb01a82fac 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java @@ -73,11 +73,11 @@ public class PluginManagerConfigurable extends BaseConfigurable implements Searc if (column >= 0) { myPluginManagerMain.pluginsModel.setSortKey(new RowSorter.SortKey(column, SortOrder.ASCENDING)); } - if (myUISettings.AVAILABLE_SORT_BY_STATUS) { - myPluginManagerMain.pluginsModel.setSortByStatus(true); - } - myPluginManagerMain.pluginsModel.sort(); + myPluginManagerMain.pluginsModel.setSortByStatus(myUISettings.AVAILABLE_SORT_BY_STATUS); + } else { + myPluginManagerMain.pluginsModel.setSortByStatus(myUISettings.INSTALLED_SORT_BY_STATUS); } + myPluginManagerMain.pluginsModel.sort(); getSplitterProportions().restoreSplitterProportions(myPluginManagerMain.getMainPanel()); } @@ -99,6 +99,8 @@ public class PluginManagerConfigurable extends BaseConfigurable implements Searc } } myUISettings.AVAILABLE_SORT_BY_STATUS = myPluginManagerMain.pluginsModel.isSortByStatus(); + } else { + myUISettings.INSTALLED_SORT_BY_STATUS = myPluginManagerMain.pluginsModel.isSortByStatus(); } Disposer.dispose(myPluginManagerMain); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java index 4e2f4395a292..8891bb01c92c 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java @@ -21,10 +21,7 @@ import com.intellij.ide.IdeBundle; import com.intellij.ide.ui.search.SearchUtil; import com.intellij.ide.ui.search.SearchableOptionsRegistrar; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.ActionToolbar; -import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; @@ -234,7 +231,7 @@ public abstract class PluginManagerMain implements Disposable { public void finished() { UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { - if (list != null) { + if (list != null && errorMessages.isEmpty()) { modifyPluginsList(list); propagateUpdates(list); setDownloadStatus(false); @@ -488,6 +485,28 @@ public abstract class PluginManagerMain implements Disposable { return false; } + protected class SortByStatusAction extends ToggleAction { + + protected SortByStatusAction(final String title) { + super(title, title, IconLoader.getIcon("/objectBrowser/sortByType.png")); + } + + @Override + public boolean isSelected(AnActionEvent e) { + return pluginsModel.isSortByStatus(); + } + + @Override + public void setSelected(AnActionEvent e, boolean state) { + IdeaPluginDescriptor[] selected = pluginTable.getSelectedObjects(); + pluginsModel.setSortByStatus(state); + pluginsModel.sort(); + if (selected != null) { + select(selected); + } + } + } + public class MyPluginsFilter extends FilterComponent { public MyPluginsFilter() { @@ -496,6 +515,7 @@ public abstract class PluginManagerMain implements Disposable { public void filter() { pluginsModel.filter(getFilter().toLowerCase()); + TableUtil.ensureSelectionExists(getPluginTable()); } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerUISettings.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerUISettings.java index 9fbd978a736a..0085d5301d7b 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerUISettings.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerUISettings.java @@ -44,6 +44,7 @@ public class PluginManagerUISettings implements PersistentStateComponent result = new Vector(); + if (parent == null) { + Container root = toSelect.getParent(); + while (true) { + Container _superRoot = root.getParent(); + if (_superRoot == null) break; + root = _superRoot; + } + + for (Component component : root.getComponents()) { + result.add(new ComponentNode(toSelect, component)); + } + } else { + if (parent instanceof Container) { + for (Component component : ((Container)parent).getComponents()) { + result.add(new ComponentNode(toSelect, component)); + } + } + } + + return result; + } + } + } + private static class HighlightComponent extends JComponent { private Color myColor; @@ -226,7 +413,7 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { private InspectorTableModel myModel; private DimensionsComponent myDimensionComponent; - private InspectorTable(@NotNull final JComponent component) { + private InspectorTable(@NotNull final Component component) { setLayout(new BorderLayout()); myModel = new InspectorTableModel(component); @@ -258,13 +445,13 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { } private static class DimensionsComponent extends JComponent { - private JComponent myComponent; + private Component myComponent; private int myWidth; private int myHeight; private Border myBorder; private Insets myInsets; - private DimensionsComponent(@NotNull final JComponent component) { + private DimensionsComponent(@NotNull final Component component) { myComponent = component; setOpaque(true); setBackground(Color.WHITE); @@ -278,8 +465,10 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { public void update() { myWidth = myComponent.getWidth(); myHeight = myComponent.getHeight(); - myBorder = myComponent.getBorder(); - myInsets = myComponent.getInsets(); + if (myComponent instanceof JComponent) { + myBorder = ((JComponent)myComponent).getBorder(); + myInsets = ((JComponent)myComponent).getInsets(); + } } @Override @@ -485,17 +674,17 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { "isShowing", "isEnabled", "isLightweight", "isFocusable", "isFocusOwner" }; - private JComponent myComponent; + private Component myComponent; private List myProperties = new ArrayList(); - public InspectorTableModel(@NotNull final JComponent c) { + public InspectorTableModel(@NotNull final Component c) { myComponent = c; fillTable(); } private void fillTable() { - final Class cls = myComponent.getClass(); + final Class cls = myComponent.getClass(); for (final String methodName: JCOMPONENT_METHODS) { try { final Method method = cls.getMethod(methodName); diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 9c7c302d025b..f6b736c31f7d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -108,6 +108,8 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application private int myRestartCode = 0; private volatile int myExitCode = 0; private final Disposable myLastDisposable = Disposer.newDisposable(); // will be disposed last + + private boolean myHandlingInitComponentError; private final AtomicBoolean mySaveSettingsIsInProgress = new AtomicBoolean(false); @SuppressWarnings({"UseOfArchaicSystemPropertyAccessors"}) @@ -332,36 +334,46 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application @Override protected void handleInitComponentError(final Throwable ex, final boolean fatal, final String componentClassName) { - if (PluginManager.isPluginClass(componentClassName)) { - LOG.error(ex); - PluginId pluginId = PluginManager.getPluginByClassName(componentClassName); - @NonNls final String errorMessage = "Plugin " + pluginId.getIdString() + " failed to initialize and will be disabled:\n" + ex.getMessage() + - "\nPlease restart " + ApplicationNamesInfo.getInstance().getFullProductName() + "."; - PluginManager.disablePlugin(pluginId.getIdString()); - if (!myHeadlessMode) { - JOptionPane.showMessageDialog(null, errorMessage); - } - else { - //noinspection UseOfSystemOutOrSystemErr - System.out.println(errorMessage); - System.exit(1); - } - return; // do not call super + if (myHandlingInitComponentError) { + return; } - if (fatal) { - LOG.error(ex); - @NonNls final String errorMessage = "Fatal error initializing class " + componentClassName + ":\n" + - ex.toString() + - "\nComplete error stacktrace was written to " + PathManager.getLogPath() + "/idea.log"; - if (!myHeadlessMode) { - JOptionPane.showMessageDialog(null, errorMessage); + myHandlingInitComponentError = true; + try { + if (PluginManager.isPluginClass(componentClassName)) { + LOG.error(ex); + PluginId pluginId = PluginManager.getPluginByClassName(componentClassName); + @NonNls final String errorMessage = + "Plugin " + pluginId.getIdString() + " failed to initialize and will be disabled:\n" + ex.getMessage() + + "\nPlease restart " + ApplicationNamesInfo.getInstance().getFullProductName() + "."; + PluginManager.disablePlugin(pluginId.getIdString()); + if (!myHeadlessMode) { + JOptionPane.showMessageDialog(null, errorMessage); + } + else { + //noinspection UseOfSystemOutOrSystemErr + System.out.println(errorMessage); + System.exit(1); + } + return; // do not call super } - else { - //noinspection UseOfSystemOutOrSystemErr - System.out.println(errorMessage); + if (fatal) { + LOG.error(ex); + @NonNls final String errorMessage = "Fatal error initializing class " + componentClassName + ":\n" + + ex.toString() + + "\nComplete error stacktrace was written to " + PathManager.getLogPath() + "/idea.log"; + if (!myHeadlessMode) { + JOptionPane.showMessageDialog(null, errorMessage); + } + else { + //noinspection UseOfSystemOutOrSystemErr + System.out.println(errorMessage); + } } + super.handleInitComponentError(ex, fatal, componentClassName); + } + finally { + myHandlingInitComponentError = false; } - super.handleInitComponentError(ex, fatal, componentClassName); } private void loadApplicationComponents() { diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java b/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java index 67f5ec6b52f5..f45e1bcd8aa2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java @@ -152,6 +152,11 @@ public class FrameWrapper implements Disposable, DataProvider { myFocusWatcher.install(myComponent); myShown = true; frame.setVisible(true); + + if (UIUtil.isUnderAlloyLookAndFeel()) { + //please ask [kb] before remove it + frame.setMaximizedBounds(null); + } } public void close() { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/SymlinkDirectory.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/SymlinkDirectory.java index 28dfa5d2226e..dc12c2d4b485 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/SymlinkDirectory.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/SymlinkDirectory.java @@ -15,9 +15,11 @@ */ package com.intellij.openapi.vfs.newvfs.impl; +import com.intellij.openapi.util.AtomicNotNullLazyValue; import com.intellij.openapi.util.NullableComputable; import com.intellij.openapi.util.RecursionManager; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem; import com.intellij.openapi.vfs.newvfs.VfsImplUtil; import org.jetbrains.annotations.NotNull; @@ -25,28 +27,72 @@ import org.jetbrains.annotations.Nullable; /** * @author Dmitry Avdeev - * Date: 10/31/11 + * @since 31.10.2011 */ +@SuppressWarnings("NonSynchronizedMethodOverridesSynchronizedMethod") public class SymlinkDirectory extends VirtualDirectoryImpl { + private final AtomicNotNullLazyValue myTarget = new AtomicNotNullLazyValue() { + @NotNull + @Override + protected VirtualDirectoryImpl compute() { + final String path = getFileSystem().resolveSymLink(SymlinkDirectory.this); + VirtualFile file = null; + if (path != null) { + file = findFile(path, false); + } + if (file == SymlinkDirectory.this && file != null) { + final VirtualFile parent = file.getParent(); + if (parent instanceof VirtualDirectoryImpl) { + ((VirtualDirectoryImpl)parent).removeChild(file); + file = findFile(path, true); + } + } + return file instanceof VirtualDirectoryImpl ? (VirtualDirectoryImpl)file : new VirtualDirectoryImpl("foo", SymlinkDirectory.this, getFileSystem(), 0); + } - @Nullable - private final VirtualFile myTarget; + @Nullable + private VirtualFile findFile(final String path, final boolean refresh) { + return RecursionManager.doPreventingRecursion(SymlinkDirectory.this, false, new NullableComputable() { + @Override + public VirtualFile compute() { + return refresh ? VfsImplUtil.refreshAndFindFileByPath(getFileSystem(), path) : VfsImplUtil.findFileByPath(getFileSystem(), path); + } + }); + } + }; public SymlinkDirectory(@NotNull String name, final VirtualDirectoryImpl parent, @NotNull final NewVirtualFileSystem fs, final int id) { super(name, parent, fs, id); - final String path = fs.resolveSymLink(this); + } - myTarget = path == null ? null : RecursionManager.doPreventingRecursion("", false, new NullableComputable() { - @Override - public VirtualFile compute() { - return VfsImplUtil.findFileByPath(getFileSystem(), path); - } - }); + @Override + public VirtualFileSystemEntry findChild(@NotNull String name) { + return myTarget.getValue().findChild(name); + } + + @Override + public NewVirtualFile findChildIfCached(@NotNull String name) { + return myTarget.getValue().findChildIfCached(name); + } + + @Override + public NewVirtualFile findChildById(int id) { + return myTarget.getValue().findChildById(id); + } + + @Override + public NewVirtualFile findChildByIdIfCached(int id) { + return myTarget.getValue().findChildByIdIfCached(id); + } + + @Override + public NewVirtualFile refreshAndFindChild(@NotNull String name) { + return myTarget.getValue().refreshAndFindChild(name); } @NotNull @Override public VirtualFile[] getChildren() { - return myTarget == null ? VirtualFile.EMPTY_ARRAY : myTarget.getChildren(); + return myTarget.getValue().getChildren(); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java index 1f2a85384360..128963c96843 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java @@ -63,6 +63,8 @@ import java.util.*; * @author max */ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { + private static final boolean ALT_SYMLINK_HANDLING = "true".equals(System.getProperty("idea.io.alt.symlink")); + private static final VirtualFileSystemEntry NULL_VIRTUAL_FILE = new VirtualFileImpl("*?;%NULL", null, -42); private final NewVirtualFileSystem myFS; @@ -165,7 +167,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { final VirtualFileSystemEntry child; final NewVirtualFileSystem fs = getFileSystem(); if (PersistentFS.isDirectory(id)) { - child = /*PersistentFS.isSymLink(id) ? new SymlinkDirectory(name, this, fs, id) :*/ new VirtualDirectoryImpl(name, this, fs, id); + child = ALT_SYMLINK_HANDLING && PersistentFS.isSymLink(id) ? new SymlinkDirectory(name, this, fs, id) : new VirtualDirectoryImpl(name, this, fs, id); } else { child = new VirtualFileImpl(name, this, id); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java index c5ae1e9efeb6..e7735ffaf980 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java @@ -259,9 +259,9 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx { myWidgetMap.clear(); myChildren.clear(); - myLeftPanel.removeAll(); - myRightPanel.removeAll(); - myCenterPanel.removeAll(); + if (myLeftPanel != null) myLeftPanel.removeAll(); + if (myRightPanel != null) myRightPanel.removeAll(); + if (myCenterPanel != null) myCenterPanel.removeAll(); } private void addWidget(@NotNull final StatusBarWidget widget, @NotNull final Position pos, @NotNull final String anchor) { diff --git a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties index bd92a2f434ea..aa4dedba329e 100644 --- a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties +++ b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties @@ -290,10 +290,10 @@ dialog.edit.template.label.abbreviation=&Abbreviation: dialog.edit.template.label.group=&Group: dialog.edit.template.label.description=&Description: dialog.edit.template.options.title=Options -dialog.edit.template.label.expand.with=&Expand with +dialog.edit.template.label.expand.with=E&xpand with dialog.edit.template.checkbox.reformat.according.to.style=&Reformat according to style dialog.edit.template.checkbox.shorten.fq.names=Shorten &FQ names -dialog.edit.template.checkbox.use.static.import=Use static import if possible +dialog.edit.template.checkbox.use.static.import=Use static &import if possible dialog.edit.template.context.title=Context dialog.edit.template.checkbox.html=&HTML dialog.edit.template.checkbox.xml=&XML 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 a10a86bffcbc..746baebfa6e5 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java @@ -81,9 +81,13 @@ public class FileUrlProvider implements TestLocationProvider, DumbAware { return Collections.emptyList(); } + if (lineNumber < 0) { + LOG.warn("Tests location provider: line number should be >= 1. Path: " + path); + } + final List locations = new ArrayList(2); for (VirtualFile file : virtualFiles) { - locations.add(createLocationFor(project, file, lineNumber)); + locations.add(createLocationFor(project, file, lineNumber < 1 ? 1 : lineNumber)); } return locations; } diff --git a/platform/testFramework/src/com/intellij/testFramework/AbstractVcsTestCase.java b/platform/testFramework/src/com/intellij/testFramework/AbstractVcsTestCase.java index bb765b69ed25..742765f3cc98 100644 --- a/platform/testFramework/src/com/intellij/testFramework/AbstractVcsTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/AbstractVcsTestCase.java @@ -337,7 +337,11 @@ public abstract class AbstractVcsTestCase { @Override protected void run() throws Throwable { try { - file.setBinaryContent(newContent.getBytes()); + final long newModTs = Math.max(System.currentTimeMillis(), file.getModificationStamp() + 1100); + final long newTs = Math.max(System.currentTimeMillis(), file.getTimeStamp() + 1100); + file.setBinaryContent(newContent.getBytes(), newModTs, newTs); + final File file1 = new File(file.getPath()); + file1.setLastModified(newModTs); } catch(IOException ex) { throw new RuntimeException(ex); diff --git a/platform/util/src/com/intellij/ui/EngravedTextGraphics.java b/platform/util/src/com/intellij/ui/EngravedTextGraphics.java index 94ee8c265c2e..a82bd87bf0c3 100644 --- a/platform/util/src/com/intellij/ui/EngravedTextGraphics.java +++ b/platform/util/src/com/intellij/ui/EngravedTextGraphics.java @@ -51,10 +51,13 @@ public class EngravedTextGraphics extends Graphics2DDelegate { public void drawChars(char[] data, int offset, int length, int x, int y) { if (ALLOW_ENGRAVEMENT) { final Color color = getColor(); - setColor(myShadowColor); - super.drawChars(data, offset, length, x + myXOffset, y + myYOffset); + + if (color != myShadowColor) { + setColor(myShadowColor); + super.drawChars(data, offset, length, x + myXOffset, y + myYOffset); - setColor(color); + setColor(color); + } } super.drawChars(data, offset, length, x, y); @@ -64,11 +67,12 @@ public class EngravedTextGraphics extends Graphics2DDelegate { public void drawString(String str, int x, int y) { if (ALLOW_ENGRAVEMENT) { final Color color = getColor(); + if (color != myShadowColor) { + setColor(myShadowColor); + super.drawString(str, x + myXOffset, y + myYOffset); - setColor(myShadowColor); - super.drawString(str, x + myXOffset, y + myYOffset); - - setColor(color); + setColor(color); + } } super.drawString(str, x, y); } @@ -78,10 +82,12 @@ public class EngravedTextGraphics extends Graphics2DDelegate { if (ALLOW_ENGRAVEMENT) { final Color color = getColor(); - setColor(myShadowColor); - super.drawString(iterator, x + myXOffset, y + myYOffset); + if (color != myShadowColor) { + setColor(myShadowColor); + super.drawString(iterator, x + myXOffset, y + myYOffset); - setColor(color); + setColor(color); + } } super.drawString(iterator, x, y); } @@ -91,10 +97,12 @@ public class EngravedTextGraphics extends Graphics2DDelegate { if (ALLOW_ENGRAVEMENT) { final Color color = getColor(); - setColor(myShadowColor); - super.drawString(iterator, x + myXOffset, y + myYOffset); + if (color != myShadowColor) { + setColor(myShadowColor); + super.drawString(iterator, x + myXOffset, y + myYOffset); - setColor(color); + setColor(color); + } } super.drawString(iterator, x, y); } @@ -104,10 +112,12 @@ public class EngravedTextGraphics extends Graphics2DDelegate { if (ALLOW_ENGRAVEMENT) { final Color color = getColor(); - setColor(myShadowColor); - super.drawString(s, x + myXOffset, y + myYOffset); + if (color != myShadowColor) { + setColor(myShadowColor); + super.drawString(s, x + myXOffset, y + myYOffset); - setColor(color); + setColor(color); + } } super.drawString(s, x, y); } diff --git a/platform/util/src/com/intellij/util/containers/Queue.java b/platform/util/src/com/intellij/util/containers/Queue.java index 1dbe2e36756c..94e5b230c5eb 100644 --- a/platform/util/src/com/intellij/util/containers/Queue.java +++ b/platform/util/src/com/intellij/util/containers/Queue.java @@ -106,6 +106,7 @@ public class Queue { public void clear() { Arrays.fill(myArray, null); myFirst = myLast = 0; + isWrapped = false; } public boolean process(@NotNull Processor processor) { @@ -127,4 +128,13 @@ public class Queue { } return true; } + + @Override + public String toString() { + List list = Arrays.asList(myArray); + if (isWrapped) { + return "[[[ " +list.subList(0, myLast) + " ||| ... " + list.subList(myLast, myFirst) + " ... ||| " + list.subList(myFirst, myArray.length) + " ]]]"; + } + return "[[[ ... " +list.subList(0, myFirst) + " ... ||| " + list.subList(myFirst, myLast) + " ||| ... " + list.subList(myFirst, myArray.length) + " ... ]]]"; + } } diff --git a/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java b/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java index c7dc592bb474..842cd469f4a4 100644 --- a/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java +++ b/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java @@ -17,7 +17,6 @@ package com.intellij.util.pico; import com.intellij.util.ReflectionCache; import com.intellij.util.containers.ConcurrentHashMap; -import com.intellij.util.containers.FList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.picocontainer.*; @@ -25,6 +24,7 @@ import org.picocontainer.defaults.*; import java.io.Serializable; import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicReference; public class DefaultPicoContainer implements MutablePicoContainer, Serializable { @@ -34,11 +34,11 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable private final Set children = new HashSet(); private final Map componentKeyToAdapterCache = new ConcurrentHashMap(); - private final LinkedHashSetWrapper componentAdapters = new LinkedHashSetWrapper(); + private final AtomicReference> componentAdapters = new AtomicReference>(new LinkedHashSet()); // Keeps track of instantiation order. - private final LinkedHashSetWrapper orderedComponentAdapters = new LinkedHashSetWrapper(); + private final AtomicReference> orderedComponentAdapters = new AtomicReference>(new LinkedHashSet()); private final Map classNameToAdapter = new ConcurrentHashMap(); - private final AtomicReference> nonAssignableComponentAdapters = new AtomicReference>(FList.emptyList()); + private final CopyOnWriteArrayList nonAssignableComponentAdapters = new CopyOnWriteArrayList(); public DefaultPicoContainer(@NotNull ComponentAdapterFactory componentAdapterFactory, PicoContainer parent) { this.componentAdapterFactory = componentAdapterFactory; @@ -50,7 +50,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable } public Collection getComponentAdapters() { - return componentAdapters.getImmutableSet(); + return Collections.unmodifiableCollection(componentAdapters.get()); } public Map getAssignablesCache() { @@ -59,7 +59,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable public Collection getNonAssignableAdapters() { - return nonAssignableComponentAdapters.get().getReversedList(); + return nonAssignableComponentAdapters; } @Nullable @@ -141,34 +141,51 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable classNameToAdapter.put(classKey, componentAdapter); } else { - do { - FList oldList = nonAssignableComponentAdapters.get(); - FList newList = oldList.prepend(componentAdapter); - if (nonAssignableComponentAdapters.compareAndSet(oldList, newList)) { - break; - } - } while (true); + nonAssignableComponentAdapters.add(componentAdapter); } - componentAdapters.add(componentAdapter); + addElement(componentAdapters, componentAdapter); componentKeyToAdapterCache.put(componentKey, componentAdapter); return componentAdapter; } + private static void addElement(AtomicReference> collectionHolder, T element) { + do { + LinkedHashSet oldCollection = collectionHolder.get(); + if (oldCollection.contains(element)) { + return; + } + + LinkedHashSet newCollection = new LinkedHashSet(oldCollection); + newCollection.add(element); + + if (collectionHolder.compareAndSet(oldCollection, newCollection)) break; + } while (true); + } + + private static void removeElement(AtomicReference> collectionHolder, T element) { + do { + LinkedHashSet oldCollection = collectionHolder.get(); + + LinkedHashSet newCollection = new LinkedHashSet(oldCollection); + newCollection.remove(element); + + if (collectionHolder.compareAndSet(oldCollection, newCollection)) break; + } while (true); + } + public ComponentAdapter unregisterComponent(Object componentKey) { ComponentAdapter adapter = componentKeyToAdapterCache.remove(componentKey); - componentAdapters.remove(adapter); - orderedComponentAdapters.remove(adapter); + removeElement(componentAdapters, adapter); + removeElement(orderedComponentAdapters, adapter); return adapter; } private void addOrderedComponentAdapter(ComponentAdapter componentAdapter) { - if (!orderedComponentAdapters.contains(componentAdapter)) { - orderedComponentAdapters.add(componentAdapter); - } + addElement(orderedComponentAdapters, componentAdapter); } public List getComponentInstances() throws PicoException { @@ -181,7 +198,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable } Map adapterToInstanceMap = new HashMap(); - for (final ComponentAdapter componentAdapter : componentAdapters.getImmutableSet()) { + for (final ComponentAdapter componentAdapter : componentAdapters.get()) { if (ReflectionCache.isAssignable(componentType, componentAdapter.getComponentImplementation())) { Object componentInstance = getInstance(componentAdapter); adapterToInstanceMap.put(componentAdapter, componentInstance); @@ -193,7 +210,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable } List result = new ArrayList(); - for (ComponentAdapter componentAdapter : orderedComponentAdapters.getImmutableSet()) { + for (ComponentAdapter componentAdapter : orderedComponentAdapters.get()) { final Object componentInstance = adapterToInstanceMap.get(componentAdapter); if (componentInstance != null) { // may be null in the case of the "implicit" adapter @@ -223,7 +240,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable @Nullable private Object getInstance(ComponentAdapter componentAdapter) { - final boolean isLocal = componentAdapters.contains(componentAdapter); + final boolean isLocal = componentAdapters.get().contains(componentAdapter); if (isLocal) { return getLocalInstance(componentAdapter); @@ -342,50 +359,4 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable public PicoContainer getParent() { return parent; } - - private static class LinkedHashSetWrapper { - - private volatile Set immutableSet; - - private final LinkedHashSet synchronizedSet = new LinkedHashSet(); - - private final ConcurrentHashMap concurrentSet = new ConcurrentHashMap(); - - public boolean contains(@Nullable T element) { - return element != null && concurrentSet.containsKey(element); - } - - public void add(@NotNull T element) { - synchronized (synchronizedSet) { - immutableSet = null; - synchronizedSet.add(element); - concurrentSet.put(element, element); - } - } - - public void remove(@Nullable T element) { - if (element == null) return; - synchronized (synchronizedSet) { - immutableSet = null; - synchronizedSet.remove(element); - concurrentSet.remove(element); - } - } - - @NotNull - public Set getImmutableSet() { - Set res = immutableSet; - if (res == null) { - synchronized (synchronizedSet) { - res = immutableSet; - if (res == null) { - res = Collections.unmodifiableSet((Set)synchronizedSet.clone()); - immutableSet = res; - } - } - } - - return res; - } - } } \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/ui/FormBuilder.java b/platform/util/src/com/intellij/util/ui/FormBuilder.java index 33f0d68b71ef..540b3af3c6fc 100644 --- a/platform/util/src/com/intellij/util/ui/FormBuilder.java +++ b/platform/util/src/com/intellij/util/ui/FormBuilder.java @@ -51,21 +51,17 @@ public class FormBuilder { } public FormBuilder addLabeledComponent(String labelText, JComponent component, final int verticalSpace) { - JLabel label = null; - if (labelText != null) { - label = new JLabel(UIUtil.removeMnemonic(labelText)); - label.setDisplayedMnemonicIndex(UIUtil.getDisplayMnemonicIndex(labelText)); - label.setLabelFor(component); - } - - return addLabelAndValueComponents(label, component, verticalSpace, false, false); + return addLabeledComponent(labelText, component, verticalSpace, false); } public FormBuilder addLabeledComponent(String labelText, JComponent component, final int verticalSpace, boolean labelOnTop) { JLabel label = null; if (labelText != null) { label = new JLabel(UIUtil.removeMnemonic(labelText)); - label.setDisplayedMnemonicIndex(UIUtil.getDisplayMnemonicIndex(labelText)); + final int index = UIUtil.getDisplayMnemonicIndex(labelText); + if (index != -1) { + label.setDisplayedMnemonic(labelText.charAt(index+1)); + } label.setLabelFor(component); } @@ -104,7 +100,7 @@ public class FormBuilder { c.weightx = 1.0; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; - c.insets = new Insets(verticalInset, 0, 0, this.indent); + c.insets = new Insets(verticalInset, 0, this.indent, 0); if (label != null) panel.add(label, c); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeDiffRequestPresentable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeDiffRequestPresentable.java index e2bbf1b169a5..896753e6c56d 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeDiffRequestPresentable.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeDiffRequestPresentable.java @@ -83,12 +83,16 @@ public class ChangeDiffRequestPresentable implements DiffRequestPresentable { String afterPath = aRev != null ? aRev.getFile().getPath() : null; String title; if (beforePath != null && afterPath != null && !beforePath.equals(afterPath)) { + beforePath = FileUtil.toSystemDependentName(beforePath); + afterPath = FileUtil.toSystemDependentName(afterPath); title = beforePath + " -> " + afterPath; } else if (beforePath != null) { + beforePath = FileUtil.toSystemDependentName(beforePath); title = beforePath; } else if (afterPath != null) { + afterPath = FileUtil.toSystemDependentName(afterPath); title = afterPath; } else { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/MergedDiffRequestPresentable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/MergedDiffRequestPresentable.java index cfa453a07882..4a08b11121d4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/MergedDiffRequestPresentable.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/MergedDiffRequestPresentable.java @@ -21,6 +21,7 @@ import com.intellij.openapi.diff.MergeRequest; import com.intellij.openapi.diff.SimpleDiffRequest; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Getter; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vcs.FilePathImpl; import com.intellij.openapi.vcs.VcsBundle; import com.intellij.openapi.vcs.changes.actions.*; @@ -57,8 +58,8 @@ public class MergedDiffRequestPresentable implements DiffRequestPresentable { } final MergeRequest request = DiffRequestFactory.getInstance() .create3WayDiffRequest(revisionTexts.getLocal().toString(), revisionTexts.getPatched(), revisionTexts.getBase().toString(), myProject, null, null); - request.setWindowTitle(VcsBundle.message("patch.apply.conflict.title", myFile.getPresentableUrl())); - request.setVersionTitles(new String[] {"Current Version", "Base Version", myAfterTitle}); + request.setWindowTitle(VcsBundle.message("patch.apply.conflict.title", FileUtil.toSystemDependentName(myFile.getPresentableUrl()))); + request.setVersionTitles(new String[] {"Current Version", "Base Version", FileUtil.toSystemDependentName(myAfterTitle)}); return new MyResult(request, DiffPresentationReturnValue.useRequest); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java index f8defdf183f0..1eb2f2347d47 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java @@ -107,17 +107,27 @@ public abstract class GenericNotifierImpl { } } - public void ensureNotify(final T obj) { + public boolean ensureNotify(final T obj) { final MyNotification notification; synchronized (myLock) { final Key key = getKey(obj); if (myState.containsKey(key)) { - return; + return false; } notification = new MyNotification(myGroupId, myTitle, getNotificationContent(obj), myType, myListener, obj, getToString(obj)); myState.put(key, notification); } + final boolean state = onFirstNotification(obj); + if (state) { + removeLazyNotification(obj); + return true; + } Notifications.Bus.notify(notification, myProject); + return false; + } + + protected boolean onFirstNotification(T obj) { + return false; } public void removeLazyNotificationByKey(final Key key) { diff --git a/plugins/git4idea/lib/ini4j/0002-Let_comment_be_on_the_same_line_as_section_header.patch b/plugins/git4idea/lib/ini4j/0002-Let_comment_be_on_the_same_line_as_section_header.patch new file mode 100644 index 000000000000..3920b1ba0453 --- /dev/null +++ b/plugins/git4idea/lib/ini4j/0002-Let_comment_be_on_the_same_line_as_section_header.patch @@ -0,0 +1,39 @@ +Index: src/main/java/org/ini4j/spi/IniParser.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>x-MacCyrillic +=================================================================== +--- src/main/java/org/ini4j/spi/IniParser.java (date 1319206062000) ++++ src/main/java/org/ini4j/spi/IniParser.java (revision ) +@@ -114,10 +114,19 @@ + { + String sectionName; + +- if (line.charAt(line.length() - 1) != SECTION_END) ++ if (line.charAt(line.length() - 1) != SECTION_END) + { ++ int sectionEnd = line.lastIndexOf(SECTION_END); ++ String afterSectionEnd = line.substring(sectionEnd + 1).trim(); ++ if (afterSectionEnd.isEmpty() || isComment(afterSectionEnd.charAt(0))) ++ { ++ line = line.substring(0, sectionEnd + 1); ++ } ++ else ++ { + parseError(line, source.getLineNumber()); +- } ++ } ++ } + + sectionName = unescapeFilter(line.substring(1, line.length() - 1).trim()); + if ((sectionName.length() == 0) && !getConfig().isUnnamedSection()) +@@ -133,5 +142,9 @@ + handler.startSection(sectionName); + + return sectionName; ++ } ++ ++ private boolean isComment(char c) { ++ return COMMENTS.indexOf(c) >= 0; + } + } diff --git a/plugins/git4idea/lib/ini4j/ini4j-0.5.2-patched-sources.zip b/plugins/git4idea/lib/ini4j/ini4j-0.5.2-patched-sources.zip index 253722c7abbd..46cf85f7a366 100644 Binary files a/plugins/git4idea/lib/ini4j/ini4j-0.5.2-patched-sources.zip and b/plugins/git4idea/lib/ini4j/ini4j-0.5.2-patched-sources.zip differ diff --git a/plugins/git4idea/lib/ini4j/ini4j-0.5.2-patched.jar b/plugins/git4idea/lib/ini4j/ini4j-0.5.2-patched.jar index e9ddbc45df23..efb8c6991b96 100644 Binary files a/plugins/git4idea/lib/ini4j/ini4j-0.5.2-patched.jar and b/plugins/git4idea/lib/ini4j/ini4j-0.5.2-patched.jar differ diff --git a/plugins/git4idea/src/git4idea/actions/GitPull.java b/plugins/git4idea/src/git4idea/actions/GitPull.java index 0b799e47c79c..98304bc1a462 100644 --- a/plugins/git4idea/src/git4idea/actions/GitPull.java +++ b/plugins/git4idea/src/git4idea/actions/GitPull.java @@ -73,12 +73,11 @@ public class GitPull extends GitRepositoryAction { public void run(@NotNull ProgressIndicator indicator) { GitRepository repository = GitRepositoryManager.getInstance(project).getRepositoryForRoot(dialog.gitRoot()); assert repository != null : "Repository can't be null for root " + dialog.gitRoot(); - String remoteName = dialog.getRemote(); - GitRemote remote = GitUtil.findRemoteByName(repository, remoteName); - if (remote == null) { - return; - } - String url = remote.getFirstUrl(); + String remoteOrUrl = dialog.getRemote(); + + + GitRemote remote = GitUtil.findRemoteByName(repository, remoteOrUrl); + String url = (remote == null) ? remoteOrUrl : remote.getFirstUrl(); if (url == null) { return; } diff --git a/plugins/git4idea/src/git4idea/history/GitLogStatusInfo.java b/plugins/git4idea/src/git4idea/history/GitLogStatusInfo.java index b2685b659a6d..5dd30712ca6e 100644 --- a/plugins/git4idea/src/git4idea/history/GitLogStatusInfo.java +++ b/plugins/git4idea/src/git4idea/history/GitLogStatusInfo.java @@ -44,9 +44,9 @@ class GitLogStatusInfo { */ private static void verifyParameters(@NotNull GitChangeType type, @NotNull String path, @Nullable String secondPath) { if (type.requiresSecondPath()) { - LOG.assertTrue(secondPath != null, "Rename change should have the second path"); + LOG.assertTrue(secondPath != null, String.format("Rename change should have the second path. type=%s, path1=%s, path2=%s", type, path, secondPath)); } else { - LOG.assertTrue(secondPath == null, "Second path should be null in case of change type [" + type + "]"); + LOG.assertTrue(secondPath == null, String.format("Second path should be null. type=%s, path1=%s, path2=%s", type, path, secondPath)); } } diff --git a/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java b/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java index 4d8c40d18cd6..b3a356756735 100644 --- a/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java +++ b/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java @@ -22,6 +22,8 @@ import com.intellij.ide.passwordSafe.impl.PasswordSafeImpl; import com.intellij.ide.passwordSafe.impl.PasswordSafeProvider; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import git4idea.GitBranch; +import git4idea.GitVcs; import git4idea.push.GitSimplePushResult; import git4idea.remote.GitRememberedInputs; import git4idea.repo.GitRemote; @@ -33,6 +35,7 @@ import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.errors.NoRemoteRepositoryException; import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.TransportException; +import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.transport.RefSpec; @@ -44,6 +47,7 @@ import java.io.IOException; import java.net.ProxySelector; import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; @@ -83,7 +87,8 @@ public final class GitHttpAdapter { try { final Git git = convertToGit(repository); final GitHttpCredentialsProvider provider = new GitHttpCredentialsProvider(repository.getProject(), remoteUrl); - GeneralResult result = callWithAuthRetry(new GitHttpRemoteCommand.Fetch(git, provider, remoteUrl, convertRefSpecs(remote.getFetchRefSpecs()))); + GeneralResult result = callWithAuthRetry(new GitHttpRemoteCommand.Fetch(git, provider, remoteUrl, convertRefSpecs(remote.getFetchRefSpecs())), + repository.getProject()); resultType = convertToFetchResultType(result); } catch (IOException e) { logException(repository, remote.getName(), remoteUrl, e, "fetching"); @@ -128,7 +133,7 @@ public final class GitHttpAdapter { final Git git = convertToGit(repository); final GitHttpCredentialsProvider provider = new GitHttpCredentialsProvider(repository.getProject(), remoteUrl); GitHttpRemoteCommand.Push pushCommand = new GitHttpRemoteCommand.Push(git, provider, remote.getName(), remoteUrl, convertRefSpecs(Collections.singletonList(pushSpec))); - GeneralResult result = callWithAuthRetry(pushCommand); + GeneralResult result = callWithAuthRetry(pushCommand, repository.getProject()); GitSimplePushResult pushResult = pushCommand.getResult(); if (pushResult == null) { return convertToPushResultType(result); @@ -156,12 +161,45 @@ public final class GitHttpAdapter { } } + @NotNull + public static Collection lsRemote(@NotNull GitRepository repository, @NotNull String remoteName, @NotNull String remoteUrl) { + try { + final Git git = convertToGit(repository); + final GitHttpCredentialsProvider provider = new GitHttpCredentialsProvider(repository.getProject(), remoteUrl); + GitHttpRemoteCommand.LsRemote lsRemoteCommand = new GitHttpRemoteCommand.LsRemote(git, provider, remoteUrl); + callWithAuthRetry(lsRemoteCommand, repository.getProject()); + return convertRefsToStrings(lsRemoteCommand.getRefs()); + } catch (IOException e) { + logException(repository, remoteName, remoteUrl, e, "fetching"); + } + catch (InvalidRemoteException e) { + logException(repository, remoteName, remoteUrl, e, "fetching"); + } + catch (URISyntaxException e) { + logException(repository, remoteName, remoteUrl, e, "fetching"); + } + return Collections.emptyList(); + } + + @NotNull + private static Collection convertRefsToStrings(@NotNull Collection lsRemoteCommandRefs) { + Collection refs = new ArrayList(); + for (Ref ref : lsRemoteCommandRefs) { + String refName = ref.getName(); + if (refName.startsWith(GitBranch.REFS_HEADS_PREFIX)) { + refName = refName.substring(GitBranch.REFS_HEADS_PREFIX.length()); + } + refs.add(refName); + } + return refs; + } + @NotNull public static GitFetchResult cloneRepository(@NotNull Project project, @NotNull final File directory, @NotNull final String url) { GitFetchResult.Type resultType; try { final GitHttpCredentialsProvider provider = new GitHttpCredentialsProvider(project, url); - GeneralResult result = callWithAuthRetry(new GitHttpRemoteCommand.Clone(directory, provider, url)); + GeneralResult result = callWithAuthRetry(new GitHttpRemoteCommand.Clone(directory, provider, url), project); resultType = convertToFetchResultType(result); } catch (InvalidRemoteException e) { @@ -205,7 +243,7 @@ public final class GitHttpAdapter { * If user enters incorrect data, he has 2 more attempts to go before failure. * Cleanups are executed after each incorrect attempt to enter password, and after other retriable actions. */ - private static GeneralResult callWithAuthRetry(@NotNull GitHttpRemoteCommand command) throws InvalidRemoteException, IOException, URISyntaxException { + private static GeneralResult callWithAuthRetry(@NotNull GitHttpRemoteCommand command, @NotNull Project project) throws InvalidRemoteException, IOException, URISyntaxException { ProxySelector defaultProxySelector = ProxySelector.getDefault(); if (GitHttpProxySupport.shouldUseProxy()) { ProxySelector.setDefault(GitHttpProxySupport.newProxySelector()); @@ -271,10 +309,19 @@ public final class GitHttpAdapter { return GeneralResult.NOT_AUTHORIZED; } finally { + log(command, project); ProxySelector.setDefault(defaultProxySelector); } } + private static void log(@NotNull GitHttpRemoteCommand command, @NotNull Project project) { + GitVcs vcs = GitVcs.getInstance(project); + if (vcs != null) { + vcs.showCommandLine(command.getCommandString()); + } + LOG.info(command.getLogString()); + } + private static boolean smartHttpPushNotSupported(JGitInternalException e) { if (e.getCause() instanceof NotSupportedException) { NotSupportedException nse = (NotSupportedException)e.getCause(); diff --git a/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java b/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java index 5f67a781697f..5c9477d6f415 100644 --- a/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java +++ b/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java @@ -16,6 +16,8 @@ package git4idea.jgit; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; import git4idea.push.GitSimplePushResult; import org.eclipse.jgit.JGitText; import org.eclipse.jgit.api.CloneCommand; @@ -38,9 +40,7 @@ import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; /** * @author Kirill Likhodedov @@ -49,9 +49,11 @@ interface GitHttpRemoteCommand { String getUrl(); void setUrl(String url); - void run() throws InvalidRemoteException, URISyntaxException; + void run() throws InvalidRemoteException, URISyntaxException, TransportException; void cleanup(); GitHttpCredentialsProvider getCredentialsProvider(); + String getLogString(); + String getCommandString(); class Fetch implements GitHttpRemoteCommand { @@ -60,7 +62,7 @@ interface GitHttpRemoteCommand { private String myUrl; private final List myRefSpecs; - Fetch(@NotNull Git git, @NotNull GitHttpCredentialsProvider credentialsProvider, String url, List refSpecs) { + Fetch(@NotNull Git git, @NotNull GitHttpCredentialsProvider credentialsProvider, @NotNull String url, @NotNull List refSpecs) { myGit = git; myCredentialsProvider = credentialsProvider; myUrl = url; @@ -91,6 +93,25 @@ interface GitHttpRemoteCommand { return myCredentialsProvider; } + @Override + public String getLogString() { + return getCommandString(); + } + + @Override + public String getCommandString() { + return String.format("git fetch %s %s", myUrl, getRefspecsAsString(myRefSpecs)); + } + + static String getRefspecsAsString(@NotNull List refSpecs) { + return StringUtil.join(refSpecs, new Function() { + @Override + public String fun(RefSpec spec) { + return spec.toString(); + } + }, ","); + } + @Override public void cleanup() { } @@ -132,6 +153,16 @@ interface GitHttpRemoteCommand { return myCredentialsProvider; } + @Override + public String getLogString() { + return getCommandString(); + } + + @Override + public String getCommandString() { + return String.format("git clone %s %s", myUrl, myTargetDirectory.getPath()); + } + @Override public void cleanup() { if (myTargetDirectory.exists()) { @@ -200,7 +231,17 @@ interface GitHttpRemoteCommand { public GitHttpCredentialsProvider getCredentialsProvider() { return myCredentialsProvider; } - + + @Override + public String getLogString() { + return String.format("git push %s (%s) %s", myRemoteName, myUrl, GitHttpRemoteCommand.Fetch.getRefspecsAsString(myPushSpecs)); + } + + @Override + public String getCommandString() { + return String.format("git push %s %s", myRemoteName, GitHttpRemoteCommand.Fetch.getRefspecsAsString(myPushSpecs)); + } + @Override public void cleanup() { } @@ -339,6 +380,118 @@ interface GitHttpRemoteCommand { } } + class LsRemote implements GitHttpRemoteCommand { + + private final Git myGit; + private final GitHttpCredentialsProvider myCredentialsProvider; + private String myUrl; + private Collection myResultRefs; + + public LsRemote(@NotNull Git git, @NotNull GitHttpCredentialsProvider credentialsProvider, @NotNull String url) { + myGit = git; + myCredentialsProvider = credentialsProvider; + myUrl = url; + } + + @Override + public void run() throws InvalidRemoteException, TransportException { + myResultRefs = call(); + } + + @Override + public void cleanup() { + } + + @Override + public GitHttpCredentialsProvider getCredentialsProvider() { + return myCredentialsProvider; + } + + @Override + public String getLogString() { + return getCommandString(); + } + + @Override + public String getCommandString() { + return String.format("git ls-remote --heads %s ", myUrl); + } + + @Override + public String getUrl() { + return myUrl; + } + + @Override + public void setUrl(@NotNull String url) { + myUrl = url; + } + + @NotNull + public Collection getRefs() { + return myResultRefs == null ? Collections.emptyList() : myResultRefs; + } + + /* + Copy-paste of org.eclipse.jgit.api.LsRemote#call with the following changes: + 1. More specific exceptions declaration. + 2. Use CredentialsProvider. + 3. We don't need --tags, we always need --heads. + */ + private Collection call() throws TransportException, InvalidRemoteException { + try { + Transport transport = Transport.open(myGit.getRepository(), myUrl); + + try { + Collection refSpecs = new ArrayList(1); + refSpecs.add(new RefSpec("refs/heads/*:refs/remotes/origin/*")); + Collection refs; + Map refmap = new HashMap(); + transport.setCredentialsProvider(myCredentialsProvider); + FetchConnection fc = transport.openFetch(); + try { + refs = fc.getRefs(); + if (refSpecs.isEmpty()) { + for (Ref r : refs) { + refmap.put(r.getName(), r); + } + } + else { + for (Ref r : refs) { + for (RefSpec rs : refSpecs) { + if (rs.matchSource(r)) { + refmap.put(r.getName(), r); + break; + } + } + } + } + } + finally { + fc.close(); + } + return refmap.values(); + } + catch (TransportException e) { + throw new JGitInternalException( + JGitText.get().exceptionCaughtDuringExecutionOfLsRemoteCommand, + e); + } + finally { + transport.close(); + } + } + catch (URISyntaxException e) { + throw new InvalidRemoteException(MessageFormat.format( + JGitText.get().invalidRemote, myUrl)); + } + catch (NotSupportedException e) { + throw new JGitInternalException( + JGitText.get().exceptionCaughtDuringExecutionOfLsRemoteCommand, + e); + } + } + } } diff --git a/plugins/git4idea/src/git4idea/merge/GitPullDialog.java b/plugins/git4idea/src/git4idea/merge/GitPullDialog.java index 78e9f5dc0e29..dd4056af5133 100644 --- a/plugins/git4idea/src/git4idea/merge/GitPullDialog.java +++ b/plugins/git4idea/src/git4idea/merge/GitPullDialog.java @@ -29,13 +29,19 @@ import git4idea.commands.GitHandlerUtil; import git4idea.commands.GitLineHandler; import git4idea.commands.GitSimpleHandler; import git4idea.i18n.GitBundle; +import git4idea.jgit.GitHttpAdapter; +import git4idea.repo.GitRepository; +import git4idea.repo.GitRepositoryManager; import git4idea.ui.GitUIUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.DocumentEvent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -165,27 +171,50 @@ public class GitPullDialog extends DialogWrapper { listener.changedUpdate(null); myGetBranchesButton.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { - GitSimpleHandler h = new GitSimpleHandler(myProject, gitRoot(), GitCommand.LS_REMOTE); - h.addParameters("--heads", myRemote.getSelectedItem().toString()); - String output = GitHandlerUtil.doSynchronously(h, GitBundle.getString("pull.getting.remote.branches"), h.printableCommandLine()); - if (output == null) { - return; - } myBranchChooser.removeAllElements(); - for (String line : output.split("\n")) { - if (line.length() == 0) { - continue; - } - int pos = line.lastIndexOf('/'); - if (pos == -1) { - pos = line.lastIndexOf('\t'); - } - myBranchChooser.addElement(line.substring(pos + 1), false); + Collection remoteBranches = getRemoteBranches((GitDeprecatedRemote)myRemote.getSelectedItem()); + for (String branch : remoteBranches) { + myBranchChooser.addElement(branch, false); } } }); } + @NotNull + private Collection getRemoteBranches(@NotNull GitDeprecatedRemote remote) { + if (GitHttpAdapter.isHttpUrlWithoutUserCredentials(remote.fetchUrl())) { + GitRepository repository = GitRepositoryManager.getInstance(myProject).getRepositoryForRoot(gitRoot()); + if (repository == null) { + return Collections.emptyList(); + } + return GitHttpAdapter.lsRemote(repository, remote.name(), remote.fetchUrl()); + } + return lsRemoteNatively(remote); + } + + @NotNull + private Collection lsRemoteNatively(@NotNull GitDeprecatedRemote remote) { + GitSimpleHandler h = new GitSimpleHandler(myProject, gitRoot(), GitCommand.LS_REMOTE); + h.addParameters("--heads", remote.toString()); + String output = GitHandlerUtil.doSynchronously(h, GitBundle.getString("pull.getting.remote.branches"), h.printableCommandLine()); + if (output == null) { + return Collections.emptyList(); + } + + Collection remoteBranches = new ArrayList(); + for (String line : output.split("\n")) { + if (line.length() == 0) { + continue; + } + int pos = line.lastIndexOf('/'); + if (pos == -1) { + pos = line.lastIndexOf('\t'); + } + remoteBranches.add(line.substring(pos + 1)); + } + return remoteBranches; + } + /** * @return a pull handler configured according to dialog options */ diff --git a/plugins/git4idea/src/git4idea/process/GitBranchOperationsProcessor.java b/plugins/git4idea/src/git4idea/process/GitBranchOperationsProcessor.java index d0c695bc6be5..0c2dc295431d 100644 --- a/plugins/git4idea/src/git4idea/process/GitBranchOperationsProcessor.java +++ b/plugins/git4idea/src/git4idea/process/GitBranchOperationsProcessor.java @@ -453,7 +453,7 @@ public final class GitBranchOperationsProcessor { private void displayCompareDialog(List headToBranch, List branchToHead, String branchName) { if (headToBranch.isEmpty() && branchToHead.isEmpty()) { String currentBranch = GitBranchUiUtil.getBranchNameOrRev(myRepository); - Messages.showInfoMessage(myProject, String.format("There are no changes in the Git log between %s and %s", + Messages.showInfoMessage(myProject, String.format("There are no changes between %s and %s", currentBranch, branchName), "No Changes Detected"); } else { new GitCompareBranchesDialog(myRepository, branchName, headToBranch, branchToHead).show(); diff --git a/plugins/git4idea/src/git4idea/push/GitPushResult.java b/plugins/git4idea/src/git4idea/push/GitPushResult.java index 1f4df573ee11..ee16ee2d3357 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushResult.java +++ b/plugins/git4idea/src/git4idea/push/GitPushResult.java @@ -174,7 +174,7 @@ class GitPushResult { } @NotNull - Map getRejectedPushesForCurrentBranch() { + Map getRejectedPushesFromCurrentBranchToTrackedBranch(GitPushInfo pushInfo) { final Map rejectedPushesForCurrentBranch = new HashMap(); for (Map.Entry entry : group().myRejectedResults.entrySet()) { GitRepository repository = entry.getKey(); @@ -184,7 +184,29 @@ class GitPushResult { } GitPushRepoResult repoResult = entry.getValue(); GitPushBranchResult curBranchResult = repoResult.getBranchResults().get(currentBranch); - if (curBranchResult != null && curBranchResult.isRejected()) { + + if (curBranchResult == null) { + continue; + } + + String trackedBranchName; + try { + String simpleName = currentBranch.getTrackedBranchName(myProject, repository.getRoot()); + if (simpleName != null && simpleName.startsWith(GitBranch.REFS_HEADS_PREFIX)) { + simpleName = simpleName.substring(GitBranch.REFS_HEADS_PREFIX.length()); + } + String remote = currentBranch.getTrackedRemoteName(myProject, repository.getRoot()); + trackedBranchName = remote + "/" + simpleName; + } + catch (VcsException e) { + LOG.info("Couldn't get tracked branch for branch " + currentBranch, e); + continue; + } + if (!pushInfo.getPushSpecs().get(repository).getDest().getName().equals(trackedBranchName)) { + // push from current branch was rejected, but it was a push not to the tracked branch => ignore + continue; + } + if (curBranchResult.isRejected()) { rejectedPushesForCurrentBranch.put(repository, currentBranch); } } diff --git a/plugins/git4idea/src/git4idea/push/GitPusher.java b/plugins/git4idea/src/git4idea/push/GitPusher.java index 53899779c8aa..ed83f78e39b7 100644 --- a/plugins/git4idea/src/git4idea/push/GitPusher.java +++ b/plugins/git4idea/src/git4idea/push/GitPusher.java @@ -63,6 +63,7 @@ public final class GitPusher { private static final Logger LOG = Logger.getInstance(GitPusher.class); private static final String INDICATOR_TEXT = "Pushing"; + private static final int MAX_PUSH_ATTEMPTS = 10; private final Project myProject; private final ProgressIndicator myProgressIndicator; @@ -105,6 +106,11 @@ public final class GitPusher { public boolean shouldUpdate() { return getUpdateMethod() != null; } + + @Override + public String toString() { + return String.format("UpdateSettings{myUpdateAllRoots=%s, myUpdateMethod=%s}", myUpdateAllRoots, myUpdateMethod); + } } public GitPusher(@NotNull Project project, @NotNull ProgressIndicator indicator) { @@ -202,7 +208,7 @@ public final class GitPusher { * Makes push, shows the result in a notification. If push for current branch is rejected, shows a dialog proposing to update. */ public void push(@NotNull GitPushInfo pushInfo) { - push(pushInfo, null, null); + push(pushInfo, null, null, 0); } /** @@ -212,9 +218,9 @@ public final class GitPusher { * option. * Also, at the end results are merged and are shown in a single notification. */ - private void push(@NotNull GitPushInfo pushInfo, @Nullable GitPushResult previousResult, @Nullable UpdateSettings updateSettings) { + private void push(@NotNull GitPushInfo pushInfo, @Nullable GitPushResult previousResult, @Nullable UpdateSettings updateSettings, int attempt) { GitPushResult result = tryPushAndGetResult(pushInfo); - handleResult(pushInfo, result, previousResult, updateSettings); + handleResult(pushInfo, result, previousResult, updateSettings, attempt); } @NotNull @@ -427,7 +433,8 @@ public final class GitPusher { // if in a failed repo, a branch was rejected that had nothing to push, don't notify about the rejection. // Besides all of the above, don't confuse users with 1 repository with all this "repository/root" stuff; // don't confuse users which push only a single branch with all this "branch" stuff. - private void handleResult(@NotNull GitPushInfo pushInfo, @NotNull GitPushResult result, @Nullable GitPushResult previousResult, @Nullable UpdateSettings updateSettings) { + private void handleResult(@NotNull GitPushInfo pushInfo, @NotNull GitPushResult result, @Nullable GitPushResult previousResult, @Nullable UpdateSettings updateSettings, + int pushAttempt) { result.mergeFrom(previousResult); if (result.isEmpty()) { @@ -440,10 +447,13 @@ public final class GitPusher { else { // there were no errors, but there might be some rejected branches on some of the repositories // => for current branch propose to update and re-push it. For others just warn - Map rejectedPushesForCurrentBranch = result.getRejectedPushesForCurrentBranch(); + Map rejectedPushesForCurrentBranch = result.getRejectedPushesFromCurrentBranchToTrackedBranch(pushInfo); - if (!rejectedPushesForCurrentBranch.isEmpty()) { + if (pushAttempt <= MAX_PUSH_ATTEMPTS && !rejectedPushesForCurrentBranch.isEmpty()) { + LOG.info( + String.format("Rejected pushes for current branches: %n%s%nUpdate settings: %s", rejectedPushesForCurrentBranch, updateSettings)); + if (updateSettings == null) { // show dialog only when push is rejected for the first time in a row, otherwise reuse previously chosen update method // and don't show the dialog again if user has chosen not to ask again @@ -464,7 +474,7 @@ public final class GitPusher { if (updateResult) { myProgressIndicator.setText(INDICATOR_TEXT); GitPushInfo newPushInfo = pushInfo.retain(rejectedPushesForCurrentBranch); - push(newPushInfo, adjustedPushResult, updateSettings); + push(newPushInfo, adjustedPushResult, updateSettings, pushAttempt + 1); return; // don't notify - next push will notify all results in compound } } diff --git a/plugins/git4idea/src/git4idea/repo/GitConfig.java b/plugins/git4idea/src/git4idea/repo/GitConfig.java index e106bc5ef83d..830233ff0f76 100644 --- a/plugins/git4idea/src/git4idea/repo/GitConfig.java +++ b/plugins/git4idea/src/git4idea/repo/GitConfig.java @@ -53,7 +53,8 @@ class GitConfig { private static final Pattern REMOTE_SECTION = Pattern.compile("remote \"(.*)\""); private static final Pattern URL_SECTION = Pattern.compile("url \"(.*)\""); - private static final Pattern BRANCH_SECTION = Pattern.compile("branch \"(.*)\""); + private static final Pattern BRANCH_INFO_SECTION = Pattern.compile("branch \"(.*)\""); + private static final Pattern BRANCH_COMMON_PARAMS_SECTION = Pattern.compile("branch"); private final Collection myRemotes; private final Collection myBranchTrackInfos; @@ -109,7 +110,8 @@ class GitConfig { ini.load(configFile); } catch (IOException e) { - throw new GitRepoStateException("Couldn't load .git/config file at " + configFile.getPath(), e); + LOG.error(new GitRepoStateException("Couldn't load .git/config file at " + configFile.getPath(), e)); + return new GitConfig(Collections.emptyList(), Collections.emptyList()); } IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginManager.getPluginByClassName(GitConfig.class.getName())); @@ -156,7 +158,7 @@ class GitConfig { return null; } boolean merge = mergeName != null; - String remoteBranch = (merge ? mergeName : rebaseName); + final String remoteBranch = (merge ? mergeName : rebaseName); GitRemote branchRemote = null; for (GitRemote remote : remotes) { @@ -170,17 +172,22 @@ class GitConfig { return null; } + assert remoteBranch != null; // this is checked in StringUtil.isEmptyOrSpaces return new GitBranchTrackInfo(branchName, branchRemote, remoteBranch, merge); } @Nullable private static BranchConfig parseBranchSection(String sectionName, Profile.Section section, ClassLoader classLoader) { BranchBean branchBean = section.as(BranchBean.class, classLoader); - Matcher matcher = BRANCH_SECTION.matcher(sectionName); + Matcher matcher = BRANCH_INFO_SECTION.matcher(sectionName); if (matcher.matches()) { return new BranchConfig(matcher.group(1), branchBean); } - LOG.error(String.format("Invalid branch section format in .git/config. sectionName: %s section: %s", sectionName, section)); + if (BRANCH_COMMON_PARAMS_SECTION.matcher(sectionName).matches()) { + LOG.debug(String.format("Common branch option(s) defined .git/config. sectionName: %s%n section: %s", sectionName, section)); + return null; + } + LOG.error(String.format("Invalid branch section format in .git/config. sectionName: %s%n section: %s", sectionName, section)); return null; } diff --git a/plugins/git4idea/src/git4idea/ui/GitUIUtil.java b/plugins/git4idea/src/git4idea/ui/GitUIUtil.java index a8a04ac9eeb5..f4c947ebc396 100644 --- a/plugins/git4idea/src/git4idea/ui/GitUIUtil.java +++ b/plugins/git4idea/src/git4idea/ui/GitUIUtil.java @@ -58,13 +58,17 @@ public class GitUIUtil { private GitUIUtil() { } public static void notifyMessages(Project project, @Nullable String title, @Nullable String description, NotificationType type, boolean important, @Nullable Collection messages) { - if (StringUtil.isEmptyOrSpaces(title)) { - title = description; + if (title == null) { + title = ""; } String desc = (description != null ? description.replace("\n", "
") : ""); if (messages != null && !messages.isEmpty()) { desc += "
" + StringUtil.join(messages, "
"); } + if (StringUtil.isEmptyOrSpaces(desc)) { + desc = StringUtil.isEmptyOrSpaces(title) ? "Error" : title; // description is not allowed to be empty, title is => moving title text to description + title = ""; + } NotificationGroup group = important ? GitVcs.IMPORTANT_ERROR_NOTIFICATION : GitVcs.NOTIFICATION_GROUP_ID; group.createNotification(title, desc, type, null).notify(project.isDefault() ? null : project); } diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java index 3918b54e7f3d..10ea5e2df3a4 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java @@ -34,6 +34,7 @@ import git4idea.merge.GitConflictResolver; import git4idea.merge.GitMerger; import git4idea.rebase.GitRebaser; import git4idea.stash.GitChangesSaver; +import git4idea.ui.GitUIUtil; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -242,7 +243,8 @@ public class GitUpdateProcess { if (branch == null) { LOG.info("checkTrackedBranchesConfigured current branch is null"); notifyImportantError(myProject, "Can't update: no current branch", - "You are in 'detached HEAD' state, which means that you're not on any branch.
" + + "You are in 'detached HEAD' state, which means that you're not on any branch" + + rootStringIfNeeded(root) + "Checkout a branch to make update possible."); return false; } @@ -251,15 +253,17 @@ public class GitUpdateProcess { final String branchName = branch.getName(); LOG.info("checkTrackedBranchesConfigured tracked branch is null for current branch " + branch); notifyImportantError(myProject, "Can't update: no tracked branch", - "No tracked branch configured for branch " + branchName + - "
To make your branch track a remote branch call, for example,
" + + "No tracked branch configured for branch " + GitUIUtil.code(branchName) + + rootStringIfNeeded(root) + + "To make your branch track a remote branch call, for example,
" + "git branch --set-upstream " + branchName + " origin/" + branchName + ""); return false; } if (!tracked.exists(root)) { LOG.info("checkTrackedBranchesConfigured tracked branch " + tracked + " doesn't exist."); notifyMessage(myProject, "Can't update: tracked branch doesn't exist.", - "Tracked branch " + tracked.getName() + " doesn't exist, so there is nothing to update.
" + + "Tracked branch " + tracked.getName() + " doesn't exist, so there is nothing to update" + + rootStringIfNeeded(root) + "The branch will be automatically created when you push to it.", NotificationType.WARNING, true, null); return false; @@ -274,6 +278,13 @@ public class GitUpdateProcess { return true; } + private String rootStringIfNeeded(@NotNull VirtualFile root) { + if (myRoots.size() < 2) { + return ".
"; + } + return "
in Git repository " + GitUIUtil.code(root.getPresentableUrl()) + "
"; + } + /** * Check if merge is in progress, propose to resolve conflicts. * @return true if merge is in progress, which means that update can't continue. diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java index 8b38ae20f06e..3bd9e960a01c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.jar.Attributes; +import java.util.regex.Pattern; /** @@ -39,6 +40,8 @@ public class GroovyHotSwapper extends JavaProgramPatcher { private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.debugger.GroovyHotSwapper"); private static final String GROOVY_HOTSWAP_AGENT_PATH = "groovy.hotswap.agent.path"; + private static final Pattern SPRING_LOADED_PATTERN = Pattern.compile("-javaagent:.+springloaded-core-[^/\\\\]+\\.jar"); + private static boolean endsWithAny(String s, List endings) { for (String extension : endings) { if (s.endsWith(extension)) { @@ -64,6 +67,16 @@ public class GroovyHotSwapper extends JavaProgramPatcher { return false; } + private static boolean hasSpringLoadedReloader(JavaParameters javaParameters) { + for (String param : javaParameters.getVMParametersList().getParameters()) { + if (SPRING_LOADED_PATTERN.matcher(param).matches()) { + return true; + } + } + + return false; + } + public void patchJavaParameters(Executor executor, RunProfile configuration, JavaParameters javaParameters) { if (!executor.getId().equals(DefaultDebugExecutor.EXECUTOR_ID)) { return; @@ -72,7 +85,11 @@ public class GroovyHotSwapper extends JavaProgramPatcher { if (!Registry.is("enable.groovy.hotswap")) { return; } - + + if (hasSpringLoadedReloader(javaParameters)) { + return; + } + if (!(configuration instanceof RunConfiguration)) { return; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcProjectViewPane.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcProjectViewPane.java index cd9db60656bb..b8e88faf0ca2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcProjectViewPane.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcProjectViewPane.java @@ -141,10 +141,10 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id final TreeExpander expander = new DefaultTreeExpander(myTree); final CommonActionsManager actionsManager = CommonActionsManager.getInstance(); group.addAction(new ScrollFromSourceAction()); - group.addAction(myAutoScrollFromSourceHandler.createToggleAction()); - group.addAction(myAutoScrollToSourceHandler.createToggleAction()); + group.addAction(myAutoScrollFromSourceHandler.createToggleAction()).setAsSecondary(true); + group.addAction(myAutoScrollToSourceHandler.createToggleAction()).setAsSecondary(true); group.add(actionsManager.createCollapseAllAction(expander, myTree)); - group.addAction(new HideEmptyMiddlePackagesAction()); + group.addAction(new HideEmptyMiddlePackagesAction()).setAsSecondary(true); return ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent(); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/copy/GroovyCopyClassTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/copy/GroovyCopyClassTest.java index f02f6534306a..cc774f8591cb 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/copy/GroovyCopyClassTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/copy/GroovyCopyClassTest.java @@ -59,7 +59,7 @@ public class GroovyCopyClassTest extends LightCodeInsightFixtureTestCase { myFixture.copyFileToProject(testName + ".groovy", "/foo/" + testName + ".groovy"); //would be copied as file - assertTrue( + assertFalse( CopyClassesHandler.canCopyClass(myFixture.getJavaFacade().findClass("foo." + testName, GlobalSearchScope.allScope(getProject())))); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationNotifier.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationNotifier.java index b52507b49238..95edf056f9f5 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationNotifier.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationNotifier.java @@ -156,12 +156,12 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl resultRef = new Ref(); - ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + final Runnable checker = new Runnable() { @Override public void run() { try { @@ -106,11 +108,20 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl { myAuthManager = new SvnAuthenticationManager(myProject, new File(getConfigurationDirectory())); getInteractiveManager(svnVcs); // to init - myAuthManager.setAuthenticationProvider(new SvnAuthenticationProvider(svnVcs, myInteractiveProvider)); + myAuthManager.setAuthenticationProvider(new SvnAuthenticationProvider(svnVcs, myInteractiveProvider, RUNTIME_AUTH_CACHE)); myAuthManager.setRuntimeStorage(RUNTIME_AUTH_CACHE); } return myAuthManager; diff --git a/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/dialogs/SvnAuthenticationProvider.java b/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/dialogs/SvnAuthenticationProvider.java index 23081a7edbb0..a46d4b5bc400 100644 --- a/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/dialogs/SvnAuthenticationProvider.java +++ b/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/dialogs/SvnAuthenticationProvider.java @@ -27,6 +27,7 @@ import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider; import org.tmatesoft.svn.core.auth.SVNAuthentication; import org.tmatesoft.svn.core.auth.SVNUserNameAuthentication; +import org.tmatesoft.svn.core.internal.wc.ISVNAuthenticationStorage; /** * @author alex @@ -36,8 +37,11 @@ public class SvnAuthenticationProvider implements ISVNAuthenticationProvider { private final Project myProject; private final SvnAuthenticationNotifier myAuthenticationNotifier; private final ISVNAuthenticationProvider mySvnInteractiveAuthenticationProvider; + private final ISVNAuthenticationStorage myAuthenticationStorage; - public SvnAuthenticationProvider(final SvnVcs svnVcs, final ISVNAuthenticationProvider provider) { + public SvnAuthenticationProvider(final SvnVcs svnVcs, final ISVNAuthenticationProvider provider, + final ISVNAuthenticationStorage authenticationStorage) { + myAuthenticationStorage = authenticationStorage; myProject = svnVcs.getProject(); myAuthenticationNotifier = svnVcs.getAuthNotifier(); mySvnInteractiveAuthenticationProvider = provider; @@ -64,7 +68,9 @@ public class SvnAuthenticationProvider implements ISVNAuthenticationProvider { // outside-project url return mySvnInteractiveAuthenticationProvider.requestClientAuthentication(kind, url, realm, errorMessage, previousAuth, authMayBeStored); } else { - myAuthenticationNotifier.ensureNotify(obj); + if (myAuthenticationNotifier.ensureNotify(obj)) { + return (SVNAuthentication) myAuthenticationStorage.getData(kind, realm); + } } return null; } diff --git a/plugins/svn4ideaOld/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java b/plugins/svn4ideaOld/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java index fb525e325f21..1fcbf1a4f0f8 100644 --- a/plugins/svn4ideaOld/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java +++ b/plugins/svn4ideaOld/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java @@ -80,7 +80,8 @@ public class SvnAuthenticationTest extends PlatformTestCase { myAuthenticationManager = new SvnAuthenticationManager(myProject, configFile); myInteractiveProvider = new SvnTestInteractiveAuthentication(myAuthenticationManager); - myAuthenticationManager.setAuthenticationProvider(new SvnAuthenticationProvider(vcs, myInteractiveProvider)); + myAuthenticationManager.setAuthenticationProvider(new SvnAuthenticationProvider(vcs, myInteractiveProvider, + SvnConfiguration.RUNTIME_AUTH_CACHE)); myAuthenticationManager.setRuntimeStorage(SvnConfiguration.RUNTIME_AUTH_CACHE); myTestInteraction = new TestInteraction();