mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git@git.labs.intellij.net:idea/community
This commit is contained in:
@@ -143,7 +143,6 @@ public class DfaUtil {
|
||||
return codeBlock;
|
||||
}
|
||||
|
||||
@Nullable("null means DFA analysis has failed (too complex to analyze)")
|
||||
public static Collection<? extends PsiElement> getPossibleInitializationElements(final PsiElement qualifierExpression) {
|
||||
if (qualifierExpression instanceof PsiMethodCallExpression) {
|
||||
return Collections.singletonList(qualifierExpression);
|
||||
@@ -152,8 +151,7 @@ public class DfaUtil {
|
||||
final PsiElement targetElement = ((PsiReferenceExpression)qualifierExpression).resolve();
|
||||
if (targetElement instanceof PsiVariable) {
|
||||
final Collection<? extends PsiElement> variableValues = getCachedVariableValues((PsiVariable)targetElement, qualifierExpression);
|
||||
if (variableValues == null) return null;
|
||||
if (variableValues.isEmpty() && targetElement instanceof PsiField) {
|
||||
if ((variableValues == null || variableValues.isEmpty())) {
|
||||
return getVariableAssignmentsInFile((PsiVariable)targetElement, false);
|
||||
}
|
||||
return variableValues;
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.ide;
|
||||
import com.intellij.application.options.codeStyle.LanguageCodeStyleSettingsProvider;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.StdLanguages;
|
||||
import com.intellij.psi.codeStyle.CodeStyleCustomizationsConsumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -44,6 +45,17 @@ public class JavaLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSett
|
||||
return GENERAL_CODE_SAMPLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customizeSpacingOptions(CodeStyleCustomizationsConsumer consumer) {
|
||||
consumer.showAllStandardOptions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customizeBlankLinesOptions(CodeStyleCustomizationsConsumer consumer) {
|
||||
consumer.showAllStandardOptions();
|
||||
}
|
||||
|
||||
|
||||
private static final String GENERAL_CODE_SAMPLE = "public class Foo {\n" +
|
||||
" public int[] X = new int[]{1, 3, 5 7, 9, 11};\n" +
|
||||
"\n" +
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.psi.impl.source.tree.Factory;
|
||||
import com.intellij.psi.impl.source.tree.LeafElement;
|
||||
import com.intellij.psi.impl.source.tree.SharedImplUtil;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.javadoc.PsiDocTagValue;
|
||||
import com.intellij.psi.javadoc.PsiDocToken;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
@@ -50,7 +51,9 @@ public class PsiDocParamRef extends CompositePsiElement implements PsiDocTagValu
|
||||
public PsiReference getReference() {
|
||||
PsiReference cachedReference = myCachedReference;
|
||||
if (cachedReference != null) return cachedReference;
|
||||
final PsiDocCommentOwner owner = PsiTreeUtil.getParentOfType(this, PsiDocCommentOwner.class);
|
||||
final PsiDocComment comment = PsiTreeUtil.getParentOfType(this, PsiDocComment.class);
|
||||
if (comment == null) return null;
|
||||
final PsiDocCommentOwner owner = comment.getOwner();
|
||||
if (!(owner instanceof PsiMethod) &&
|
||||
!(owner instanceof PsiClass)) return null;
|
||||
final ASTNode valueToken = findChildByType(JavaDocTokenType.DOC_TAG_VALUE_TOKEN);
|
||||
|
||||
@@ -108,16 +108,16 @@ public interface ASTNode extends UserDataHolder {
|
||||
ASTNode getLastChildNode();
|
||||
|
||||
/**
|
||||
* Returns the previous sibling of this node in the tree.
|
||||
* Returns the next sibling of this node in the tree.
|
||||
*
|
||||
* @return the previous sibling node.
|
||||
* @return the next sibling node.
|
||||
*/
|
||||
ASTNode getTreeNext();
|
||||
|
||||
/**
|
||||
* Returns the next sibling of this node in the tree.
|
||||
* Returns the previous sibling of this node in the tree.
|
||||
*
|
||||
* @return the next sibling node.
|
||||
* @return the previous sibling node.
|
||||
*/
|
||||
ASTNode getTreePrev();
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.psi.codeStyle;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public interface CodeStyleCustomizationsConsumer {
|
||||
void showAllStandardOptions();
|
||||
void showStandardOptions(String... optionNames);
|
||||
void showCustomOption(Class<? extends CustomCodeStyleSettings> settingsClass, String fieldName, String optionName, String groupName);
|
||||
|
||||
String AROUND_OPERATORS = ApplicationBundle.message("group.spaces.around.operators");
|
||||
String BEFORE_PARENTHESES = ApplicationBundle.message("group.spaces.before.parentheses");
|
||||
String BEFORE_LEFT_BRACE = ApplicationBundle.message("group.spaces.before.left.brace");
|
||||
String WITHIN_PARENTHESES = ApplicationBundle.message("group.spaces.within.parentheses");
|
||||
String TERNARY_OPERATOR = ApplicationBundle.message("group.spaces.in.ternary.operator");
|
||||
String TYPE_ARGUMENTS = ApplicationBundle.message("group.spaces.in.type.arguments");
|
||||
String OTHER = ApplicationBundle.message("group.spaces.other");
|
||||
}
|
||||
@@ -44,4 +44,8 @@ public abstract class CodeStyleSettingsProvider {
|
||||
public String getConfigurableDisplayName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean hasSettingsPage() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-5
@@ -208,11 +208,13 @@ public class CodeStyleSchemesConfigurable extends SearchableConfigurable.Parent.
|
||||
myPanels = new ArrayList<CodeStyleConfigurableWrapper>();
|
||||
|
||||
for (final CodeStyleSettingsProvider provider : Extensions.getExtensions(CodeStyleSettingsProvider.EXTENSION_POINT_NAME)) {
|
||||
myPanels.add(new CodeStyleConfigurableWrapper(provider, new CodeStyleSettingsPanelFactory() {
|
||||
public NewCodeStyleSettingsPanel createPanel(final CodeStyleScheme scheme) {
|
||||
return new NewCodeStyleSettingsPanel(provider.createSettingsPage(scheme.getCodeStyleSettings(), ensureModel().getCloneSettings(scheme)));
|
||||
}
|
||||
}));
|
||||
if (provider.hasSettingsPage()) {
|
||||
myPanels.add(new CodeStyleConfigurableWrapper(provider, new CodeStyleSettingsPanelFactory() {
|
||||
public NewCodeStyleSettingsPanel createPanel(final CodeStyleScheme scheme) {
|
||||
return new NewCodeStyleSettingsPanel(provider.createSettingsPage(scheme.getCodeStyleSettings(), ensureModel().getCloneSettings(scheme)));
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return myPanels.toArray(new Configurable[myPanels.size()]);
|
||||
|
||||
+120
-124
@@ -16,34 +16,36 @@
|
||||
package com.intellij.application.options.codeStyle;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleCustomizationsConsumer;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
|
||||
import com.intellij.ui.OptionGroup;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
public class CodeStyleBlankLinesPanel extends MultilanguageCodeStyleAbstractPanel {
|
||||
private JTextField myKeepBlankLinesInDeclarations;
|
||||
private JTextField myKeepBlankLinesInCode;
|
||||
private JTextField myBlankLinesBeforePackage;
|
||||
private JTextField myBlankLinesAfterPackage;
|
||||
private JTextField myBlankLinesBeforeImports;
|
||||
private JTextField myBlankLinesAfterImports;
|
||||
private JTextField myBlankLinesAroundClass;
|
||||
private JTextField myBlankLinesAroundField;
|
||||
private JTextField myBlankLinesAroundMethod;
|
||||
private JTextField myBlankLinesBeforeMethodBody;
|
||||
private JTextField myBlankLinesAroundFieldI;
|
||||
private JTextField myBlankLinesAroundMethodI;
|
||||
private JTextField myBlankLinesAfterClassHeader;
|
||||
private JTextField myKeepBlankLinesBeforeRBrace;
|
||||
public class CodeStyleBlankLinesPanel extends MultilanguageCodeStyleAbstractPanel implements CodeStyleCustomizationsConsumer {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.application.options.codeStyle.CodeStyleBlankLinesPanel");
|
||||
|
||||
private List<IntOption> myOptions = new ArrayList<IntOption>();
|
||||
private Set<String> myAllowedOptions = new HashSet<String>();
|
||||
private boolean myAllOptionsAllowed = false;
|
||||
|
||||
private final JPanel myPanel = new JPanel(new GridBagLayout());
|
||||
|
||||
public CodeStyleBlankLinesPanel(CodeStyleSettings settings) {
|
||||
super(settings);
|
||||
|
||||
for(LanguageCodeStyleSettingsProvider provider: Extensions.getExtensions(LanguageCodeStyleSettingsProvider.EP_NAME)) {
|
||||
provider.customizeBlankLinesOptions(this);
|
||||
}
|
||||
|
||||
myPanel
|
||||
.add(createKeepBlankLinesPanel(),
|
||||
new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 4, 0, 4), 0, 0));
|
||||
@@ -69,38 +71,17 @@ public class CodeStyleBlankLinesPanel extends MultilanguageCodeStyleAbstractPane
|
||||
private JPanel createBlankLinesPanel() {
|
||||
OptionGroup optionGroup = new OptionGroup(ApplicationBundle.message("title.blank.lines"));
|
||||
|
||||
myBlankLinesBeforePackage = createTextField();
|
||||
optionGroup.add(new JLabel(ApplicationBundle.message("editbox.blanklines.before.package.statement")), myBlankLinesBeforePackage);
|
||||
|
||||
myBlankLinesAfterPackage = createTextField();
|
||||
optionGroup.add(new JLabel(ApplicationBundle.message("editbox.blanklines.after.package.statement")), myBlankLinesAfterPackage);
|
||||
|
||||
myBlankLinesBeforeImports = createTextField();
|
||||
optionGroup.add(new JLabel(ApplicationBundle.message("editbox.blanklines.before.imports")), myBlankLinesBeforeImports);
|
||||
|
||||
myBlankLinesAfterImports = createTextField();
|
||||
optionGroup.add(new JLabel(ApplicationBundle.message("editbox.blanklines.after.imports")), myBlankLinesAfterImports);
|
||||
|
||||
myBlankLinesAroundClass = createTextField();
|
||||
optionGroup.add(new JLabel(ApplicationBundle.message("editbox.blanklines.around.class")), myBlankLinesAroundClass);
|
||||
|
||||
myBlankLinesAroundField = createTextField();
|
||||
optionGroup.add(new JLabel(ApplicationBundle.message("editbox.blanklines.around.field")), myBlankLinesAroundField);
|
||||
|
||||
myBlankLinesAroundMethod = createTextField();
|
||||
optionGroup.add(new JLabel(ApplicationBundle.message("editbox.blanklines.around.method")), myBlankLinesAroundMethod);
|
||||
|
||||
myBlankLinesBeforeMethodBody = createTextField();
|
||||
optionGroup.add(new JLabel(ApplicationBundle.message("editbox.blanklines.before.method.body")), myBlankLinesBeforeMethodBody);
|
||||
|
||||
myBlankLinesAroundFieldI = createTextField();
|
||||
optionGroup.add(new JLabel("Around field in interface:"), myBlankLinesAroundFieldI);
|
||||
|
||||
myBlankLinesAroundMethodI = createTextField();
|
||||
optionGroup.add(new JLabel("Around method in interface:"), myBlankLinesAroundMethodI);
|
||||
|
||||
myBlankLinesAfterClassHeader = createTextField();
|
||||
optionGroup.add(new JLabel(ApplicationBundle.message("editbox.blanklines.after.class.header")), myBlankLinesAfterClassHeader);
|
||||
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.before.package.statement"), "BLANK_LINES_BEFORE_PACKAGE");
|
||||
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.after.package.statement"), "BLANK_LINES_AFTER_PACKAGE");
|
||||
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.before.imports"), "BLANK_LINES_BEFORE_IMPORTS");
|
||||
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.after.imports"), "BLANK_LINES_AFTER_IMPORTS");
|
||||
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.around.class"), "BLANK_LINES_AROUND_CLASS");
|
||||
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.around.field"), "BLANK_LINES_AROUND_FIELD");
|
||||
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.around.method"), "BLANK_LINES_AROUND_METHOD");
|
||||
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.before.method.body"), "BLANK_LINES_BEFORE_METHOD_BODY");
|
||||
createOption(optionGroup, "Around field in interface:", "BLANK_LINES_AROUND_FIELD_IN_INTERFACE");
|
||||
createOption(optionGroup, "Around method in interface:", "BLANK_LINES_AROUND_METHOD_IN_INTERFACE");
|
||||
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.after.class.header"), "BLANK_LINES_AFTER_CLASS_HEADER");
|
||||
|
||||
return optionGroup.createPanel();
|
||||
}
|
||||
@@ -108,97 +89,41 @@ public class CodeStyleBlankLinesPanel extends MultilanguageCodeStyleAbstractPane
|
||||
private JPanel createKeepBlankLinesPanel() {
|
||||
OptionGroup optionGroup = new OptionGroup(ApplicationBundle.message("title.keep.blank.lines"));
|
||||
|
||||
myKeepBlankLinesInDeclarations = createTextField();
|
||||
optionGroup.add(new JLabel(ApplicationBundle.message("editbox.keep.blanklines.in.declarations")), myKeepBlankLinesInDeclarations);
|
||||
|
||||
myKeepBlankLinesInCode = createTextField();
|
||||
optionGroup.add(new JLabel(ApplicationBundle.message("editbox.keep.blanklines.in.code")), myKeepBlankLinesInCode);
|
||||
|
||||
myKeepBlankLinesBeforeRBrace = createTextField();
|
||||
optionGroup.add(new JLabel(ApplicationBundle.message("editbox.keep.blanklines.before.rbrace")), myKeepBlankLinesBeforeRBrace);
|
||||
createOption(optionGroup, ApplicationBundle.message("editbox.keep.blanklines.in.declarations"), "KEEP_BLANK_LINES_IN_DECLARATIONS");
|
||||
createOption(optionGroup, ApplicationBundle.message("editbox.keep.blanklines.in.code"), "KEEP_BLANK_LINES_IN_CODE");
|
||||
createOption(optionGroup, ApplicationBundle.message("editbox.keep.blanklines.before.rbrace"), "KEEP_BLANK_LINES_BEFORE_RBRACE");
|
||||
|
||||
return optionGroup.createPanel();
|
||||
}
|
||||
|
||||
protected void resetImpl(final CodeStyleSettings settings) {
|
||||
myKeepBlankLinesInDeclarations.setText(String.valueOf(settings.KEEP_BLANK_LINES_IN_DECLARATIONS));
|
||||
myKeepBlankLinesInCode.setText(String.valueOf(settings.KEEP_BLANK_LINES_IN_CODE));
|
||||
myKeepBlankLinesBeforeRBrace.setText(String.valueOf(settings.KEEP_BLANK_LINES_BEFORE_RBRACE));
|
||||
myBlankLinesBeforePackage.setText(String.valueOf(settings.BLANK_LINES_BEFORE_PACKAGE));
|
||||
myBlankLinesAfterPackage.setText(String.valueOf(settings.BLANK_LINES_AFTER_PACKAGE));
|
||||
myBlankLinesBeforeImports.setText(String.valueOf(settings.BLANK_LINES_BEFORE_IMPORTS));
|
||||
myBlankLinesAfterImports.setText(String.valueOf(settings.BLANK_LINES_AFTER_IMPORTS));
|
||||
myBlankLinesAroundClass.setText(String.valueOf(settings.BLANK_LINES_AROUND_CLASS));
|
||||
myBlankLinesAroundField.setText(String.valueOf(settings.BLANK_LINES_AROUND_FIELD));
|
||||
myBlankLinesAroundMethod.setText(String.valueOf(settings.BLANK_LINES_AROUND_METHOD));
|
||||
myBlankLinesBeforeMethodBody.setText(String.valueOf(settings.BLANK_LINES_BEFORE_METHOD_BODY));
|
||||
myBlankLinesAroundFieldI.setText(String.valueOf(settings.BLANK_LINES_AROUND_FIELD_IN_INTERFACE));
|
||||
myBlankLinesAroundMethodI.setText(String.valueOf(settings.BLANK_LINES_AROUND_METHOD_IN_INTERFACE));
|
||||
myBlankLinesAfterClassHeader.setText(String.valueOf(settings.BLANK_LINES_AFTER_CLASS_HEADER));
|
||||
private void createOption(OptionGroup optionGroup, String label, String fieldName) {
|
||||
if (myAllOptionsAllowed || myAllowedOptions.contains(fieldName)) {
|
||||
IntOption option = new IntOption(CodeStyleSettings.class, fieldName);
|
||||
optionGroup.add(new JLabel(label), option.myTextField);
|
||||
myOptions.add(option);
|
||||
}
|
||||
}
|
||||
|
||||
protected void resetImpl(final CodeStyleSettings settings) {
|
||||
for (IntOption option : myOptions) {
|
||||
option.setValue(option.getFieldValue(settings));
|
||||
}
|
||||
}
|
||||
|
||||
public void apply(CodeStyleSettings settings) {
|
||||
settings.KEEP_BLANK_LINES_IN_DECLARATIONS = getValue(myKeepBlankLinesInDeclarations);
|
||||
settings.KEEP_BLANK_LINES_IN_CODE = getValue(myKeepBlankLinesInCode);
|
||||
settings.KEEP_BLANK_LINES_BEFORE_RBRACE = getValue(myKeepBlankLinesBeforeRBrace);
|
||||
settings.BLANK_LINES_BEFORE_PACKAGE = getValue(myBlankLinesBeforePackage);
|
||||
settings.BLANK_LINES_AFTER_PACKAGE = getValue(myBlankLinesAfterPackage);
|
||||
settings.BLANK_LINES_BEFORE_IMPORTS = getValue(myBlankLinesBeforeImports);
|
||||
settings.BLANK_LINES_AFTER_IMPORTS = getValue(myBlankLinesAfterImports);
|
||||
settings.BLANK_LINES_AROUND_CLASS = getValue(myBlankLinesAroundClass);
|
||||
settings.BLANK_LINES_AROUND_FIELD = getValue(myBlankLinesAroundField);
|
||||
settings.BLANK_LINES_AROUND_METHOD = getValue(myBlankLinesAroundMethod);
|
||||
settings.BLANK_LINES_BEFORE_METHOD_BODY = getValue(myBlankLinesBeforeMethodBody);
|
||||
|
||||
settings.BLANK_LINES_AROUND_FIELD_IN_INTERFACE = getValue(myBlankLinesAroundFieldI);
|
||||
settings.BLANK_LINES_AROUND_METHOD_IN_INTERFACE = getValue(myBlankLinesAroundMethodI);
|
||||
|
||||
settings.BLANK_LINES_AFTER_CLASS_HEADER = getValue(myBlankLinesAfterClassHeader);
|
||||
|
||||
for (IntOption option : myOptions) {
|
||||
option.setFieldValue(settings, option.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isModified(CodeStyleSettings settings) {
|
||||
boolean isModified;
|
||||
isModified = settings.KEEP_BLANK_LINES_IN_DECLARATIONS != getValue(myKeepBlankLinesInDeclarations);
|
||||
isModified |= settings.KEEP_BLANK_LINES_IN_CODE != getValue(myKeepBlankLinesInCode);
|
||||
isModified |= settings.KEEP_BLANK_LINES_BEFORE_RBRACE != getValue(myKeepBlankLinesBeforeRBrace);
|
||||
isModified |= settings.BLANK_LINES_BEFORE_PACKAGE != getValue(myBlankLinesBeforePackage);
|
||||
isModified |= settings.BLANK_LINES_AFTER_PACKAGE != getValue(myBlankLinesAfterPackage);
|
||||
isModified |= settings.BLANK_LINES_BEFORE_IMPORTS != getValue(myBlankLinesBeforeImports);
|
||||
isModified |= settings.BLANK_LINES_AFTER_IMPORTS != getValue(myBlankLinesAfterImports);
|
||||
isModified |= settings.BLANK_LINES_AROUND_CLASS != getValue(myBlankLinesAroundClass);
|
||||
isModified |= settings.BLANK_LINES_AROUND_FIELD != getValue(myBlankLinesAroundField);
|
||||
isModified |= settings.BLANK_LINES_AROUND_METHOD != getValue(myBlankLinesAroundMethod);
|
||||
isModified |= settings.BLANK_LINES_BEFORE_METHOD_BODY != getValue(myBlankLinesBeforeMethodBody);
|
||||
isModified |= settings.BLANK_LINES_AROUND_FIELD_IN_INTERFACE != getValue(myBlankLinesAroundFieldI);
|
||||
isModified |= settings.BLANK_LINES_AROUND_METHOD_IN_INTERFACE != getValue(myBlankLinesAroundMethodI);
|
||||
isModified |= settings.BLANK_LINES_AFTER_CLASS_HEADER != getValue(myBlankLinesAfterClassHeader);
|
||||
return isModified;
|
||||
|
||||
}
|
||||
|
||||
private static int getValue(JTextField textField) {
|
||||
int ret = 0;
|
||||
try {
|
||||
ret = Integer.parseInt(textField.getText());
|
||||
if (ret < 0) {
|
||||
ret = 0;
|
||||
}
|
||||
if (ret > 10) {
|
||||
ret = 10;
|
||||
for (IntOption option : myOptions) {
|
||||
if (option.getFieldValue(settings) != option.getValue()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
//bad number entered
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return false;
|
||||
|
||||
private static JTextField createTextField() {
|
||||
JTextField field = new JTextField(6);
|
||||
field.setMinimumSize(new Dimension(30, field.getMinimumSize().height));
|
||||
return field;
|
||||
}
|
||||
|
||||
protected int getRightMargin() {
|
||||
@@ -212,4 +137,75 @@ public class CodeStyleBlankLinesPanel extends MultilanguageCodeStyleAbstractPane
|
||||
protected void prepareForReformat(final PsiFile psiFile) {
|
||||
//psiFile.putUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY, LanguageLevel.HIGHEST);
|
||||
}
|
||||
|
||||
public void showAllStandardOptions() {
|
||||
myAllOptionsAllowed = true;
|
||||
}
|
||||
|
||||
public void showStandardOptions(String... optionNames) {
|
||||
Collections.addAll(myAllowedOptions, optionNames);
|
||||
}
|
||||
|
||||
public void showCustomOption(Class<? extends CustomCodeStyleSettings> settingsClass,
|
||||
String fieldName,
|
||||
String optionName,
|
||||
String groupName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private static class IntOption {
|
||||
private final JTextField myTextField;
|
||||
private final Field myTarget;
|
||||
|
||||
private IntOption(Class targetClass, String fieldName) {
|
||||
try {
|
||||
myTarget = targetClass.getField(fieldName);
|
||||
}
|
||||
catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
myTextField = new JTextField(6);
|
||||
myTextField.setMinimumSize(new Dimension(30, myTextField.getMinimumSize().height));
|
||||
}
|
||||
|
||||
private int getFieldValue(CodeStyleSettings settings) {
|
||||
try {
|
||||
return myTarget.getInt(settings);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFieldValue(CodeStyleSettings settings, int value) {
|
||||
try {
|
||||
myTarget.setInt(settings, value);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private int getValue() {
|
||||
int ret = 0;
|
||||
try {
|
||||
ret = Integer.parseInt(myTextField.getText());
|
||||
if (ret < 0) {
|
||||
ret = 0;
|
||||
}
|
||||
if (ret > 10) {
|
||||
ret = 10;
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
//bad number entered
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void setValue(int fieldValue) {
|
||||
myTextField.setText(String.valueOf(fieldValue));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+57
-12
@@ -16,13 +16,24 @@
|
||||
package com.intellij.application.options.codeStyle;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
//import com.intellij.openapi.editor.Editor;
|
||||
//import com.intellij.openapi.editor.EditorSettings;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleCustomizationsConsumer;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class CodeStyleSpacesPanel extends OptionTreeWithPreviewPanel implements CodeStyleCustomizationsConsumer {
|
||||
private boolean myShowAllStandardOptions = false;
|
||||
private Set<String> myAllowedOptions;
|
||||
private MultiMap<String, Trinity<Class<? extends CustomCodeStyleSettings>, String, String>> myCustomOptions;
|
||||
|
||||
public class CodeStyleSpacesPanel extends OptionTreeWithPreviewPanel {
|
||||
public CodeStyleSpacesPanel(CodeStyleSettings settings) {
|
||||
super(settings);
|
||||
}
|
||||
@@ -32,15 +43,13 @@ public class CodeStyleSpacesPanel extends OptionTreeWithPreviewPanel {
|
||||
return LanguageCodeStyleSettingsProvider.SettingsType.SPACING_SETTINGS;
|
||||
}
|
||||
|
||||
private static final String AROUND_OPERATORS = ApplicationBundle.message("group.spaces.around.operators");
|
||||
private static final String BEFORE_PARENTHESES = ApplicationBundle.message("group.spaces.before.parentheses");
|
||||
private static final String BEFORE_LEFT_BRACE = ApplicationBundle.message("group.spaces.before.left.brace");
|
||||
private static final String WITHIN_PARENTHESES = ApplicationBundle.message("group.spaces.within.parentheses");
|
||||
private static final String TERNARY_OPERATOR = ApplicationBundle.message("group.spaces.in.ternary.operator");
|
||||
private static final String TYPE_ARGUMENTS = ApplicationBundle.message("group.spaces.in.type.arguments");
|
||||
private static final String OTHER = ApplicationBundle.message("group.spaces.other");
|
||||
|
||||
protected void initTables() {
|
||||
myAllowedOptions = new HashSet<String>();
|
||||
myCustomOptions = new MultiMap<String, Trinity<Class<? extends CustomCodeStyleSettings>, String, String>>();
|
||||
for(LanguageCodeStyleSettingsProvider provider: Extensions.getExtensions(LanguageCodeStyleSettingsProvider.EP_NAME)) {
|
||||
provider.customizeSpacingOptions(this);
|
||||
}
|
||||
|
||||
initBooleanField("SPACE_BEFORE_METHOD_CALL_PARENTHESES", ApplicationBundle.message("checkbox.spaces.method.call.parentheses"), BEFORE_PARENTHESES);
|
||||
initBooleanField("SPACE_BEFORE_METHOD_PARENTHESES", ApplicationBundle.message("checkbox.spaces.method.declaration.parentheses"), BEFORE_PARENTHESES);
|
||||
initBooleanField("SPACE_BEFORE_IF_PARENTHESES", ApplicationBundle.message("checkbox.spaces.if.parentheses"), BEFORE_PARENTHESES);
|
||||
@@ -50,6 +59,7 @@ public class CodeStyleSpacesPanel extends OptionTreeWithPreviewPanel {
|
||||
initBooleanField("SPACE_BEFORE_SWITCH_PARENTHESES", ApplicationBundle.message("checkbox.spaces.switch.parentheses"), BEFORE_PARENTHESES);
|
||||
initBooleanField("SPACE_BEFORE_SYNCHRONIZED_PARENTHESES", ApplicationBundle.message("checkbox.spaces.synchronized.parentheses"), BEFORE_PARENTHESES);
|
||||
initBooleanField("SPACE_BEFORE_ANOTATION_PARAMETER_LIST", ApplicationBundle.message("checkbox.spaces.annotation.parameters"), BEFORE_PARENTHESES);
|
||||
initCustomOptions(BEFORE_PARENTHESES);
|
||||
|
||||
initBooleanField("SPACE_AROUND_ASSIGNMENT_OPERATORS", ApplicationBundle.message("checkbox.spaces.assignment.operators"), AROUND_OPERATORS);
|
||||
initBooleanField("SPACE_AROUND_LOGICAL_OPERATORS", ApplicationBundle.message("checkbox.spaces.logical.operators"), AROUND_OPERATORS);
|
||||
@@ -59,6 +69,7 @@ public class CodeStyleSpacesPanel extends OptionTreeWithPreviewPanel {
|
||||
initBooleanField("SPACE_AROUND_ADDITIVE_OPERATORS", ApplicationBundle.message("checkbox.spaces.additive.operators"), AROUND_OPERATORS);
|
||||
initBooleanField("SPACE_AROUND_MULTIPLICATIVE_OPERATORS", ApplicationBundle.message("checkbox.spaces.multiplicative.operators"), AROUND_OPERATORS);
|
||||
initBooleanField("SPACE_AROUND_SHIFT_OPERATORS", ApplicationBundle.message("checkbox.spaces.shift.operators"), AROUND_OPERATORS);
|
||||
initCustomOptions(AROUND_OPERATORS);
|
||||
|
||||
initBooleanField("SPACE_BEFORE_CLASS_LBRACE", ApplicationBundle.message("checkbox.spaces.class.left.brace"), BEFORE_LEFT_BRACE);
|
||||
initBooleanField("SPACE_BEFORE_METHOD_LBRACE", ApplicationBundle.message("checkbox.spaces.method.left.brace"), BEFORE_LEFT_BRACE);
|
||||
@@ -73,6 +84,7 @@ public class CodeStyleSpacesPanel extends OptionTreeWithPreviewPanel {
|
||||
initBooleanField("SPACE_BEFORE_FINALLY_LBRACE", ApplicationBundle.message("checkbox.spaces.finally.left.brace"), BEFORE_LEFT_BRACE);
|
||||
initBooleanField("SPACE_BEFORE_SYNCHRONIZED_LBRACE", ApplicationBundle.message("checkbox.spaces.synchronized.left.brace"), BEFORE_LEFT_BRACE);
|
||||
initBooleanField("SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE", ApplicationBundle.message("checkbox.spaces.array.initializer.left.brace"), BEFORE_LEFT_BRACE);
|
||||
initCustomOptions(BEFORE_LEFT_BRACE);
|
||||
|
||||
initBooleanField("SPACE_WITHIN_PARENTHESES", ApplicationBundle.message("checkbox.spaces.parentheses"), WITHIN_PARENTHESES);
|
||||
initBooleanField("SPACE_WITHIN_METHOD_CALL_PARENTHESES", ApplicationBundle.message("checkbox.spaces.checkbox.spaces.method.call.parentheses"), WITHIN_PARENTHESES);
|
||||
@@ -85,15 +97,18 @@ public class CodeStyleSpacesPanel extends OptionTreeWithPreviewPanel {
|
||||
initBooleanField("SPACE_WITHIN_SYNCHRONIZED_PARENTHESES", ApplicationBundle.message("checkbox.spaces.synchronized.parentheses"), WITHIN_PARENTHESES);
|
||||
initBooleanField("SPACE_WITHIN_CAST_PARENTHESES", ApplicationBundle.message("checkbox.spaces.type.cast.parentheses"), WITHIN_PARENTHESES);
|
||||
initBooleanField("SPACE_WITHIN_ANNOTATION_PARENTHESES", ApplicationBundle.message("checkbox.spaces.annotation.parentheses"), WITHIN_PARENTHESES);
|
||||
initCustomOptions(WITHIN_PARENTHESES);
|
||||
|
||||
initBooleanField("SPACE_BEFORE_QUEST", ApplicationBundle.message("checkbox.spaces.before.question"), TERNARY_OPERATOR);
|
||||
initBooleanField("SPACE_AFTER_QUEST", ApplicationBundle.message("checkbox.spaces.after.question"), TERNARY_OPERATOR);
|
||||
initBooleanField("SPACE_BEFORE_COLON", ApplicationBundle.message("checkbox.spaces.before.colon"), TERNARY_OPERATOR);
|
||||
initBooleanField("SPACE_AFTER_COLON", ApplicationBundle.message("checkbox.spaces.after.colon"), TERNARY_OPERATOR);
|
||||
initCustomOptions(TERNARY_OPERATOR);
|
||||
|
||||
initBooleanField("SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS", ApplicationBundle.message("checkbox.spaces.after.comma"), TYPE_ARGUMENTS);
|
||||
initCustomOptions(TYPE_ARGUMENTS);
|
||||
|
||||
initBooleanField("SPACE_AFTER_LABEL", ApplicationBundle.message("checkbox.spaces.after.colon.in.label.declaration"), OTHER);
|
||||
//TODO looks like this option is never implemented: initBooleanField("SPACE_AFTER_LABEL", ApplicationBundle.message("checkbox.spaces.after.colon.in.label.declaration"), OTHER);
|
||||
initBooleanField("SPACE_WITHIN_BRACKETS", ApplicationBundle.message("checkbox.spaces.within.brackets"), OTHER);
|
||||
initBooleanField("SPACE_WITHIN_ARRAY_INITIALIZER_BRACES", ApplicationBundle.message("checkbox.spaces.within.array.initializer.braces"), OTHER);
|
||||
initBooleanField("SPACE_AFTER_COMMA", ApplicationBundle.message("checkbox.spaces.after.comma"), OTHER);
|
||||
@@ -102,6 +117,13 @@ public class CodeStyleSpacesPanel extends OptionTreeWithPreviewPanel {
|
||||
initBooleanField("SPACE_BEFORE_SEMICOLON", ApplicationBundle.message("checkbox.spaces.before.semicolon"), OTHER);
|
||||
initBooleanField("SPACE_AFTER_TYPE_CAST", ApplicationBundle.message("checkbox.spaces.after.type.cast"), OTHER);
|
||||
initBooleanField("SPACE_AFTER_UNARY_OPERATOR", ApplicationBundle.message("checkbox.spaces.after.unary.operator"), OTHER);
|
||||
initCustomOptions(OTHER);
|
||||
}
|
||||
|
||||
private void initCustomOptions(String groupName) {
|
||||
for(Trinity<Class<? extends CustomCodeStyleSettings>, String, String> option: myCustomOptions.get(groupName)) {
|
||||
initCustomBooleanField(option.first, option.second, option.third, groupName);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -117,7 +139,30 @@ public class CodeStyleSpacesPanel extends OptionTreeWithPreviewPanel {
|
||||
}
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected void initBooleanField(@NonNls String fieldName, String cbName, String groupName) {
|
||||
if (myShowAllStandardOptions || myAllowedOptions.contains(fieldName)) {
|
||||
super.initBooleanField(fieldName, cbName, groupName);
|
||||
}
|
||||
}
|
||||
|
||||
public JComponent getPanel() {
|
||||
return getInternalPanel();
|
||||
}
|
||||
|
||||
public void showAllStandardOptions() {
|
||||
myShowAllStandardOptions = true;
|
||||
}
|
||||
|
||||
public void showStandardOptions(String... optionNames) {
|
||||
Collections.addAll(myAllowedOptions, optionNames);
|
||||
}
|
||||
|
||||
public void showCustomOption(Class<? extends CustomCodeStyleSettings> settingsClass,
|
||||
String fieldName,
|
||||
String optionName,
|
||||
String groupName) {
|
||||
myCustomOptions.putValue(groupName,
|
||||
Trinity.<Class<? extends CustomCodeStyleSettings>, String, String>create(settingsClass, fieldName, optionName));
|
||||
}
|
||||
}
|
||||
|
||||
+7
@@ -18,6 +18,7 @@ package com.intellij.application.options.codeStyle;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.psi.codeStyle.CodeStyleCustomizationsConsumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -41,6 +42,12 @@ public abstract class LanguageCodeStyleSettingsProvider {
|
||||
|
||||
public abstract String getCodeSample(@NotNull SettingsType settingsType);
|
||||
|
||||
public void customizeSpacingOptions(CodeStyleCustomizationsConsumer consumer) {
|
||||
}
|
||||
|
||||
public void customizeBlankLinesOptions(CodeStyleCustomizationsConsumer consumer) {
|
||||
}
|
||||
|
||||
public static Language[] getLanguagesWithCodeStyleSettings() {
|
||||
ArrayList<Language> langs = new ArrayList<Language>();
|
||||
for (LanguageCodeStyleSettingsProvider provider : Extensions.getExtensions(EP_NAME)) {
|
||||
|
||||
+70
-26
@@ -18,11 +18,12 @@ package com.intellij.application.options.codeStyle;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.*;
|
||||
@@ -40,7 +41,6 @@ import java.util.ArrayList;
|
||||
public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleAbstractPanel {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.application.options.CodeStyleSpacesPanel");
|
||||
private final JTree myOptionsTree;
|
||||
private final HashMap<BooleanOptionKey, Field> myKeyToFieldMap = new HashMap<BooleanOptionKey, Field>();
|
||||
private final ArrayList<BooleanOptionKey> myKeys = new ArrayList<BooleanOptionKey>();
|
||||
private final JPanel myPanel = new JPanel(new GridBagLayout());
|
||||
|
||||
@@ -144,7 +144,7 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
|
||||
resetNode(root, settings);
|
||||
}
|
||||
|
||||
private void resetNode(TreeNode node, final CodeStyleSettings settings) {
|
||||
private static void resetNode(TreeNode node, final CodeStyleSettings settings) {
|
||||
if (node instanceof MyToggleTreeNode) {
|
||||
resetMyTreeNode((MyToggleTreeNode)node, settings);
|
||||
return;
|
||||
@@ -155,11 +155,10 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
|
||||
}
|
||||
}
|
||||
|
||||
private void resetMyTreeNode(MyToggleTreeNode childNode, final CodeStyleSettings settings) {
|
||||
private static void resetMyTreeNode(MyToggleTreeNode childNode, final CodeStyleSettings settings) {
|
||||
try {
|
||||
BooleanOptionKey key = (BooleanOptionKey)childNode.getKey();
|
||||
Field field = myKeyToFieldMap.get(key);
|
||||
childNode.setSelected(field.getBoolean(settings));
|
||||
childNode.setSelected(key.getValue(settings));
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
LOG.error(e);
|
||||
@@ -175,7 +174,7 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
|
||||
applyNode(root, settings);
|
||||
}
|
||||
|
||||
private void applyNode(TreeNode node, final CodeStyleSettings settings) {
|
||||
private static void applyNode(TreeNode node, final CodeStyleSettings settings) {
|
||||
if (node instanceof MyToggleTreeNode) {
|
||||
applyToggleNode((MyToggleTreeNode)node, settings);
|
||||
return;
|
||||
@@ -186,18 +185,9 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
|
||||
}
|
||||
}
|
||||
|
||||
private void applyToggleNode(MyToggleTreeNode childNode, final CodeStyleSettings settings) {
|
||||
try {
|
||||
BooleanOptionKey key = (BooleanOptionKey)childNode.getKey();
|
||||
Field field = myKeyToFieldMap.get(key);
|
||||
field.set(settings, childNode.isSelected() ? Boolean.TRUE : Boolean.FALSE);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
private static void applyToggleNode(MyToggleTreeNode childNode, final CodeStyleSettings settings) {
|
||||
BooleanOptionKey key = (BooleanOptionKey)childNode.getKey();
|
||||
key.setValue(settings, childNode.isSelected() ? Boolean.TRUE : Boolean.FALSE);
|
||||
}
|
||||
|
||||
public boolean isModified(CodeStyleSettings settings) {
|
||||
@@ -210,7 +200,7 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
|
||||
|
||||
}
|
||||
|
||||
private boolean isModified(TreeNode node, final CodeStyleSettings settings) {
|
||||
private static boolean isModified(TreeNode node, final CodeStyleSettings settings) {
|
||||
if (node instanceof MyToggleTreeNode) {
|
||||
if (isToggleNodeModified((MyToggleTreeNode)node, settings)) {
|
||||
return true;
|
||||
@@ -225,11 +215,10 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isToggleNodeModified(MyToggleTreeNode childNode, final CodeStyleSettings settings) {
|
||||
private static boolean isToggleNodeModified(MyToggleTreeNode childNode, final CodeStyleSettings settings) {
|
||||
try {
|
||||
BooleanOptionKey key = (BooleanOptionKey)childNode.getKey();
|
||||
Field field = myKeyToFieldMap.get(key);
|
||||
return childNode.isSelected() != field.getBoolean(settings);
|
||||
return childNode.isSelected() != key.getValue(settings);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
LOG.error(e);
|
||||
@@ -244,13 +233,27 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
|
||||
try {
|
||||
Class styleSettingsClass = CodeStyleSettings.class;
|
||||
Field field = styleSettingsClass.getField(fieldName);
|
||||
BooleanOptionKey key = new BooleanOptionKey(groupName, cbName);
|
||||
myKeyToFieldMap.put(key, field);
|
||||
BooleanOptionKey key = new BooleanOptionKey(groupName, cbName, field);
|
||||
myKeys.add(key);
|
||||
}
|
||||
catch (NoSuchFieldException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
catch (SecurityException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected <T extends CustomCodeStyleSettings> void initCustomBooleanField(@NotNull Class<T> customClass, String fieldName, String cbName, String groupName) {
|
||||
try {
|
||||
Field field = customClass.getField(fieldName);
|
||||
myKeys.add(new CustomBooleanOptionKey(groupName, cbName, customClass, field));
|
||||
}
|
||||
catch (NoSuchFieldException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
catch (SecurityException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,10 +362,12 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
|
||||
private static class BooleanOptionKey {
|
||||
final String groupName;
|
||||
final String cbName;
|
||||
final Field field;
|
||||
|
||||
public BooleanOptionKey(String groupName, String cbName) {
|
||||
public BooleanOptionKey(String groupName, String cbName, Field field) {
|
||||
this.groupName = groupName;
|
||||
this.cbName = cbName;
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
@@ -374,6 +379,45 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
|
||||
public int hashCode() {
|
||||
return cbName.hashCode();
|
||||
}
|
||||
|
||||
public void setValue(CodeStyleSettings settings, Boolean aBoolean) {
|
||||
try {
|
||||
field.set(settings, aBoolean);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getValue(CodeStyleSettings settings) throws IllegalAccessException {
|
||||
return field.getBoolean(settings);
|
||||
}
|
||||
}
|
||||
|
||||
private static class CustomBooleanOptionKey<T extends CustomCodeStyleSettings> extends BooleanOptionKey {
|
||||
private final Class<T> mySettingsClass;
|
||||
|
||||
public CustomBooleanOptionKey(String groupName, String cbName, Class<T> settingsClass, Field field) {
|
||||
super(groupName, cbName, field);
|
||||
mySettingsClass = settingsClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(CodeStyleSettings settings, Boolean aBoolean) {
|
||||
final CustomCodeStyleSettings customSettings = settings.getCustomSettings(mySettingsClass);
|
||||
try {
|
||||
field.set(customSettings, aBoolean);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getValue(CodeStyleSettings settings) throws IllegalAccessException {
|
||||
final CustomCodeStyleSettings customSettings = settings.getCustomSettings(mySettingsClass);
|
||||
return field.getBoolean(customSettings);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyToggleTreeNode extends DefaultMutableTreeNode {
|
||||
|
||||
@@ -222,11 +222,6 @@ public class CustomTemplateCallback {
|
||||
myBuilder.insertText(offset, text);
|
||||
}
|
||||
|
||||
public void insertNewLine() {
|
||||
myBuilder.insertText(myOffset, "\n");
|
||||
myOffset++;
|
||||
}
|
||||
|
||||
public boolean newLineBefore() {
|
||||
int i = myOffset - 1;
|
||||
CharSequence text = myBuilder.getText();
|
||||
|
||||
@@ -47,6 +47,10 @@ public class CollectionFactory {
|
||||
return new ArrayList<T>();
|
||||
}
|
||||
|
||||
public static <T> HashSet<T> hashSet() {
|
||||
return new HashSet<T>();
|
||||
}
|
||||
|
||||
public static <T, V> LinkedHashMap<T, V> linkedMap() {
|
||||
return new LinkedHashMap<T,V>();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.openapi.vcs;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@Target({ElementType.METHOD})
|
||||
public @interface CalledInAny {
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.openapi.vcs;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
// competes to calculate The Result
|
||||
public class ConcurrentTasks<T> {
|
||||
private volatile boolean myResultKnown;
|
||||
private final Semaphore mySemaphore;
|
||||
private volatile T myResult;
|
||||
private volatile int myCntAlive;
|
||||
private final ProgressIndicator myParentIndicator;
|
||||
private final Consumer<Consumer<T>>[] myTasks;
|
||||
|
||||
public void compute() {
|
||||
final EmptyProgressIndicator pi = new EmptyProgressIndicator() {
|
||||
@Override
|
||||
public void checkCanceled() {
|
||||
if (myResultKnown || (myParentIndicator != null) && myParentIndicator.isCanceled()) {
|
||||
super.cancel();
|
||||
}
|
||||
super.checkCanceled();
|
||||
}
|
||||
};
|
||||
myCntAlive = myTasks.length;
|
||||
mySemaphore.down();
|
||||
|
||||
final List<Future<?>> futures = new LinkedList<Future<?>>();
|
||||
for (final Consumer<Consumer<T>> task : myTasks) {
|
||||
if (myResultKnown) break;
|
||||
final Runnable computableProxy = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
task.consume(new Consumer<T>() {
|
||||
public void consume(T t) {
|
||||
myResult = t;
|
||||
myResultKnown = true;
|
||||
-- myCntAlive;
|
||||
mySemaphore.up();
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
-- myCntAlive;
|
||||
if (myCntAlive == 0) {
|
||||
mySemaphore.up();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
final Future<?> future = ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
|
||||
public void run() {
|
||||
ProgressManager.getInstance().runProcess(computableProxy, pi);
|
||||
}
|
||||
});
|
||||
futures.add(future);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
mySemaphore.waitFor(1000);
|
||||
if (myResultKnown) break;
|
||||
pi.checkCanceled();
|
||||
}
|
||||
// in it possible to even interrupt() threads involved, but at the moment it's better for tasks themselves to check cancel status
|
||||
for (Future<?> future : futures) {
|
||||
if ((! future.isCancelled() && (! future.isDone()))) {
|
||||
future.cancel(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isResultKnown() {
|
||||
return myResultKnown;
|
||||
}
|
||||
|
||||
public T getResult() {
|
||||
return myResult;
|
||||
}
|
||||
|
||||
public ConcurrentTasks(final ProgressIndicator parentIndicator, final Consumer<Consumer<T>>... tasks) {
|
||||
myParentIndicator = parentIndicator;
|
||||
myTasks = tasks;
|
||||
mySemaphore = new Semaphore();
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.openapi.vcs.changes.committed;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class RunBackgroundable {
|
||||
private RunBackgroundable() {
|
||||
}
|
||||
|
||||
public static void run(@NotNull final Task task) {
|
||||
final ProgressManager pm = ProgressManager.getInstance();
|
||||
if (ApplicationManager.getApplication().isDispatchThread()) {
|
||||
pm.run(task);
|
||||
} else {
|
||||
task.run(pm.getProgressIndicator());
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -5,5 +5,5 @@ This inspection reports on any access to a <b><font color="#000080">static</font
|
||||
of any non-threadsafe type specified below, which is accessed from an instance field or a
|
||||
non-synchronized block. It is possible that the static field is accessed from
|
||||
multiple threads, which can lead to unspecified side effects.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -4,5 +4,5 @@
|
||||
This inspection reports any calls to JUnit's <b><font color="#000080">assertEquals()</font></b>
|
||||
method where the expected result and actual result arguments are of incompatible
|
||||
types. While such a call might theoretically be useful, most likely it represents a bug.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -2,5 +2,5 @@
|
||||
<body><table> <tr> <td valign="top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This global inspection reports any boolean fields which are always negated when read.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -5,5 +5,5 @@ This inspection reports any <b><font color="#000080">catch</font></b> block wher
|
||||
the caught exception is immediately rethrown, without performing any action on it.
|
||||
Such <b><font color="#000080">catch</font></b> blocks are unnecessary or lack error
|
||||
handling.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -8,5 +8,5 @@ classes are reported by this inspection.
|
||||
<p>
|
||||
Use the field below to specify the maximum number of dependencies a class may have
|
||||
before triggering this inspection
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -9,5 +9,5 @@ Only top-level classes are reported by this inspection.
|
||||
Use the field below to specify the maximum number of dependents a class may have before
|
||||
triggering this inspection
|
||||
</p>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -9,5 +9,5 @@ Only top-level classes are reported by this inspection.
|
||||
Use the field below to specify the maximum number of direct or indirect dependencies
|
||||
a class may have before triggering this inspection
|
||||
</p>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -9,5 +9,5 @@ are reported by this inspection.
|
||||
Use the field below to specify the maximum number of direct or indirect dependents
|
||||
a class may have before triggering this inspection
|
||||
</p>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -10,5 +10,5 @@ methods of <b><font color="#000080">java.net.URL</font></b>.
|
||||
<b><font color="#000080">java.net.URL</font></b>'s equals and hashCode method use a DNS
|
||||
lookup, which depending on the availability of the network and the speed of the DNS server
|
||||
can cause significant delays.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -4,5 +4,5 @@
|
||||
This inspection reports any parameters of <b><font color="#000080">java.util.Comparator.compare()</font></b>
|
||||
which are not used. Most likely this is the result of a typing mistake and one parameter is compared
|
||||
with itself or the method is not implemented correctly.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -3,5 +3,5 @@
|
||||
<font face="verdana" size="-1">
|
||||
This global inspection reports any classes which are mutually or cyclically dependent on
|
||||
other classes. Such cyclic dependencies make for fragile code and high maintenance costs.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -3,5 +3,5 @@
|
||||
<font face="verdana" size="-1">
|
||||
This global inspection reports any packages which are mutually or cyclically dependent
|
||||
on other packages. Such cyclic dependencies make for fragile code and high maintenance costs.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -5,5 +5,5 @@ This inspection reports instances of <b><font color="#000080">Enumeration</font>
|
||||
used, which can be replaced equivalent <b><font color="#000080">Iterator</font></b>
|
||||
constructs. <b><font color="#000080">Iterator</font></b>s are part of the Java
|
||||
Collection Framework, which has been available since Java 1.2.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -8,5 +8,5 @@ problems because those methods uses a DNS lookup
|
||||
to determine the equality of two <b><font color="#000080">java.net.URL</font></b> objects.
|
||||
Depending on the availability of the network and the speed of the DNS server, this can cause
|
||||
significant delays.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -2,5 +2,5 @@
|
||||
<body><table> <tr> <td valign="top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This global inspection reports any instance fields which can be moved to a subclass.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -5,5 +5,5 @@ This inspection reports any arrays used in <b><font color="#000080">String</font
|
||||
concatenations or as parameters to <b><font color="#000080">java.io.PrintStream</font></b>
|
||||
methods (such as <b><font color="#000080">System.out.println()</font></b>). Usually in such
|
||||
a case, the contents of the array were meant to be used and the not array object itself.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -3,5 +3,5 @@
|
||||
<font face="verdana" size="-1">This inspection reports any Law of Demeter violations.
|
||||
See here <a href="http://en.wikipedia.org/wiki/Law_of_Demeter">http://en.wikipedia.org/wiki/Law_of_Demeter</a>
|
||||
for an explanation what the Law of Demeter is.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -4,5 +4,5 @@
|
||||
This inspection reports any <b><font color="#000080">List.indexOf()</font></b>
|
||||
expressions which can be replaced with the method
|
||||
<b><font color="#000080">List.contains()</font></b>.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -11,5 +11,5 @@ in a <b><font color="#000080">while</font></b> or <b><font color="#000080">for</
|
||||
loops and the last or only statement in a <b><font color="#000080">do-while</font></b> loop.
|
||||
Such a loop would be clearer if the if statement was removed and its condition
|
||||
was made an explicit loop condition.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -5,5 +5,5 @@ is added individually using a for loop. Such constructs may be replaced by a cal
|
||||
<b><font color="#000080">Collection.addAll(Arrays.asList())</font></b>.
|
||||
<br>
|
||||
This inspection provides a quick fix.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -8,5 +8,5 @@ equal to <b><font color="#000080">this</font></b> for instance methods
|
||||
or ClassName.<b><font color="#000080">class</font></b> for static methods. In
|
||||
such cases the synchronized statements may be replaced by their contents and the
|
||||
containing method marked <b><font color="#000080">synchronized</font></b>.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -2,5 +2,5 @@
|
||||
<body><table> <tr> <td valign="top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This global inspection reports methods which only ever return a constant.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -6,5 +6,5 @@ indicate an overly fragmented design.
|
||||
<p>
|
||||
Use the field below to specify the minimum number of classes a module may have before triggering this inspection.
|
||||
</p>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -6,5 +6,5 @@ indicate a lack of design clarity.
|
||||
<p>
|
||||
Use the field below to specify the maximum number of classes a module may have before triggering this inspection.
|
||||
</p>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -6,5 +6,5 @@ and <b><font color="#000080">new StringBuilder()</font></b> calls with an argume
|
||||
with type <b><font color="#000080">char</font></b>. Such an argument is silently
|
||||
casted to an interger used to specify the length of the buffer. Usually this is
|
||||
not what was intended.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -5,5 +5,5 @@ This inspection reports any use of <b><font color="#000080">==</font></b> to tes
|
||||
rather than the <b><font color="#000080">".equals()"</font></b> method. With auto-boxing it is easy
|
||||
to make the mistake of comparing two Integer (or other subclass of java.lang.Number) objects instead
|
||||
of two ints.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -2,5 +2,5 @@
|
||||
<body><table> <tr> <td valign="top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This global inspection reports any packages which are present in multiple modules.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -6,5 +6,5 @@ indicate an overly fragmented design.
|
||||
<p>
|
||||
Use the field below to specify the minimum number of classes a package may have before triggering this inspection.
|
||||
</p>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -6,5 +6,5 @@ indicate a lack of design clarity.
|
||||
<p>
|
||||
Use the field below to specify the maximum number of classes a package may have before triggering this inspection.
|
||||
</p>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -5,5 +5,5 @@ This inspection reports any instances of constructors with too many parameters.
|
||||
with too many parameters can be a good sign that refactoring is necessary.
|
||||
<p>
|
||||
Use the field provided below to specify the maximum acceptable number of parameters a constructor might have.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -3,5 +3,5 @@
|
||||
<font face="verdana" size="-1">
|
||||
This global inspection reports any static fields wich are only used in a differenc class than the one they
|
||||
are defined in. Such fields can be moved.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -4,5 +4,5 @@
|
||||
This inspection reports any suspicious indentation of statements after a control statement
|
||||
without braces. Such indentation can make it look like the statement is part of the control
|
||||
statement, when in fact it will be executed after the control stratement.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -8,5 +8,5 @@ Because of this, it is possible that some other part of the system
|
||||
which uses an object initialized with the same literal, is actually holding a
|
||||
reference to the exact same object. This can create unexpected dead-lock situations,
|
||||
if the string was thought to be private.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -4,5 +4,5 @@
|
||||
This inspection reports any instances of <b><font color="#000080">Throwable</font></b>
|
||||
instantiation, where the created <b><font color="#000080">Throwable</font></b>
|
||||
is never actually thrown. Most often this is the result of a simple mistake.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -7,5 +7,5 @@ with a zero-length array argument. When passing in an array of too small size, t
|
||||
<b><font color="#000080">toArray()</font></b> method has to construct a new array of
|
||||
the right size using reflection. This has significantly worse performance than passing
|
||||
in an array of at least the size of the collection itself.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -9,5 +9,5 @@ to be initialized separately in a <b><font color="#000080">readObject</font></b>
|
||||
during deserialization. Any <b><font color="#000080">transient</font></b> fields which
|
||||
are not initialized during normal object construction are considered to use the default
|
||||
initialization and are not reported by this inspection.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -22,5 +22,5 @@ and <b><font color="#000080">containsValue()</font></b>.
|
||||
Use the third checkbox below to specify if this inspection should warn when a type can be
|
||||
weakened to <b><font color="#000080">java.lang.Object</font></b>. Weakening to
|
||||
<b><font color="#000080">java.lang.Object</font></b> is often not very useful.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets</font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -12,5 +12,5 @@ This inspection reports any unnecessary unary minuses. For example:</font>
|
||||
<b><font color="#000080">i</font> = <font color="#000080">i</font> - 8;</b>
|
||||
</pre>
|
||||
</td></tr>
|
||||
<tr><td height="20"><font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font></td></tr></table> </body>
|
||||
<tr><td height="20"><font face="verdana" size="-2">Powered by InspectionGadgets</font></td></tr></table> </body>
|
||||
</html>
|
||||
+1
-1
@@ -7,5 +7,5 @@ These constructors can have somewhat unpredictable results because many numbers
|
||||
cannot be represented exactly in a <b><font color="#000080">double</font></b>.
|
||||
It is recommend to use the constructors which accept a String instead.
|
||||
</font></td></tr>
|
||||
<tr><td height="20"><font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font></td></tr></table> </body>
|
||||
<tr><td height="20"><font face="verdana" size="-2">Powered by InspectionGadgets</font></td></tr></table> </body>
|
||||
</html>
|
||||
@@ -5,5 +5,5 @@ This inspection reports on field accesses which are not qualified with
|
||||
<b><font color="#000080">this</font></b> or some other qualifier. Some coding styles
|
||||
mandate that all field accesses are qualified to prevent confusion with local
|
||||
variable or parameter accesses.</font></td></tr>
|
||||
<tr><td height="20"><font face="verdana" size="-2">New in 7, Powered by InspectionGadgets</font></td></tr></table> </body>
|
||||
<tr><td height="20"><font face="verdana" size="-2">Powered by InspectionGadgets</font></td></tr></table> </body>
|
||||
</html>
|
||||
+4
-3
@@ -53,9 +53,10 @@ public class GroovyConditionalWithIdenticalBranchesInspection extends BaseInspec
|
||||
return "Collapse conditional expression";
|
||||
}
|
||||
|
||||
public void doFix(Project project, ProblemDescriptor descriptor)
|
||||
throws IncorrectOperationException {
|
||||
final GrConditionalExpression expression = (GrConditionalExpression) descriptor.getPsiElement();
|
||||
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
if (!(element instanceof GrConditionalExpression)) return;
|
||||
final GrConditionalExpression expression = (GrConditionalExpression)element;
|
||||
final GrExpression thenBranch = expression.getThenBranch();
|
||||
replaceExpression(expression, thenBranch.getText());
|
||||
}
|
||||
|
||||
+15
-14
@@ -37,9 +37,10 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
*/
|
||||
public class BuiltInTypeFilter implements ElementFilter {
|
||||
public boolean isAcceptable(Object element, PsiElement context) {
|
||||
PsiElement previous = PsiImplUtil.realPrevious(context.getParent().getPrevSibling());
|
||||
if (previous != null &&
|
||||
GroovyTokenTypes.mAT.equals(previous.getNode().getElementType())) {
|
||||
final PsiElement parent = context.getParent();
|
||||
if (parent == null) return false;
|
||||
PsiElement previous = PsiImplUtil.realPrevious(parent.getPrevSibling());
|
||||
if (previous != null && GroovyTokenTypes.mAT.equals(previous.getNode().getElementType())) {
|
||||
return false;
|
||||
}
|
||||
if (GroovyCompletionUtil.asSimpleVariable(context) ||
|
||||
@@ -47,29 +48,29 @@ public class BuiltInTypeFilter implements ElementFilter {
|
||||
GroovyCompletionUtil.asVariableInBlock(context)) {
|
||||
return true;
|
||||
}
|
||||
if ((context.getParent() instanceof GrParameter &&
|
||||
((GrParameter) context.getParent()).getTypeElementGroovy() == null) ||
|
||||
context.getParent() instanceof GrReferenceElement &&
|
||||
!(context.getParent().getParent() instanceof GrImportStatement) &&
|
||||
!(context.getParent().getParent() instanceof GrPackageDefinition) &&
|
||||
!(context.getParent().getParent() instanceof GrArgumentList)) {
|
||||
if ((parent instanceof GrParameter &&
|
||||
((GrParameter)parent).getTypeElementGroovy() == null) ||
|
||||
parent instanceof GrReferenceElement &&
|
||||
!(parent.getParent() instanceof GrImportStatement) &&
|
||||
!(parent.getParent() instanceof GrPackageDefinition) &&
|
||||
!(parent.getParent() instanceof GrArgumentList)) {
|
||||
PsiElement prevSibling = context.getPrevSibling();
|
||||
if (context.getParent() instanceof GrReferenceElement && prevSibling != null && prevSibling.getNode() != null) {
|
||||
if (parent instanceof GrReferenceElement && prevSibling != null && prevSibling.getNode() != null) {
|
||||
ASTNode node = prevSibling.getNode();
|
||||
return !GroovyTokenTypes.DOTS.contains(node.getElementType());
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (PsiImplUtil.realPrevious(context.getParent().getPrevSibling()) instanceof GrModifierList) {
|
||||
if (PsiImplUtil.realPrevious(parent.getPrevSibling()) instanceof GrModifierList) {
|
||||
return true;
|
||||
}
|
||||
if (PsiImplUtil.realPrevious(context.getPrevSibling()) instanceof GrModifierList) {
|
||||
return true;
|
||||
}
|
||||
return context.getParent() instanceof GrExpression &&
|
||||
context.getParent().getParent() instanceof GroovyFile &&
|
||||
GroovyCompletionUtil.isNewStatement(context, false);
|
||||
return parent instanceof GrExpression &&
|
||||
parent.getParent() instanceof GroovyFile &&
|
||||
GroovyCompletionUtil.isNewStatement(context, false);
|
||||
}
|
||||
|
||||
public boolean isClassAcceptable(Class hintClass) {
|
||||
|
||||
+8
-3
@@ -346,9 +346,14 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
|
||||
|
||||
public GrMethod createMethodFromText(@NotNull String methodText) {
|
||||
GroovyFileBase file = createDummyFile(methodText);
|
||||
GrTopLevelDefintion defintion = file.getTopLevelDefinitions()[0];
|
||||
assert defintion != null && defintion instanceof GrMethod;
|
||||
return ((GrMethod) defintion);
|
||||
try {
|
||||
GrTopLevelDefintion defintion = file.getTopLevelDefinitions()[0];
|
||||
assert defintion != null && defintion instanceof GrMethod;
|
||||
return ((GrMethod)defintion);
|
||||
}
|
||||
catch (Error error) {
|
||||
throw new IncorrectOperationException("Can't create method from text: '" + file.getText() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
|
||||
public class GroovyWithTypeCastSurrounder extends GroovyExpressionSurrounder {
|
||||
protected TextRange surroundExpression(GrExpression expression) {
|
||||
GrParenthesizedExpression parenthesized = (GrParenthesizedExpression) GroovyPsiElementFactory.getInstance(expression.getProject()).createTopElementFromText("((Type)a)");
|
||||
parenthesized = (GrParenthesizedExpression) expression.replaceWithExpression(parenthesized, true);
|
||||
parenthesized = (GrParenthesizedExpression) expression.replaceWithExpression(parenthesized, false);
|
||||
GrTypeCastExpression typeCast = (GrTypeCastExpression) parenthesized.getOperand();
|
||||
replaceToOldExpression(typeCast.getOperand(), expression);
|
||||
GrTypeElement typeElement = typeCast.getCastTypeElement();
|
||||
|
||||
@@ -22,8 +22,8 @@ hg4idea.revert=Revert
|
||||
hg4idea.commit=Commit
|
||||
|
||||
hg4idea.configuration.title=Mercurial Configuration
|
||||
hg4idea.configuration.description=Path to hg executable
|
||||
hg4idea.configuration.executable.error=\"{0}\" doesn't appear to be a valid hg executable
|
||||
hg4idea.configuration.description=Full path to hg executable
|
||||
hg4idea.configuration.executable.error=\"{0}\" doesn\'t appear to be a valid hg executable
|
||||
|
||||
hg4idea.command.executable.error=Error executing \"{0}\". Make sure you have setup the right executable in Mercurial configuration
|
||||
|
||||
@@ -54,4 +54,3 @@ hg4idea.status.currentBranch.text=<html><b>{0}</b></html>
|
||||
hg4idea.status.currentBranch.description=<html>Current mercurial branch</html>
|
||||
hg4idea.warning.no-default-update-path=Skipped \"{0}\". No default update path.
|
||||
hg4idea.merge.please-commit=Merged heads, please commit repository \"{0}\"
|
||||
hg4idea.error.invalidExecutable=\"{0}\" is not a valid mercurial executable
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<text value="&Specify executable path"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="42f2c" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="pathSelector">
|
||||
<component id="42f2c" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="pathSelector" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false">
|
||||
<minimum-size width="100" height="-1"/>
|
||||
|
||||
@@ -45,14 +45,6 @@ public class HgConfigurationIdePanel {
|
||||
this.globalSettings = globalSettings;
|
||||
loadSettings();
|
||||
|
||||
String title = HgVcsMessages.message("hg4idea.configuration.title");
|
||||
String description = HgVcsMessages.message("hg4idea.configuration.description");
|
||||
|
||||
pathSelector.addBrowseFolderListener(
|
||||
title, description, null,
|
||||
new FileChooserDescriptor(true, false, false, false, false, false)
|
||||
);
|
||||
|
||||
final ActionListener listener = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
pathSelector.setEnabled(selectRadioButton.isSelected());
|
||||
@@ -109,54 +101,7 @@ public class HgConfigurationIdePanel {
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// GUI initializer generated by IntelliJ IDEA GUI Designer
|
||||
// >>> IMPORTANT!! <<<
|
||||
// DO NOT EDIT OR ADD ANY CODE HERE!
|
||||
$$$setupUI$$$();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method generated by IntelliJ IDEA GUI Designer
|
||||
* >>> IMPORTANT!! <<<
|
||||
* DO NOT edit this method OR call it in your code!
|
||||
*
|
||||
* @noinspection ALL
|
||||
*/
|
||||
private void $$$setupUI$$$() {
|
||||
basePanel = new JPanel();
|
||||
basePanel.setLayout(new GridLayoutManager(2, 1, new Insets(0, 0, 0, 0), -1, -1));
|
||||
final JPanel panel1 = new JPanel();
|
||||
panel1.setLayout(new GridLayoutManager(2, 2, new Insets(0, 0, 0, 0), -1, -1));
|
||||
basePanel.add(panel1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
|
||||
panel1.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Path to hg executable"));
|
||||
autoRadioButton = new JRadioButton();
|
||||
autoRadioButton.setSelected(true);
|
||||
autoRadioButton.setText("Autodetect hg in PATH");
|
||||
autoRadioButton.setMnemonic('A');
|
||||
autoRadioButton.setDisplayedMnemonicIndex(0);
|
||||
panel1.add(autoRadioButton, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
|
||||
selectRadioButton = new JRadioButton();
|
||||
selectRadioButton.setEnabled(true);
|
||||
selectRadioButton.setText("Specify executable path");
|
||||
selectRadioButton.setMnemonic('S');
|
||||
selectRadioButton.setDisplayedMnemonicIndex(0);
|
||||
panel1.add(selectRadioButton, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
|
||||
pathSelector = new TextFieldWithBrowseButton();
|
||||
pathSelector.setEnabled(false);
|
||||
panel1.add(pathSelector, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, new Dimension(100, -1), null, null, 0, false));
|
||||
final Spacer spacer1 = new Spacer();
|
||||
basePanel.add(spacer1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
|
||||
ButtonGroup buttonGroup;
|
||||
buttonGroup = new ButtonGroup();
|
||||
buttonGroup.add(autoRadioButton);
|
||||
buttonGroup.add(selectRadioButton);
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection ALL
|
||||
*/
|
||||
public JComponent $$$getRootComponent$$$() {
|
||||
return basePanel;
|
||||
private void createUIComponents() {
|
||||
pathSelector = new HgSetExecutablePathPanel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.zmlx.hg4idea.ui.HgSetExecutableDialog">
|
||||
<grid id="27dc6" binding="centerPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="27dc6" binding="myCenterPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="564" height="400"/>
|
||||
@@ -8,7 +8,7 @@
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="40fef" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="hgExecutablePath">
|
||||
<component id="c91cc" class="org.zmlx.hg4idea.ui.HgSetExecutablePathPanel" binding="myHgExecutablePath" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="9" fill="0" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="400" height="-1"/>
|
||||
@@ -16,27 +16,17 @@
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="a1421" class="javax.swing.JLabel" binding="infoLabel">
|
||||
<component id="a1421" class="javax.swing.JLabel" binding="myInfoLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Full path to hg executable or 'hg' if PATH has it:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="c771f" class="javax.swing.JLabel" binding="errorLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<font style="2"/>
|
||||
<foreground awt-color="red"/>
|
||||
<text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.error.invalidExecutable"/>
|
||||
<text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.configuration.description"/>
|
||||
</properties>
|
||||
</component>
|
||||
<vspacer id="4c273">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
</children>
|
||||
|
||||
@@ -14,26 +14,16 @@ package org.zmlx.hg4idea.ui;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.uiDesigner.core.GridConstraints;
|
||||
import com.intellij.uiDesigner.core.GridLayoutManager;
|
||||
import com.intellij.uiDesigner.core.Spacer;
|
||||
import org.zmlx.hg4idea.HgVcsMessages;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Insets;
|
||||
import java.util.ResourceBundle;
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public class HgSetExecutableDialog extends DialogWrapper {
|
||||
private JPanel centerPanel;
|
||||
private TextFieldWithBrowseButton hgExecutablePath;
|
||||
private JLabel infoLabel;
|
||||
private JLabel errorLabel;
|
||||
private JPanel myCenterPanel;
|
||||
private HgSetExecutablePathPanel myHgExecutablePath;
|
||||
private JLabel myInfoLabel;
|
||||
|
||||
public HgSetExecutableDialog(Project project) {
|
||||
super(project, false);
|
||||
@@ -42,81 +32,24 @@ public class HgSetExecutableDialog extends DialogWrapper {
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return centerPanel;
|
||||
return myCenterPanel;
|
||||
}
|
||||
|
||||
public void setBadHgPath(String hgPath) {
|
||||
hgExecutablePath.setText(hgPath);
|
||||
errorLabel.setText(HgVcsMessages.message("hg4idea.error.invalidExecutable", hgPath));
|
||||
myHgExecutablePath.setText(hgPath);
|
||||
setErrorText(HgVcsMessages.message("hg4idea.configuration.executable.error", hgPath));
|
||||
}
|
||||
|
||||
public String getNewHgPath() {
|
||||
return hgExecutablePath.getText();
|
||||
return myHgExecutablePath.getText();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
// GUI initializer generated by IntelliJ IDEA GUI Designer
|
||||
// >>> IMPORTANT!! <<<
|
||||
// DO NOT EDIT OR ADD ANY CODE HERE!
|
||||
$$$setupUI$$$();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method generated by IntelliJ IDEA GUI Designer
|
||||
* >>> IMPORTANT!! <<<
|
||||
* DO NOT edit this method OR call it in your code!
|
||||
*
|
||||
* @noinspection ALL
|
||||
*/
|
||||
private void $$$setupUI$$$() {
|
||||
centerPanel = new JPanel();
|
||||
centerPanel.setLayout(new GridLayoutManager(4, 1, new Insets(0, 0, 0, 0), -1, -1));
|
||||
hgExecutablePath = new TextFieldWithBrowseButton();
|
||||
centerPanel.add(hgExecutablePath, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, new Dimension(400, -1), null, 0, false));
|
||||
infoLabel = new JLabel();
|
||||
infoLabel.setText("Full path to hg executable or 'hg' if PATH has it:");
|
||||
centerPanel.add(infoLabel, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
|
||||
errorLabel = new JLabel();
|
||||
errorLabel.setFont(new Font(errorLabel.getFont().getName(), Font.ITALIC, errorLabel.getFont().getSize()));
|
||||
errorLabel.setForeground(Color.red);
|
||||
this.$$$loadLabelText$$$(errorLabel, ResourceBundle.getBundle("org/zmlx/hg4idea/HgVcsMessages").getString("hg4idea.error.invalidExecutable"));
|
||||
centerPanel.add(errorLabel, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
|
||||
final Spacer spacer1 = new Spacer();
|
||||
centerPanel.add(spacer1, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection ALL
|
||||
*/
|
||||
private void $$$loadLabelText$$$(JLabel component, String text) {
|
||||
StringBuffer result = new StringBuffer();
|
||||
boolean haveMnemonic = false;
|
||||
char mnemonic = '\0';
|
||||
int mnemonicIndex = -1;
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
if (text.charAt(i) == '&') {
|
||||
i++;
|
||||
if (i == text.length()) break;
|
||||
if (!haveMnemonic && text.charAt(i) != '&') {
|
||||
haveMnemonic = true;
|
||||
mnemonic = text.charAt(i);
|
||||
mnemonicIndex = result.length();
|
||||
}
|
||||
private void createUIComponents() {
|
||||
myHgExecutablePath = new HgSetExecutablePathPanel();
|
||||
myHgExecutablePath.addOKListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
setErrorText("");
|
||||
}
|
||||
result.append(text.charAt(i));
|
||||
}
|
||||
component.setText(result.toString());
|
||||
if (haveMnemonic) {
|
||||
component.setDisplayedMnemonic(mnemonic);
|
||||
component.setDisplayedMnemonicIndex(mnemonicIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection ALL
|
||||
*/
|
||||
public JComponent $$$getRootComponent$$$() {
|
||||
return centerPanel;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.zmlx.hg4idea.ui;
|
||||
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.zmlx.hg4idea.HgVcsMessages;
|
||||
import org.zmlx.hg4idea.command.HgVersionCommand;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* HgSetExecutablePathPanel is a {@link com.intellij.openapi.ui.TextFieldWithBrowseButton}, which opens a file chooser for hg executable
|
||||
* and checks validity of the selected file to be an hg executable.
|
||||
*/
|
||||
class HgSetExecutablePathPanel extends TextFieldWithBrowseButton {
|
||||
|
||||
private final Set<ActionListener> myOkListeners = new HashSet<ActionListener>();
|
||||
|
||||
HgSetExecutablePathPanel() {
|
||||
FileChooserDescriptor descriptor = new FileChooserDescriptor(true, false, false, false, false, false) {
|
||||
public void validateSelectedFiles(VirtualFile[] files) throws Exception {
|
||||
HgVersionCommand command = new HgVersionCommand();
|
||||
String path = files[0].getPath();
|
||||
if (!command.isValid(path)) {
|
||||
throw new ConfigurationException(HgVcsMessages.message("hg4idea.configuration.executable.error", path));
|
||||
}
|
||||
for (ActionListener okListener : myOkListeners) {
|
||||
okListener.actionPerformed(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
addBrowseFolderListener(HgVcsMessages.message("hg4idea.configuration.title"), HgVcsMessages.message("hg4idea.configuration.description"), null, descriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener which will be called when file chooser dialog is closed successfully.
|
||||
*/
|
||||
void addOKListener(ActionListener listener) {
|
||||
myOkListeners.add(listener);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -68,6 +68,7 @@ import org.jetbrains.idea.svn.actions.ShowPropertiesDiffWithLocalAction;
|
||||
import org.jetbrains.idea.svn.actions.SvnMergeProvider;
|
||||
import org.jetbrains.idea.svn.annotate.SvnAnnotationProvider;
|
||||
import org.jetbrains.idea.svn.checkin.SvnCheckinEnvironment;
|
||||
import org.jetbrains.idea.svn.dialogs.SvnBranchPointsCalculator;
|
||||
import org.jetbrains.idea.svn.dialogs.SvnFormatWorker;
|
||||
import org.jetbrains.idea.svn.dialogs.WCInfo;
|
||||
import org.jetbrains.idea.svn.history.*;
|
||||
@@ -144,6 +145,8 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
|
||||
public static final Topic<Runnable> ROOTS_RELOADED = new Topic<Runnable>("ROOTS_RELOADED", Runnable.class);
|
||||
private VcsListener myVcsListener;
|
||||
|
||||
private SvnBranchPointsCalculator mySvnBranchPointsCalculator;
|
||||
|
||||
private final RootsToWorkingCopies myRootsToWorkingCopies;
|
||||
private final SvnAuthenticationNotifier myAuthNotifier;
|
||||
private static RareLogger.LogFilter[] ourLogFilters;
|
||||
@@ -365,6 +368,7 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
|
||||
FrameStateManager.getInstance().addListener(myFrameStateListener);
|
||||
|
||||
myAuthNotifier.init();
|
||||
mySvnBranchPointsCalculator = new SvnBranchPointsCalculator(myProject);
|
||||
|
||||
// do one time after project loaded
|
||||
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() {
|
||||
@@ -466,6 +470,8 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
|
||||
|
||||
myAuthNotifier.stop();
|
||||
myAuthNotifier.clear();
|
||||
|
||||
mySvnBranchPointsCalculator = null;
|
||||
}
|
||||
|
||||
public VcsShowConfirmationOption getAddConfirmation() {
|
||||
@@ -1038,4 +1044,8 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
|
||||
public CommittedChangeList getRevisionChanges(VcsFileRevision revision, VirtualFile file) throws VcsException {
|
||||
return ShowAllSubmittedFilesAction.loadRevisions(getProject(), (SvnFileRevision)revision, file, false);
|
||||
}
|
||||
|
||||
public SvnBranchPointsCalculator getSvnBranchPointsCalculator() {
|
||||
return mySvnBranchPointsCalculator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class BranchMerger implements IMerger {
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return "Merge from " + myBranchName;
|
||||
return "Merge all from " + myBranchName;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
|
||||
@@ -17,56 +17,29 @@ package org.jetbrains.idea.svn.dialogs;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.vcs.AbstractVcsHelper;
|
||||
import com.intellij.openapi.vcs.CommittedChangesProvider;
|
||||
import com.intellij.openapi.vcs.ObjectsConvertor;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.BackgroundFromStartOption;
|
||||
import com.intellij.openapi.vcs.changes.ui.ChangesViewBalloonProblemNotifier;
|
||||
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.DottedBorder;
|
||||
import com.intellij.ui.components.labels.LinkLabel;
|
||||
import com.intellij.ui.components.labels.LinkListener;
|
||||
import com.intellij.util.AsynchConsumer;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.io.EqualityPolicy;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.NestedCopyType;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.WorkingCopyFormat;
|
||||
import org.jetbrains.idea.svn.actions.ChangeListsMergerFactory;
|
||||
import org.jetbrains.idea.svn.actions.SelectBranchPopup;
|
||||
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
|
||||
import org.jetbrains.idea.svn.checkout.SvnCheckoutProvider;
|
||||
import org.jetbrains.idea.svn.history.FirstInBranch;
|
||||
import org.jetbrains.idea.svn.history.SvnChangeList;
|
||||
import org.jetbrains.idea.svn.history.SvnRepositoryLocation;
|
||||
import org.jetbrains.idea.svn.integrate.IMerger;
|
||||
import org.jetbrains.idea.svn.integrate.MergerFactory;
|
||||
import org.jetbrains.idea.svn.integrate.SvnIntegrateChangesTask;
|
||||
import org.jetbrains.idea.svn.integrate.WorkingCopyInfo;
|
||||
import org.jetbrains.idea.svn.mergeinfo.BranchInfo;
|
||||
import org.jetbrains.idea.svn.mergeinfo.SvnMergeInfoCache;
|
||||
import org.jetbrains.idea.svn.update.UpdateEventHandler;
|
||||
import org.tmatesoft.svn.core.SVNDepth;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -77,8 +50,6 @@ import java.awt.event.FocusEvent;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class CopiesPanel {
|
||||
@@ -291,149 +262,11 @@ public class CopiesPanel {
|
||||
private void mergeFrom(final WCInfo wcInfo, final VirtualFile root, final LinkLabel mergeLabel) {
|
||||
SelectBranchPopup.showForBranchRoot(myProject, root, new SelectBranchPopup.BranchSelectedCallback() {
|
||||
public void branchSelected(Project project, SvnBranchConfigurationNew configuration, String url, long revision) {
|
||||
if (url.equals(wcInfo.getRootUrl())) {
|
||||
showErrorBalloon("Cannot merge from self");
|
||||
return;
|
||||
}
|
||||
ProgressManager.getInstance().run(new MergeCalculator(wcInfo, root, url, configuration.getBaseName(url)));
|
||||
new QuickMerge(project, url, wcInfo, configuration.getBaseName(url), configuration).execute();
|
||||
}
|
||||
}, "Select branch", mergeLabel);
|
||||
}
|
||||
|
||||
private void showErrorBalloon(final String s) {
|
||||
ChangesViewBalloonProblemNotifier.showMe(myProject, s, MessageType.ERROR);
|
||||
}
|
||||
|
||||
private class MergeCalculator extends Task.Backgroundable {
|
||||
private final WCInfo myWcInfo;
|
||||
private final VirtualFile myRoot;
|
||||
private final String mySourceUrl;
|
||||
private final String myBranchName;
|
||||
private boolean myIsReintegrate;
|
||||
|
||||
private final List<CommittedChangeList> myNotMerged;
|
||||
private String myMergeTitle;
|
||||
private BranchInfo myBranchInfo;
|
||||
|
||||
private MergeCalculator(WCInfo wcInfo, VirtualFile root, String sourceUrl, String branchName) {
|
||||
super(CopiesPanel.this.myProject, "Calculating not merged revisions", true, BackgroundFromStartOption.getInstance());
|
||||
myWcInfo = wcInfo;
|
||||
myRoot = root;
|
||||
mySourceUrl = sourceUrl;
|
||||
myBranchName = branchName;
|
||||
myNotMerged = new LinkedList<CommittedChangeList>();
|
||||
myMergeTitle = "Merge from " + branchName;
|
||||
}
|
||||
|
||||
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
// branch is info holder
|
||||
new FirstInBranch(myVcs, myWcInfo.getRepositoryRoot(), myWcInfo.getRootUrl(), mySourceUrl,
|
||||
new Consumer<FirstInBranch.CopyData>() {
|
||||
public void consume(FirstInBranch.CopyData copyData) {
|
||||
if (copyData == null) {
|
||||
showErrorBalloon("Merge start wasn't found");
|
||||
return;
|
||||
}
|
||||
|
||||
myIsReintegrate = ! copyData.isTrunkSupposedCorrect();
|
||||
if (! myWcInfo.getFormat().supportsMergeInfo()) return;
|
||||
final long localLatest = Math.max(copyData.getCopyTargetRevision(), copyData.getCopySourceRevision());
|
||||
myBranchInfo = new BranchInfo(myVcs, myWcInfo.getRepositoryRoot(), myWcInfo.getRootUrl(), mySourceUrl, mySourceUrl, myVcs.createWCClient());
|
||||
|
||||
final CommittedChangesProvider<SvnChangeList,ChangeBrowserSettings> committedChangesProvider =
|
||||
myVcs.getCommittedChangesProvider();
|
||||
final ChangeBrowserSettings settings = new ChangeBrowserSettings();
|
||||
settings.CHANGE_AFTER = Long.toString(localLatest);
|
||||
try {
|
||||
committedChangesProvider.loadCommittedChanges(settings, new SvnRepositoryLocation(mySourceUrl),
|
||||
committedChangesProvider.getUnlimitedCountValue(), new AsynchConsumer<CommittedChangeList>() {
|
||||
public void finished() {
|
||||
}
|
||||
|
||||
public void consume(CommittedChangeList committedChangeList) {
|
||||
final SvnChangeList svnList = (SvnChangeList)committedChangeList;
|
||||
if (localLatest >= svnList.getNumber()) return;
|
||||
|
||||
final SvnMergeInfoCache.MergeCheckResult checkResult =
|
||||
myBranchInfo.checkList(svnList, myWcInfo.getPath());
|
||||
if (SvnMergeInfoCache.MergeCheckResult.NOT_MERGED.equals(checkResult)) {
|
||||
myNotMerged.add(svnList);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (VcsException e) {
|
||||
AbstractVcsHelper.getInstance(myProject).showErrors(Collections.singletonList(e), "Checking revisions for merge fault");
|
||||
}
|
||||
}
|
||||
}).run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
onSuccess();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private MergerFactory askParameters() {
|
||||
final int result = Messages.showDialog(myProject, myNotMerged.size() + " not merged revision(s) found.", myMergeTitle,
|
||||
new String[]{"Merge &all", "&Select revisions to merge", "Cancel"}, 0, Messages.getQuestionIcon());
|
||||
if (result == 2) return null;
|
||||
|
||||
final MergerFactory factory;
|
||||
if (result == 0) {
|
||||
factory = createMergeAllFactory();
|
||||
} else {
|
||||
final ToBeMergedDialog dialog = new ToBeMergedDialog(myProject, myNotMerged, myMergeTitle, myBranchInfo);
|
||||
dialog.show();
|
||||
if (dialog.getExitCode() == DialogWrapper.CANCEL_EXIT_CODE) {
|
||||
return null;
|
||||
}
|
||||
final List<CommittedChangeList> lists = dialog.getSelected();
|
||||
if (lists.isEmpty()) return null;
|
||||
factory = new ChangeListsMergerFactory(lists);
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
|
||||
private MergerFactory createMergeAllFactory() {
|
||||
return new MergerFactory() {
|
||||
public IMerger createMerger(SvnVcs vcs, File target, UpdateEventHandler handler, SVNURL currentBranchUrl) {
|
||||
return new BranchMerger(vcs, currentBranchUrl, myWcInfo.getUrl(), myWcInfo.getPath(), handler, myIsReintegrate, myBranchName);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
if (! myWcInfo.getFormat().supportsMergeInfo()) {
|
||||
doMerge(createMergeAllFactory());
|
||||
return;
|
||||
}
|
||||
if (myNotMerged.isEmpty()) {
|
||||
ChangesViewBalloonProblemNotifier.showMe(myProject, "Everything is up-to-date", MessageType.WARNING);
|
||||
return;
|
||||
}
|
||||
final MergerFactory factory = askParameters();
|
||||
if (factory == null) return;
|
||||
doMerge(factory);
|
||||
}
|
||||
|
||||
private void doMerge(MergerFactory factory) {
|
||||
final SVNURL sourceUrlUrl;
|
||||
try {
|
||||
sourceUrlUrl = SVNURL.parseURIEncoded(mySourceUrl);
|
||||
} catch (SVNException e) {
|
||||
showErrorBalloon("Cannot merge: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
final SvnIntegrateChangesTask task = new SvnIntegrateChangesTask(SvnVcs.getInstance(myProject),
|
||||
new WorkingCopyInfo(myWcInfo.getPath(), true), factory, sourceUrlUrl, myMergeTitle, false);
|
||||
ProgressManager.getInstance().run(task);
|
||||
}
|
||||
}
|
||||
|
||||
private void setFocusableForLinks(final LinkLabel label) {
|
||||
final Border border = new DottedBorder(new Insets(1,2,1,1), Color.black);
|
||||
label.setFocusable(true);
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.idea.svn.dialogs;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.CalledInAwt;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ValueHolder;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
|
||||
// cache. persistent. by request
|
||||
public class FactsCalculator<In, Out> {
|
||||
private final Project myProject;
|
||||
private final String myTaskTitle;
|
||||
private final ValueHolder<Out, In> myCache;
|
||||
private final Convertor<In, Out> myLive;
|
||||
|
||||
public FactsCalculator(Project project, String taskTitle, ValueHolder<Out, In> cache, Convertor<In, Out> live) {
|
||||
myProject = project;
|
||||
myTaskTitle = taskTitle;
|
||||
myCache = cache;
|
||||
myLive = live;
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
public void get(final In in, final Consumer<Out> resultConsumer) {
|
||||
new RunOrContinuation<Out>(myProject, myTaskTitle) {
|
||||
@Override
|
||||
protected Out calculate() {
|
||||
return myCache.getValue(in);
|
||||
}
|
||||
@Override
|
||||
protected Out calculateLong() {
|
||||
final Out result = myLive.convert(in);
|
||||
if (result != null) {
|
||||
myCache.setValue(result, in);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
protected void processResult(Out out) {
|
||||
resultConsumer.consume(out);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.idea.svn.dialogs;
|
||||
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.changes.BackgroundFromStartOption;
|
||||
import com.intellij.openapi.vcs.changes.committed.RunBackgroundable;
|
||||
import com.intellij.openapi.vcs.changes.ui.ChangesViewBalloonProblemNotifier;
|
||||
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
import com.intellij.util.AsynchConsumer;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.actions.ChangeListsMergerFactory;
|
||||
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
|
||||
import org.jetbrains.idea.svn.history.CopyData;
|
||||
import org.jetbrains.idea.svn.history.FirstInBranch;
|
||||
import org.jetbrains.idea.svn.history.SvnChangeList;
|
||||
import org.jetbrains.idea.svn.history.SvnRepositoryLocation;
|
||||
import org.jetbrains.idea.svn.integrate.IMerger;
|
||||
import org.jetbrains.idea.svn.integrate.MergerFactory;
|
||||
import org.jetbrains.idea.svn.integrate.SvnIntegrateChangesTask;
|
||||
import org.jetbrains.idea.svn.integrate.WorkingCopyInfo;
|
||||
import org.jetbrains.idea.svn.mergeinfo.BranchInfo;
|
||||
import org.jetbrains.idea.svn.mergeinfo.SvnMergeInfoCache;
|
||||
import org.jetbrains.idea.svn.update.UpdateEventHandler;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class QuickMerge {
|
||||
private final Project myProject;
|
||||
private final String myBranchName;
|
||||
private final SvnBranchConfigurationNew myConfiguration;
|
||||
private final WCInfo myWcInfo;
|
||||
private String mySourceUrl;
|
||||
private SvnVcs myVcs;
|
||||
private final String myTitle;
|
||||
|
||||
public QuickMerge(Project project, String sourceUrl, WCInfo wcInfo, final String branchName, final SvnBranchConfigurationNew configuration) {
|
||||
myProject = project;
|
||||
myBranchName = branchName;
|
||||
myConfiguration = configuration;
|
||||
myVcs = SvnVcs.getInstance(project);
|
||||
mySourceUrl = sourceUrl;
|
||||
myWcInfo = wcInfo;
|
||||
myTitle = "Merge from " + myBranchName;
|
||||
}
|
||||
|
||||
private void correctSourceUrl() throws SVNException {
|
||||
final SVNURL branch = myConfiguration.getWorkingBranch(myWcInfo.getUrl());
|
||||
if (branch != null && (! myWcInfo.getUrl().equals(branch))) {
|
||||
final String branchString = branch.toString();
|
||||
if (SVNPathUtil.isAncestor(branchString, myWcInfo.getRootUrl())) {
|
||||
final String subPath = SVNPathUtil.getRelativePath(branchString, myWcInfo.getRootUrl());
|
||||
mySourceUrl = SVNPathUtil.append(mySourceUrl, subPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean prompt(final String question) {
|
||||
return Messages.showOkCancelDialog(myProject, question, myTitle, Messages.getQuestionIcon()) == 0;
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
public void execute() {
|
||||
if (SVNPathUtil.isAncestor(mySourceUrl, myWcInfo.getRootUrl()) || SVNPathUtil.isAncestor(myWcInfo.getRootUrl(), mySourceUrl)) {
|
||||
showErrorBalloon("Cannot merge from self");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
correctSourceUrl();
|
||||
}
|
||||
catch (SVNException e) {
|
||||
showErrorBalloon(e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
if (! myWcInfo.getFormat().supportsMergeInfo()) {
|
||||
mergeAll();
|
||||
return;
|
||||
}
|
||||
|
||||
final int result = Messages.showDialog(myProject, "Merge all?", myTitle,
|
||||
new String[]{"Merge &all", "&Select revisions to merge", "Cancel"}, 0, Messages.getQuestionIcon());
|
||||
if (result == 2) return;
|
||||
if (result == 0) {
|
||||
mergeAll();
|
||||
return;
|
||||
}
|
||||
|
||||
ProgressManager.getInstance().run(new MergeCalculator(myProject, myWcInfo, mySourceUrl, myBranchName));
|
||||
}
|
||||
|
||||
@CalledInAny
|
||||
private void showErrorBalloon(final String s) {
|
||||
ChangesViewBalloonProblemNotifier.showMe(myProject, s, MessageType.ERROR);
|
||||
}
|
||||
|
||||
// continuation... continuation.. hidden continuation..
|
||||
private void mergeAll() {
|
||||
// suppose we're in branch
|
||||
myVcs.getSvnBranchPointsCalculator().getFirstCopyPoint(myWcInfo.getRepositoryRoot(), mySourceUrl, myWcInfo.getRootUrl(),
|
||||
new Consumer<SvnBranchPointsCalculator.WrapperInvertor<SvnBranchPointsCalculator.BranchCopyData>>() {
|
||||
public void consume(SvnBranchPointsCalculator.WrapperInvertor<SvnBranchPointsCalculator.BranchCopyData> result) {
|
||||
if (result == null) {
|
||||
showErrorBalloon("Merge start wasn't found");
|
||||
return;
|
||||
}
|
||||
final boolean reintegrate = result.isInvertedSense();
|
||||
final MergerFactory mergerFactory = new MergerFactory() {
|
||||
public IMerger createMerger(SvnVcs vcs, File target, UpdateEventHandler handler, SVNURL currentBranchUrl) {
|
||||
return new BranchMerger(vcs, currentBranchUrl, myWcInfo.getUrl(), myWcInfo.getPath(), handler, reintegrate, myBranchName);
|
||||
}
|
||||
};
|
||||
|
||||
final String title = "Merging all from " + myBranchName + (reintegrate ? " (reintegrate)" : "");
|
||||
doMerge(mergerFactory, title);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@CalledInAny
|
||||
private void doMerge(final MergerFactory factory, final String mergeTitle) {
|
||||
final SVNURL sourceUrlUrl;
|
||||
try {
|
||||
sourceUrlUrl = SVNURL.parseURIEncoded(mySourceUrl);
|
||||
} catch (SVNException e) {
|
||||
showErrorBalloon("Cannot merge: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
final SvnIntegrateChangesTask task = new SvnIntegrateChangesTask(SvnVcs.getInstance(myProject),
|
||||
new WorkingCopyInfo(myWcInfo.getPath(), true), factory, sourceUrlUrl, mergeTitle, false);
|
||||
RunBackgroundable.run(task);
|
||||
}
|
||||
|
||||
private class MergeCalculator extends Task.Backgroundable {
|
||||
private final WCInfo myWcInfo;
|
||||
private final String mySourceUrl;
|
||||
private final String myBranchName;
|
||||
private boolean myIsReintegrate;
|
||||
|
||||
private final List<CommittedChangeList> myNotMerged;
|
||||
private String myMergeTitle;
|
||||
private BranchInfo myBranchInfo;
|
||||
|
||||
private MergeCalculator(Project project, WCInfo wcInfo, String sourceUrl, String branchName) {
|
||||
super(project, "Calculating not merged revisions", true, BackgroundFromStartOption.getInstance());
|
||||
myWcInfo = wcInfo;
|
||||
mySourceUrl = sourceUrl;
|
||||
myBranchName = branchName;
|
||||
myNotMerged = new LinkedList<CommittedChangeList>();
|
||||
myMergeTitle = "Merge from " + branchName;
|
||||
}
|
||||
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
// branch is info holder
|
||||
new FirstInBranch(myVcs, myWcInfo.getRepositoryRoot(), myWcInfo.getRootUrl(), mySourceUrl,
|
||||
new Consumer<CopyData>() {
|
||||
public void consume(CopyData copyData) {
|
||||
if (copyData == null) {
|
||||
showErrorBalloon("Merge start wasn't found");
|
||||
return;
|
||||
}
|
||||
|
||||
myIsReintegrate = ! copyData.isTrunkSupposedCorrect();
|
||||
if (! myWcInfo.getFormat().supportsMergeInfo()) return;
|
||||
final long localLatest = Math.max(copyData.getCopyTargetRevision(), copyData.getCopySourceRevision());
|
||||
myBranchInfo = new BranchInfo(myVcs, myWcInfo.getRepositoryRoot(), myWcInfo.getRootUrl(), mySourceUrl, mySourceUrl, myVcs.createWCClient());
|
||||
|
||||
final CommittedChangesProvider<SvnChangeList,ChangeBrowserSettings> committedChangesProvider =
|
||||
myVcs.getCommittedChangesProvider();
|
||||
final ChangeBrowserSettings settings = new ChangeBrowserSettings();
|
||||
settings.CHANGE_AFTER = Long.toString(localLatest);
|
||||
try {
|
||||
committedChangesProvider.loadCommittedChanges(settings, new SvnRepositoryLocation(mySourceUrl),
|
||||
committedChangesProvider.getUnlimitedCountValue(), new AsynchConsumer<CommittedChangeList>() {
|
||||
public void finished() {
|
||||
}
|
||||
|
||||
public void consume(CommittedChangeList committedChangeList) {
|
||||
final SvnChangeList svnList = (SvnChangeList)committedChangeList;
|
||||
if (localLatest >= svnList.getNumber()) return;
|
||||
|
||||
final SvnMergeInfoCache.MergeCheckResult checkResult =
|
||||
myBranchInfo.checkList(svnList, myWcInfo.getPath());
|
||||
if (SvnMergeInfoCache.MergeCheckResult.NOT_MERGED.equals(checkResult)) {
|
||||
myNotMerged.add(svnList);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (VcsException e) {
|
||||
AbstractVcsHelper.getInstance(myProject).showErrors(Collections.singletonList(e), "Checking revisions for merge fault");
|
||||
}
|
||||
}
|
||||
}).run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
onSuccess();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private MergerFactory askParameters() {
|
||||
final MergerFactory factory;
|
||||
final ToBeMergedDialog dialog = new ToBeMergedDialog(myProject, myNotMerged, myMergeTitle, myBranchInfo);
|
||||
dialog.show();
|
||||
if (dialog.getExitCode() == DialogWrapper.CANCEL_EXIT_CODE) {
|
||||
return null;
|
||||
}
|
||||
final List<CommittedChangeList> lists = dialog.getSelected();
|
||||
if (lists.isEmpty()) return null;
|
||||
factory = new ChangeListsMergerFactory(lists);
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
if (myNotMerged.isEmpty()) {
|
||||
ChangesViewBalloonProblemNotifier.showMe(myProject, "Everything is up-to-date", MessageType.WARNING);
|
||||
return;
|
||||
}
|
||||
final MergerFactory factory = askParameters();
|
||||
if (factory == null) return;
|
||||
doMerge(factory, myMergeTitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.idea.svn.dialogs;
|
||||
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vcs.CalledInAwt;
|
||||
import com.intellij.openapi.vcs.CalledInBackground;
|
||||
import com.intellij.openapi.vcs.changes.BackgroundFromStartOption;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class RunOrContinuation<T> {
|
||||
protected final Project myProject;
|
||||
private final String myTaskTitle;
|
||||
private boolean myWasCanceled;
|
||||
|
||||
protected RunOrContinuation(final Project project, final String taskTitle) {
|
||||
myProject = project;
|
||||
myTaskTitle = taskTitle;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@CalledInAwt
|
||||
protected abstract T calculate();
|
||||
@Nullable
|
||||
@CalledInBackground
|
||||
protected abstract T calculateLong();
|
||||
@CalledInAwt
|
||||
protected abstract void processResult(final T t);
|
||||
|
||||
protected void cancel() {
|
||||
myWasCanceled = true;
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
public void execute() {
|
||||
final Ref<T> refT = new Ref<T>();
|
||||
refT.set(calculate());
|
||||
if ((! myWasCanceled) && (! refT.isNull())) {
|
||||
processResult(refT.get());
|
||||
return;
|
||||
}
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(myProject, myTaskTitle, true, BackgroundFromStartOption.getInstance()) {
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
refT.set(calculateLong());
|
||||
}
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
if ((! myWasCanceled) && (! refT.isNull())) processResult(refT.get());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.idea.svn.dialogs;
|
||||
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.ValueHolder;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.EnumeratorStringDescriptor;
|
||||
import com.intellij.util.io.PersistentHashMap;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.history.CopyData;
|
||||
import org.jetbrains.idea.svn.history.FirstInBranch;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class SvnBranchPointsCalculator {
|
||||
private final FactsCalculator<KeyData, WrapperInvertor<BranchCopyData>> myCalculator;
|
||||
|
||||
private PersistentHolder myPersistentHolder;
|
||||
|
||||
public SvnBranchPointsCalculator(final Project project) {
|
||||
final File vcs = new File(PathManager.getSystemPath(), "vcs");
|
||||
File file = new File(vcs, "svn_copy_sources");
|
||||
file.mkdirs();
|
||||
file = new File(file, project.getLocationHash());
|
||||
|
||||
// todo when will it die?
|
||||
ValueHolder<WrapperInvertor<BranchCopyData>, KeyData> cache = null;
|
||||
|
||||
try {
|
||||
myPersistentHolder = new PersistentHolder(file);
|
||||
cache = new ValueHolder<WrapperInvertor<BranchCopyData>, KeyData>() {
|
||||
public WrapperInvertor<BranchCopyData> getValue(KeyData dataHolder) {
|
||||
try {
|
||||
return myPersistentHolder.getBestHit(dataHolder.getRepoUrl(), dataHolder.getSourceUrl(), dataHolder.getTargetUrl());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// todo carefully check
|
||||
public void setValue(WrapperInvertor<BranchCopyData> value, KeyData dataHolder) {
|
||||
try {
|
||||
myPersistentHolder.put(dataHolder.getRepoUrl(),
|
||||
value.isInvertedSense() ? dataHolder.getSourceUrl() : dataHolder.getTargetUrl(), value.getWrapped());
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (IOException e) {
|
||||
cache = new ValueHolder<WrapperInvertor<BranchCopyData>, KeyData>() {
|
||||
public WrapperInvertor<BranchCopyData> getValue(KeyData dataHolder) {
|
||||
return null;
|
||||
}
|
||||
public void setValue(WrapperInvertor<BranchCopyData> value, KeyData dataHolder) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
myCalculator = new FactsCalculator<KeyData, WrapperInvertor<BranchCopyData>>(project, "Looking for branch origin", cache, new Loader(project));
|
||||
}
|
||||
|
||||
private static class BranchDataExternalizer implements DataExternalizer<TreeMap<String,BranchCopyData>> {
|
||||
public void save(DataOutput out, TreeMap<String,BranchCopyData> value) throws IOException {
|
||||
out.writeInt(value.size());
|
||||
for (Map.Entry<String, BranchCopyData> entry : value.entrySet()) {
|
||||
out.writeUTF(entry.getKey());
|
||||
final BranchCopyData entryValue = entry.getValue();
|
||||
out.writeUTF(entryValue.getSource());
|
||||
out.writeUTF(entryValue.getTarget());
|
||||
out.writeLong(entryValue.getSourceRevision());
|
||||
out.writeLong(entryValue.getTargetRevision());
|
||||
}
|
||||
}
|
||||
|
||||
public TreeMap<String,BranchCopyData> read(DataInput in) throws IOException {
|
||||
final TreeMap<String,BranchCopyData> result = new TreeMap<String, BranchCopyData>();
|
||||
|
||||
final int num = in.readInt();
|
||||
for (int i = 0; i < num; i++) {
|
||||
final String key = in.readUTF();
|
||||
final String source = in.readUTF();
|
||||
final String target = in.readUTF();
|
||||
final long sourceRevision = in.readLong();
|
||||
final long targetRevision = in.readLong();
|
||||
|
||||
result.put(key, new BranchCopyData(source, sourceRevision, target, targetRevision));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WrapperInvertor<T extends Invertor<T>> {
|
||||
private final T myWrapped;
|
||||
private final boolean myInvertedSense;
|
||||
|
||||
public WrapperInvertor(boolean invertedSense, T wrapped) {
|
||||
myInvertedSense = invertedSense;
|
||||
myWrapped = wrapped;
|
||||
}
|
||||
|
||||
public boolean isInvertedSense() {
|
||||
return myInvertedSense;
|
||||
}
|
||||
|
||||
public T getWrapped() {
|
||||
return myWrapped;
|
||||
}
|
||||
|
||||
public T getTrue() {
|
||||
return myInvertedSense ? myWrapped.invertSelf() : myWrapped;
|
||||
}
|
||||
|
||||
public T inverted() {
|
||||
return myWrapped.invertSelf();
|
||||
}
|
||||
}
|
||||
|
||||
private static class PersistentHolder {
|
||||
private final PersistentHashMap<String, TreeMap<String, BranchCopyData>> myPersistentMap;
|
||||
private final MultiMap<String, String> myForSearchMap;
|
||||
private final Object myLock;
|
||||
|
||||
PersistentHolder(final File file) throws IOException {
|
||||
myLock = new Object();
|
||||
myPersistentMap = new PersistentHashMap<String, TreeMap<String, BranchCopyData>>(
|
||||
file, new EnumeratorStringDescriptor(), new BranchDataExternalizer());
|
||||
final Ref<IOException> excRef = new Ref<IOException>();
|
||||
// list for values by default
|
||||
myForSearchMap = new MultiMap<String, String>();
|
||||
myPersistentMap.iterateData(new Processor<String>() {
|
||||
public boolean process(final String s) {
|
||||
try {
|
||||
final TreeMap<String, BranchCopyData> map = myPersistentMap.get(s);
|
||||
myForSearchMap.put(s, new ArrayList<String>(map.keySet()));
|
||||
}
|
||||
catch (IOException e) {
|
||||
excRef.set(e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (! excRef.isNull()) {
|
||||
throw excRef.get();
|
||||
}
|
||||
|
||||
for (String key : myForSearchMap.keySet()) {
|
||||
Collections.sort((List<String>) myForSearchMap.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
public void put(final String uid, final String target, final BranchCopyData data) throws IOException {
|
||||
// todo - rewrite of rather big piece; consider rewriting
|
||||
synchronized (myLock) {
|
||||
TreeMap<String, BranchCopyData> map = myPersistentMap.get(uid);
|
||||
if (map == null) {
|
||||
map = new TreeMap<String, BranchCopyData>();
|
||||
}
|
||||
map.put(target, data);
|
||||
myPersistentMap.put(uid, map);
|
||||
if (myForSearchMap.containsKey(uid)) {
|
||||
final List<String> list = (List<String>)myForSearchMap.get(uid);
|
||||
final int idx = Collections.binarySearch(list, target);
|
||||
if (idx < 0) {
|
||||
final int insertionIdx = - idx - 1;
|
||||
list.add(insertionIdx, target);
|
||||
}
|
||||
} else {
|
||||
myForSearchMap.putValue(uid, target);
|
||||
}
|
||||
}
|
||||
myPersistentMap.force();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public WrapperInvertor<BranchCopyData> getBestHit(final String repoUrl, final String source, final String target) throws IOException {
|
||||
final List<String> keys;
|
||||
synchronized (myLock) {
|
||||
keys = (List<String>) myForSearchMap.get(repoUrl);
|
||||
}
|
||||
// keys are never removed, so we can use 2 synchronized blocks
|
||||
final String sourceMatching = getMatchingUrl(keys, source);
|
||||
final String targetMatching = getMatchingUrl(keys, target);
|
||||
|
||||
if (sourceMatching == null && targetMatching == null) return null;
|
||||
|
||||
synchronized (myLock) {
|
||||
final TreeMap<String, BranchCopyData> map = myPersistentMap.get(repoUrl);
|
||||
|
||||
final boolean sourceIsOut = sourceMatching == null;
|
||||
if (sourceIsOut || targetMatching == null) {
|
||||
// if found by "target" url - we correctly thought that target of copy is target
|
||||
return sourceIsOut ? new WrapperInvertor<BranchCopyData>(false, map.get(targetMatching)) :
|
||||
new WrapperInvertor<BranchCopyData>(false, map.get(sourceMatching));
|
||||
}
|
||||
final BranchCopyData sourceData = map.get(sourceMatching);
|
||||
final BranchCopyData targetData = map.get(targetMatching);
|
||||
|
||||
final boolean inverted = sourceData.getTargetRevision() > targetData.getTargetRevision();
|
||||
return new WrapperInvertor<BranchCopyData>(inverted, inverted ? sourceData : targetData);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getMatchingUrl(List<String> keys, String source) {
|
||||
final int idx = Collections.binarySearch(keys, source);
|
||||
if (idx >= 0) return keys.get(idx);
|
||||
final int beforeInsertionIdx = - idx - 2;
|
||||
if (beforeInsertionIdx < 0) return null;
|
||||
final String candidate = keys.get(beforeInsertionIdx);
|
||||
if (source.startsWith(candidate)) return candidate;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Loader implements Convertor<KeyData, WrapperInvertor<BranchCopyData>> {
|
||||
private SvnVcs myVcs;
|
||||
|
||||
private Loader(final Project project) {
|
||||
myVcs = SvnVcs.getInstance(project);
|
||||
}
|
||||
|
||||
public WrapperInvertor<BranchCopyData> convert(final KeyData keyData) {
|
||||
final Ref<WrapperInvertor<BranchCopyData>> result = new Ref<WrapperInvertor<BranchCopyData>>();
|
||||
|
||||
new FirstInBranch(myVcs, keyData.getRepoUrl(), keyData.getTargetUrl(), keyData.getSourceUrl(), new Consumer<CopyData>() {
|
||||
public void consume(CopyData copyData) {
|
||||
if (copyData != null) {
|
||||
final boolean correct = copyData.isTrunkSupposedCorrect();
|
||||
final BranchCopyData branchCopyData;
|
||||
if (correct) {
|
||||
branchCopyData = new BranchCopyData(keyData.getSourceUrl(), copyData.getCopySourceRevision(), keyData.getTargetUrl(),
|
||||
copyData.getCopyTargetRevision());
|
||||
} else {
|
||||
branchCopyData = new BranchCopyData(keyData.getTargetUrl(), copyData.getCopySourceRevision(), keyData.getSourceUrl(),
|
||||
copyData.getCopyTargetRevision());
|
||||
}
|
||||
result.set(new WrapperInvertor<BranchCopyData>(! correct, branchCopyData));
|
||||
}
|
||||
}
|
||||
}).run();
|
||||
return result.get();
|
||||
}
|
||||
}
|
||||
|
||||
private static class KeyData {
|
||||
private final String myRepoUrl;
|
||||
private final String mySourceUrl;
|
||||
private final String myTargetUrl;
|
||||
|
||||
public KeyData(final String repoUID, final String sourceUrl, final String targetUrl) {
|
||||
myRepoUrl = repoUID;
|
||||
mySourceUrl = sourceUrl;
|
||||
myTargetUrl = targetUrl;
|
||||
}
|
||||
|
||||
public String getRepoUrl() {
|
||||
return myRepoUrl;
|
||||
}
|
||||
|
||||
public String getSourceUrl() {
|
||||
return mySourceUrl;
|
||||
}
|
||||
|
||||
public String getTargetUrl() {
|
||||
return myTargetUrl;
|
||||
}
|
||||
}
|
||||
|
||||
public static class BranchCopyData implements Invertor<BranchCopyData> {
|
||||
private final String mySource;
|
||||
private final String myTarget;
|
||||
private final long mySourceRevision;
|
||||
private final long myTargetRevision;
|
||||
|
||||
public BranchCopyData(String source, long sourceRevision, String target, long targetRevision) {
|
||||
mySource = source;
|
||||
mySourceRevision = sourceRevision;
|
||||
myTarget = target;
|
||||
myTargetRevision = targetRevision;
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return mySource;
|
||||
}
|
||||
|
||||
public long getSourceRevision() {
|
||||
return mySourceRevision;
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return myTarget;
|
||||
}
|
||||
|
||||
public long getTargetRevision() {
|
||||
return myTargetRevision;
|
||||
}
|
||||
|
||||
public BranchCopyData invertSelf() {
|
||||
return new BranchCopyData(myTarget, myTargetRevision, mySource, mySourceRevision);
|
||||
}
|
||||
}
|
||||
|
||||
private interface Invertor<T> {
|
||||
T invertSelf();
|
||||
}
|
||||
|
||||
public void getFirstCopyPoint(final String repoUID, final String sourceUrl, final String targetUrl, Consumer<WrapperInvertor<BranchCopyData>> consumer) {
|
||||
myCalculator.get(new KeyData(repoUID, sourceUrl, targetUrl), consumer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
public class CopyData {
|
||||
private final long myCopySourceRevision;
|
||||
private final long myCopyTargetRevision;
|
||||
private final boolean myTrunkSupposedCorrect;
|
||||
|
||||
public CopyData(long copySourceRevision, long copyTargetRevision, boolean trunkSupposedCorrect) {
|
||||
myCopySourceRevision = copySourceRevision;
|
||||
myCopyTargetRevision = copyTargetRevision;
|
||||
myTrunkSupposedCorrect = trunkSupposedCorrect;
|
||||
}
|
||||
|
||||
public long getCopySourceRevision() {
|
||||
return myCopySourceRevision;
|
||||
}
|
||||
|
||||
public long getCopyTargetRevision() {
|
||||
return myCopyTargetRevision;
|
||||
}
|
||||
|
||||
public boolean isTrunkSupposedCorrect() {
|
||||
return myTrunkSupposedCorrect;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vcs.ConcurrentTasks;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
@@ -26,27 +29,16 @@ import java.util.Map;
|
||||
|
||||
public class FirstInBranch implements Runnable {
|
||||
private final SvnVcs myVcs;
|
||||
private final String myRepositoryRoot;
|
||||
private final String myFullBranchUrl;
|
||||
private final String myFullTrunkUrl;
|
||||
private final String myBranchUrl;
|
||||
private final String myTrunkUrl;
|
||||
private final Consumer<CopyData> myConsumer;
|
||||
private CopyData myResult;
|
||||
private final boolean myPrimary;
|
||||
|
||||
public FirstInBranch(final SvnVcs vcs, final String repositoryRoot, final String branchUrl, final String trunkUrl, final Consumer<CopyData> consumer) {
|
||||
this(vcs, repositoryRoot, branchUrl, trunkUrl, consumer, true);
|
||||
}
|
||||
|
||||
public FirstInBranch(final SvnVcs vcs, final String repositoryRoot, final String branchUrl, final String trunkUrl, final Consumer<CopyData> consumer, final boolean primary) {
|
||||
myPrimary = primary;
|
||||
myVcs = vcs;
|
||||
myRepositoryRoot = repositoryRoot;
|
||||
myConsumer = consumer;
|
||||
|
||||
myResult = null;
|
||||
|
||||
myFullBranchUrl = branchUrl;
|
||||
myFullTrunkUrl = trunkUrl;
|
||||
myBranchUrl = relativePath(repositoryRoot, branchUrl);
|
||||
@@ -59,65 +51,84 @@ public class FirstInBranch implements Runnable {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
final SVNLogClient logClient = myVcs.createLogClient();
|
||||
|
||||
final SVNURL branchURL;
|
||||
final SVNURL trunkURL;
|
||||
try {
|
||||
logClient.doLog(SVNURL.parseURIEncoded(myFullBranchUrl), null, SVNRevision.UNDEFINED, SVNRevision.HEAD, SVNRevision.create(0), true, true, 0,
|
||||
new ISVNLogEntryHandler() {
|
||||
public void handleLogEntry(final SVNLogEntry logEntry) throws SVNException {
|
||||
final Map map = logEntry.getChangedPaths();
|
||||
for (Object o : map.values()) {
|
||||
final SVNLogEntryPath path = (SVNLogEntryPath) o;
|
||||
final String localPath = path.getPath();
|
||||
final String copyPath = path.getCopyPath();
|
||||
|
||||
if ('A' == path.getType() &&
|
||||
(myBranchUrl.equals(localPath) || SVNPathUtil.isAncestor(localPath, myBranchUrl)) &&
|
||||
(myTrunkUrl.equals(copyPath)) || SVNPathUtil.isAncestor(copyPath, myTrunkUrl)) {
|
||||
myResult = new CopyData(path.getCopyRevision(), logEntry.getRevision(), myPrimary);
|
||||
throw new MockException();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (MockException e) {
|
||||
myConsumer.consume(myResult);
|
||||
return;
|
||||
branchURL = SVNURL.parseURIEncoded(myFullBranchUrl);
|
||||
trunkURL = SVNURL.parseURIEncoded(myFullTrunkUrl);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
myConsumer.consume(myResult);
|
||||
myConsumer.consume(null);
|
||||
return;
|
||||
}
|
||||
if (myPrimary) {
|
||||
new FirstInBranch(myVcs, myRepositoryRoot, myFullTrunkUrl, myFullBranchUrl, myConsumer, false).run();
|
||||
|
||||
final ConcurrentTasks<CopyData> tasks =
|
||||
new ConcurrentTasks<CopyData>(ProgressManager.getInstance().getProgressIndicator(), createTask(branchURL), createTask(trunkURL));
|
||||
tasks.compute();
|
||||
if (tasks.isResultKnown()) {
|
||||
myConsumer.consume(tasks.getResult());
|
||||
} else {
|
||||
myConsumer.consume(myResult);
|
||||
myConsumer.consume(null);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MockException extends RuntimeException {}
|
||||
private Consumer<Consumer<CopyData>> createTask(final SVNURL branchURL) {
|
||||
return new Consumer<Consumer<CopyData>>() {
|
||||
public void consume(final Consumer<CopyData> copyDataConsumer) {
|
||||
final SVNLogClient logClient = myVcs.createLogClient();
|
||||
final long start1 = getStart(logClient, branchURL);
|
||||
if (start1 > 0) {
|
||||
final SVNRevision start1Rev = SVNRevision.create(start1);
|
||||
try {
|
||||
logClient.doLog(branchURL, null, SVNRevision.UNDEFINED, start1Rev, start1Rev, true, true, 1, new ISVNLogEntryHandler() {
|
||||
public void handleLogEntry(SVNLogEntry logEntry) throws SVNException {
|
||||
checkForCopy(logEntry, copyDataConsumer);
|
||||
}
|
||||
});
|
||||
} catch (SVNException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static class CopyData {
|
||||
private final long myCopySourceRevision;
|
||||
private final long myCopyTargetRevision;
|
||||
private final boolean myTrunkSupposedCorrect;
|
||||
private static long getStart(final SVNLogClient logClient, final SVNURL url) {
|
||||
final Ref<Long> myRevisionCandidate = new Ref<Long>(0L);
|
||||
try {
|
||||
logClient.doLog(url, null, SVNRevision.UNDEFINED, SVNRevision.HEAD, SVNRevision.create(0),
|
||||
true, false, 0, new ISVNLogEntryHandler() {
|
||||
public void handleLogEntry(SVNLogEntry logEntry) throws SVNException {
|
||||
ProgressManager.checkCanceled();
|
||||
|
||||
public CopyData(long copySourceRevision, long copyTargetRevision, boolean trunkSupposedCorrect) {
|
||||
myCopySourceRevision = copySourceRevision;
|
||||
myCopyTargetRevision = copyTargetRevision;
|
||||
myTrunkSupposedCorrect = trunkSupposedCorrect;
|
||||
myRevisionCandidate.set(logEntry.getRevision());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public long getCopySourceRevision() {
|
||||
return myCopySourceRevision;
|
||||
catch (SVNException e) {
|
||||
//
|
||||
}
|
||||
return myRevisionCandidate.get();
|
||||
}
|
||||
|
||||
public long getCopyTargetRevision() {
|
||||
return myCopyTargetRevision;
|
||||
}
|
||||
private void checkForCopy(final SVNLogEntry logEntry, final Consumer<CopyData> result) {
|
||||
final Map map = logEntry.getChangedPaths();
|
||||
for (Object o : map.values()) {
|
||||
final SVNLogEntryPath path = (SVNLogEntryPath) o;
|
||||
final String localPath = path.getPath();
|
||||
final String copyPath = path.getCopyPath();
|
||||
|
||||
public boolean isTrunkSupposedCorrect() {
|
||||
return myTrunkSupposedCorrect;
|
||||
if ('A' == path.getType()) {
|
||||
if ((myBranchUrl.equals(localPath) || SVNPathUtil.isAncestor(localPath, myBranchUrl)) &&
|
||||
(myTrunkUrl.equals(copyPath)) || SVNPathUtil.isAncestor(copyPath, myTrunkUrl)) {
|
||||
result.consume(new CopyData(path.getCopyRevision(), logEntry.getRevision(), true));
|
||||
} else {
|
||||
if ((myBranchUrl.equals(copyPath) || SVNPathUtil.isAncestor(copyPath, myBranchUrl)) &&
|
||||
(myTrunkUrl.equals(localPath)) || SVNPathUtil.isAncestor(localPath, myTrunkUrl)) {
|
||||
result.consume(new CopyData(path.getCopyRevision(), logEntry.getRevision(), false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,16 +56,20 @@ public class SvnIntegrateChangesTask extends Task.Backgroundable {
|
||||
|
||||
private final List<VcsException> myExceptions;
|
||||
|
||||
private final UpdateEventHandler myHandler;
|
||||
private final IMerger myMerger;
|
||||
private final ResolveWorker myResolveWorker;
|
||||
private UpdateEventHandler myHandler;
|
||||
private IMerger myMerger;
|
||||
private ResolveWorker myResolveWorker;
|
||||
private FilePathImpl myMergeTarget;
|
||||
private final String myTitle;
|
||||
private final MergerFactory myMergerFactory;
|
||||
private final SVNURL myCurrentBranchUrl;
|
||||
private boolean myDryRun;
|
||||
|
||||
public SvnIntegrateChangesTask(final SvnVcs vcs, final WorkingCopyInfo info, final MergerFactory mergerFactory,
|
||||
final SVNURL currentBranchUrl, final String title, final boolean dryRun) {
|
||||
super(vcs.getProject(), title, true, VcsConfiguration.getInstance(vcs.getProject()).getUpdateOption());
|
||||
myMergerFactory = mergerFactory;
|
||||
myCurrentBranchUrl = currentBranchUrl;
|
||||
myDryRun = dryRun;
|
||||
myTitle = title;
|
||||
|
||||
@@ -76,10 +80,6 @@ public class SvnIntegrateChangesTask extends Task.Backgroundable {
|
||||
|
||||
myAccomulatedFiles = new UpdatedFilesReverseSide(UpdatedFiles.create());
|
||||
myExceptions = new ArrayList<VcsException>();
|
||||
|
||||
myHandler = new IntegrateEventHandler(myVcs, ProgressManager.getInstance().getProgressIndicator());
|
||||
myMerger = mergerFactory.createMerger(myVcs, new File(info.getLocalPath()), myHandler, currentBranchUrl);
|
||||
myResolveWorker = new ResolveWorker(myInfo.isUnderProjectRoot(), myProject);
|
||||
}
|
||||
|
||||
private void indicatorOnStart() {
|
||||
@@ -93,6 +93,10 @@ public class SvnIntegrateChangesTask extends Task.Backgroundable {
|
||||
}
|
||||
|
||||
public void run(@NotNull final ProgressIndicator indicator) {
|
||||
myHandler = new IntegrateEventHandler(myVcs, ProgressManager.getInstance().getProgressIndicator());
|
||||
myMerger = myMergerFactory.createMerger(myVcs, new File(myInfo.getLocalPath()), myHandler, myCurrentBranchUrl);
|
||||
myResolveWorker = new ResolveWorker(myInfo.isUnderProjectRoot(), myProject);
|
||||
|
||||
BlockReloadingUtil.block();
|
||||
myProjectLevelVcsManager.startBackgroundVcsOperation();
|
||||
|
||||
|
||||
@@ -157,6 +157,7 @@ public class BranchInfo {
|
||||
final String absoluteInTrunkPath = SVNPathUtil.append(myRepositoryRoot, path);
|
||||
if (! absoluteInTrunkPath.startsWith(myTrunkPathCorrespondingToLocalBranchPath)) {
|
||||
result.putValue(SvnMergeInfoCache.MergeCheckResult.NOT_EXISTS, path);
|
||||
continue;
|
||||
}
|
||||
final String relativeToTrunkPath = absoluteInTrunkPath.substring(myTrunkPathCorrespondingToLocalBranchPath.length());
|
||||
final String localPathInBranch = new File(branchPath, relativeToTrunkPath).getAbsolutePath();
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.dialogs.WCInfoWithBranches;
|
||||
import org.jetbrains.idea.svn.dialogs.WCPaths;
|
||||
import org.jetbrains.idea.svn.history.CopyData;
|
||||
import org.jetbrains.idea.svn.history.FirstInBranch;
|
||||
import org.jetbrains.idea.svn.history.SvnChangeList;
|
||||
import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
|
||||
@@ -167,8 +168,8 @@ public class SvnMergeInfoCache {
|
||||
myRevision = -1;
|
||||
|
||||
ApplicationManager.getApplication().executeOnPooledThread(new FirstInBranch(vcs, repositoryRoot, branchUrl, trunkUrl,
|
||||
new Consumer<FirstInBranch.CopyData>() {
|
||||
public void consume(FirstInBranch.CopyData copyData) {
|
||||
new Consumer<CopyData>() {
|
||||
public void consume(CopyData copyData) {
|
||||
if (copyData == null) return;
|
||||
myRevision = copyData.getCopySourceRevision();
|
||||
if (myRevision != -1) {
|
||||
|
||||
@@ -42,6 +42,6 @@
|
||||
Property <font color="#000080"><b>abc</b></font> will be reported as unnecessarily inherited in the file <b>messages_fr.properties</b>.
|
||||
<br>
|
||||
</font>
|
||||
<p><font face="verdana" size="-2">New in 7</font></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
or configuring the <b>Settings|General|File Encoding|Default encoding</b> setting,
|
||||
or by setting up the file/directory encoding in the <b>Settings|File/Directory Options|File Encodings</b>.
|
||||
</font>
|
||||
<p><font face="verdana" size="-2">New in 7</font></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -4,6 +4,6 @@
|
||||
This inspection lets you control MIME type name validity.
|
||||
|
||||
</font>
|
||||
<p><font face="verdana" size="-2">New in 7</font></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -9,6 +9,6 @@
|
||||
<li>another <b><font color="#000080">@TestOnly</font></b>-annotated method
|
||||
</ul>
|
||||
</font>
|
||||
<p><font face="verdana" size="-2">New in 7</font></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
<font face="verdana" size="-1">This inspection reports libraries attached to the specified inspection scope that
|
||||
are not used directly from code.<br><br>
|
||||
</font>
|
||||
<p><font face="verdana" size="-2">New in 7</font></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
<font face="verdana" size="-1">Checks consistency of <b>DTD</b> specific references, e.g. references to XML entity or to DTD element declaration.
|
||||
The validation works in DTD or XML file types.<br>
|
||||
</font>
|
||||
<p><font face="verdana" size="-2">New in 7</font></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,7 +3,7 @@
|
||||
<font face="verdana" size="-1">Reports empty tags (like <b>script</b>) that do not work in some browsers.
|
||||
The validation works in html or jsp file types.<br>
|
||||
</font>
|
||||
<p><font face="verdana" size="-2">New in 7</font></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,6 +3,6 @@
|
||||
<font face="verdana" size="-1">Reports <b>empty</b> tag body.
|
||||
The validation works in XML / JSP / JSPX / HTML/ XHTML file types.<br>
|
||||
</font>
|
||||
<p><font face="verdana" size="-2">New in 7</font></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,6 +3,6 @@
|
||||
<font face="verdana" size="-1">Thoroughly checks XML files for DTD / schema compliance using Xerces validator.
|
||||
The validation works in XML or XHTML file types.<br>
|
||||
</font>
|
||||
<p><font face="verdana" size="-2">New in 7</font></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -2,6 +2,6 @@
|
||||
<body>
|
||||
<font face="verdana" size="-1">This inspection spots extra closing tag for the empty elements like IMG or BR.<br>
|
||||
</font>
|
||||
<p><font face="verdana" size="-2">New in 7</font></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,6 +3,6 @@
|
||||
<font face="verdana" size="-1">This inspection highlight unknown HTML tag attributes as invalid and provides an ability to mark
|
||||
such attributes as Custom to not highlight them as invalid.<br>
|
||||
</font>
|
||||
<p><font face="verdana" size="-2">New in 7</font></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,6 +3,6 @@
|
||||
<font face="verdana" size="-1">This inspection highlights unknown HTML tags and provides an ability to mark such tags as Custom to
|
||||
not highlight them as unknown in future.<br>
|
||||
</font>
|
||||
<p><font face="verdana" size="-2">New in 7</font></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -2,6 +2,6 @@
|
||||
<body>
|
||||
<font face="verdana" size="-1">This inspection checks if root tag name is the same as in <doctype>.<br>
|
||||
</font>
|
||||
<p><font face="verdana" size="-2">New in 7</font></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user