Merge commit 'origin/master'

This commit is contained in:
Sascha Weinreuter
2011-12-09 15:53:57 +01:00
82 changed files with 1626 additions and 715 deletions
+3
View File
@@ -143,6 +143,9 @@ private def layoutMac(Map args, String home, Paths paths) {
</array>
"""
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
@@ -102,7 +102,9 @@ public class CompilerUtil {
* @param files
*/
public static void refreshIOFiles(@NotNull final Collection<File> files) {
LocalFileSystem.getInstance().refreshIoFiles(files);
if (!files.isEmpty()) {
LocalFileSystem.getInstance().refreshIoFiles(files);
}
}
public static void refreshIODirectories(@NotNull final Collection<File> 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) {
@@ -274,11 +274,12 @@ public class JavacCompiler extends ExternalCompiler {
}
public static List<String> addAdditionalSettings(List<String> commandLine, JavacSettings javacSettings, boolean isAnnotationProcessing,
JavaSdkVersion version, Project project, final boolean annotationProcessorsEnabled) {
JavaSdkVersion version, Project project, boolean annotationProcessorsEnabled) {
final List<String> additionalOptions = new ArrayList<String>();
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()));
}
@@ -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) {
@@ -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);
@@ -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);
}
}
}
@@ -84,7 +84,7 @@ public class LibrariesLayoutPanel extends ProjectLayoutPanel<LibraryDescriptor>{
}
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) {
@@ -100,7 +100,7 @@ public class ModulesLayoutPanel extends ProjectLayoutPanel<ModuleDescriptor>{
}
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) {
@@ -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<T> 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<T> extends JPanel {
}
});
}
myChooser.selectElements(ContainerUtil.createMaybeSingletonList(ContainerUtil.getFirstItem(files)));
myChooser.addElementsMarkListener(new ElementsChooser.ElementsMarkListener<File>() {
@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<T> 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() {
@@ -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();
}
}
}
@@ -134,6 +134,32 @@ public class GenerateConstructorHandler extends GenerateMembersHandlerBase {
return members;
}
@Override
protected MemberChooser<ClassMember> createMembersChooser(ClassMember[] members,
boolean allowEmptySelection,
boolean copyJavadocCheckbox,
Project project) {
final MemberChooser<ClassMember> chooser = super.createMembersChooser(members, allowEmptySelection, copyJavadocCheckbox, project);
final List<ClassMember> preselection = preselect(members);
if (!preselection.isEmpty()) {
chooser.selectElements(preselection.toArray(new ClassMember[preselection.size()]));
}
return chooser;
}
protected static List<ClassMember> preselect(ClassMember[] members) {
final List<ClassMember> preselection = new ArrayList<ClassMember>();
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<? extends GenerationInfo> generateMemberPrototypes(PsiClass aClass, ClassMember[] members) throws IncorrectOperationException {
List<PsiMethod> baseConstructors = new ArrayList<PsiMethod>();
@@ -183,15 +183,23 @@ public abstract class GenerateMembersHandlerBase implements CodeInsightActionHan
@Nullable
protected ClassMember[] chooseMembers(ClassMember[] members, boolean allowEmptySelection, boolean copyJavadocCheckbox, Project project) {
MemberChooser<ClassMember> chooser = new MemberChooser<ClassMember>(members, allowEmptySelection, true, project);
chooser.setTitle(myChooserTitle);
chooser.setCopyJavadocVisible(copyJavadocCheckbox);
MemberChooser<ClassMember> chooser = createMembersChooser(members, allowEmptySelection, copyJavadocCheckbox, project);
chooser.show();
myToCopyJavaDoc = chooser.isCopyJavadoc();
final List<ClassMember> list = chooser.getSelectedElements();
return list == null ? null : list.toArray(new ClassMember[list.size()]);
}
protected MemberChooser<ClassMember> createMembersChooser(ClassMember[] members,
boolean allowEmptySelection,
boolean copyJavadocCheckbox,
Project project) {
MemberChooser<ClassMember> chooser = new MemberChooser<ClassMember>(members, allowEmptySelection, true, project);
chooser.setTitle(myChooserTitle);
chooser.setCopyJavadocVisible(copyJavadocCheckbox);
return chooser;
}
@NotNull
protected List<? extends GenerationInfo> generateMemberPrototypes(PsiClass aClass, ClassMember[] members) throws IncorrectOperationException {
ArrayList<GenerationInfo> array = new ArrayList<GenerationInfo>();
@@ -91,6 +91,7 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase {
}
continue;
}
if (!(element instanceof PsiFileSystemItem)) return null;
}
fillResultsMap(result, containingFile, topLevelClasses);
if (relativeMap != null) {
@@ -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<Pair<PsiMethod, PsiSubstitutor>> findMethodsAndTheirSubstitutorsByName(@NonNls String name, boolean checkBases) {
return PsiClassImplUtil.findMethodsAndTheirSubstitutorsByName(this, name, checkBases);
}
@Override
@NotNull
public List<Pair<PsiMethod, PsiSubstitutor>> 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<HierarchicalMethodSignature> 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);
}
}
@@ -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<Pair<PsiMethod, PsiSubstitutor>> findMethodsAndTheirSubstitutorsByName(@NonNls String name, boolean checkBases) {
return PsiClassImplUtil.findMethodsAndTheirSubstitutorsByName(this, name, checkBases);
}
@Override
@NotNull
public List<Pair<PsiMethod, PsiSubstitutor>> 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<HierarchicalMethodSignature> 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);
}
}
@@ -26,7 +26,7 @@ public class LightTypeParameter extends LightClass implements PsiTypeParameter {
@Override
public PsiTypeParameter getDelegate() {
return (PsiTypeParameter)myDelegate;
return (PsiTypeParameter)super.getDelegate();
}
@Override
@@ -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;
}
}
@@ -0,0 +1,6 @@
class Test {
private int a;
private final int b;
private int c;
private final int d;
}
@@ -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<ClassMember> 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" +
@@ -314,6 +314,16 @@ public class StubBasedPsiElementBase<T extends StubElement> 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();
@@ -48,22 +48,14 @@ public class LineMarkerInfo<T extends PsiElement> {
private final GutterIconRenderer.Alignment myIconAlignment;
@Nullable private final GutterIconNavigationHandler<T> myNavigationHandler;
public LineMarkerInfo(T element,
public LineMarkerInfo(@NotNull T element,
int startOffset,
Icon icon,
int updatePass,
@Nullable Function<? super T, String> tooltipProvider,
@Nullable GutterIconNavigationHandler<T> navHandler,
GutterIconRenderer.Alignment alignment) {
myIcon = icon;
myTooltipProvider = tooltipProvider;
myIconAlignment = alignment;
elementRef = new WeakReference<T>(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,
@@ -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
@@ -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();
@@ -58,6 +58,7 @@ public class SearchResults implements DocumentListener {
private Set<RangeMarker> myExcluded = new HashSet<RangeMarker>();
private Editor myEditor;
private Project myProject;
private FindModel myFindModel;
private int myMatchesLimit = 100;
@@ -72,8 +73,9 @@ public class SearchResults implements DocumentListener {
private Stack<Pair<FindModel, LiveOccurrence>> myCursorPositions = new Stack<Pair<FindModel, LiveOccurrence>>();
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
@@ -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
@@ -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<Macro, Macro>() {
public Macro convert(Macro macro) {
if (macro instanceof PromptMacro)
return new Macro.Silent(macro, "");
return macro;
}
}));
final Convertor<Macro, Macro> convertor = new Convertor<Macro, Macro>() {
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)
);
}
}
@@ -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) {
@@ -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);
}
@@ -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) {
@@ -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<Processor<Document>> finishRunnables = new SmartList<Processor<Document>>();
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));
}
@@ -417,6 +417,11 @@ public abstract class AbstractInplaceIntroducer<V extends PsiNameIdentifierOwner
highlightManager.addOccurrenceHighlight(editor, startOffset, startOffset + variableNameLength, attributes, 0, highlighters, null);
}
}
for (RangeHighlighter highlighter : highlighters) {
highlighter.setGreedyToLeft(true);
highlighter.setGreedyToRight(true);
}
}
protected void restoreState(final V psiField) {
@@ -669,6 +669,7 @@ public class VariableInplaceRenamer {
});
}
}, RENAME_TITLE, null);
PsiDocumentManager.getInstance(myProject).commitDocument(myEditor.getDocument());
}
private static VirtualFile getTopLevelVirtualFile(final FileViewProvider fileViewProvider) {
@@ -35,7 +35,7 @@ import java.util.Locale;
@SuppressWarnings({"HardCodedStringLiteral"})
public class IndexInfrastructure {
private static final int VERSION = 8;
private static final int VERSION = 9;
private static final TObjectLongHashMap<ID<?, ?>> ourIndexIdToCreationStamp = new TObjectLongHashMap<ID<?, ?>>();
private static final boolean ourUnitTestMode = ApplicationManager.getApplication().isUnitTestMode();
@@ -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<Value> extends UpdatableValueContainer<Value> implements Cloneable{
private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.ValueContainerImpl");
private HashMap<Value, Object> myInputIdMapping;
public ValueContainerImpl() {
@@ -60,17 +63,19 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
@Override
public void removeAssociatedValue(int inputId) {
Value toRemove = null;
final List<Value> toRemove = new ArrayList<Value>(1);
for (final Iterator<Value> 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);
}
}
}
@@ -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()));
}
@@ -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();
}
}
}
@@ -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);
}
}
});
}
@@ -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<IdeaPluginDescriptor> getComparator() {
final Comparator<IdeaPluginDescriptor> comparator = super.getComparator();
return new Comparator<IdeaPluginDescriptor>() {
@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<IdeaPluginDescriptor> comparator = super.getColumnComparator();
return new Comparator<IdeaPluginDescriptor>() {
@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);
}
};
}
}
}
@@ -908,11 +908,26 @@ public class PluginManager {
if (descriptor != null && !descriptor.getOptionalConfigs().isEmpty()) {
final Map<PluginId, IdeaPluginDescriptorImpl> descriptors = new HashMap<PluginId, IdeaPluginDescriptorImpl>(descriptor.getOptionalConfigs().size());
for (Map.Entry<PluginId, String> 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);
}
@@ -165,7 +165,7 @@ class PluginManagerColumnInfo extends ColumnInfo<IdeaPluginDescriptor, String> {
return comparator;
}
private Comparator<IdeaPluginDescriptor> getColumnComparator() {
protected Comparator<IdeaPluginDescriptor> getColumnComparator() {
if (isSortByName()) {
return new Comparator<IdeaPluginDescriptor>() {
public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) {
@@ -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);
@@ -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());
}
}
@@ -44,6 +44,7 @@ public class PluginManagerUISettings implements PersistentStateComponent<Element
public int AVAILABLE_SORT_MODE = 0;
public boolean AVAILABLE_SORT_BY_STATUS = false;
public boolean INSTALLED_SORT_BY_STATUS = false;
public JDOMExternalizableStringList myOutdatedPlugins = new JDOMExternalizableStringList();
public JDOMExternalizableStringList myInstalledPlugins = new JDOMExternalizableStringList();
@@ -15,10 +15,10 @@
*/
package com.intellij.idea;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.ApplicationInfoProvider;
import com.intellij.openapi.diagnostic.IdeaLoggingEvent;
@@ -185,14 +185,8 @@ public class IdeaLogger extends Logger {
private static ApplicationInfoProvider getIdeaInfoProvider() {
return new ApplicationInfoProvider() {
public String getInfo() {
ApplicationImpl application = (ApplicationImpl)ApplicationManager.getApplication();
if (application != null && application.isComponentsCreated()) {
if (application.hasComponent(ApplicationInfo.class)) {
ApplicationInfoEx ideInfo = (ApplicationInfoEx)application.getComponent(ApplicationInfo.class);
return ideInfo.getFullApplicationName() + " " + "Build #" + ideInfo.getBuild().asString();
}
}
return null;
final ApplicationInfoEx info = ApplicationInfoImpl.getShadowInstance();
return info.getFullApplicationName() + " " + "Build #" + info.getBuild().asString();
}
};
}
@@ -15,6 +15,10 @@
*/
package com.intellij.internal.inspector;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.notification.NotificationsManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ToggleAction;
@@ -25,16 +29,20 @@ import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.ColorUIResource;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.InvocationTargetException;
@@ -42,6 +50,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Vector;
/**
* User: spLeaner
@@ -62,6 +71,12 @@ public class UiInspectorAction extends ToggleAction implements DumbAware {
myInspector = new UiInspector();
Toolkit.getDefaultToolkit().addAWTEventListener(myInspector, AWTEvent.MOUSE_EVENT_MASK);
}
UiInspectorNotification[] existing =
NotificationsManager.getNotificationsManager().getNotificationsOfType(UiInspectorNotification.class, null);
if (existing.length == 0) {
Notifications.Bus.notify(new UiInspectorNotification(), null);
}
}
else {
if (myInspector != null) {
@@ -71,41 +86,36 @@ public class UiInspectorAction extends ToggleAction implements DumbAware {
}
}
}
private static class UiInspectorNotification extends Notification {
private UiInspectorNotification() {
super(Notifications.SYSTEM_MESSAGES_GROUP_ID, "UI Inspector", "Control-Alt-Click to view component info!",
NotificationType.INFORMATION);
}
}
private static class InspectorWindow extends JFrame {
private InspectorTable myInspectorTable;
private UiInspector myUiInspector;
private JComponent myComponent;
private boolean myHighlighted = false;
private boolean myHighlighted = true;
private HighlightComponent myHighlightComponent;
private HierarchyTree myHierarchyTree;
private final JPanel myWrapperPanel;
private InspectorWindow(@NotNull final JComponent component, UiInspector uiInspector) throws HeadlessException {
myComponent = component;
myUiInspector = uiInspector;
getRootPane().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setLayout(new BorderLayout());
final String simpleName = component.getClass().getSimpleName();
setTitle(simpleName.length() == 0 ? component.getClass().getName() : simpleName);
JToolBar bar = new JToolBar(JToolBar.HORIZONTAL);
JToolBar bar = new JToolBar(SwingConstants.HORIZONTAL);
bar.setFloatable(false);
bar.add(new AbstractAction("Show parent", IconLoader.getIcon("/nodes/parentsIntroduction.png")) {
public void actionPerformed(ActionEvent e) {
Container parent = component.getParent();
if (parent instanceof JComponent) {
myUiInspector.showInspector((JComponent) parent);
}
}
@Override
public boolean isEnabled() {
return myComponent.getParent() != null;
}
});
bar.add(new AbstractAction("Highlight", IconLoader.getIcon("/toolbar/unknown.png")) {
public void actionPerformed(ActionEvent e) {
myHighlighted = !myHighlighted;
@@ -122,7 +132,7 @@ public class UiInspectorAction extends ToggleAction implements DumbAware {
bar.add(new AbstractAction("Refresh", IconLoader.getIcon("/vcs/refresh.png")) {
public void actionPerformed(ActionEvent e) {
myInspectorTable.refresh();
getCurrentTable().refresh();
}
@Override
@@ -133,9 +143,31 @@ public class UiInspectorAction extends ToggleAction implements DumbAware {
add(bar, BorderLayout.NORTH);
myWrapperPanel = new JPanel(new BorderLayout());
add(new JLabel(component.getClass().getName()), BorderLayout.SOUTH);
myInspectorTable = new InspectorTable(component);
add(myInspectorTable, BorderLayout.CENTER);
myHierarchyTree = new HierarchyTree(component) {
@Override
public void onComponentChanged(Component c) {
highlight(myComponent, true);
switchInfo(c);
if (myHighlighted) highlight(c, false);
}
};
myWrapperPanel.add(myInspectorTable, BorderLayout.CENTER);
JSplitPane splitPane = new JSplitPane();
splitPane.setDividerLocation(0.5);
splitPane.setRightComponent(myWrapperPanel);
JScrollPane pane = new JScrollPane(myHierarchyTree);
splitPane.setLeftComponent(pane);
add(splitPane, BorderLayout.CENTER);
myHierarchyTree.expandPath();
addWindowListener(new WindowAdapter() {
@Override
@@ -157,6 +189,18 @@ public class UiInspectorAction extends ToggleAction implements DumbAware {
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "CLOSE");
}
private InspectorTable getCurrentTable() {
return myInspectorTable;
}
private void switchInfo(Component c) {
myInspectorTable = new InspectorTable(c);
myWrapperPanel.removeAll();
myWrapperPanel.add(myInspectorTable, BorderLayout.CENTER);
myWrapperPanel.revalidate();
myWrapperPanel.repaint();
}
public void close() {
highlight(myComponent, true);
myComponent = null;
@@ -193,7 +237,150 @@ public class UiInspectorAction extends ToggleAction implements DumbAware {
return myComponent;
}
}
private static class ComponentTreeCellRenderer extends JLabel implements TreeCellRenderer {
private ComponentTreeCellRenderer() {
setOpaque(true);
setFont(UIUtil.getLabelFont().deriveFont(11f));
setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3));
}
@Override
public Component getTreeCellRendererComponent(JTree tree,
Object value,
boolean selected,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {
Color foreground = selected ? UIUtil.getTreeSelectionForeground() : UIUtil.getTreeForeground();
Color background = selected ? UIUtil.getTreeSelectionBackground() : null;
if (value instanceof HierarchyTree.ComponentNode) {
HierarchyTree.ComponentNode componentNode = (HierarchyTree.ComponentNode)value;
Component component = componentNode.getOwnComponent();
String name = component.getClass().getSimpleName();
if (name.length() == 0) {
name = component.getClass().getSuperclass().getSimpleName();
}
if (!selected) {
if (!component.isVisible()) {
foreground = Color.GRAY;
} else if (component.getWidth() == 0 || component.getHeight() == 0) {
foreground = new Color(128, 10, 0);
}
if (componentNode.getToSelect() == componentNode.getOwnComponent()) {
background = new Color(31, 128, 8, 58);
}
}
setText(name);
}
setForeground(foreground);
setBackground(background);
return this;
}
}
private abstract static class HierarchyTree extends JTree implements TreeSelectionListener {
private final JComponent myComponent;
private HierarchyTree(JComponent c) {
myComponent = c;
setModel(buildModel(c));
setCellRenderer(new ComponentTreeCellRenderer());
getSelectionModel().addTreeSelectionListener(this);
}
public void expandPath() {
TreeUtil.expandAll(this);
int count = getRowCount();
ComponentNode node = new ComponentNode(myComponent, myComponent.getParent());
for (int i = 0; i < count; i++) {
TreePath row = getPathForRow(i);
if (row.getLastPathComponent().equals(node)) {
setSelectionPath(row);
scrollPathToVisible(getSelectionPath());
break;
}
}
}
@Override
public void valueChanged(TreeSelectionEvent e) {
TreePath path = e.getNewLeadSelectionPath();
Object component = path.getLastPathComponent();
if (component instanceof ComponentNode) {
Component c = ((ComponentNode)component).getOwnComponent();
onComponentChanged(c);
}
}
private static TreeModel buildModel(JComponent c) {
return new DefaultTreeModel(new ComponentNode(c, null));
}
public abstract void onComponentChanged(Component c);
private static class ComponentNode extends DefaultMutableTreeNode {
private final Component myParent;
private final Component myToSelect;
private ComponentNode(Object userObject, Component parent) {
super(userObject);
myParent = parent == null ? SwingUtilities.getWindowAncestor((Component) userObject) : parent;
myToSelect = (Component)userObject;
children = prepareChildren(myToSelect, parent);
}
public Component getOwnComponent() {
return myParent;
}
public Component getToSelect() {
return myToSelect;
}
@Override
public String toString() {
return myParent.getClass().getName();
}
@Override
public boolean equals(Object obj) {
return obj instanceof ComponentNode && ((ComponentNode)obj).getOwnComponent() == getOwnComponent();
}
@SuppressWarnings("UseOfObsoleteCollectionType")
private static Vector prepareChildren(Component toSelect, Component parent) {
Vector<ComponentNode> result = new Vector<ComponentNode>();
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<PropertyBean> myProperties = new ArrayList<PropertyBean>();
public InspectorTableModel(@NotNull final JComponent c) {
public InspectorTableModel(@NotNull final Component c) {
myComponent = c;
fillTable();
}
private void fillTable() {
final Class<? extends JComponent> cls = myComponent.getClass();
final Class<? extends Component> cls = myComponent.getClass();
for (final String methodName: JCOMPONENT_METHODS) {
try {
final Method method = cls.getMethod(methodName);
@@ -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() {
@@ -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() {
@@ -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<VirtualDirectoryImpl> myTarget = new AtomicNotNullLazyValue<VirtualDirectoryImpl>() {
@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<VirtualFile>() {
@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<VirtualFile>() {
@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();
}
}
@@ -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);
@@ -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) {
@@ -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
@@ -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<Location> locations = new ArrayList<Location>(2);
for (VirtualFile file : virtualFiles) {
locations.add(createLocationFor(project, file, lineNumber));
locations.add(createLocationFor(project, file, lineNumber < 1 ? 1 : lineNumber));
}
return locations;
}
@@ -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);
@@ -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);
}
@@ -106,6 +106,7 @@ public class Queue<T> {
public void clear() {
Arrays.fill(myArray, null);
myFirst = myLast = 0;
isWrapped = false;
}
public boolean process(@NotNull Processor<T> processor) {
@@ -127,4 +128,13 @@ public class Queue<T> {
}
return true;
}
@Override
public String toString() {
List<Object> 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) + " ... ]]]";
}
}
@@ -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<PicoContainer> children = new HashSet<PicoContainer>();
private final Map<Object, ComponentAdapter> componentKeyToAdapterCache = new ConcurrentHashMap<Object, ComponentAdapter>();
private final LinkedHashSetWrapper<ComponentAdapter> componentAdapters = new LinkedHashSetWrapper<ComponentAdapter>();
private final AtomicReference<LinkedHashSet<ComponentAdapter>> componentAdapters = new AtomicReference<LinkedHashSet<ComponentAdapter>>(new LinkedHashSet<ComponentAdapter>());
// Keeps track of instantiation order.
private final LinkedHashSetWrapper<ComponentAdapter> orderedComponentAdapters = new LinkedHashSetWrapper<ComponentAdapter>();
private final AtomicReference<LinkedHashSet<ComponentAdapter>> orderedComponentAdapters = new AtomicReference<LinkedHashSet<ComponentAdapter>>(new LinkedHashSet<ComponentAdapter>());
private final Map<String, ComponentAdapter> classNameToAdapter = new ConcurrentHashMap<String, ComponentAdapter>();
private final AtomicReference<FList<ComponentAdapter>> nonAssignableComponentAdapters = new AtomicReference<FList<ComponentAdapter>>(FList.<ComponentAdapter>emptyList());
private final CopyOnWriteArrayList<ComponentAdapter> nonAssignableComponentAdapters = new CopyOnWriteArrayList<ComponentAdapter>();
public DefaultPicoContainer(@NotNull ComponentAdapterFactory componentAdapterFactory, PicoContainer parent) {
this.componentAdapterFactory = componentAdapterFactory;
@@ -50,7 +50,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable
}
public Collection<ComponentAdapter> getComponentAdapters() {
return componentAdapters.getImmutableSet();
return Collections.unmodifiableCollection(componentAdapters.get());
}
public Map<String, ComponentAdapter> getAssignablesCache() {
@@ -59,7 +59,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable
public Collection<ComponentAdapter> 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<ComponentAdapter> oldList = nonAssignableComponentAdapters.get();
FList<ComponentAdapter> 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 <T> void addElement(AtomicReference<LinkedHashSet<T>> collectionHolder, T element) {
do {
LinkedHashSet<T> oldCollection = collectionHolder.get();
if (oldCollection.contains(element)) {
return;
}
LinkedHashSet<T> newCollection = new LinkedHashSet<T>(oldCollection);
newCollection.add(element);
if (collectionHolder.compareAndSet(oldCollection, newCollection)) break;
} while (true);
}
private static <T> void removeElement(AtomicReference<LinkedHashSet<T>> collectionHolder, T element) {
do {
LinkedHashSet<T> oldCollection = collectionHolder.get();
LinkedHashSet<T> newCollection = new LinkedHashSet<T>(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<ComponentAdapter, Object> adapterToInstanceMap = new HashMap<ComponentAdapter, Object>();
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<Object> result = new ArrayList<Object>();
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<T> {
private volatile Set<T> immutableSet;
private final LinkedHashSet<T> synchronizedSet = new LinkedHashSet<T>();
private final ConcurrentHashMap<T, T> concurrentSet = new ConcurrentHashMap<T, T>();
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<T> getImmutableSet() {
Set<T> res = immutableSet;
if (res == null) {
synchronized (synchronizedSet) {
res = immutableSet;
if (res == null) {
res = Collections.unmodifiableSet((Set<T>)synchronizedSet.clone());
immutableSet = res;
}
}
}
return res;
}
}
}
@@ -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);
@@ -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 {
@@ -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);
}
@@ -107,17 +107,27 @@ public abstract class GenericNotifierImpl<T, Key> {
}
}
public void ensureNotify(final T obj) {
public boolean ensureNotify(final T obj) {
final MyNotification<T> notification;
synchronized (myLock) {
final Key key = getKey(obj);
if (myState.containsKey(key)) {
return;
return false;
}
notification = new MyNotification<T>(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) {
@@ -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;
}
}
Binary file not shown.
@@ -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;
}
@@ -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));
}
}
@@ -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<String> 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<String> convertRefsToStrings(@NotNull Collection<Ref> lsRemoteCommandRefs) {
Collection<String> refs = new ArrayList<String>();
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();
@@ -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<RefSpec> myRefSpecs;
Fetch(@NotNull Git git, @NotNull GitHttpCredentialsProvider credentialsProvider, String url, List<RefSpec> refSpecs) {
Fetch(@NotNull Git git, @NotNull GitHttpCredentialsProvider credentialsProvider, @NotNull String url, @NotNull List<RefSpec> 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<RefSpec> refSpecs) {
return StringUtil.join(refSpecs, new Function<RefSpec, String>() {
@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<Ref> 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<Ref> getRefs() {
return myResultRefs == null ? Collections.<Ref>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<Ref> call() throws TransportException, InvalidRemoteException {
try {
Transport transport = Transport.open(myGit.getRepository(), myUrl);
try {
Collection<RefSpec> refSpecs = new ArrayList<RefSpec>(1);
refSpecs.add(new RefSpec("refs/heads/*:refs/remotes/origin/*"));
Collection<Ref> refs;
Map<String, Ref> refmap = new HashMap<String, Ref>();
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);
}
}
}
}
@@ -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<String> remoteBranches = getRemoteBranches((GitDeprecatedRemote)myRemote.getSelectedItem());
for (String branch : remoteBranches) {
myBranchChooser.addElement(branch, false);
}
}
});
}
@NotNull
private Collection<String> 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<String> 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<String> remoteBranches = new ArrayList<String>();
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
*/
@@ -453,7 +453,7 @@ public final class GitBranchOperationsProcessor {
private void displayCompareDialog(List<GitCommit> headToBranch, List<GitCommit> 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 <code>%s</code> and <code>%s</code>",
Messages.showInfoMessage(myProject, String.format("<html>There are no changes between <code>%s</code> and <code>%s</code></html>",
currentBranch, branchName), "No Changes Detected");
} else {
new GitCompareBranchesDialog(myRepository, branchName, headToBranch, branchToHead).show();
@@ -174,7 +174,7 @@ class GitPushResult {
}
@NotNull
Map<GitRepository, GitBranch> getRejectedPushesForCurrentBranch() {
Map<GitRepository, GitBranch> getRejectedPushesFromCurrentBranchToTrackedBranch(GitPushInfo pushInfo) {
final Map<GitRepository, GitBranch> rejectedPushesForCurrentBranch = new HashMap<GitRepository, GitBranch>();
for (Map.Entry<GitRepository, GitPushRepoResult> 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);
}
}
@@ -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<GitRepository, GitBranch> rejectedPushesForCurrentBranch = result.getRejectedPushesForCurrentBranch();
Map<GitRepository, GitBranch> 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
}
}
@@ -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<GitRemote> myRemotes;
private final Collection<GitBranchTrackInfo> 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.<GitRemote>emptyList(), Collections.<GitBranchTrackInfo>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;
}
@@ -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<String> messages) {
if (StringUtil.isEmptyOrSpaces(title)) {
title = description;
if (title == null) {
title = "";
}
String desc = (description != null ? description.replace("\n", "<br/>") : "");
if (messages != null && !messages.isEmpty()) {
desc += "<hr/>" + StringUtil.join(messages, "<br/>");
}
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);
}
@@ -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.<br/>" +
"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 +
"<br/>To make your branch track a remote branch call, for example,<br/>" +
"No tracked branch configured for branch " + GitUIUtil.code(branchName) +
rootStringIfNeeded(root) +
"To make your branch track a remote branch call, for example,<br/>" +
"<code>git branch --set-upstream " + branchName + " origin/" + branchName + "</code>");
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 <code>" + tracked.getName() + "</code> doesn't exist, so there is nothing to update.<br/>" +
"Tracked branch <code>" + tracked.getName() + "</code> 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 ".<br/>";
}
return "<br/>in Git repository " + GitUIUtil.code(root.getPresentableUrl()) + "<br/>";
}
/**
* Check if merge is in progress, propose to resolve conflicts.
* @return true if merge is in progress, which means that update can't continue.
@@ -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<String> 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;
}
@@ -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();
}
@@ -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()))));
}
@@ -156,12 +156,12 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
}
@Override
public void ensureNotify(AuthenticationRequest obj) {
public boolean ensureNotify(AuthenticationRequest obj) {
final SVNURL key = getKey(obj);
myCopiesPassiveResults.remove(key);
/*VcsBalloonProblemNotifier.showOverChangesView(myVcs.getProject(), "You are not authenticated to '" + obj.getRealm() + "'." +
"To login, see pending notifications.", MessageType.ERROR);*/
super.ensureNotify(obj);
return super.ensureNotify(obj);
}
@NotNull
@@ -18,7 +18,9 @@ package org.jetbrains.idea.svn;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
@@ -95,7 +97,7 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
final Ref<Boolean> resultRef = new Ref<Boolean>();
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
final Runnable checker = new Runnable() {
@Override
public void run() {
try {
@@ -106,11 +108,20 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
if (result) {
onStateChangedToSuccess(obj);
}
} finally {
}
finally {
myVerificationInProgress = false;
}
}
});
};
final ApplicationEx application = (ApplicationEx)ApplicationManager.getApplication();
// also do not show auth if thread does not have progress indicator
if (application.holdsReadLock() || application.isDispatchThread() || ! ProgressManager.getInstance().hasProgressIndicator()) {
application.executeOnPooledThread(checker);
} else {
checker.run();
return resultRef.get();
}
return false;
}
@@ -156,12 +167,21 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
}
@Override
public void ensureNotify(AuthenticationRequest obj) {
public boolean ensureNotify(AuthenticationRequest obj) {
final SVNURL key = getKey(obj);
myCopiesPassiveResults.remove(key);
/*VcsBalloonProblemNotifier.showOverChangesView(myVcs.getProject(), "You are not authenticated to '" + obj.getRealm() + "'." +
"To login, see pending notifications.", MessageType.ERROR);*/
super.ensureNotify(obj);
return super.ensureNotify(obj);
}
@Override
protected boolean onFirstNotification(AuthenticationRequest obj) {
if (ProgressManager.getInstance().hasProgressIndicator()) {
return ask(obj, null);
} else {
return false;
}
}
@NotNull
@@ -259,7 +259,7 @@ public class SvnConfiguration implements PersistentStateComponent<Element> {
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;
@@ -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;
}
@@ -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();