mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge commit 'origin/master'
This commit is contained in:
@@ -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) {
|
||||
|
||||
+14
-5
@@ -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()));
|
||||
}
|
||||
|
||||
+7
-3
@@ -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) {
|
||||
|
||||
+2
-1
@@ -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() {
|
||||
|
||||
+22
-11
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+26
@@ -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>();
|
||||
|
||||
+11
-3
@@ -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
|
||||
|
||||
+11
@@ -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;
|
||||
}
|
||||
}
|
||||
+6
@@ -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,
|
||||
|
||||
+9
-3
@@ -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));
|
||||
}
|
||||
|
||||
+5
@@ -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) {
|
||||
|
||||
+1
@@ -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()));
|
||||
}
|
||||
|
||||
+1
-19
@@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+43
-19
@@ -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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
+216
-27
@@ -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);
|
||||
|
||||
+38
-26
@@ -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() {
|
||||
|
||||
+57
-11
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -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);
|
||||
|
||||
+3
-3
@@ -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);
|
||||
|
||||
|
||||
+4
@@ -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 {
|
||||
|
||||
+3
-2
@@ -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) {
|
||||
|
||||
+39
@@ -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.
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;
|
||||
}
|
||||
|
||||
+3
-3
@@ -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();
|
||||
}
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+8
-2
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user