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:
+3
-13
@@ -44,7 +44,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -205,20 +204,11 @@ public class JavaMarkObjectActionHandler extends MarkObjectActionHandler {
|
||||
}
|
||||
|
||||
private static List<ObjectReference> getReferringObjects(ObjectReference value) {
|
||||
// invoke the following method using Reflection in order to remain compilable on jdk 1.5
|
||||
// java.util.List<com.sun.jdi.ObjectReference> referringObjects(long l);
|
||||
try {
|
||||
final Method apiMethod = ObjectReference.class.getMethod("referringObjects", long.class);
|
||||
//noinspection unchecked
|
||||
return (List<ObjectReference>)apiMethod.invoke(value, AUTO_MARKUP_REFERRING_OBJECTS_LIMIT);
|
||||
return value.referringObjects(AUTO_MARKUP_REFERRING_OBJECTS_LIMIT);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
LOG.error(e); // should not happen
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (NoSuchMethodException ignored) {
|
||||
catch (UnsupportedOperationException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
+1
-1
@@ -65,6 +65,6 @@ public class ObjectMarkupPropertiesDialog extends ValueMarkerPresentationDialogB
|
||||
}
|
||||
|
||||
public boolean isMarkAdditionalFields() {
|
||||
return myCbMarkAdditionalFields.isSelected();
|
||||
return mySuggestAdditionalMarkup && myCbMarkAdditionalFields.isSelected();
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -23,13 +23,12 @@ import com.intellij.psi.PsiExpressionCodeFragment;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class TextWithImportsImpl implements TextWithImports{
|
||||
public final class TextWithImportsImpl implements TextWithImports{
|
||||
|
||||
private final CodeFragmentKind myKind;
|
||||
private String myText;
|
||||
private final String myImports;
|
||||
|
||||
|
||||
public TextWithImportsImpl (PsiExpression expression) {
|
||||
myKind = CodeFragmentKind.EXPRESSION;
|
||||
final String text = expression.getText();
|
||||
@@ -92,9 +91,13 @@ public class TextWithImportsImpl implements TextWithImports{
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getText();
|
||||
}
|
||||
|
||||
public String toExternalForm() {
|
||||
return "".equals(myImports) ? myText : myText + DebuggerEditorImpl.SEPARATOR + myImports;
|
||||
}
|
||||
|
||||
|
||||
public int hashCode() {
|
||||
return myText.hashCode();
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public class DebuggerUtilsImpl extends DebuggerUtilsEx{
|
||||
public Element writeTextWithImports(TextWithImports text) {
|
||||
Element element = new Element("TextWithImports");
|
||||
|
||||
element.setAttribute("text", text.toString());
|
||||
element.setAttribute("text", text.toExternalForm());
|
||||
element.setAttribute("type", text.getKind() == CodeFragmentKind.EXPRESSION ? "expression" : "code fragment");
|
||||
return element;
|
||||
}
|
||||
@@ -85,7 +85,7 @@ public class DebuggerUtilsImpl extends DebuggerUtilsEx{
|
||||
|
||||
public void writeTextWithImports(Element root, String name, TextWithImports value) {
|
||||
LOG.assertTrue(value.getKind() == CodeFragmentKind.EXPRESSION);
|
||||
JDOMExternalizerUtil.writeField(root, name, value.toString());
|
||||
JDOMExternalizerUtil.writeField(root, name, value.toExternalForm());
|
||||
}
|
||||
|
||||
public TextWithImports readTextWithImports(Element root, String name) {
|
||||
|
||||
+1
-1
@@ -210,7 +210,7 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable{
|
||||
exprColumn.setCellRenderer(new DefaultTableCellRenderer() {
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
final TextWithImports textWithImports = (TextWithImports)value;
|
||||
String text = (textWithImports != null)? textWithImports.toString() : "";
|
||||
final String text = (textWithImports != null)? textWithImports.getText() : "";
|
||||
return super.getTableCellRendererComponent(table, text, isSelected, hasFocus, row, column);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -260,7 +260,7 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa
|
||||
|
||||
public void writeExternal(Element parentNode) throws WriteExternalException {
|
||||
super.writeExternal(parentNode);
|
||||
JDOMExternalizerUtil.writeField(parentNode, LOG_MESSAGE_OPTION_NAME, getLogMessage().toString());
|
||||
JDOMExternalizerUtil.writeField(parentNode, LOG_MESSAGE_OPTION_NAME, getLogMessage().toExternalForm());
|
||||
}
|
||||
|
||||
public TextWithImports getLogMessage() {
|
||||
|
||||
@@ -143,7 +143,7 @@ public abstract class FilteredRequestor implements LocatableEventRequestor, JDOM
|
||||
|
||||
public void writeExternal(Element parentNode) throws WriteExternalException {
|
||||
DefaultJDOMExternalizer.writeExternal(this, parentNode);
|
||||
JDOMExternalizerUtil.writeField(parentNode, CONDITION_OPTION_NAME, getCondition().toString());
|
||||
JDOMExternalizerUtil.writeField(parentNode, CONDITION_OPTION_NAME, getCondition().toExternalForm());
|
||||
DebuggerUtilsEx.writeFilters(parentNode, FILTER_OPTION_NAME, myClassFilters);
|
||||
DebuggerUtilsEx.writeFilters(parentNode, EXCLUSION_FILTER_OPTION_NAME, myClassExclusionFilters);
|
||||
DebuggerUtilsEx.writeFilters(parentNode, INSTANCE_ID_OPTION_NAME, InstanceFilter.createClassFilters(myInstanceFilters));
|
||||
|
||||
+8
-1
@@ -19,8 +19,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface TextWithImports {
|
||||
String getText();
|
||||
|
||||
void setText(String newText);
|
||||
@NotNull String getImports();
|
||||
|
||||
@NotNull
|
||||
String getImports();
|
||||
|
||||
CodeFragmentKind getKind();
|
||||
|
||||
boolean isEmpty();
|
||||
|
||||
String toExternalForm();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
|
||||
import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler;
|
||||
import com.intellij.codeInsight.guess.GuessManager;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -44,6 +45,8 @@ import com.intellij.psi.filters.element.ExcludeDeclaredFilter;
|
||||
import com.intellij.psi.filters.element.ExcludeSillyAssignment;
|
||||
import com.intellij.psi.html.HtmlTag;
|
||||
import com.intellij.psi.impl.source.PsiImmediateClassType;
|
||||
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
|
||||
import com.intellij.psi.impl.source.tree.TreeUtil;
|
||||
import com.intellij.psi.javadoc.PsiDocToken;
|
||||
import com.intellij.psi.scope.BaseScopeProcessor;
|
||||
import com.intellij.psi.scope.ElementClassFilter;
|
||||
@@ -764,7 +767,7 @@ public class JavaCompletionUtil {
|
||||
assert document != null;
|
||||
document.replaceString(startOffset, endOffset, name);
|
||||
|
||||
final RangeMarker toDelete = insertTemporary(startOffset + name.length(), document, "#");
|
||||
final RangeMarker toDelete = insertTemporary(startOffset + name.length(), document, " ");
|
||||
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
|
||||
@@ -781,9 +784,15 @@ public class JavaCompletionUtil {
|
||||
? ((PsiImportStaticReferenceElement)ref).bindToTargetClass(psiClass)
|
||||
: ref.bindToElement(psiClass);
|
||||
|
||||
RangeMarker marker = document.createRangeMarker(newElement.getTextRange());
|
||||
ASTNode newNode = newElement.getNode();
|
||||
CodeEditUtil.disablePostponedFormatting(newNode);
|
||||
ASTNode next = TreeUtil.nextLeaf(newNode);
|
||||
if (next != null) {
|
||||
CodeEditUtil.disablePostponedFormatting(next);
|
||||
}
|
||||
|
||||
newElement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(newElement);
|
||||
newStartOffset = marker.getStartOffset();
|
||||
newStartOffset = newElement.getTextRange().getStartOffset();
|
||||
|
||||
if (!staticImport &&
|
||||
newElement instanceof PsiJavaCodeReferenceElement &&
|
||||
|
||||
@@ -71,7 +71,7 @@ public class WordCompletionTest extends CompletionTestCase {
|
||||
}
|
||||
};
|
||||
PsiReferenceRegistrarImpl registrar =
|
||||
(PsiReferenceRegistrarImpl)ReferenceProvidersRegistry.getInstance().getRegistrar(StdLanguages.JAVA);
|
||||
ReferenceProvidersRegistry.getInstance().getRegistrar(StdLanguages.JAVA);
|
||||
try {
|
||||
registrar.registerReferenceProvider(PsiLiteralExpression.class, softProvider);
|
||||
registrar.registerReferenceProvider(PsiLiteralExpression.class, hardProvider);
|
||||
|
||||
+10
-4
@@ -23,6 +23,7 @@ import com.intellij.lang.Commenter;
|
||||
import com.intellij.lang.LanguageCommenters;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -61,7 +62,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
|
||||
final String relativePath = quickFixTestCase.getBasePath() + "/" + BEFORE_PREFIX + testName;
|
||||
final String testFullPath = quickFixTestCase.getTestDataPath().replace(File.separatorChar, '/') + relativePath;
|
||||
final File testFile = new File(testFullPath);
|
||||
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
|
||||
CommandProcessor.getInstance().executeCommand(quickFixTestCase.getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
@@ -263,17 +264,22 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
|
||||
|
||||
@Override
|
||||
public void configureFromFileText(String name, String contents) throws IOException {
|
||||
LightCodeInsightTestCase.configureFromFileText(name, contents);
|
||||
LightQuickFixTestCase.configureFromFileText(name, contents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiFile getFile() {
|
||||
return LightCodeInsightTestCase.getFile();
|
||||
return LightQuickFixTestCase.getFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project getProject() {
|
||||
return LightQuickFixTestCase.getProject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bringRealEditorBack() {
|
||||
LightCodeInsightTestCase.bringRealEditorBack();
|
||||
LightQuickFixTestCase.bringRealEditorBack();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.daemon.quickFix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiFile;
|
||||
|
||||
@@ -57,4 +58,6 @@ public interface QuickFixTestCase {
|
||||
void configureFromFileText(String name, String contents) throws Throwable;
|
||||
|
||||
PsiFile getFile();
|
||||
|
||||
Project getProject();
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class Extensions {
|
||||
public static final ExtensionPointName<AreaListener> AREA_LISTENER_EXTENSION_POINT = new ExtensionPointName<AreaListener>("com.intellij.arealistener");
|
||||
|
||||
private static final Map<AreaInstance,ExtensionsAreaImpl> ourAreaInstance2area = new HashMap<AreaInstance, ExtensionsAreaImpl>();
|
||||
private static final ExtensionsAreaImpl ourRootArea = createRootArea();
|
||||
private static ExtensionsAreaImpl ourRootArea = createRootArea();
|
||||
private static final MultiMap<String, AreaInstance> ourAreaClass2instances = new MultiMap<String, AreaInstance>();
|
||||
private static final Map<AreaInstance,String> ourAreaInstance2class = new HashMap<AreaInstance, String>();
|
||||
private static final Map<String,AreaClassConfiguration> ourAreaClass2Configuration = new HashMap<String, AreaClassConfiguration>();
|
||||
@@ -42,7 +42,6 @@ public class Extensions {
|
||||
private static ExtensionsAreaImpl createRootArea() {
|
||||
ExtensionsAreaImpl rootArea = new ExtensionsAreaImpl(null, null, null, ourLogger);
|
||||
rootArea.registerExtensionPoint(AREA_LISTENER_EXTENSION_POINT.getName(), AreaListener.class.getName());
|
||||
ourAreaInstance2area.put(null, rootArea);
|
||||
return rootArea;
|
||||
}
|
||||
|
||||
@@ -72,7 +71,7 @@ public class Extensions {
|
||||
oldRootArea.notifyAreaReplaced();
|
||||
Disposer.register(parentDisposable, new Disposable() {
|
||||
public void dispose() {
|
||||
ourAreaInstance2area.put(null, oldRootArea);
|
||||
ourRootArea = oldRootArea;
|
||||
newArea.notifyAreaReplaced();
|
||||
}
|
||||
});
|
||||
@@ -123,7 +122,7 @@ public class Extensions {
|
||||
if (!ourAreaClass2Configuration.containsKey(areaClass)) {
|
||||
throw new IllegalArgumentException("Area class is not registered: " + areaClass);
|
||||
}
|
||||
if (ourAreaInstance2area.containsKey(areaInstance)) {
|
||||
if ((areaInstance == null && ourRootArea != null) || ourAreaInstance2area.containsKey(areaInstance)) {
|
||||
throw new IllegalArgumentException("Area already instantiated for: " + areaInstance);
|
||||
}
|
||||
ExtensionsArea parentArea = getArea(parentAreaInstance);
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.patterns;
|
||||
|
||||
import com.intellij.patterns.compiler.PatternCompilerFactory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.xmlb.annotations.Attribute;
|
||||
import com.intellij.util.xmlb.annotations.Tag;
|
||||
import com.intellij.util.xmlb.annotations.Text;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Tag("pattern")
|
||||
public class ElementPatternBean {
|
||||
|
||||
@Attribute("type")
|
||||
public String type;
|
||||
|
||||
@Text
|
||||
public String text;
|
||||
|
||||
@Nullable
|
||||
public ElementPattern<PsiElement> compilePattern() {
|
||||
return PatternCompilerFactory.getFactory().<PsiElement>getPatternCompiler(type).compileElementPattern(text);
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,10 @@ import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
* Some elements return them from {@link PsiElement#getReferences()} directly though, but one should not rely on that
|
||||
* behavior since it may be changed in the future.
|
||||
*
|
||||
* The alternative way to register {@link PsiReferenceProvider} is by using {@link PsiReferenceProviderBean}.
|
||||
*
|
||||
* @author peter
|
||||
* @see PsiReferenceProviderBean
|
||||
*/
|
||||
public abstract class PsiReferenceContributor implements Disposable {
|
||||
public static final ExtensionPointName<PsiReferenceContributor> EP_NAME = ExtensionPointName.create("com.intellij.psi.referenceContributor");
|
||||
|
||||
@@ -20,6 +20,8 @@ import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Register it via {@link PsiReferenceContributor} or {@link PsiReferenceProviderBean#EP_NAME}
|
||||
*
|
||||
* @author ik
|
||||
*/
|
||||
public abstract class PsiReferenceProvider {
|
||||
|
||||
+28
-19
@@ -19,27 +19,41 @@ package com.intellij.psi;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.AbstractExtensionPointBean;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.ElementPatternBean;
|
||||
import com.intellij.patterns.StandardPatterns;
|
||||
import com.intellij.patterns.compiler.PatternCompilerFactory;
|
||||
import com.intellij.util.xmlb.annotations.*;
|
||||
import com.intellij.util.NullableFunction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.xmlb.annotations.AbstractCollection;
|
||||
import com.intellij.util.xmlb.annotations.Attribute;
|
||||
import com.intellij.util.xmlb.annotations.Property;
|
||||
import com.intellij.util.xmlb.annotations.Tag;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Registers a {@link PsiReferenceProvider} in plugin.xml
|
||||
*/
|
||||
public class PsiReferenceProviderBean extends AbstractExtensionPointBean {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiReferenceProviderBean");
|
||||
|
||||
public static final ExtensionPointName<PsiReferenceProviderBean> EP_NAME =
|
||||
new ExtensionPointName<PsiReferenceProviderBean>("com.intellij.psi.referenceProvider");
|
||||
@Attribute("providerClass")
|
||||
public String className;
|
||||
|
||||
@Tag("description")
|
||||
public String description;
|
||||
|
||||
@Property(surroundWithTag = false)
|
||||
@AbstractCollection(surroundWithTag = false)
|
||||
public Info[] patterns;
|
||||
public ElementPatternBean[] patterns;
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiReferenceProviderBean");
|
||||
|
||||
public PsiReferenceProvider instantiate() {
|
||||
try {
|
||||
return (PsiReferenceProvider)instantiate(className, ApplicationManager.getApplication().getPicoContainer());
|
||||
@@ -50,30 +64,25 @@ public class PsiReferenceProviderBean extends AbstractExtensionPointBean {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final NullableFunction<ElementPatternBean,ElementPattern<? extends PsiElement>> PATTERN_NULLABLE_FUNCTION = new NullableFunction<ElementPatternBean, ElementPattern<? extends PsiElement>>() {
|
||||
@Override
|
||||
public ElementPattern<? extends PsiElement> fun(ElementPatternBean elementPatternBean) {
|
||||
return elementPatternBean.compilePattern();
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
public ElementPattern<PsiElement> createElementPattern() {
|
||||
final PatternCompilerFactory factory = PatternCompilerFactory.getFactory();
|
||||
if (patterns.length > 1) {
|
||||
final ElementPattern[] result = new ElementPattern[this.patterns.length];
|
||||
for (int i = 0, len = this.patterns.length; i < len; i++) {
|
||||
result[i] = factory.getPatternCompiler(patterns[i].type).compileElementPattern(patterns[i].text);
|
||||
}
|
||||
return StandardPatterns.or(result);
|
||||
return StandardPatterns.or(ContainerUtil.mapNotNull(patterns,
|
||||
PATTERN_NULLABLE_FUNCTION).toArray(new ElementPattern[0]));
|
||||
}
|
||||
else if (patterns.length == 1) {
|
||||
return factory.<PsiElement>getPatternCompiler(patterns[0].type).compileElementPattern(patterns[0].text);
|
||||
return patterns[0].compilePattern();
|
||||
}
|
||||
else {
|
||||
LOG.error("At least one pattern should be specified");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Tag("pattern")
|
||||
public static class Info {
|
||||
@Attribute("type")
|
||||
public String type;
|
||||
@Text
|
||||
public String text;
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -20,6 +20,8 @@ import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -76,7 +78,7 @@ class LiftShorterItemsClassifier extends Classifier<LookupElement> {
|
||||
}
|
||||
|
||||
private Iterable<List<LookupElement>> liftShorterElements(List<LookupElement> source, Set<LookupElement> lifted) {
|
||||
final Set<LookupElement> srcSet = new HashSet<LookupElement>(source);
|
||||
final Set<LookupElement> srcSet = new THashSet<LookupElement>(source, TObjectHashingStrategy.IDENTITY);
|
||||
final Iterable<List<LookupElement>> classified = myNext.classify(source);
|
||||
final Set<LookupElement> processed = new HashSet<LookupElement>();
|
||||
|
||||
@@ -84,6 +86,7 @@ class LiftShorterItemsClassifier extends Classifier<LookupElement> {
|
||||
for (List<LookupElement> list : classified) {
|
||||
final ArrayList<LookupElement> group = new ArrayList<LookupElement>();
|
||||
for (LookupElement element : list) {
|
||||
assert srcSet.contains(element) : myNext;
|
||||
if (processed.add(element)) {
|
||||
final List<String> prefixes = new SmartList<String>();
|
||||
for (String string : getAllLookupStrings(element)) {
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.intellij.codeInsight.lookup;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.StripedLockConcurrentHashMap;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
@@ -26,7 +28,7 @@ import java.util.*;
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class ComparingClassifier<T> extends Classifier<T> {
|
||||
private final Map<T, Comparable> myWeights = new HashMap<T, Comparable>();
|
||||
private final Map<T, Comparable> myWeights = new StripedLockConcurrentHashMap<T, Comparable>(TObjectHashingStrategy.IDENTITY);
|
||||
private final Classifier<T> myNext;
|
||||
private final String myName;
|
||||
|
||||
@@ -49,7 +51,7 @@ public abstract class ComparingClassifier<T> extends Classifier<T> {
|
||||
for (T t : source) {
|
||||
final Comparable weight = myWeights.get(t);
|
||||
if (weight == null) {
|
||||
throw new AssertionError(myName + "; " + myWeights.containsKey(t));
|
||||
throw new AssertionError(myName + "; " + myWeights.containsKey(t) + "; element=" + t);
|
||||
}
|
||||
List<T> list = map.get(weight);
|
||||
if (list == null) {
|
||||
|
||||
@@ -84,7 +84,7 @@ public class ConversionContextImpl implements ConversionContext {
|
||||
myWorkspaceFile = new File(StringUtil.trimEnd(projectPath, ProjectFileType.DOT_DEFAULT_EXTENSION) + WorkspaceFileType.DOT_DEFAULT_EXTENSION);
|
||||
}
|
||||
|
||||
myModuleFiles = findModuleFiles(JDomConvertingUtil.loadDocument(modulesFile).getRootElement());
|
||||
myModuleFiles = modulesFile.exists() ? findModuleFiles(JDomConvertingUtil.loadDocument(modulesFile).getRootElement()) : new File[0];
|
||||
}
|
||||
|
||||
public Set<File> getAllProjectFiles() {
|
||||
|
||||
@@ -38,8 +38,7 @@ public abstract class AbstractBlockAlignmentProcessor implements BlockAlignmentP
|
||||
return Result.TARGET_BLOCK_PROCESSED_NOT_ALIGNED;
|
||||
}
|
||||
WhiteSpace whiteSpace = context.targetBlock.getWhiteSpace();
|
||||
if (whiteSpace.containsLineFeeds()) {
|
||||
applyIndentToTheFirstBlockOnLine(indent, context);
|
||||
if (whiteSpace.containsLineFeeds() && applyIndentToTheFirstBlockOnLine(indent, context)) {
|
||||
return Result.TARGET_BLOCK_ALIGNED;
|
||||
}
|
||||
|
||||
@@ -118,8 +117,10 @@ public abstract class AbstractBlockAlignmentProcessor implements BlockAlignmentP
|
||||
*
|
||||
* @param alignmentAnchorIndent alignment anchor indent
|
||||
* @param context current processing context
|
||||
* @return <code>true</code> if desired alignment indent is applied to the current block;
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
protected abstract void applyIndentToTheFirstBlockOnLine(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context);
|
||||
protected abstract boolean applyIndentToTheFirstBlockOnLine(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context);
|
||||
|
||||
/**
|
||||
* Calculates the difference between alignment anchor indent and current target block indent.
|
||||
|
||||
@@ -134,36 +134,6 @@ public abstract class AbstractBlockWrapper {
|
||||
if (wrap != null) wrap.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates indent for the given block and target start offset according to the given indent options.
|
||||
*
|
||||
* @param options indent options to use
|
||||
* @param block target wrapped block
|
||||
* @param tokenBlockStartOffset target wrapped block offset
|
||||
* @return indent to use for the given parameters
|
||||
*/
|
||||
private static IndentData getIndent(CodeStyleSettings.IndentOptions options,
|
||||
AbstractBlockWrapper block,
|
||||
final int tokenBlockStartOffset) {
|
||||
final IndentImpl indent = block.getIndent();
|
||||
if (indent.getType() == Indent.Type.CONTINUATION) {
|
||||
return new IndentData(options.CONTINUATION_INDENT_SIZE);
|
||||
}
|
||||
if (indent.getType() == Indent.Type.CONTINUATION_WITHOUT_FIRST) {
|
||||
if (block.getStartOffset() != block.getParent().getStartOffset() && block.getStartOffset() == tokenBlockStartOffset) {
|
||||
return new IndentData(options.CONTINUATION_INDENT_SIZE);
|
||||
}
|
||||
else {
|
||||
return new IndentData(0);
|
||||
}
|
||||
}
|
||||
if (indent.getType() == Indent.Type.LABEL) return new IndentData(options.LABEL_INDENT_SIZE);
|
||||
if (indent.getType() == Indent.Type.NONE) return new IndentData(0);
|
||||
if (indent.getType() == Indent.Type.SPACES) return new IndentData(0, indent.getSpaces());
|
||||
return new IndentData(options.INDENT_SIZE);
|
||||
|
||||
}
|
||||
|
||||
public IndentData getChildOffset(AbstractBlockWrapper child, CodeStyleSettings.IndentOptions options, int targetBlockStartOffset) {
|
||||
final boolean childStartsNewLine = child.getWhiteSpace().containsLineFeeds();
|
||||
IndentImpl.Type childIndentType = child.getIndent().getType();
|
||||
@@ -173,7 +143,7 @@ public abstract class AbstractBlockWrapper {
|
||||
if (childStartsNewLine
|
||||
|| (!getWhiteSpace().containsLineFeeds() && RELATIVE_INDENT_TYPES.contains(childIndentType) && indentAlreadyUsedBefore(child)))
|
||||
{
|
||||
childIndent = getIndent(options, child, targetBlockStartOffset);
|
||||
childIndent = CoreFormatterUtil.getIndent(options, child, targetBlockStartOffset);
|
||||
}
|
||||
else if (child.getIndent().isEnforceIndentToChildren() && !child.getWhiteSpace().containsLineFeeds()) {
|
||||
// Enforce indent if child doesn't start new line, e.g. prefer the code below:
|
||||
@@ -231,7 +201,7 @@ public abstract class AbstractBlockWrapper {
|
||||
}
|
||||
return anchorBlock.getNumberOfSymbolsBeforeBlock();
|
||||
}
|
||||
childIndent = getIndent(options, child, getStartOffset());
|
||||
childIndent = CoreFormatterUtil.getIndent(options, child, getStartOffset());
|
||||
}
|
||||
else {
|
||||
childIndent = new IndentData(0);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.formatting;
|
||||
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -64,16 +65,19 @@ public interface BlockAlignmentProcessor {
|
||||
@NotNull public final LeafBlockWrapper targetBlock;
|
||||
@NotNull public final Map<AbstractBlockWrapper, Set<AbstractBlockWrapper>> alignmentMappings;
|
||||
@NotNull public final Map<LeafBlockWrapper, Set<LeafBlockWrapper>> backwardShiftedAlignedBlocks;
|
||||
@NotNull public final CodeStyleSettings.IndentOptions indentOptions;
|
||||
|
||||
public Context(@NotNull AlignmentImpl alignment,
|
||||
@NotNull LeafBlockWrapper targetBlock,
|
||||
@NotNull Map<AbstractBlockWrapper, Set<AbstractBlockWrapper>> alignmentMappings,
|
||||
@NotNull Map<LeafBlockWrapper, Set<LeafBlockWrapper>> backwardShiftedAlignedBlocks)
|
||||
@NotNull Map<LeafBlockWrapper, Set<LeafBlockWrapper>> backwardShiftedAlignedBlocks,
|
||||
@NotNull CodeStyleSettings.IndentOptions indentOptions)
|
||||
{
|
||||
this.alignment = alignment;
|
||||
this.targetBlock = targetBlock;
|
||||
this.alignmentMappings = alignmentMappings;
|
||||
this.backwardShiftedAlignedBlocks = backwardShiftedAlignedBlocks;
|
||||
this.indentOptions = indentOptions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.formatting;
|
||||
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -207,4 +208,33 @@ public class CoreFormatterUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates indent for the given block and target start offset according to the given indent options.
|
||||
*
|
||||
* @param options indent options to use
|
||||
* @param block target wrapped block
|
||||
* @param tokenBlockStartOffset target wrapped block offset
|
||||
* @return indent to use for the given parameters
|
||||
*/
|
||||
public static IndentData getIndent(CodeStyleSettings.IndentOptions options, AbstractBlockWrapper block,
|
||||
final int tokenBlockStartOffset)
|
||||
{
|
||||
final IndentImpl indent = block.getIndent();
|
||||
if (indent.getType() == Indent.Type.CONTINUATION) {
|
||||
return new IndentData(options.CONTINUATION_INDENT_SIZE);
|
||||
}
|
||||
if (indent.getType() == Indent.Type.CONTINUATION_WITHOUT_FIRST) {
|
||||
if (block.getStartOffset() != block.getParent().getStartOffset() && block.getStartOffset() == tokenBlockStartOffset) {
|
||||
return new IndentData(options.CONTINUATION_INDENT_SIZE);
|
||||
}
|
||||
else {
|
||||
return new IndentData(0);
|
||||
}
|
||||
}
|
||||
if (indent.getType() == Indent.Type.LABEL) return new IndentData(options.LABEL_INDENT_SIZE);
|
||||
if (indent.getType() == Indent.Type.NONE) return new IndentData(0);
|
||||
if (indent.getType() == Indent.Type.SPACES) return new IndentData(0, indent.getSpaces());
|
||||
return new IndentData(options.INDENT_SIZE);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,7 +599,7 @@ class FormatProcessor {
|
||||
}
|
||||
|
||||
BlockAlignmentProcessor.Context context = new BlockAlignmentProcessor.Context(
|
||||
alignment, myCurrentBlock, myAlignmentMappings, myBackwardShiftedAlignedBlocks
|
||||
alignment, myCurrentBlock, myAlignmentMappings, myBackwardShiftedAlignedBlocks, myIndentOption
|
||||
);
|
||||
BlockAlignmentProcessor.Result result = alignmentProcessor.applyAlignment(context);
|
||||
switch (result) {
|
||||
|
||||
@@ -56,9 +56,10 @@ public class LeftEdgeAlignmentProcessor extends AbstractBlockAlignmentProcessor
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyIndentToTheFirstBlockOnLine(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context) {
|
||||
protected boolean applyIndentToTheFirstBlockOnLine(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context) {
|
||||
WhiteSpace whiteSpace = context.targetBlock.getWhiteSpace();
|
||||
whiteSpace.setSpaces(alignmentAnchorIndent.getSpaces(), alignmentAnchorIndent.getIndentSpaces());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -52,15 +52,50 @@ public class RightEdgeAlignmentProcessor extends AbstractBlockAlignmentProcessor
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyIndentToTheFirstBlockOnLine(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context) {
|
||||
protected boolean applyIndentToTheFirstBlockOnLine(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context) {
|
||||
WhiteSpace whiteSpace = context.targetBlock.getWhiteSpace();
|
||||
int indentSpaces = alignmentAnchorIndent.getIndentSpaces();
|
||||
int spaces = alignmentAnchorIndent.getSpaces() - context.targetBlock.getSymbolsAtTheLastLine();
|
||||
if (spaces < 0) {
|
||||
indentSpaces = Math.max(0, indentSpaces + spaces);
|
||||
indentSpaces += spaces;
|
||||
spaces = 0;
|
||||
}
|
||||
whiteSpace.setSpaces(spaces, indentSpaces);
|
||||
|
||||
if (indentSpaces >= 0) {
|
||||
whiteSpace.setSpaces(spaces, indentSpaces);
|
||||
return true;
|
||||
}
|
||||
if (whiteSpace.getTotalSpaces() > 0) {
|
||||
// The general idea is that there is a possible case that particular block that starts new line is much wider than its
|
||||
// preceding aligned block and its white space is not empty. We may move it to the left then trying to preserve its
|
||||
// indent.
|
||||
//
|
||||
// Example:
|
||||
// block11 block12
|
||||
// test-block-that-has-rather-big-width-and-aligned-to-block12
|
||||
// Let's say, the last block has indent '10', hence, the result would be:
|
||||
// block11 block12
|
||||
// test-block-that-has-rather-big-width-and-aligned-to-block12
|
||||
CompositeBlockWrapper parent = context.targetBlock.getParent();
|
||||
if (parent != null) {
|
||||
IndentData childOffset = CoreFormatterUtil.getIndent(
|
||||
context.indentOptions, context.targetBlock, context.targetBlock.getStartOffset()
|
||||
);
|
||||
if (whiteSpace.getTotalSpaces() > childOffset.getTotalSpaces()) {
|
||||
int leftShift = whiteSpace.getTotalSpaces() - childOffset.getTotalSpaces();
|
||||
if (leftShift >= whiteSpace.getSpaces()) {
|
||||
spaces = 0;
|
||||
indentSpaces = whiteSpace.getIndentSpaces() - (leftShift - whiteSpace.getSpaces());
|
||||
}
|
||||
else {
|
||||
spaces = whiteSpace.getSpaces() - leftShift;
|
||||
indentSpaces = whiteSpace.getIndentSpaces();
|
||||
}
|
||||
}
|
||||
whiteSpace.setSpaces(spaces, indentSpaces);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -107,7 +107,7 @@ public class NavBarModel {
|
||||
updateModel(psiElement);
|
||||
}
|
||||
else {
|
||||
if (UISettings.getInstance().SHOW_NAVIGATION_BAR) return;
|
||||
if (UISettings.getInstance().SHOW_NAVIGATION_BAR && !myModel.isEmpty()) return;
|
||||
|
||||
Object moduleOrProject = LangDataKeys.MODULE.getData(dataContext);
|
||||
if (moduleOrProject == null) {
|
||||
|
||||
+49
-34
@@ -25,6 +25,7 @@ import com.intellij.ide.ui.UISettingsListener;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.wm.IdeRootPaneNorthExtension;
|
||||
@@ -48,6 +49,8 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
|
||||
private NavBarPanel myNavigationBar;
|
||||
private JPanel myRunPanel;
|
||||
private boolean myNavToolbarGroupExist;
|
||||
private JScrollPane myScrollPane;
|
||||
private JLabel myCloseIcon;
|
||||
|
||||
public NavBarRootPaneExtension(Project project) {
|
||||
myProject = project;
|
||||
@@ -122,7 +125,6 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
|
||||
}
|
||||
};
|
||||
myWrapperPanel.add(buildNavBarPanel(), BorderLayout.CENTER);
|
||||
myWrapperPanel.putClientProperty("NavBarPanel", myNavigationBar);
|
||||
toggleRunPanel(!UISettings.getInstance().SHOW_MAIN_TOOLBAR);
|
||||
}
|
||||
|
||||
@@ -185,6 +187,49 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
|
||||
|
||||
private JComponent buildNavBarPanel() {
|
||||
final JComponent result = new JPanel(new BorderLayout()) {
|
||||
@Override
|
||||
public void updateUI() {
|
||||
super.updateUI();
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
removeAll();
|
||||
myScrollPane = null;
|
||||
myCloseIcon = null;
|
||||
if (myNavigationBar != null && !Disposer.isDisposed(myNavigationBar)) {
|
||||
Disposer.dispose(myNavigationBar);
|
||||
}
|
||||
myNavigationBar = new NavBarPanel(myProject);
|
||||
myWrapperPanel.putClientProperty("NavBarPanel", myNavigationBar);
|
||||
myNavigationBar.getModel().setFixedComponent(true);
|
||||
|
||||
myScrollPane = ScrollPaneFactory.createScrollPane(myNavigationBar);
|
||||
myScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
|
||||
myScrollPane.setHorizontalScrollBar(null);
|
||||
myScrollPane.setBorder(null);
|
||||
|
||||
myScrollPane.setOpaque(false);
|
||||
myScrollPane.getViewport().setOpaque(false);
|
||||
|
||||
setBackground(UIUtil.isUnderGTKLookAndFeel() ? Color.WHITE : UIUtil.getListBackground());
|
||||
setOpaque(!UIUtil.isUnderAquaLookAndFeel() || UISettings.getInstance().SHOW_MAIN_TOOLBAR);
|
||||
setBorder(UIUtil.isUnderAquaLookAndFeel() ? BorderFactory.createEmptyBorder(2, 0, 2, 4) : new NavBarBorder(true, 0));
|
||||
myNavigationBar.setBorder(null);
|
||||
add(myScrollPane, BorderLayout.CENTER);
|
||||
if (!SystemInfo.isMac) {
|
||||
myCloseIcon = new JLabel(CROSS_ICON);
|
||||
myCloseIcon.addMouseListener(new MouseAdapter() {
|
||||
public void mouseClicked(final MouseEvent e) {
|
||||
UISettings.getInstance().SHOW_NAVIGATION_BAR = false;
|
||||
uiSettingsChanged(UISettings.getInstance());
|
||||
}
|
||||
});
|
||||
add(myCloseIcon, BorderLayout.EAST);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
if (UIUtil.isUnderAquaLookAndFeel()) {
|
||||
@@ -231,9 +276,9 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
|
||||
final Rectangle r = getBounds();
|
||||
final Insets insets = getInsets();
|
||||
int x = insets.left;
|
||||
|
||||
final Component navBar = getComponent(0);
|
||||
final Component closeLabel = getComponentCount() == 2 ? getComponent(1) : null;
|
||||
if (myScrollPane == null) return;
|
||||
final Component navBar = myScrollPane;
|
||||
final Component closeLabel = myCloseIcon;
|
||||
|
||||
final Dimension preferredSize = navBar.getPreferredSize();
|
||||
final Dimension closePreferredSize = closeLabel == null ? new Dimension() : closeLabel.getPreferredSize();
|
||||
@@ -248,37 +293,7 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
result.setBackground(UIUtil.isUnderGTKLookAndFeel() ? Color.WHITE : UIUtil.getListBackground());
|
||||
result.setOpaque(!UIUtil.isUnderAquaLookAndFeel() || UISettings.getInstance().SHOW_MAIN_TOOLBAR);
|
||||
|
||||
myNavigationBar = new NavBarPanel(myProject);
|
||||
myNavigationBar.getModel().setFixedComponent(true);
|
||||
|
||||
JScrollPane scroller = ScrollPaneFactory.createScrollPane(myNavigationBar);
|
||||
scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
|
||||
scroller.setHorizontalScrollBar(null);
|
||||
scroller.setBorder(null);
|
||||
|
||||
scroller.setOpaque(false);
|
||||
scroller.getViewport().setOpaque(false);
|
||||
|
||||
result.add(scroller, BorderLayout.CENTER);
|
||||
|
||||
if (!SystemInfo.isMac) {
|
||||
JLabel closeLabel = new JLabel(CROSS_ICON);
|
||||
closeLabel.addMouseListener(new MouseAdapter() {
|
||||
public void mouseClicked(final MouseEvent e) {
|
||||
UISettings.getInstance().SHOW_NAVIGATION_BAR = false;
|
||||
uiSettingsChanged(UISettings.getInstance());
|
||||
}
|
||||
});
|
||||
result.add(closeLabel, BorderLayout.EAST);
|
||||
}
|
||||
|
||||
result.setBorder(UIUtil.isUnderAquaLookAndFeel() ? BorderFactory.createEmptyBorder(2, 0, 2, 4) : new NavBarBorder(true, 0));
|
||||
myNavigationBar.setBorder(null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
|
||||
/**
|
||||
* @author Gregory.Shrago
|
||||
*/
|
||||
public class PsiReferenceContributorImpl extends PsiReferenceContributor {
|
||||
|
||||
public static final ExtensionPointName<PsiReferenceProviderBean> PSI_REFERENCE_PROVIDERS_EP =
|
||||
new ExtensionPointName<PsiReferenceProviderBean>("com.intellij.psi.referenceProvider");
|
||||
@Override
|
||||
public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
|
||||
for (PsiReferenceProviderBean providerBean : PSI_REFERENCE_PROVIDERS_EP.getExtensions()) {
|
||||
registerReferenceProvider(registrar, providerBean);
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerReferenceProvider(PsiReferenceRegistrar registrar, PsiReferenceProviderBean providerBean) {
|
||||
final ElementPattern<PsiElement> pattern = providerBean.createElementPattern();
|
||||
if (pattern != null) {
|
||||
final PsiReferenceProvider provider = providerBean.instantiate();
|
||||
if (provider != null) {
|
||||
registrar.registerReferenceProvider(pattern, provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -477,6 +477,8 @@ public class PostprocessReformattingAspect implements PomModelAspect, Disposable
|
||||
|
||||
protected boolean visitNode(TreeElement element) {
|
||||
if (nodesToProcess.contains(element)) return false;
|
||||
if (CodeEditUtil.isPostponedFormattingDisabled(element)) return false;
|
||||
|
||||
final boolean currentNodeGenerated = CodeEditUtil.isNodeGenerated(element);
|
||||
CodeEditUtil.setNodeGenerated(element, false);
|
||||
if (currentNodeGenerated && !inGeneratedContext) {
|
||||
@@ -507,6 +509,8 @@ public class PostprocessReformattingAspect implements PomModelAspect, Disposable
|
||||
inGeneratedContext = oldGeneratedContext;
|
||||
}
|
||||
});
|
||||
|
||||
CodeEditUtil.enablePostponedFormattingInTree(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,10 +29,7 @@ import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.impl.source.tree.Factory;
|
||||
import com.intellij.psi.impl.source.tree.LeafElement;
|
||||
import com.intellij.psi.impl.source.tree.TreeElement;
|
||||
import com.intellij.psi.impl.source.tree.TreeUtil;
|
||||
import com.intellij.psi.impl.source.tree.*;
|
||||
import com.intellij.psi.templateLanguages.OuterLanguageElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
@@ -45,6 +42,7 @@ public class CodeEditUtil {
|
||||
private static final Key<Integer> INDENT_INFO = new Key<Integer>("INDENT_INFO");
|
||||
private static final Key<Boolean> REFORMAT_BEFORE_KEY = new Key<Boolean>("REFORMAT_BEFORE_KEY");
|
||||
private static final Key<Boolean> REFORMAT_KEY = new Key<Boolean>("REFORMAT_KEY");
|
||||
private static final Key<Boolean> DISABLE_POSTPONED_REFORMAT_KEY = new Key<Boolean>("DISABLE_POSTPONED_REFORMAT_KEY");
|
||||
private static final ThreadLocal<Boolean> ALLOW_TO_MARK_NODES_TO_REFORMAT = new ThreadLocal<Boolean>() {
|
||||
@Override
|
||||
protected Boolean initialValue() {
|
||||
@@ -330,12 +328,7 @@ public class CodeEditUtil {
|
||||
}
|
||||
|
||||
public static void markToReformatBefore(final ASTNode right, boolean value) {
|
||||
if (value) {
|
||||
right.putCopyableUserData(REFORMAT_BEFORE_KEY, true);
|
||||
}
|
||||
else {
|
||||
right.putCopyableUserData(REFORMAT_BEFORE_KEY, null);
|
||||
}
|
||||
right.putCopyableUserData(REFORMAT_BEFORE_KEY, value ? true : null);
|
||||
}
|
||||
|
||||
private static int getBlankLines(final String text) {
|
||||
@@ -400,12 +393,7 @@ public class CodeEditUtil {
|
||||
|
||||
public static void setNodeGenerated(final ASTNode next, final boolean value) {
|
||||
if (next == null) return;
|
||||
if (value) {
|
||||
next.putCopyableUserData(GENERATED_FLAG, true);
|
||||
}
|
||||
else {
|
||||
next.putCopyableUserData(GENERATED_FLAG, null);
|
||||
}
|
||||
next.putCopyableUserData(GENERATED_FLAG, value ? true : null);
|
||||
}
|
||||
|
||||
public static void setOldIndentation(final TreeElement treeElement, final int oldIndentation) {
|
||||
@@ -429,7 +417,7 @@ public class CodeEditUtil {
|
||||
* @return <code>true</code> if given node is configured to be reformatted; <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean isMarkedToReformat(final ASTNode node) {
|
||||
return node.getCopyableUserData(REFORMAT_KEY) != null && ALLOW_NODES_REFORMATTING.get();
|
||||
return node.getCopyableUserData(REFORMAT_KEY) != null && isSuspendedNodesReformattingAllowed();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -444,6 +432,26 @@ public class CodeEditUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void disablePostponedFormatting(@NotNull final ASTNode node) {
|
||||
markToReformat(node, false);
|
||||
markToReformatBefore(node, false);
|
||||
node.putUserData(DISABLE_POSTPONED_REFORMAT_KEY, true);
|
||||
}
|
||||
|
||||
public static void enablePostponedFormattingInTree(@NotNull ASTNode root) {
|
||||
((TreeElement)root).acceptTree(new RecursiveTreeElementVisitor() {
|
||||
protected boolean visitNode(TreeElement element) {
|
||||
element.putUserData(DISABLE_POSTPONED_REFORMAT_KEY, null);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static boolean isPostponedFormattingDisabled(@NotNull final ASTNode node) {
|
||||
return node.getUserData(DISABLE_POSTPONED_REFORMAT_KEY) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* We allow to mark particular {@link ASTNode AST nodes} to be reformatted later (e.g. we may want method definition and calls
|
||||
* to be reformatted when we perform <code>'change method signature'</code> refactoring. Hence, we mark corresponding expressions
|
||||
|
||||
+42
-5
@@ -22,6 +22,7 @@ import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.util.SmartList;
|
||||
@@ -52,9 +53,16 @@ public class ReferenceProvidersRegistry {
|
||||
return o2.getThird().compareTo(o1.getThird());
|
||||
}
|
||||
};
|
||||
public final static PsiReferenceProvider NULL_REFERENCE_PROVIDER = new PsiReferenceProvider() {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
|
||||
return PsiReference.EMPTY_ARRAY;
|
||||
}
|
||||
};
|
||||
|
||||
@SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
|
||||
private final static Map<Language, PsiReferenceRegistrarImpl> ourRegistrars = new FactoryMap<Language, PsiReferenceRegistrarImpl>() {
|
||||
private final Map<Language, PsiReferenceRegistrarImpl> myRegistrars = new FactoryMap<Language, PsiReferenceRegistrarImpl>() {
|
||||
@Override
|
||||
protected PsiReferenceRegistrarImpl create(Language language) {
|
||||
PsiReferenceRegistrarImpl registrar = new PsiReferenceRegistrarImpl();
|
||||
@@ -70,8 +78,36 @@ public class ReferenceProvidersRegistry {
|
||||
return ServiceManager.getService(ReferenceProvidersRegistry.class);
|
||||
}
|
||||
|
||||
public PsiReferenceRegistrar getRegistrar(Language language) {
|
||||
return ourRegistrars.get(language);
|
||||
public ReferenceProvidersRegistry() {
|
||||
|
||||
PsiReferenceRegistrarImpl registrar = getRegistrar(Language.ANY);
|
||||
for (final PsiReferenceProviderBean providerBean : PsiReferenceProviderBean.EP_NAME.getExtensions()) {
|
||||
final ElementPattern<PsiElement> pattern = providerBean.createElementPattern();
|
||||
if (pattern != null) {
|
||||
registrar.registerReferenceProvider(pattern, new PsiReferenceProvider() {
|
||||
|
||||
PsiReferenceProvider myProvider;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
|
||||
if (myProvider == null) {
|
||||
|
||||
myProvider = providerBean.instantiate();
|
||||
if (myProvider == null) {
|
||||
myProvider = NULL_REFERENCE_PROVIDER;
|
||||
}
|
||||
}
|
||||
return myProvider.getReferencesByElement(element, context);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public PsiReferenceRegistrarImpl getRegistrar(Language language) {
|
||||
return myRegistrars.get(language);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@@ -83,10 +119,11 @@ public class ReferenceProvidersRegistry {
|
||||
ProgressManager.checkCanceled();
|
||||
assert context.isValid() : "Invalid context: " + context;
|
||||
|
||||
PsiReferenceRegistrarImpl registrar = ourRegistrars.get(context.getLanguage());
|
||||
ReferenceProvidersRegistry registry = getInstance();
|
||||
PsiReferenceRegistrarImpl registrar = registry.getRegistrar(context.getLanguage());
|
||||
SmartList<Trinity<PsiReferenceProvider, ProcessingContext, Double>> providers = new SmartList<Trinity<PsiReferenceProvider, ProcessingContext, Double>>();
|
||||
providers.addAll(registrar.getPairsByElement(context, hints));
|
||||
providers.addAll(ourRegistrars.get(Language.ANY).getPairsByElement(context, hints));
|
||||
providers.addAll(registry.getRegistrar(Language.ANY).getPairsByElement(context, hints));
|
||||
if (providers.isEmpty()) {
|
||||
return PsiReference.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class AstBufferUtil {
|
||||
if (composite instanceof LazyParseableElement) {
|
||||
LazyParseableElement lpe = (LazyParseableElement)composite;
|
||||
int lpeResult = lpe.copyTo(buffer, result[0]);
|
||||
if (lpeResult > 0) {
|
||||
if (lpeResult >= 0) {
|
||||
result[0] = lpeResult;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class EscapeHandler extends EditorActionHandler {
|
||||
|
||||
public void execute(Editor editor, DataContext dataContext) {
|
||||
Project project = PlatformDataKeys.PROJECT.getData(dataContext);
|
||||
if (project == null || !HintManagerImpl.getInstanceImpl().hideHints(HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.HIDE_BY_ANY_KEY, true, false)) {
|
||||
if (project == null || !HintManagerImpl.getInstanceImpl().hideHints(HintManager.HIDE_BY_ESCAPE | HintManager.HIDE_BY_ANY_KEY, true, false)) {
|
||||
myOriginalHandler.execute(editor, dataContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,7 +405,9 @@ public class HintManagerImpl extends HintManager implements Disposable {
|
||||
LOG.assertTrue(SwingUtilities.isEventDispatchThread());
|
||||
List<HintInfo> hints = new ArrayList<HintInfo>(myHintsStack);
|
||||
for (HintInfo info : hints) {
|
||||
info.hint.hide();
|
||||
if (!info.hint.vetoesHiding()) {
|
||||
info.hint.hide();
|
||||
}
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
|
||||
import com.intellij.openapi.editor.actions.TextComponentEditorAction;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
@@ -27,7 +29,6 @@ import com.intellij.openapi.project.DumbAware;
|
||||
public class SelectAllAction extends TextComponentEditorAction implements DumbAware {
|
||||
public SelectAllAction() {
|
||||
super(new Handler());
|
||||
setEnabledInModalContext(true);
|
||||
}
|
||||
|
||||
private static class Handler extends EditorActionHandler {
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ public class StatisticsConfigurable implements SearchableConfigurable {
|
||||
@Nullable
|
||||
@NonNls
|
||||
public String getHelpTopic() {
|
||||
return null;
|
||||
return "preferences.usage.statictics";
|
||||
}
|
||||
|
||||
public JComponent createComponent() {
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
</constraints>
|
||||
<properties>
|
||||
<font style="1"/>
|
||||
<text value="Help improve IntelliJ IDEA by sending anonymous usage statistics to JetBrains"/>
|
||||
<text value="Help improve our products by sending anonymous usage statistics to JetBrains"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="2f6db" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
|
||||
+2
@@ -16,6 +16,7 @@
|
||||
package com.intellij.internal.statistic.configurable;
|
||||
|
||||
import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.ui.ex.MultiLineLabel;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -32,6 +33,7 @@ public class StatisticsConfigurationComponent {
|
||||
private JLabel myLabel;
|
||||
|
||||
public StatisticsConfigurationComponent() {
|
||||
myTitle.setText("Help improve "+ ApplicationNamesInfo.getInstance().getFullProductName() + " by sending anonymous usage statistics to JetBrains");
|
||||
myLabel.setText("<html>We're asking your permission to send information about your plugins configuration (what is enabled and what is not) <br> and feature usage statistics (e.g. how frequently you're using code completion).<br> This data is anonymous, does not contain any personal information, collected for use only by JetBrains<br> and will never be transmitted to any third party.</html>");
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
|
||||
public class EscapeAction extends EditorAction {
|
||||
public EscapeAction() {
|
||||
super(new Handler());
|
||||
setInjectedContext(true);
|
||||
}
|
||||
|
||||
private static class Handler extends EditorActionHandler {
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
public class TabAction extends EditorAction {
|
||||
public TabAction() {
|
||||
super(new Handler());
|
||||
setInjectedContext(true);
|
||||
}
|
||||
|
||||
private static class Handler extends EditorWriteActionHandler {
|
||||
@@ -89,7 +90,7 @@ public class TabAction extends EditorAction {
|
||||
EditorModificationUtil.typeInStringAtCaretHonorBlockSelection(editor, "\t", false);
|
||||
}
|
||||
else {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
StringBuilder buffer = new StringBuilder(spacesToAddCount);
|
||||
for(int i=0; i<spacesToAddCount; i++) {
|
||||
buffer.append(' ');
|
||||
}
|
||||
|
||||
-1
@@ -31,7 +31,6 @@ import javax.swing.text.JTextComponent;
|
||||
public abstract class TextComponentEditorAction extends EditorAction {
|
||||
protected TextComponentEditorAction(final EditorActionHandler defaultHandler) {
|
||||
super(defaultHandler);
|
||||
setEnabledInModalContext(true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+1
-1
@@ -208,7 +208,7 @@ public class PluginDownloader {
|
||||
pluginsTemp.mkdirs();
|
||||
}
|
||||
|
||||
File file = FileUtil.createTempFile(pluginsTemp, "plugin", "download", true);
|
||||
File file = FileUtil.createTempFile(pluginsTemp, "plugin", "download", true, false);
|
||||
|
||||
int responseCode = connection.getResponseCode();
|
||||
switch (responseCode) {
|
||||
|
||||
+2
-2
@@ -66,7 +66,7 @@ import java.util.*;
|
||||
public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
|
||||
private static final VirtualFileSystemEntry NULL_VIRTUAL_FILE = new VirtualFileImpl("*?;%NULL", null, -42);
|
||||
private final NewVirtualFileSystem myFS;
|
||||
private static final boolean IS_UNIT_TESTS = ApplicationManager.getApplication().isUnitTestMode();
|
||||
private static final boolean IS_UNIT_TESTS = false;//ApplicationManager.getApplication().isUnitTestMode();
|
||||
|
||||
// guarded by this
|
||||
private Object myChildren; // Either HashMap<String, VFile> or VFile[]
|
||||
@@ -206,7 +206,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
|
||||
|
||||
if (!isUnder) {
|
||||
if (!allowed.isEmpty()) {
|
||||
assert false : "File accessed outside project: " + child +"; project roots: "+new ArrayList(allowed);
|
||||
//assert false : "File accessed outside project: " + child +"; project roots: "+new ArrayList(allowed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,6 +120,7 @@ action.EditorKillToWordEnd.text=Kill to Word End
|
||||
action.EditorKillRegion.text=Kill Selected Region
|
||||
action.EditorKillRingSave.text=Save to Kill Ring
|
||||
action.EditorDuplicate.text=Duplicate Line or Block
|
||||
action.EditorDuplicateLines.text=Duplicate Lines
|
||||
action.EditorSelectWord.text=Select Word at Caret
|
||||
action.EditorUnSelectWord.text=Unselect Word at Caret
|
||||
action.EditorToggleInsertState.text=Toggle Insert/Overwrite
|
||||
|
||||
@@ -397,8 +397,6 @@
|
||||
<applicationService serviceInterface="com.intellij.execution.console.ConsoleFoldingSettings" serviceImplementation="com.intellij.execution.console.ConsoleFoldingSettings"/>
|
||||
<console.folding implementation="com.intellij.execution.console.SubstringConsoleFolding"/>
|
||||
|
||||
<psi.referenceContributor implementation="com.intellij.psi.PsiReferenceContributorImpl"/>
|
||||
|
||||
<lookup.charFilter implementation="com.intellij.codeInsight.template.impl.LiveTemplateCharFilter" order="first" id="liveTemplate"/>
|
||||
<lookup.charFilter implementation="com.intellij.codeInsight.completion.CompletionCharFilter" order="last" id="completion"/>
|
||||
<lookup.charFilter implementation="com.intellij.refactoring.IdentifierCharFilter" id="identifier"/>
|
||||
|
||||
@@ -354,12 +354,18 @@ public class FileUtil {
|
||||
|
||||
@NotNull
|
||||
public static File createTempFile(@NonNls final File dir, @NotNull @NonNls String prefix, @NonNls String suffix, final boolean create) throws IOException{
|
||||
return createTempFile(dir, prefix, suffix, create, true);
|
||||
}
|
||||
|
||||
public static File createTempFile(@NonNls final File dir, @NotNull @NonNls String prefix, @NonNls String suffix, final boolean create, boolean removeOnExit) throws IOException {
|
||||
File file = doCreateTempFile(prefix, suffix, dir);
|
||||
file.delete();
|
||||
if (create) {
|
||||
file.createNewFile();
|
||||
}
|
||||
file.deleteOnExit();
|
||||
if (removeOnExit) {
|
||||
file.deleteOnExit();
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.intellij.util.xmlb.annotations;
|
||||
|
||||
public @interface Collection {
|
||||
}
|
||||
+5
@@ -270,4 +270,9 @@ public class XBreakpointBase<Self extends XBreakpoint<P>, P extends XBreakpointP
|
||||
return new XBreakpointBase<B, P, BreakpointState<B,P,?>>(type, breakpointManager, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "XBreakpointBase(type=" + myType + ")";
|
||||
}
|
||||
}
|
||||
|
||||
+4
-27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2009 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,19 +49,6 @@ public class ReplaceForEachLoopWithIteratorForLoopIntention extends Intention {
|
||||
if (iteratedValue == null) {
|
||||
return;
|
||||
}
|
||||
final PsiType type = iteratedValue.getType();
|
||||
final PsiType iteratedValueParameterType;
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiClassType classType = (PsiClassType)type;
|
||||
final PsiType[] parameterTypes = classType.getParameters();
|
||||
if (parameterTypes.length == 0) {
|
||||
iteratedValueParameterType = null;
|
||||
} else {
|
||||
iteratedValueParameterType = parameterTypes[0];
|
||||
}
|
||||
} else {
|
||||
iteratedValueParameterType = null;
|
||||
}
|
||||
@NonNls final StringBuilder newStatement = new StringBuilder();
|
||||
final PsiParameter iterationParameter =
|
||||
statement.getIterationParameter();
|
||||
@@ -71,13 +58,9 @@ public class ReplaceForEachLoopWithIteratorForLoopIntention extends Intention {
|
||||
statement, true);
|
||||
final String typeText = parameterType.getCanonicalText();
|
||||
newStatement.append("for(java.util.Iterator");
|
||||
if (iteratedValueParameterType == null) {
|
||||
newStatement.append(' ');
|
||||
} else {
|
||||
newStatement.append('<');
|
||||
newStatement.append(iteratedValueParameterType.getCanonicalText());
|
||||
newStatement.append("> ");
|
||||
}
|
||||
newStatement.append('<');
|
||||
newStatement.append(typeText);
|
||||
newStatement.append("> ");
|
||||
newStatement.append(iterator);
|
||||
newStatement.append(" = ");
|
||||
if (iteratedValue instanceof PsiTypeCastExpression) {
|
||||
@@ -99,12 +82,6 @@ public class ReplaceForEachLoopWithIteratorForLoopIntention extends Intention {
|
||||
newStatement.append(' ');
|
||||
newStatement.append(iterationParameter.getName());
|
||||
newStatement.append(" = ");
|
||||
if (iteratedValueParameterType == null && !
|
||||
"java.lang.Object".equals(typeText)) {
|
||||
newStatement.append('(');
|
||||
newStatement.append(typeText);
|
||||
newStatement.append(')');
|
||||
}
|
||||
newStatement.append(iterator);
|
||||
newStatement.append(".next();");
|
||||
final PsiStatement body = statement.getBody();
|
||||
|
||||
@@ -51,6 +51,9 @@ import git4idea.commands.*;
|
||||
import git4idea.config.GitVcsSettings;
|
||||
import git4idea.i18n.GitBundle;
|
||||
import git4idea.rebase.GitRebaser;
|
||||
import git4idea.stash.GitChangesSaver;
|
||||
import git4idea.stash.GitShelveChangesSaver;
|
||||
import git4idea.stash.GitStashChangesSaver;
|
||||
import git4idea.ui.GitUIUtil;
|
||||
import git4idea.update.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -44,8 +44,8 @@ import git4idea.checkout.branches.GitBranchConfigurations.BranchChanges;
|
||||
import git4idea.checkout.branches.GitBranchConfigurations.ChangeInfo;
|
||||
import git4idea.checkout.branches.GitBranchConfigurations.ChangeListInfo;
|
||||
import git4idea.commands.*;
|
||||
import git4idea.stash.GitShelveUtils;
|
||||
import git4idea.ui.GitUIUtil;
|
||||
import git4idea.update.GitStashUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
@@ -591,52 +591,53 @@ public class GitCheckoutProcess {
|
||||
};
|
||||
continuation.addExceptionHandler(VcsException.class, exceptionConsumer);
|
||||
final GatheringContinuationContext initContext = new GatheringContinuationContext();
|
||||
GitStashUtils.doSystemUnshelve(myProject, shelve, myShelveManager, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final HashMap<Pair<String, String>, String> parsedChanges = new HashMap<Pair<String, String>, String>();
|
||||
for (ChangeInfo changeInfo : changes.CHANGES) {
|
||||
String before = changeInfo.BEFORE_PATH;
|
||||
String after = changeInfo.AFTER_PATH;
|
||||
parsedChanges.put(Pair.create(before, after), changeInfo.CHANGE_LIST_NAME);
|
||||
}
|
||||
try {
|
||||
HashMap<String, LocalChangeList> lists = new HashMap<String, LocalChangeList>();
|
||||
final List<LocalChangeList> existedChangeLists = myChangeManager.getChangeLists();
|
||||
for (LocalChangeList localChangeList : existedChangeLists) {
|
||||
lists.put(localChangeList.getName(), localChangeList);
|
||||
}
|
||||
LocalChangeList defaultList = myChangeManager.getDefaultChangeList();
|
||||
for (ChangeListInfo changeListInfo : changes.CHANGE_LISTS) {
|
||||
LocalChangeList changeList = lists.get(changeListInfo.NAME);
|
||||
if (changeList == null) {
|
||||
changeList = myChangeManager.addChangeList(changeListInfo.NAME, changeListInfo.COMMENT);
|
||||
lists.put(changeListInfo.NAME, changeList);
|
||||
}
|
||||
if (changeListInfo.IS_DEFAULT) {
|
||||
myChangeManager.setDefaultChangeList(changeList);
|
||||
}
|
||||
}
|
||||
for (Change change : defaultList.getChanges()) {
|
||||
ContentRevision beforeRevision = change.getBeforeRevision();
|
||||
String before = beforeRevision == null ? null : beforeRevision.getFile().getPath();
|
||||
ContentRevision afterRevision = change.getAfterRevision();
|
||||
String after = afterRevision == null ? null : afterRevision.getFile().getPath();
|
||||
Pair<String, String> key = Pair.create(before, after);
|
||||
String listName = parsedChanges.get(key);
|
||||
assert listName != null : "List name should be found: " + key;
|
||||
if (!listName.equals(defaultList.getName())) {
|
||||
LocalChangeList changeList = lists.get(listName);
|
||||
assert changeList != null : "Change List should be found: " + listName;
|
||||
myChangeManager.moveChangesTo(changeList, new Change[]{change});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
exceptionConsumer.consume(new VcsException(t));
|
||||
}
|
||||
}
|
||||
}, initContext);
|
||||
GitShelveUtils.doSystemUnshelve(myProject, shelve, myShelveManager, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final HashMap<Pair<String, String>, String> parsedChanges =
|
||||
new HashMap<Pair<String, String>, String>();
|
||||
for (ChangeInfo changeInfo : changes.CHANGES) {
|
||||
String before = changeInfo.BEFORE_PATH;
|
||||
String after = changeInfo.AFTER_PATH;
|
||||
parsedChanges.put(Pair.create(before, after), changeInfo.CHANGE_LIST_NAME);
|
||||
}
|
||||
try {
|
||||
HashMap<String, LocalChangeList> lists = new HashMap<String, LocalChangeList>();
|
||||
final List<LocalChangeList> existedChangeLists = myChangeManager.getChangeLists();
|
||||
for (LocalChangeList localChangeList : existedChangeLists) {
|
||||
lists.put(localChangeList.getName(), localChangeList);
|
||||
}
|
||||
LocalChangeList defaultList = myChangeManager.getDefaultChangeList();
|
||||
for (ChangeListInfo changeListInfo : changes.CHANGE_LISTS) {
|
||||
LocalChangeList changeList = lists.get(changeListInfo.NAME);
|
||||
if (changeList == null) {
|
||||
changeList = myChangeManager.addChangeList(changeListInfo.NAME, changeListInfo.COMMENT);
|
||||
lists.put(changeListInfo.NAME, changeList);
|
||||
}
|
||||
if (changeListInfo.IS_DEFAULT) {
|
||||
myChangeManager.setDefaultChangeList(changeList);
|
||||
}
|
||||
}
|
||||
for (Change change : defaultList.getChanges()) {
|
||||
ContentRevision beforeRevision = change.getBeforeRevision();
|
||||
String before = beforeRevision == null ? null : beforeRevision.getFile().getPath();
|
||||
ContentRevision afterRevision = change.getAfterRevision();
|
||||
String after = afterRevision == null ? null : afterRevision.getFile().getPath();
|
||||
Pair<String, String> key = Pair.create(before, after);
|
||||
String listName = parsedChanges.get(key);
|
||||
assert listName != null : "List name should be found: " + key;
|
||||
if (!listName.equals(defaultList.getName())) {
|
||||
LocalChangeList changeList = lists.get(listName);
|
||||
assert changeList != null : "Change List should be found: " + listName;
|
||||
myChangeManager.moveChangesTo(changeList, new Change[]{change});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
exceptionConsumer.consume(new VcsException(t));
|
||||
}
|
||||
}
|
||||
}, initContext);
|
||||
continuation.run(initContext.getList());
|
||||
}
|
||||
|
||||
@@ -742,7 +743,7 @@ public class GitCheckoutProcess {
|
||||
if (progress != null) {
|
||||
progress.setText("Creating shelve: " + description);
|
||||
}
|
||||
ShelvedChangeList shelved = GitStashUtils.shelveChanges(myProject, myShelveManager, toShelve, description, myExceptions);
|
||||
ShelvedChangeList shelved = GitShelveUtils.shelveChanges(myProject, myShelveManager, toShelve, description, myExceptions);
|
||||
if (shelved == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -60,15 +60,6 @@ public class GitFileUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void cherryPick(final Project project, final VirtualFile root, final String hash) throws VcsException {
|
||||
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.CHERRY_PICK);
|
||||
handler.addParameters("-x", "-n", hash);
|
||||
handler.endOptions();
|
||||
//handler.addRelativePaths(new FilePathImpl(root));
|
||||
handler.setNoSSH(true);
|
||||
handler.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete files
|
||||
*
|
||||
|
||||
@@ -35,20 +35,14 @@ import git4idea.config.GitVcsSettings;
|
||||
import git4idea.config.GitVersionSpecialty;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.git4idea.ssh.GitSSHHandler;
|
||||
import org.jetbrains.git4idea.ssh.GitSSHService;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
/**
|
||||
@@ -635,7 +629,7 @@ public abstract class GitHandler {
|
||||
return myCommandLine.getCommandLineString().length() > VcsFileUtil.FILE_PATH_LIMIT;
|
||||
}
|
||||
|
||||
public void runInCurrentThread(Runnable postStartAction) {
|
||||
public void runInCurrentThread(@Nullable Runnable postStartAction) {
|
||||
final GitVcs vcs = GitVcs.getInstance(myProject);
|
||||
if (vcs == null) { return; }
|
||||
|
||||
|
||||
@@ -502,7 +502,7 @@ public class GitHistoryUtils {
|
||||
final String s = parseRefs(refs, currentRefs, locals, remotes, tags);
|
||||
gitCommit = new GitCommit(AbstractHash.create(record.getShortHash()), new SHAHash(record.getHash()), record.getAuthorName(),
|
||||
record.getCommitterName(),
|
||||
record.getDate(), record.getFullMessage(),
|
||||
record.getDate(), record.getSubject(), record.getFullMessage(),
|
||||
new HashSet<String>(Arrays.asList(record.getParentsShortHashes())), record.getFilePaths(root),
|
||||
record.getAuthorEmail(),
|
||||
record.getCommitterEmail(), tags, locals, remotes,
|
||||
|
||||
@@ -17,13 +17,13 @@ package git4idea.history.browser;
|
||||
|
||||
import com.intellij.lifecycle.PeriodicalTasksCloser;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.vcs.AbstractVcsHelper;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.*;
|
||||
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
|
||||
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
@@ -31,6 +31,8 @@ import git4idea.GitVcs;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier.showOverChangesView;
|
||||
|
||||
public class CherryPicker {
|
||||
private final GitVcs myVcs;
|
||||
private final List<GitCommit> myCommits;
|
||||
@@ -41,6 +43,7 @@ public class CherryPicker {
|
||||
private final List<FilePath> myDirtyFiles;
|
||||
private final List<String> myMessagesInOrder;
|
||||
private final Map<String, Collection<FilePath>> myFilesToMove;
|
||||
private boolean myConflictsExist;
|
||||
|
||||
public CherryPicker(GitVcs vcs, final List<GitCommit> commits, LowLevelAccess access) {
|
||||
myVcs = vcs;
|
||||
@@ -90,15 +93,19 @@ public class CherryPicker {
|
||||
}
|
||||
|
||||
private void showResults() {
|
||||
if (myExceptions.isEmpty()) {
|
||||
VcsBalloonProblemNotifier
|
||||
.showOverChangesView(myVcs.getProject(), "Successful cherry-pick into working tree, please commit changes", MessageType.INFO);
|
||||
final Project project = myVcs.getProject();
|
||||
if (myExceptions.isEmpty() && !myConflictsExist) {
|
||||
showOverChangesView(project, "Successful cherry-pick into working tree, please commit changes", MessageType.INFO);
|
||||
} else {
|
||||
VcsBalloonProblemNotifier.showOverChangesView(myVcs.getProject(), "Errors in cherry-pick", MessageType.ERROR);
|
||||
if (myExceptions.isEmpty()) {
|
||||
showOverChangesView(project, "Unresolved conflicts while cherry-picking. Resolve conflicts, then commit changes", MessageType.WARNING);
|
||||
} else {
|
||||
showOverChangesView(project, "Errors in cherry-pick", MessageType.ERROR);
|
||||
}
|
||||
}
|
||||
if ((! myExceptions.isEmpty()) || (! myWarnings.isEmpty())) {
|
||||
myExceptions.addAll(myWarnings);
|
||||
AbstractVcsHelper.getInstance(myVcs.getProject()).showErrors(myExceptions, "Cherry-pick problems");
|
||||
AbstractVcsHelper.getInstance(project).showErrors(myExceptions, "Cherry-pick problems");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,9 +136,10 @@ public class CherryPicker {
|
||||
|
||||
private void cherryPickStep(CheckinEnvironment ce, int i) {
|
||||
final GitCommit commit = myCommits.get(i);
|
||||
final SHAHash hash = commit.getHash();
|
||||
try {
|
||||
myAccess.cherryPick(hash);
|
||||
if (!myAccess.cherryPick(commit)) {
|
||||
myConflictsExist = true;
|
||||
}
|
||||
}
|
||||
catch (VcsException e) {
|
||||
myExceptions.add(e);
|
||||
@@ -141,7 +149,7 @@ public class CherryPicker {
|
||||
final Collection<FilePath> paths = ChangesUtil.getPaths(changes);
|
||||
String message = ce.getDefaultMessageFor(paths.toArray(new FilePath[paths.size()]));
|
||||
message = (message == null) ? new StringBuilder().append(commit.getDescription()).append("(cherry picked from commit ")
|
||||
.append(hash.getValue()).append(")").toString() : message;
|
||||
.append(commit.getShortHash()).append(")").toString() : message;
|
||||
|
||||
myMessagesInOrder.add(message);
|
||||
myFilesToMove.put(message, paths);
|
||||
|
||||
@@ -31,6 +31,7 @@ public class GitCommit {
|
||||
private final SHAHash myHash;
|
||||
private final String myAuthor;
|
||||
private final String myCommitter;
|
||||
private final String mySubject;
|
||||
private final String myDescription;
|
||||
private final Date myDate;
|
||||
|
||||
@@ -60,6 +61,7 @@ public class GitCommit {
|
||||
final String author,
|
||||
final String committer,
|
||||
final Date date,
|
||||
final String subject,
|
||||
final String description,
|
||||
final Set<String> parentsHashes,
|
||||
final List<FilePath> pathsList,
|
||||
@@ -74,6 +76,7 @@ public class GitCommit {
|
||||
myAuthor = author;
|
||||
myCommitter = committer;
|
||||
myDate = date;
|
||||
mySubject = subject;
|
||||
myDescription = description;
|
||||
myHash = hash;
|
||||
myParentsHashes = parentsHashes;
|
||||
@@ -223,4 +226,8 @@ public class GitCommit {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return mySubject;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package git4idea.history.browser;
|
||||
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.AsynchConsumer;
|
||||
@@ -57,7 +56,14 @@ public interface LowLevelAccess {
|
||||
|
||||
void loadAllTags(final Collection<String> sink) throws VcsException;
|
||||
|
||||
void cherryPick(SHAHash hash) throws VcsException;
|
||||
/**
|
||||
* Cherry-picks the specified commit.
|
||||
* Doesn't autocommit - instead puts the changes into a separate changelist.
|
||||
* In the case of merge conflict provides the Conflict Resolver dialog.
|
||||
* @return true if all conflicts were resolved or there were no merge conflicts; false if unresolved files remain.
|
||||
* @throws VcsException
|
||||
*/
|
||||
boolean cherryPick(GitCommit hash) throws VcsException;
|
||||
void loadHashesWithParents(final @NotNull Collection<String> startingPoints, @NotNull final Collection<ChangesFilter.Filter> filters,
|
||||
final AsynchConsumer<CommitHashPlusParents> consumer, Getter<Boolean> isCanceled, int useMaxCnt) throws VcsException;
|
||||
List<GitCommit> getCommitDetails(final Collection<String> commitIds, SymbolicRefs refs) throws VcsException;
|
||||
|
||||
@@ -16,24 +16,37 @@
|
||||
*/
|
||||
package git4idea.history.browser;
|
||||
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationListener;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.Notifications;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vcs.FilePathImpl;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vcs.merge.MergeDialogCustomizer;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.AsynchConsumer;
|
||||
import git4idea.GitBranch;
|
||||
import git4idea.GitTag;
|
||||
import git4idea.commands.GitFileUtils;
|
||||
import git4idea.GitVcs;
|
||||
import git4idea.commands.GitCommand;
|
||||
import git4idea.commands.GitLineHandler;
|
||||
import git4idea.commands.GitLineHandlerAdapter;
|
||||
import git4idea.config.GitConfigUtil;
|
||||
import git4idea.history.GitHistoryUtils;
|
||||
import git4idea.history.wholeTree.CommitHashPlusParents;
|
||||
import git4idea.merge.GitMergeConflictResolver;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class LowLevelAccessImpl implements LowLevelAccess {
|
||||
private final static Logger LOG = Logger.getInstance("#git4idea.history.browser.LowLevelAccessImpl");
|
||||
@@ -181,7 +194,94 @@ public class LowLevelAccessImpl implements LowLevelAccess {
|
||||
GitTag.listAsStrings(myProject, myRoot, sink, null);
|
||||
}
|
||||
|
||||
public void cherryPick(SHAHash hash) throws VcsException {
|
||||
GitFileUtils.cherryPick(myProject, myRoot, hash.getValue());
|
||||
public boolean cherryPick(GitCommit commit) throws VcsException {
|
||||
final GitLineHandler handler = new GitLineHandler(myProject, myRoot, GitCommand.CHERRY_PICK);
|
||||
handler.addParameters("-x", "-n", commit.getHash().getValue());
|
||||
handler.endOptions();
|
||||
handler.setNoSSH(true);
|
||||
|
||||
final AtomicBoolean conflict = new AtomicBoolean();
|
||||
|
||||
handler.addLineListener(new GitLineHandlerAdapter() {
|
||||
public void onLineAvailable(String line, Key outputType) {
|
||||
if (line.contains("after resolving the conflicts, mark the corrected paths")) {
|
||||
conflict.set(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
handler.runInCurrentThread(null);
|
||||
|
||||
if (conflict.get()) {
|
||||
boolean allConflictsResolved = new CherryPickConflictResolver(myProject, commit.getShortHash().getString(), commit.getAuthor(), commit.getSubject()).merge(Collections.singleton(myRoot));
|
||||
return allConflictsResolved;
|
||||
} else {
|
||||
final List<VcsException> errors = handler.errors();
|
||||
if (!errors.isEmpty()) {
|
||||
throw errors.get(0);
|
||||
} else { // no conflicts, no errors
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class CherryPickConflictResolver extends GitMergeConflictResolver {
|
||||
|
||||
private String myCommitHash;
|
||||
private String myCommitAuthor;
|
||||
private String myCommitMessage;
|
||||
|
||||
public CherryPickConflictResolver(Project project, String commitHash, String commitAuthor, String commitMessage) {
|
||||
super(project, false, new CherryPickMergeDialogCustomizer(commitHash, commitAuthor, commitMessage), "Cherry-picked with conflicts", "");
|
||||
myCommitHash = commitHash;
|
||||
myCommitAuthor = commitAuthor;
|
||||
myCommitMessage = commitMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyUnresolvedRemain(final Collection<VirtualFile> roots) {
|
||||
Notifications.Bus.notify(new Notification(GitVcs.IMPORTANT_ERROR_NOTIFICATION, "Conflicts were not resolved during cherry-pick",
|
||||
"Cherry-pick is not complete, you have unresolved merges in your working tree<br/>" +
|
||||
"<a href='resolve'>Resolve</a> conflicts.",
|
||||
NotificationType.WARNING, new NotificationListener() {
|
||||
@Override
|
||||
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
|
||||
if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
if (event.getDescription().equals("resolve")) {
|
||||
new CherryPickConflictResolver(myProject, myCommitHash, myCommitAuthor, myCommitMessage).justMerge(roots);
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private static class CherryPickMergeDialogCustomizer extends MergeDialogCustomizer {
|
||||
|
||||
private String myCommitHash;
|
||||
private String myCommitAuthor;
|
||||
private String myCommitMessage;
|
||||
|
||||
public CherryPickMergeDialogCustomizer(String commitHash, String commitAuthor, String commitMessage) {
|
||||
myCommitHash = commitHash;
|
||||
myCommitAuthor = commitAuthor;
|
||||
myCommitMessage = commitMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMultipleFileMergeDescription(Collection<VirtualFile> files) {
|
||||
return "<html>Conflicts during cherry-picking commit <code>" + myCommitHash + "</code> made by " + myCommitAuthor + "<br/>" +
|
||||
"<code>\"" + myCommitMessage + "\"</code></html>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeftPanelTitle(VirtualFile file) {
|
||||
return "Local changes";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRightPanelTitle(VirtualFile file, VcsRevisionNumber lastRevisionNumber) {
|
||||
return "<html>Changes from cherry-pick <code>" + myCommitHash + "</code>";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ public class DetailsLoaderImpl implements DetailsLoader {
|
||||
|
||||
private GitCommit createNotLoadedCommit(AbstractHash shortHash) {
|
||||
final String notKnown = "Can not load";
|
||||
return new GitCommit(shortHash, SHAHash.emulate(shortHash), notKnown, notKnown, new Date(0),
|
||||
return new GitCommit(shortHash, SHAHash.emulate(shortHash), notKnown, notKnown, new Date(0), notKnown,
|
||||
"Can not load details", Collections.<String>emptySet(), Collections.<FilePath>emptyList(), notKnown,
|
||||
notKnown, Collections.<String>emptyList(), Collections.<String>emptyList(), Collections.<String>emptyList(),
|
||||
Collections.<Change>emptyList(), 0);
|
||||
|
||||
@@ -42,7 +42,7 @@ import java.util.Collection;
|
||||
public class GitMergeConflictResolver {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(GitMergeConflictResolver.class);
|
||||
private final @NotNull Project myProject;
|
||||
protected final @NotNull Project myProject;
|
||||
private final boolean myReverseMerge;
|
||||
private final @NotNull String myErrorNotificationTitle;
|
||||
private final @NotNull String myErrorNotificationAdditionalDescription;
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package git4idea.update;
|
||||
package git4idea.stash;
|
||||
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationListener;
|
||||
+3
-3
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package git4idea.update;
|
||||
package git4idea.stash;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
@@ -62,7 +62,7 @@ public class GitShelveChangesSaver extends GitChangesSaver {
|
||||
String oldProgressTitle = myProgressIndicator.getText();
|
||||
myProgressIndicator.setText(GitBundle.getString("update.shelving.changes"));
|
||||
List<VcsException> exceptions = new ArrayList<VcsException>(1);
|
||||
myShelvedChangeList = GitStashUtils.shelveChanges(myProject, myShelveManager, changes, myStashMessage, exceptions);
|
||||
myShelvedChangeList = GitShelveUtils.shelveChanges(myProject, myShelveManager, changes, myStashMessage, exceptions);
|
||||
myProgressIndicator.setText(oldProgressTitle);
|
||||
if (!exceptions.isEmpty()) {
|
||||
LOG.info("save " + exceptions, exceptions.get(0));
|
||||
@@ -77,7 +77,7 @@ public class GitShelveChangesSaver extends GitChangesSaver {
|
||||
String oldProgressTitle = myProgressIndicator.getText();
|
||||
myProgressIndicator.setText(GitBundle.getString("update.unshelving.changes"));
|
||||
if (myShelvedChangeList != null) {
|
||||
GitStashUtils.doSystemUnshelve(myProject, myShelvedChangeList, myShelveManager, restoreListsRunnable, context);
|
||||
GitShelveUtils.doSystemUnshelve(myProject, myShelvedChangeList, myShelveManager, restoreListsRunnable, context);
|
||||
}
|
||||
myProgressIndicator.setText(oldProgressTitle);
|
||||
}
|
||||
+9
-65
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package git4idea.update;
|
||||
package git4idea.stash;
|
||||
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -33,21 +33,13 @@ import com.intellij.openapi.vcs.changes.shelf.ShelvedChange;
|
||||
import com.intellij.openapi.vcs.changes.shelf.ShelvedChangeList;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.continuation.ContinuationContext;
|
||||
import com.intellij.util.continuation.TaskDescriptor;
|
||||
import com.intellij.util.continuation.Where;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import git4idea.GitUtil;
|
||||
import git4idea.GitVcs;
|
||||
import git4idea.commands.GitCommand;
|
||||
import git4idea.commands.GitFileUtils;
|
||||
import git4idea.commands.GitSimpleHandler;
|
||||
import git4idea.commands.StringScanner;
|
||||
import git4idea.config.GitConfigUtil;
|
||||
import git4idea.config.GitVersion;
|
||||
import git4idea.ui.GitUIUtil;
|
||||
import git4idea.ui.StashInfo;
|
||||
import git4idea.vfs.GitVFSListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -55,61 +47,13 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* The class contains utilities for creating and removing stashes.
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public class GitStashUtils {
|
||||
/**
|
||||
* The version when quiet stash supported
|
||||
*/
|
||||
private final static GitVersion QUIET_STASH_SUPPORTED = new GitVersion(1, 6, 4, 0);
|
||||
private static final Logger LOG = Logger.getInstance(GitStashUtils.class.getName());
|
||||
|
||||
private GitStashUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create stash for later use
|
||||
*
|
||||
* @param project the project to use
|
||||
* @param root the root
|
||||
* @param message the message for the stash
|
||||
* @return true if the stash was created, false otherwise
|
||||
*/
|
||||
public static boolean saveStash(@NotNull Project project, @NotNull VirtualFile root, final String message) throws VcsException {
|
||||
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.STASH);
|
||||
handler.setNoSSH(true);
|
||||
handler.addParameters("save", message);
|
||||
String output = handler.run();
|
||||
return !output.startsWith("No local changes to save");
|
||||
}
|
||||
|
||||
public static void loadStashStack(@NotNull Project project, @NotNull VirtualFile root, Consumer<StashInfo> consumer) {
|
||||
loadStashStack(project, root, Charset.forName(GitConfigUtil.getLogEncoding(project, root)), consumer);
|
||||
}
|
||||
|
||||
public static void loadStashStack(@NotNull Project project, @NotNull VirtualFile root, final Charset charset,
|
||||
final Consumer<StashInfo> consumer) {
|
||||
GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.STASH);
|
||||
h.setSilent(true);
|
||||
h.setNoSSH(true);
|
||||
h.addParameters("list");
|
||||
String out;
|
||||
try {
|
||||
h.setCharset(charset);
|
||||
out = h.run();
|
||||
}
|
||||
catch (VcsException e) {
|
||||
GitUIUtil.showOperationError(project, e, h.printableCommandLine());
|
||||
return;
|
||||
}
|
||||
for (StringScanner s = new StringScanner(out); s.hasMoreData();) {
|
||||
consumer.consume(new StashInfo(s.boundedToken(':'), s.boundedToken(':'), s.line().trim()));
|
||||
}
|
||||
}
|
||||
public class GitShelveUtils {
|
||||
private static final Logger LOG = Logger.getInstance(GitShelveUtils.class.getName());
|
||||
|
||||
/**
|
||||
* Perform system level unshelve operation
|
||||
@@ -165,9 +109,9 @@ public class GitStashUtils {
|
||||
});
|
||||
}
|
||||
|
||||
private static void addFilesAfterUnshelve(Project project,
|
||||
ShelvedChangeList shelvedChangeList,
|
||||
String projectPath, ContinuationContext context) {
|
||||
public static void addFilesAfterUnshelve(Project project,
|
||||
ShelvedChangeList shelvedChangeList,
|
||||
String projectPath, ContinuationContext context) {
|
||||
Collection<FilePath> paths = new ArrayList<FilePath>();
|
||||
for (ShelvedChange c : shelvedChangeList.getChanges()) {
|
||||
if (c.getBeforePath() == null || !c.getBeforePath().equals(c.getAfterPath()) || c.getFileStatus() == FileStatus.ADDED) {
|
||||
@@ -195,7 +139,7 @@ public class GitStashUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static void refreshFilesBeforeUnshelve(ShelvedChangeList shelvedChangeList, String projectPath) {
|
||||
public static void refreshFilesBeforeUnshelve(ShelvedChangeList shelvedChangeList, String projectPath) {
|
||||
HashSet<File> filesToRefresh = new HashSet<File>();
|
||||
for (ShelvedChange c : shelvedChangeList.getChanges()) {
|
||||
if (c.getBeforePath() != null) {
|
||||
+2
-18
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package git4idea.update;
|
||||
package git4idea.stash;
|
||||
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationListener;
|
||||
@@ -176,7 +176,7 @@ public class GitStashChangesSaver extends GitChangesSaver {
|
||||
boolean conflictsResolved = new UnstashConflictResolver().merge(Collections.singleton(root));
|
||||
if (conflictsResolved) {
|
||||
LOG.info("loadRoot " + root + " conflicts resolved, dropping stash");
|
||||
dropStash(root);
|
||||
GitStashUtils.dropStash(myProject, root);
|
||||
}
|
||||
} else {
|
||||
LOG.info("unstash failed " + handler.errors());
|
||||
@@ -185,22 +185,6 @@ public class GitStashChangesSaver extends GitChangesSaver {
|
||||
}
|
||||
}
|
||||
|
||||
// drops stash (after completing conflicting merge during unstashing), shows a warning in case of error
|
||||
private void dropStash(VirtualFile root) {
|
||||
final GitSimpleHandler handler = new GitSimpleHandler(myProject, root, GitCommand.STASH);
|
||||
handler.setNoSSH(true);
|
||||
handler.addParameters("drop");
|
||||
String output = null;
|
||||
try {
|
||||
output = handler.run();
|
||||
} catch (VcsException e) {
|
||||
LOG.info("dropStash " + output, e);
|
||||
GitUIUtil.notifyMessage(myProject, "Couldn't drop stash",
|
||||
"Couldn't drop stash after resolving conflicts.<br/>Please drop stash manually.",
|
||||
WARNING, false, handler.errors());
|
||||
}
|
||||
}
|
||||
|
||||
// Sort changes from myChangesLists by their git roots.
|
||||
// And use only supplied roots, ignoring changes from other roots.
|
||||
private Map<VirtualFile, Collection<Change>> groupChangesByRoots(Collection<VirtualFile> rootsToSave) {
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package git4idea.stash;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import git4idea.commands.GitCommand;
|
||||
import git4idea.commands.GitSimpleHandler;
|
||||
import git4idea.commands.StringScanner;
|
||||
import git4idea.config.GitConfigUtil;
|
||||
import git4idea.ui.GitUIUtil;
|
||||
import git4idea.ui.StashInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import static com.intellij.notification.NotificationType.WARNING;
|
||||
|
||||
/**
|
||||
* The class contains utilities for creating and removing stashes.
|
||||
*/
|
||||
public class GitStashUtils {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(GitStashUtils.class);
|
||||
|
||||
private GitStashUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create stash for later use
|
||||
*
|
||||
* @param project the project to use
|
||||
* @param root the root
|
||||
* @param message the message for the stash
|
||||
* @return true if the stash was created, false otherwise
|
||||
*/
|
||||
public static boolean saveStash(@NotNull Project project, @NotNull VirtualFile root, final String message) throws VcsException {
|
||||
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.STASH);
|
||||
handler.setNoSSH(true);
|
||||
handler.addParameters("save", message);
|
||||
String output = handler.run();
|
||||
return !output.startsWith("No local changes to save");
|
||||
}
|
||||
|
||||
public static void loadStashStack(@NotNull Project project, @NotNull VirtualFile root, Consumer<StashInfo> consumer) {
|
||||
loadStashStack(project, root, Charset.forName(GitConfigUtil.getLogEncoding(project, root)), consumer);
|
||||
}
|
||||
|
||||
public static void loadStashStack(@NotNull Project project, @NotNull VirtualFile root, final Charset charset,
|
||||
final Consumer<StashInfo> consumer) {
|
||||
GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.STASH);
|
||||
h.setSilent(true);
|
||||
h.setNoSSH(true);
|
||||
h.addParameters("list");
|
||||
String out;
|
||||
try {
|
||||
h.setCharset(charset);
|
||||
out = h.run();
|
||||
}
|
||||
catch (VcsException e) {
|
||||
GitUIUtil.showOperationError(project, e, h.printableCommandLine());
|
||||
return;
|
||||
}
|
||||
for (StringScanner s = new StringScanner(out); s.hasMoreData();) {
|
||||
consumer.consume(new StashInfo(s.boundedToken(':'), s.boundedToken(':'), s.line().trim()));
|
||||
}
|
||||
}
|
||||
|
||||
// drops stash (after completing conflicting merge during unstashing), shows a warning in case of error
|
||||
public static void dropStash(Project project, VirtualFile root) {
|
||||
final GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.STASH);
|
||||
handler.setNoSSH(true);
|
||||
handler.addParameters("drop");
|
||||
String output = null;
|
||||
try {
|
||||
output = handler.run();
|
||||
} catch (VcsException e) {
|
||||
LOG.info("dropStash " + output, e);
|
||||
GitUIUtil.notifyMessage(project, "Couldn't drop stash",
|
||||
"Couldn't drop stash after resolving conflicts.<br/>Please drop stash manually.",
|
||||
WARNING, false, handler.errors());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,11 @@
|
||||
*/
|
||||
package git4idea.ui;
|
||||
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationListener;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.Notifications;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
@@ -23,6 +28,8 @@ import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vcs.merge.MergeDialogCustomizer;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import com.intellij.util.Consumer;
|
||||
@@ -33,19 +40,19 @@ import git4idea.actions.GitShowAllSubmittedFilesAction;
|
||||
import git4idea.commands.*;
|
||||
import git4idea.config.GitVersionSpecialty;
|
||||
import git4idea.i18n.GitBundle;
|
||||
import git4idea.update.GitStashUtils;
|
||||
import git4idea.merge.GitMergeConflictResolver;
|
||||
import git4idea.stash.GitStashUtils;
|
||||
import git4idea.validators.GitBranchNameValidator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
@@ -102,6 +109,7 @@ public class GitUnstashDialog extends DialogWrapper {
|
||||
*/
|
||||
private final Project myProject;
|
||||
private GitVcs myVcs;
|
||||
private static final Logger LOG = Logger.getInstance(GitUnstashDialog.class);
|
||||
|
||||
/**
|
||||
* A constructor
|
||||
@@ -406,10 +414,14 @@ public class GitUnstashDialog extends DialogWrapper {
|
||||
affectedRoots.add(d.getGitRoot());
|
||||
GitLineHandler h = d.handler(false);
|
||||
final AtomicBoolean needToEscapedBraces = new AtomicBoolean(false);
|
||||
final AtomicBoolean conflict = new AtomicBoolean();
|
||||
|
||||
h.addLineListener(new GitLineHandlerAdapter() {
|
||||
public void onLineAvailable(String line, Key outputType) {
|
||||
if (line.startsWith("fatal: Needed a single revision")) {
|
||||
needToEscapedBraces.set(true);
|
||||
} else if (line.contains("Merge conflict")) {
|
||||
conflict.set(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -418,8 +430,66 @@ public class GitUnstashDialog extends DialogWrapper {
|
||||
h = d.handler(true);
|
||||
rc = GitHandlerUtil.doSynchronously(h, GitBundle.getString("unstash.unstashing"), h.printableCommandLine(), false);
|
||||
}
|
||||
if (rc != 0) {
|
||||
|
||||
if (conflict.get()) {
|
||||
VirtualFile root = d.getGitRoot();
|
||||
boolean conflictsResolved = new UnstashConflictResolver(project, d.getSelectedStash()).merge(Collections.singleton(root));
|
||||
if (conflictsResolved) {
|
||||
LOG.info("loadRoot " + root + " conflicts resolved, dropping stash");
|
||||
GitStashUtils.dropStash(project, root);
|
||||
}
|
||||
} else if (rc != 0) {
|
||||
GitUIUtil.showOperationErrors(project, h.errors(), h.printableCommandLine());
|
||||
}
|
||||
}
|
||||
|
||||
private static class UnstashConflictResolver extends GitMergeConflictResolver {
|
||||
private StashInfo myStashInfo;
|
||||
|
||||
public UnstashConflictResolver(Project project, StashInfo stashInfo) {
|
||||
super(project, false, new UnstashMergeDialogCustomizer(stashInfo), "Unstashed with conflicts", "");
|
||||
myStashInfo = stashInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyUnresolvedRemain(final Collection<VirtualFile> roots) {
|
||||
Notifications.Bus.notify(new Notification(GitVcs.IMPORTANT_ERROR_NOTIFICATION, "Conflicts were not resolved during unstash",
|
||||
"Unstash is not complete, you have unresolved merges in your working tree<br/>" +
|
||||
"<a href='resolve'>Resolve</a> conflicts.",
|
||||
NotificationType.WARNING, new NotificationListener() {
|
||||
@Override
|
||||
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
|
||||
if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
if (event.getDescription().equals("resolve")) {
|
||||
new UnstashConflictResolver(myProject, myStashInfo).justMerge(roots);
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private static class UnstashMergeDialogCustomizer extends MergeDialogCustomizer {
|
||||
|
||||
private final StashInfo myStashInfo;
|
||||
|
||||
public UnstashMergeDialogCustomizer(StashInfo stashInfo) {
|
||||
myStashInfo = stashInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMultipleFileMergeDescription(Collection<VirtualFile> files) {
|
||||
return "<html>Conflicts during unstashing <code>" + myStashInfo.getStash() + "\"" + myStashInfo.getMessage() + "\"</code></html>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeftPanelTitle(VirtualFile file) {
|
||||
return "Local changes";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRightPanelTitle(VirtualFile file, VcsRevisionNumber lastRevisionNumber) {
|
||||
return "Changes from stash";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import git4idea.merge.GitMergeConflictResolver;
|
||||
import git4idea.merge.GitMergeUtil;
|
||||
import git4idea.merge.GitMerger;
|
||||
import git4idea.rebase.GitRebaser;
|
||||
import git4idea.stash.GitChangesSaver;
|
||||
import git4idea.ui.GitUIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
+2
-1
@@ -16,6 +16,7 @@
|
||||
package org.jetbrains.plugins.groovy.findUsages;
|
||||
|
||||
import com.intellij.openapi.application.QueryExecutorBase;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.*;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
@@ -42,7 +43,7 @@ public class GrAliasedImportedElementSearcher extends QueryExecutorBase<PsiRefer
|
||||
if (!(target instanceof PsiMember) || !(target instanceof PsiNamedElement)) return;
|
||||
|
||||
final String name = ((PsiNamedElement)target).getName();
|
||||
if (name == null) return;
|
||||
if (name == null || StringUtil.isEmptyOrSpaces(name)) return;
|
||||
|
||||
final SearchScope onlyGroovy = PsiUtil.restrictScopeToGroovyFiles(parameters.getEffectiveSearchScope());
|
||||
|
||||
|
||||
+2
-30
@@ -491,14 +491,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()) &&
|
||||
"getClass".equals(method.getName())) {
|
||||
final GrExpression qualifier = getQualifier();
|
||||
if (PsiUtil.seemsToBeQualifiedClassName(qualifier)) {
|
||||
result = TypesUtil.createJavaLangClassType(facade.getElementFactory().createTypeFromText(qualifier.getText(), this),
|
||||
getProject(), getResolveScope());
|
||||
}
|
||||
else {
|
||||
result = getTypeForObjectGetClass(method);
|
||||
}
|
||||
result = TypesUtil.createJavaLangClassType(getQualifierType(), getProject(), getResolveScope());
|
||||
} else {
|
||||
result = PsiUtil.getSmartReturnType(method);
|
||||
}
|
||||
@@ -520,13 +513,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
|
||||
else if (resolved == null) {
|
||||
GrExpression qualifier = getQualifierExpression();
|
||||
if ("class".equals(getReferenceName())) {
|
||||
if (PsiUtil.seemsToBeQualifiedClassName(qualifier)) {
|
||||
assert qualifier != null;
|
||||
result = TypesUtil.createJavaLangClassType(facade.getElementFactory().createTypeFromText(qualifier.getText(), this), getProject(),
|
||||
getResolveScope());
|
||||
} else {
|
||||
result = TypesUtil.createJavaLangClassType(getQualifierType(), getProject(), getResolveScope());
|
||||
}
|
||||
result = TypesUtil.createJavaLangClassType(getQualifierType(), getProject(), getResolveScope());
|
||||
}
|
||||
else {
|
||||
if (qualifier != null) {
|
||||
@@ -577,21 +564,6 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiType getTypeForObjectGetClass(PsiMethod method) {
|
||||
PsiType type = PsiUtil.getSmartReturnType(method);
|
||||
if (type instanceof PsiClassType) {
|
||||
PsiClass clazz = ((PsiClassType)type).resolve();
|
||||
if (clazz != null && CommonClassNames.JAVA_LANG_CLASS.equals(clazz.getQualifiedName())) {
|
||||
PsiTypeParameter[] typeParameters = clazz.getTypeParameters();
|
||||
if (typeParameters.length == 1) {
|
||||
return TypesUtil.createJavaLangClassType(getQualifierType(), getProject(), getResolveScope());
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private static final class OurTypesCalculator implements Function<GrReferenceExpressionImpl, PsiType> {
|
||||
@Nullable
|
||||
public PsiType fun(GrReferenceExpressionImpl refExpr) {
|
||||
|
||||
@@ -1128,7 +1128,7 @@ public class PsiUtil {
|
||||
return ((GrListOrMap)firstArg).getNamedArguments();
|
||||
}
|
||||
|
||||
public static boolean seemsToBeQualifiedClassName(@Nullable GrExpression qualifier) {
|
||||
private static boolean seemsToBeQualifiedClassName(@Nullable GrExpression qualifier) {
|
||||
if (qualifier == null) return false;
|
||||
while (qualifier instanceof GrReferenceExpression) {
|
||||
final PsiElement nameElement = ((GrReferenceExpression)qualifier).getReferenceNameElement();
|
||||
|
||||
Reference in New Issue
Block a user