mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+5
@@ -214,6 +214,11 @@ public class FieldEvaluator implements Evaluator {
|
||||
return modifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "field " + myFieldName;
|
||||
}
|
||||
|
||||
private static final class FQNameClassFilter implements TargetClassFilter {
|
||||
private final String myQName;
|
||||
|
||||
|
||||
+2
-5
@@ -360,11 +360,8 @@ public class GenericsHighlightUtil {
|
||||
Map<PsiClass, PsiSubstitutor> inheritedClasses,
|
||||
Set<PsiClass> visited,
|
||||
TextRange textRange) {
|
||||
final PsiClassType[] superTypes = aClass.getSuperTypes();
|
||||
for (PsiClassType superType : superTypes) {
|
||||
superType = PsiClassImplUtil.correctType(superType, place.getResolveScope());
|
||||
if (superType == null) continue;
|
||||
final PsiClassType.ClassResolveResult result = ((PsiClassType)PsiUtil.captureToplevelWildcards(superType, place)).resolveGenerics();
|
||||
final List<PsiClassType.ClassResolveResult> superTypes = PsiClassImplUtil.getScopeCorrectedSuperTypes(aClass, place.getResolveScope());
|
||||
for (PsiClassType.ClassResolveResult result : superTypes) {
|
||||
final PsiClass superClass = result.getElement();
|
||||
if (superClass == null || visited.contains(superClass)) continue;
|
||||
PsiSubstitutor superTypeSubstitutor = result.getSubstitutor();
|
||||
|
||||
@@ -732,7 +732,7 @@ public class PsiClassImplUtil {
|
||||
return new TypeCorrector(resolveScope).correctType(originalType);
|
||||
}
|
||||
|
||||
private static List<PsiClassType.ClassResolveResult> getScopeCorrectedSuperTypes(final PsiClass aClass, GlobalSearchScope resolveScope) {
|
||||
public static List<PsiClassType.ClassResolveResult> getScopeCorrectedSuperTypes(final PsiClass aClass, GlobalSearchScope resolveScope) {
|
||||
Map<GlobalSearchScope, List<PsiClassType.ClassResolveResult>> cache =
|
||||
CachedValuesManager.getCachedValue(aClass, new CachedValueProvider<Map<GlobalSearchScope, List<PsiClassType.ClassResolveResult>>>() {
|
||||
@Nullable
|
||||
|
||||
@@ -46,7 +46,7 @@ public class PsiSuperMethodImplUtil {
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<MethodSignature, HierarchicalMethodSignature> fun(PsiClass dom) {
|
||||
return buildMethodHierarchy(dom, null, PsiSubstitutor.EMPTY, true, new THashSet<PsiClass>(), false, dom.getResolveScope(), dom);
|
||||
return buildMethodHierarchy(dom, null, PsiSubstitutor.EMPTY, true, new THashSet<PsiClass>(), false, dom.getResolveScope());
|
||||
}
|
||||
});
|
||||
private static final PsiCacheKey<FactoryMap<String, Map<MethodSignature, HierarchicalMethodSignature>>, PsiClass> SIGNATURES_BY_NAME_KEY = PsiCacheKey
|
||||
@@ -57,7 +57,7 @@ public class PsiSuperMethodImplUtil {
|
||||
@Nullable
|
||||
@Override
|
||||
protected Map<MethodSignature, HierarchicalMethodSignature> create(String methodName) {
|
||||
return buildMethodHierarchy(psiClass, methodName, PsiSubstitutor.EMPTY, true, new THashSet<PsiClass>(), false, psiClass.getResolveScope(), psiClass);
|
||||
return buildMethodHierarchy(psiClass, methodName, PsiSubstitutor.EMPTY, true, new THashSet<PsiClass>(), false, psiClass.getResolveScope());
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -133,7 +133,7 @@ public class PsiSuperMethodImplUtil {
|
||||
final boolean includePrivates,
|
||||
@NotNull final Set<PsiClass> visited,
|
||||
boolean isInRawContext,
|
||||
GlobalSearchScope resolveScope, PsiElement place) {
|
||||
GlobalSearchScope resolveScope) {
|
||||
ProgressManager.checkCanceled();
|
||||
Map<MethodSignature, HierarchicalMethodSignature> result = new LinkedHashMap<MethodSignature, HierarchicalMethodSignature>();
|
||||
final Map<MethodSignature, List<PsiMethod>> sameParameterErasureMethods = new THashMap<MethodSignature, List<PsiMethod>>(MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY);
|
||||
@@ -190,10 +190,9 @@ public class PsiSuperMethodImplUtil {
|
||||
map.put(signature, newH);
|
||||
}
|
||||
|
||||
for (PsiClassType superType : aClass.getSuperTypes()) {
|
||||
superType = PsiClassImplUtil.correctType(superType, resolveScope);
|
||||
if (superType == null) continue; //super class doesn't belong to resolve scope
|
||||
PsiClassType.ClassResolveResult superTypeResolveResult = ((PsiClassType)PsiUtil.captureToplevelWildcards(superType, place)).resolveGenerics();
|
||||
final List<PsiClassType.ClassResolveResult> superTypes = PsiClassImplUtil.getScopeCorrectedSuperTypes(aClass, resolveScope);
|
||||
|
||||
for (PsiClassType.ClassResolveResult superTypeResolveResult : superTypes) {
|
||||
PsiClass superClass = superTypeResolveResult.getElement();
|
||||
if (superClass == null) continue;
|
||||
if (!visited.add(superClass)) continue; // cyclic inheritance
|
||||
@@ -201,7 +200,7 @@ public class PsiSuperMethodImplUtil {
|
||||
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(superClass, superSubstitutor, substitutor, isInRawContext);
|
||||
|
||||
final boolean isInRawContextSuper = (isInRawContext || PsiUtil.isRawSubstitutor(superClass, superSubstitutor)) && superClass.getTypeParameters().length != 0;
|
||||
Map<MethodSignature, HierarchicalMethodSignature> superResult = buildMethodHierarchy(superClass, nameHint, finalSubstitutor, false, visited, isInRawContextSuper, resolveScope, place);
|
||||
Map<MethodSignature, HierarchicalMethodSignature> superResult = buildMethodHierarchy(superClass, nameHint, finalSubstitutor, false, visited, isInRawContextSuper, resolveScope);
|
||||
visited.remove(superClass);
|
||||
|
||||
List<Pair<MethodSignature, HierarchicalMethodSignature>> flattened = new ArrayList<Pair<MethodSignature, HierarchicalMethodSignature>>();
|
||||
|
||||
+2
-2
@@ -651,7 +651,7 @@ public class InferenceSession {
|
||||
final PsiSubstitutor substitutor = resolveSubset(Collections.singletonList(inferenceVariable), mySiteSubstitutor);
|
||||
final PsiType substitutedReturnType = substitutor.substitute(inferenceVariable.getParameter());
|
||||
if (substitutedReturnType != null) {
|
||||
addConstraint(new TypeCompatibilityConstraint(targetType, PsiUtil.captureToplevelWildcards(substitutedReturnType, (PsiExpression)myContext)));
|
||||
addConstraint(new TypeCompatibilityConstraint(targetType, PsiUtil.captureToplevelWildcards(substitutedReturnType, myContext)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -662,7 +662,7 @@ public class InferenceSession {
|
||||
LOG.assertTrue(returnType instanceof PsiClassType);
|
||||
PsiClassType substitutedCapture = (PsiClassType)returnType;
|
||||
if (!toplevel) {
|
||||
substitutedCapture = (PsiClassType)PsiUtil.captureToplevelWildcards(returnType, (PsiExpression)myContext);
|
||||
substitutedCapture = (PsiClassType)PsiUtil.captureToplevelWildcards(returnType, myContext);
|
||||
final PsiTypeParameter[] typeParameters = psiClass.getTypeParameters();
|
||||
final InferenceVariable[] copy = initBounds(null, typeParameters);
|
||||
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
interface Msg<T extends Msg<T>> {}
|
||||
|
||||
class Conv<T extends Msg<T>> {
|
||||
static <A extends Msg<A>> Conv<A> createBar(A a) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static void test() {
|
||||
Conv<? extends Msg<?>> conv = Conv.createBar((Msg) null);
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
class Test {
|
||||
public static void bar(List<? extends Number> parameters, Function<Object, String> function)
|
||||
{
|
||||
Iterable<String> objects = transform(checkNotNull(parameters), function);
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T reference) {
|
||||
return reference;
|
||||
}
|
||||
|
||||
public static <F, T> List<T> transform(final List<F> fromIterable, final Function<? super F, ? extends T> function) {
|
||||
return null;
|
||||
}
|
||||
|
||||
{
|
||||
List<List<List<Integer>>> list = asList(asList(asList(1)), asList(asList(2)));
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import java.util.List;
|
||||
|
||||
interface A<T extends List<String>> { }
|
||||
|
||||
class C {
|
||||
List<A<?>> foo(List<A<? extends Iterable<?>>> x) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
|
||||
import java.util.List;
|
||||
|
||||
interface A<T extends A<T> & Cloneable> { }
|
||||
|
||||
class C {
|
||||
List<A<? extends A<?>>> foo(List<A<?>> x) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class Test {
|
||||
void bar() {
|
||||
baz<error descr="'baz(S)' in 'Test' cannot be applied to '(java.io.Serializable & java.lang.Comparable<? extends java.io.Serializable & java.lang.Comparable<? extends java.lang.Comparable<?>>>)'">(foo(1, ""))</error>;
|
||||
}
|
||||
|
||||
<T> T foo(T x, T y) {
|
||||
return x;
|
||||
}
|
||||
|
||||
<S extends Comparable<S>> void baz(S x) { }
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
class Foo {
|
||||
static <E extends Element> void add(Klass<?> klass, E e, Consumer<E> action) {}
|
||||
|
||||
static <T> void bar(Klass<?> k, Method<T> m) {
|
||||
add(k, m, k::addMethod);
|
||||
}
|
||||
}
|
||||
|
||||
interface Element {}
|
||||
interface Method<M> extends Element {}
|
||||
interface Type<T> {
|
||||
<M, C extends Type<T>> C addMethod(Method<M> m);
|
||||
}
|
||||
interface Klass<T> extends Type<T> {}
|
||||
|
||||
//simplified
|
||||
class Foo1 {
|
||||
static void bar(Type1<?> k) {
|
||||
k.addMethod();
|
||||
}
|
||||
}
|
||||
|
||||
interface Type1<T> {
|
||||
<C extends Type1<T>> C addMethod();
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
class MyTest {
|
||||
|
||||
private Test<LinkedList> alist;
|
||||
|
||||
|
||||
public Test<LinkedList> getAlist() {
|
||||
return alist = create(Test::new, alist);
|
||||
}
|
||||
|
||||
|
||||
private <T> T create(CreateCallback<T> callback, T defaultVal) {
|
||||
if (defaultVal == null) {
|
||||
return callback.create();
|
||||
}
|
||||
return defaultVal;
|
||||
}
|
||||
|
||||
interface CreateCallback<T> {
|
||||
T create();
|
||||
}
|
||||
|
||||
class Test<E extends List> {}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
|
||||
abstract class WrapperOne<T> {
|
||||
public abstract <X> WrapperOne<X> reformChain(Reformer<? extends WrapperTwo<? extends X>> reformer);
|
||||
}
|
||||
interface WrapperTwo<T> {}
|
||||
interface Reformer<T> {
|
||||
T reform();
|
||||
}
|
||||
class ReformerClient {
|
||||
public WrapperOne<String> sampleChainA(WrapperOne<String> p, Reformer<WrapperTwo<String>> r) {
|
||||
return p.reformChain(r::reform);
|
||||
}
|
||||
|
||||
public WrapperOne<String> sampleChainB(WrapperOne<String> p, Reformer<? extends WrapperTwo<String>> r) {
|
||||
return p.reformChain(r::reform);
|
||||
}
|
||||
|
||||
public WrapperOne<String> sampleChainC(WrapperOne<String> p, Reformer<? extends WrapperTwo<String>> r) {
|
||||
return p.reformChain(r);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package p;
|
||||
abstract class B {
|
||||
void foo(A<?> a)
|
||||
{
|
||||
a.get().<error descr="Cannot resolve method 'reversed()'">reversed</error>();
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package p;
|
||||
public abstract class A <T extends java.util.Comparator> {
|
||||
public abstract T get();
|
||||
}
|
||||
@@ -124,6 +124,11 @@ public class MultipleJdksHighlightingTest extends UsefulTestCase {
|
||||
doTestWithoutLibrary();
|
||||
}
|
||||
|
||||
public void testWrongComparatorInUpperBound() throws Exception {
|
||||
addDependencies_37_78();
|
||||
doTestWithoutLibrary();
|
||||
}
|
||||
|
||||
public void testGenericComparator() throws Exception {
|
||||
addDependencies_37_78();
|
||||
doTestWithoutLibrary();
|
||||
|
||||
+25
@@ -28,6 +28,7 @@ import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
//javac option to dump bounds: -XDdumpInferenceGraphsTo=
|
||||
public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
|
||||
@NonNls private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/genericsHighlighting8";
|
||||
|
||||
@@ -885,4 +886,28 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testIDEA148348() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA148361() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA134059() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA139222() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA139156() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA139169() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA131686() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -236,6 +236,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA136325() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
+4
@@ -462,6 +462,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA148093() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.jps.incremental.Utils;
|
||||
import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTargetType;
|
||||
import org.jetbrains.jps.incremental.fs.BuildFSState;
|
||||
import org.jetbrains.jps.incremental.messages.BuildMessage;
|
||||
import org.jetbrains.jps.incremental.messages.CompilerMessage;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
|
||||
import java.io.File;
|
||||
@@ -214,12 +215,20 @@ public class Standalone {
|
||||
|
||||
@Override
|
||||
public void processMessage(BuildMessage msg) {
|
||||
String messageText = msg.getMessageText();
|
||||
String messageText;
|
||||
if (msg instanceof CompilerMessage) {
|
||||
CompilerMessage compilerMessage = (CompilerMessage) msg;
|
||||
messageText = compilerMessage.getSourcePath() + "(" + compilerMessage.getLine() + ":" + compilerMessage.getColumn() + "): " + msg.getMessageText();
|
||||
}
|
||||
else {
|
||||
messageText = msg.getMessageText();
|
||||
}
|
||||
if (messageText.isEmpty()) return;
|
||||
if (msg.getKind() == BuildMessage.Kind.ERROR) {
|
||||
System.err.println("Error: " + messageText);
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
else if (msg.getKind() != BuildMessage.Kind.PROGRESS || !messageText.startsWith("Compiled") && !messageText.startsWith("Copying")) {
|
||||
System.out.println(messageText);
|
||||
}
|
||||
|
||||
@@ -475,4 +475,44 @@ public class DvcsUtil {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String joinShortNames(@NotNull Collection<? extends Repository> repositories) {
|
||||
return joinShortNames(repositories, -1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String joinShortNames(@NotNull Collection<? extends Repository> repositories, int limit) {
|
||||
return joinWithAnd(ContainerUtil.map(repositories, new Function<Repository, String>() {
|
||||
@Override
|
||||
public String fun(@NotNull Repository repository) {
|
||||
return getShortRepositoryName(repository);
|
||||
}
|
||||
}), limit);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String joinWithAnd(@NotNull List<String> strings, int limit) {
|
||||
int size = strings.size();
|
||||
if (size == 0) return "";
|
||||
if (size == 1) return strings.get(0);
|
||||
if (size == 2) return strings.get(0) + " and " + strings.get(1);
|
||||
|
||||
boolean isLimited = limit >= 2 && limit < size;
|
||||
int listCount = isLimited ? limit - 1 : size - 1;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < listCount; i++) {
|
||||
if (i != 0) sb.append(", ");
|
||||
sb.append(strings.get(i));
|
||||
}
|
||||
|
||||
if (isLimited) {
|
||||
sb.append(" and ").append(size - limit + 1).append(" others");
|
||||
}
|
||||
else {
|
||||
sb.append(" and ").append(strings.get(size - 1));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -74,9 +74,10 @@ public class CommentByLineCommentHandler extends MultiCaretCodeInsightActionHand
|
||||
|
||||
PsiElement context = InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file);
|
||||
|
||||
if (context != null && (context.textContains('\'') || context.textContains('\"') || context.textContains('/'))) {
|
||||
if (context != null && (context.textContains('\'') || context.textContains('\"') || context.textContains('/') || context.textContains('`'))) {
|
||||
String s = context.getText();
|
||||
if (StringUtil.startsWith(s, "\"") || StringUtil.startsWith(s, "\'") || StringUtil.startsWith(s, "/")) {
|
||||
if (StringUtil.startsWith(s, "\"") || StringUtil.startsWith(s, "\'") || StringUtil.startsWith(s, "/")
|
||||
|| StringUtil.startsWith(s, "`")) {
|
||||
file = context.getContainingFile();
|
||||
editor = editor instanceof EditorWindow ? ((EditorWindow)editor).getDelegate() : editor;
|
||||
caret = caret instanceof InjectedCaret ? ((InjectedCaret)caret).getDelegate() : caret;
|
||||
|
||||
@@ -22,6 +22,7 @@ import junit.framework.TestCase;
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -75,7 +76,8 @@ public class _FirstInSuiteTest extends TestCase {
|
||||
Class.forName("com.sun.jna.Native");
|
||||
|
||||
String tempDirectory = FileUtilRt.getTempDirectory();
|
||||
System.out.println("FileUtil.getTempDirectory() = " + tempDirectory + " ("+new File(tempDirectory).list().length+" files)");
|
||||
String[] list = new File(tempDirectory).list();
|
||||
System.out.println("FileUtil.getTempDirectory() = " + tempDirectory + " (" + list.length + " files): " + Arrays.asList(list));
|
||||
}
|
||||
|
||||
// performance tests
|
||||
|
||||
@@ -116,6 +116,7 @@ public class ChunkExtractor {
|
||||
|
||||
Project project = file.getProject();
|
||||
myDocument = PsiDocumentManager.getInstance(project).getDocument(file);
|
||||
LOG.assertTrue(myDocument != null);
|
||||
final FileType fileType = file.getFileType();
|
||||
SyntaxHighlighter highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, project, file.getVirtualFile());
|
||||
highlighter = highlighter == null ? new PlainSyntaxHighlighter() : highlighter;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -520,13 +520,12 @@ public class UsageInfo2UsageAdapter implements UsageInModule,
|
||||
PsiFile file = getPsiFile();
|
||||
|
||||
if (file != null) {
|
||||
ChunkExtractor extractor = ChunkExtractor.getExtractor(file);
|
||||
Segment segment = getFirstSegment();
|
||||
|
||||
if (segment != null) {
|
||||
Document document = PsiDocumentManager.getInstance(getProject()).getDocument(file);
|
||||
|
||||
if (document != null) {
|
||||
ChunkExtractor extractor = ChunkExtractor.getExtractor(file);
|
||||
SmartList<TextChunk> chunks = new SmartList<TextChunk>();
|
||||
extractor.createTextChunks(
|
||||
this,
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.openapi.vcs;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -39,7 +40,7 @@ public abstract class VcsTaskHandler {
|
||||
return handlers.toArray(new VcsTaskHandler[handlers.size()]);
|
||||
}
|
||||
|
||||
public static class TaskInfo {
|
||||
public static class TaskInfo implements Comparable<TaskInfo> {
|
||||
|
||||
private final String myBranch;
|
||||
private final Collection<String> myRepositories;
|
||||
@@ -61,6 +62,11 @@ public abstract class VcsTaskHandler {
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(TaskInfo o) {
|
||||
return Comparing.compare(myBranch, o.myBranch);
|
||||
}
|
||||
}
|
||||
|
||||
private static final ExtensionPointName<VcsTaskHandler> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.vcs.taskHandler");
|
||||
|
||||
@@ -65,6 +65,7 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.dvcs.DvcsUtil.getShortRepositoryName;
|
||||
import static com.intellij.dvcs.DvcsUtil.joinShortNames;
|
||||
|
||||
/**
|
||||
* Git utility/helper methods
|
||||
@@ -1025,4 +1026,15 @@ public class GitUtil {
|
||||
public static String mention(@NotNull GitRepository repository) {
|
||||
return getRepositoryManager(repository.getProject()).moreThanOneRoot() ? " in " + getShortRepositoryName(repository) : "";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String mention(@NotNull Collection<GitRepository> repositories) {
|
||||
return mention(repositories, -1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String mention(@NotNull Collection<GitRepository> repositories, int limit) {
|
||||
if (repositories.isEmpty()) return "";
|
||||
return " in " + joinShortNames(repositories, limit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ abstract class GitBranchOperation {
|
||||
private final GitVcsSettings mySettings;
|
||||
|
||||
@NotNull private final Collection<GitRepository> mySuccessfulRepositories;
|
||||
@NotNull private final Collection<GitRepository> mySkippedRepositories;
|
||||
@NotNull private final Collection<GitRepository> myRemainingRepositories;
|
||||
|
||||
protected GitBranchOperation(@NotNull Project project, @NotNull GitPlatformFacade facade, @NotNull Git git,
|
||||
@@ -76,6 +77,7 @@ abstract class GitBranchOperation {
|
||||
}
|
||||
});
|
||||
mySuccessfulRepositories = new ArrayList<GitRepository>();
|
||||
mySkippedRepositories = new ArrayList<GitRepository>();
|
||||
myRemainingRepositories = new ArrayList<GitRepository>(myRepositories);
|
||||
mySettings = myFacade.getSettings(myProject);
|
||||
}
|
||||
@@ -123,18 +125,37 @@ abstract class GitBranchOperation {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks repositories as successful, i.e. they won't be handled again.
|
||||
*/
|
||||
protected void markSkip(GitRepository... repositories) {
|
||||
for (GitRepository repository : repositories) {
|
||||
mySkippedRepositories.add(repository);
|
||||
myRemainingRepositories.remove(repository);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the operation has already succeeded in at least one of repositories.
|
||||
*/
|
||||
protected boolean wereSuccessful() {
|
||||
return !mySuccessfulRepositories.isEmpty();
|
||||
}
|
||||
|
||||
protected boolean wereSkipped() {
|
||||
return !mySkippedRepositories.isEmpty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Collection<GitRepository> getSuccessfulRepositories() {
|
||||
return mySuccessfulRepositories;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
protected Collection<GitRepository> getSkippedRepositories() {
|
||||
return mySkippedRepositories;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String successfulRepositoriesJoined() {
|
||||
return GitUtil.joinToHtml(mySuccessfulRepositories);
|
||||
|
||||
@@ -94,12 +94,12 @@ public final class GitBranchWorker {
|
||||
public void checkoutNewBranchStartingFrom(@NotNull String newBranchName, @NotNull String startPoint,
|
||||
@NotNull List<GitRepository> repositories) {
|
||||
updateInfo(repositories);
|
||||
new GitCheckoutOperation(myProject, myFacade, myGit, myUiHandler, repositories, startPoint, false, newBranchName).execute();
|
||||
new GitCheckoutOperation(myProject, myFacade, myGit, myUiHandler, repositories, startPoint, false, true, newBranchName).execute();
|
||||
}
|
||||
|
||||
public void checkout(@NotNull final String reference, boolean detach, @NotNull List<GitRepository> repositories) {
|
||||
updateInfo(repositories);
|
||||
new GitCheckoutOperation(myProject, myFacade, myGit, myUiHandler, repositories, reference, detach, null).execute();
|
||||
new GitCheckoutOperation(myProject, myFacade, myGit, myUiHandler, repositories, reference, detach, false, null).execute();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package git4idea.branch;
|
||||
|
||||
import com.intellij.dvcs.DvcsUtil;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationListener;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -33,6 +35,7 @@ import git4idea.util.GitPreservingProcess;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -54,6 +57,7 @@ class GitCheckoutOperation extends GitBranchOperation {
|
||||
|
||||
@NotNull private final String myStartPointReference;
|
||||
private final boolean myDetach;
|
||||
private final boolean myRefShouldBeValid;
|
||||
@Nullable private final String myNewBranch;
|
||||
|
||||
GitCheckoutOperation(@NotNull Project project,
|
||||
@@ -63,10 +67,12 @@ class GitCheckoutOperation extends GitBranchOperation {
|
||||
@NotNull Collection<GitRepository> repositories,
|
||||
@NotNull String startPointReference,
|
||||
boolean detach,
|
||||
boolean refShouldBeValid,
|
||||
@Nullable String newBranch) {
|
||||
super(project, facade, git, uiHandler, repositories);
|
||||
myStartPointReference = startPointReference;
|
||||
myDetach = detach;
|
||||
myRefShouldBeValid = refShouldBeValid;
|
||||
myNewBranch = newBranch;
|
||||
}
|
||||
|
||||
@@ -83,11 +89,12 @@ class GitCheckoutOperation extends GitBranchOperation {
|
||||
GitLocalChangesWouldBeOverwrittenDetector localChangesDetector =
|
||||
new GitLocalChangesWouldBeOverwrittenDetector(root, GitLocalChangesWouldBeOverwrittenDetector.Operation.CHECKOUT);
|
||||
GitSimpleEventDetector unmergedFiles = new GitSimpleEventDetector(GitSimpleEventDetector.Event.UNMERGED_PREVENTING_CHECKOUT);
|
||||
GitSimpleEventDetector unknownPathspec = new GitSimpleEventDetector(GitSimpleEventDetector.Event.INVALID_REFERENCE);
|
||||
GitUntrackedFilesOverwrittenByOperationDetector untrackedOverwrittenByCheckout =
|
||||
new GitUntrackedFilesOverwrittenByOperationDetector(root);
|
||||
|
||||
GitCommandResult result = myGit.checkout(repository, myStartPointReference, myNewBranch, false, myDetach,
|
||||
localChangesDetector, unmergedFiles, untrackedOverwrittenByCheckout);
|
||||
localChangesDetector, unmergedFiles, unknownPathspec, untrackedOverwrittenByCheckout);
|
||||
if (result.success()) {
|
||||
refresh(repository);
|
||||
markSuccessful(repository);
|
||||
@@ -106,6 +113,9 @@ class GitCheckoutOperation extends GitBranchOperation {
|
||||
fatalUntrackedFilesError(repository.getRoot(), untrackedOverwrittenByCheckout.getRelativeFilePaths());
|
||||
fatalErrorHappened = true;
|
||||
}
|
||||
else if (!myRefShouldBeValid && unknownPathspec.hasHappened()) {
|
||||
markSkip(repository);
|
||||
}
|
||||
else {
|
||||
fatalError(getCommonErrorTitle(), result.getErrorOutputAsJoinedString());
|
||||
fatalErrorHappened = true;
|
||||
@@ -117,8 +127,27 @@ class GitCheckoutOperation extends GitBranchOperation {
|
||||
}
|
||||
|
||||
if (!fatalErrorHappened) {
|
||||
notifySuccess();
|
||||
updateRecentBranch();
|
||||
if (wereSuccessful()) {
|
||||
if (!wereSkipped()) {
|
||||
notifySuccess();
|
||||
updateRecentBranch();
|
||||
}
|
||||
else {
|
||||
String mentionSuccess = getSuccessMessage() + GitUtil.mention(getSuccessfulRepositories(), 4);
|
||||
String mentionSkipped = wereSkipped() ? "<br>Revision not found" + GitUtil.mention(getSkippedRepositories(), 4) : "";
|
||||
|
||||
VcsNotifier.getInstance(myProject).notifySuccess("",
|
||||
mentionSuccess +
|
||||
mentionSkipped +
|
||||
"<br><a href='rollback'>Rollback</a>",
|
||||
new RollbackOperationNotificationListener());
|
||||
updateRecentBranch();
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.assertTrue(!myRefShouldBeValid);
|
||||
notifyError("Couldn't checkout " + myStartPointReference, "Revision not found" + GitUtil.mention(getSkippedRepositories(), 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,4 +290,14 @@ class GitCheckoutOperation extends GitBranchOperation {
|
||||
repository.update();
|
||||
}
|
||||
}
|
||||
|
||||
private class RollbackOperationNotificationListener implements NotificationListener {
|
||||
@Override
|
||||
public void hyperlinkUpdate(@NotNull Notification notification,
|
||||
@NotNull HyperlinkEvent event) {
|
||||
if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED && event.getDescription().equalsIgnoreCase("rollback")) {
|
||||
rollback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,6 +273,7 @@ public class GitImpl implements Git {
|
||||
else { // checkout reference as new branch
|
||||
h.addParameters("-b", newBranch, reference);
|
||||
}
|
||||
h.endOptions();
|
||||
for (GitLineHandlerListener listener : listeners) {
|
||||
h.addLineListener(listener);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ public class GitSimpleEventDetector implements GitLineHandlerListener {
|
||||
BRANCH_NOT_FULLY_MERGED("is not fully merged"),
|
||||
MERGE_CONFLICT("Automatic merge failed; fix conflicts and then commit the result"),
|
||||
MERGE_CONFLICT_ON_UNSTASH("conflict"),
|
||||
ALREADY_UP_TO_DATE("Already up-to-date");
|
||||
ALREADY_UP_TO_DATE("Already up-to-date"),
|
||||
INVALID_REFERENCE("invalid reference:");
|
||||
|
||||
private final String myDetectionString;
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vcs.VcsNotifier;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import git4idea.DialogManager;
|
||||
import git4idea.GitPlatformFacade;
|
||||
@@ -41,7 +40,6 @@ import git4idea.util.GitFreezingProcess;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -82,7 +80,7 @@ class GitAbortRebaseProcess {
|
||||
|
||||
void abortWithConfirmation() {
|
||||
LOG.debug("Abort rebase. " + (myRepositoryToAbort == null ? "Nothing to abort" : getShortRepositoryName(myRepositoryToAbort)) +
|
||||
". Roots to rollback: " + mention(myRepositoriesToRollback.keySet()));
|
||||
". Roots to rollback: " + DvcsUtil.joinShortNames(myRepositoriesToRollback.keySet()));
|
||||
final Ref<AbortChoice> ref = Ref.create();
|
||||
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
@@ -113,7 +111,7 @@ class GitAbortRebaseProcess {
|
||||
}
|
||||
else {
|
||||
String message = "Do you want just to abort rebase" + GitUtil.mention(myRepositoryToAbort) + ",\n" +
|
||||
"or also rollback the successful rebase in " + mention(myRepositoriesToRollback.keySet()) + "?";
|
||||
"or also rollback the successful rebase" + GitUtil.mention(myRepositoriesToRollback.keySet()) + "?";
|
||||
int choice = DialogManager.showYesNoCancelDialog(myProject, message, title, "Abort & Rollback", "Abort",
|
||||
getCancelButtonText(), getQuestionIcon());
|
||||
if (choice == Messages.YES) {
|
||||
@@ -129,7 +127,7 @@ class GitAbortRebaseProcess {
|
||||
LOG.error(new Throwable());
|
||||
}
|
||||
else {
|
||||
String description = "Do you want rollback the successful rebase in " + mention(myRepositoriesToRollback.keySet()) + "?";
|
||||
String description = "Do you want rollback the successful rebase" + GitUtil.mention(myRepositoriesToRollback.keySet()) + "?";
|
||||
int choice = DialogManager.showOkCancelDialog(myProject, description, title, "Rollback", getCancelButtonText(), getQuestionIcon());
|
||||
if (choice == Messages.YES) {
|
||||
return AbortChoice.ROLLBACK_AND_ABORT;
|
||||
@@ -198,29 +196,4 @@ class GitAbortRebaseProcess {
|
||||
}
|
||||
markDirtyAndRefresh(false, true, false, toVirtualFileArray(getRootsFromRepositories(toRefresh)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String mention(@NotNull Collection<GitRepository> repositories) {
|
||||
return joinWithAnd(ContainerUtil.map(repositories, new Function<GitRepository, String>() {
|
||||
@Override
|
||||
public String fun(@NotNull GitRepository repository) {
|
||||
return getShortRepositoryName(repository);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String joinWithAnd(@NotNull List<String> strings) {
|
||||
int size = strings.size();
|
||||
if (size == 0) return "";
|
||||
if (size == 1) return strings.get(0);
|
||||
if (size == 2) return strings.get(0) + " and " + strings.get(1);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < size - 2; i++) {
|
||||
sb.append(strings.get(i)).append(", ");
|
||||
}
|
||||
sb.append(strings.get(size - 2)).append(" and ").append(strings.get(size - 1));
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,7 @@ class GitBranchPopup extends DvcsBranchPopup<GitRepository> {
|
||||
@NotNull AbstractRepositoryManager<GitRepository> repositoryManager) {
|
||||
List<GitRepository> allRepositories = repositoryManager.getRepositories();
|
||||
popupGroup.add(new GitBranchPopupActions.GitNewBranchAction(myProject, allRepositories));
|
||||
popupGroup.add(new GitBranchPopupActions.CheckoutRevisionActions(myProject, allRepositories));
|
||||
|
||||
popupGroup.addAll(createRepositoriesActions());
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import git4idea.GitBranch;
|
||||
import git4idea.branch.GitBranchUtil;
|
||||
import git4idea.branch.GitBrancher;
|
||||
@@ -50,9 +52,10 @@ class GitBranchPopupActions {
|
||||
|
||||
ActionGroup createActions(@Nullable DefaultActionGroup toInsert) {
|
||||
DefaultActionGroup popupGroup = new DefaultActionGroup(null, false);
|
||||
List<GitRepository> repositoryList = Collections.singletonList(myRepository);
|
||||
|
||||
popupGroup.addAction(new GitNewBranchAction(myProject,Collections.singletonList(myRepository)));
|
||||
popupGroup.addAction(new CheckoutRevisionActions(myProject, myRepository));
|
||||
popupGroup.addAction(new GitNewBranchAction(myProject, repositoryList));
|
||||
popupGroup.addAction(new CheckoutRevisionActions(myProject, repositoryList));
|
||||
|
||||
if (toInsert != null) {
|
||||
popupGroup.addAll(toInsert);
|
||||
@@ -63,7 +66,7 @@ class GitBranchPopupActions {
|
||||
Collections.sort(localBranches);
|
||||
for (GitBranch localBranch : localBranches) {
|
||||
if (!localBranch.equals(myRepository.getCurrentBranch())) { // don't show current branch in the list
|
||||
popupGroup.add(new LocalBranchActions(myProject, Collections.singletonList(myRepository), localBranch.getName(), myRepository));
|
||||
popupGroup.add(new LocalBranchActions(myProject, repositoryList, localBranch.getName(), myRepository));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +74,7 @@ class GitBranchPopupActions {
|
||||
List<GitBranch> remoteBranches = new ArrayList<GitBranch>(myRepository.getBranches().getRemoteBranches());
|
||||
Collections.sort(remoteBranches);
|
||||
for (GitBranch remoteBranch : remoteBranches) {
|
||||
popupGroup.add(new RemoteBranchActions(myProject, Collections.singletonList(myRepository), remoteBranch.getName(), myRepository));
|
||||
popupGroup.add(new RemoteBranchActions(myProject, repositoryList, remoteBranch.getName(), myRepository));
|
||||
}
|
||||
|
||||
return popupGroup;
|
||||
@@ -97,14 +100,14 @@ class GitBranchPopupActions {
|
||||
/**
|
||||
* Checkout manually entered tag or revision number.
|
||||
*/
|
||||
private static class CheckoutRevisionActions extends DumbAwareAction {
|
||||
public static class CheckoutRevisionActions extends DumbAwareAction {
|
||||
private final Project myProject;
|
||||
private final GitRepository myRepository;
|
||||
private final List<GitRepository> myRepositories;
|
||||
|
||||
CheckoutRevisionActions(Project project, GitRepository repository) {
|
||||
super("Checkout Tag or Revision");
|
||||
CheckoutRevisionActions(Project project, List<GitRepository> repositories) {
|
||||
super("Checkout Tag or Revision...");
|
||||
myProject = project;
|
||||
myRepository = repository;
|
||||
myRepositories = repositories;
|
||||
}
|
||||
|
||||
@Override public void actionPerformed(AnActionEvent e) {
|
||||
@@ -114,14 +117,20 @@ class GitBranchPopupActions {
|
||||
.showInputDialog(myProject, "Enter reference (branch, tag) name or commit hash", "Checkout", Messages.getQuestionIcon());
|
||||
if (reference != null) {
|
||||
GitBrancher brancher = ServiceManager.getService(myProject, GitBrancher.class);
|
||||
brancher.checkout(reference, true, Collections.singletonList(myRepository), null);
|
||||
brancher.checkout(reference, true, myRepositories, null);
|
||||
reportUsage("git.branch.checkout.revision");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
if (myRepository.isFresh()) {
|
||||
boolean isFresh = ContainerUtil.and(myRepositories, new Condition<GitRepository>() {
|
||||
@Override
|
||||
public boolean value(GitRepository repository) {
|
||||
return repository.isFresh();
|
||||
}
|
||||
});
|
||||
if (isFresh) {
|
||||
e.getPresentation().setEnabled(false);
|
||||
e.getPresentation().setDescription("Checkout is not possible before the first commit");
|
||||
}
|
||||
|
||||
@@ -218,6 +218,52 @@ public class GitBranchWorkerTest extends GitPlatformTest {
|
||||
assertCurrentBranch(myContrib, "master");
|
||||
}
|
||||
|
||||
public void test_checkout_revision_checkout_branch_with_complete_success() {
|
||||
branchWithCommit(myRepositories, "feature");
|
||||
|
||||
checkoutRevision("feature", new TestUiHandler());
|
||||
|
||||
assertDetachedState("feature");
|
||||
assertEquals("Notification about successful branch checkout is incorrect", "Checked out " + bcode("feature"),
|
||||
myVcsNotifier.getLastNotification().getContent());
|
||||
}
|
||||
|
||||
public void test_checkout_revision_checkout_ref_with_complete_success() {
|
||||
branchWithCommit(myRepositories, "feature");
|
||||
|
||||
checkoutRevision("feature~1", new TestUiHandler());
|
||||
|
||||
assertDetachedState("master");
|
||||
assertEquals("Notification about successful branch checkout is incorrect", "Checked out " + bcode("feature~1"),
|
||||
myVcsNotifier.getLastNotification().getContent());
|
||||
}
|
||||
|
||||
public void test_checkout_revision_checkout_ref_with_complete_failure() {
|
||||
branchWithCommit(myRepositories, "feature");
|
||||
|
||||
checkoutRevision("unknown_ref", new TestUiHandler());
|
||||
|
||||
assertCurrentBranch("master");
|
||||
assertCurrentRevision("master");
|
||||
assertEquals("Notification about successful branch checkout is incorrect", "Revision not found in project, community and contrib",
|
||||
myVcsNotifier.getLastNotification().getContent());
|
||||
}
|
||||
|
||||
public void test_checkout_revision_checkout_ref_with_partial_success() {
|
||||
branchWithCommit(ContainerUtil.list(myCommunity, myContrib), "feature");
|
||||
|
||||
checkoutRevision("feature", new TestUiHandler());
|
||||
|
||||
assertCurrentBranch(myUltimate, "master");
|
||||
assertDetachedState(myCommunity, "feature");
|
||||
assertDetachedState(myContrib, "feature");
|
||||
|
||||
assertEquals("Notification about successful branch checkout is incorrect",
|
||||
"Checked out " + bcode("feature") + " in community and contrib" + "<br>" +
|
||||
"Revision not found in project" + "<br><a href='rollback'>Rollback</a>",
|
||||
myVcsNotifier.getLastNotification().getContent());
|
||||
}
|
||||
|
||||
public void test_checkout_with_untracked_files_overwritten_by_checkout_in_first_repo_should_show_notification() {
|
||||
test_untracked_files_overwritten_by_in_first_repo("checkout", 1);
|
||||
}
|
||||
@@ -807,14 +853,40 @@ public class GitBranchWorkerTest extends GitPlatformTest {
|
||||
assertCurrentBranch(myContrib, "master");
|
||||
}
|
||||
|
||||
static private void assertDetachedState(GitRepository repository, String reference) {
|
||||
assertCurrentRevision(repository, reference);
|
||||
|
||||
String curBranch = getCurrentBranch(repository);
|
||||
boolean isDetached = curBranch.contains("detached");
|
||||
assertTrue("Current branch is not detached in ${repository} - " + curBranch, isDetached);
|
||||
}
|
||||
|
||||
static private void assertCurrentBranch(GitRepository repository, String name) {
|
||||
String curBranch = ObjectUtils.assertNotNull(ContainerUtil.find(git(repository, "branch").split("\n"), new Condition<String>() {
|
||||
String curBranch = getCurrentBranch(repository);
|
||||
assertEquals("Current branch is incorrect in ${repository}", name, curBranch);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getCurrentBranch(GitRepository repository) {
|
||||
return ObjectUtils.assertNotNull(ContainerUtil.find(git(repository, "branch").split("\n"), new Condition<String>() {
|
||||
@Override
|
||||
public boolean value(String s) {
|
||||
return s.contains("*");
|
||||
}
|
||||
})).replace('*', ' ').trim();
|
||||
assertEquals("Current branch is incorrect in ${repository}", name, curBranch);
|
||||
}
|
||||
|
||||
static private void assertCurrentRevision(GitRepository repository, String reference) {
|
||||
String expectedRef = git(repository, "rev-parse " + "HEAD");
|
||||
String currentRef = git(repository, "rev-parse " + reference);
|
||||
|
||||
assertEquals("Current revision is incorrect in ${repository}", expectedRef, currentRef);
|
||||
}
|
||||
|
||||
private void assertDetachedState(String reference) {
|
||||
for (GitRepository repository : myRepositories) {
|
||||
assertDetachedState(repository, reference);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertCurrentBranch(String name) {
|
||||
@@ -823,6 +895,12 @@ public class GitBranchWorkerTest extends GitPlatformTest {
|
||||
}
|
||||
}
|
||||
|
||||
private void assertCurrentRevision(String reference) {
|
||||
for (GitRepository repository : myRepositories) {
|
||||
assertCurrentRevision(repository, reference);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkoutNewBranch(String name, GitBranchUiHandler uiHandler) {
|
||||
GitBranchWorker brancher = new GitBranchWorker(myProject, myPlatformFacade, myGit, uiHandler);
|
||||
brancher.checkoutNewBranch(name, myRepositories);
|
||||
@@ -833,6 +911,11 @@ public class GitBranchWorkerTest extends GitPlatformTest {
|
||||
brancher.checkout(name, false, myRepositories);
|
||||
}
|
||||
|
||||
private void checkoutRevision(String reference, GitBranchUiHandler uiHandler) {
|
||||
GitBranchWorker brancher = new GitBranchWorker(myProject, myPlatformFacade, myGit, uiHandler);
|
||||
brancher.checkout(reference, true, myRepositories);
|
||||
}
|
||||
|
||||
private void mergeBranch(String name, GitBranchUiHandler uiHandler) {
|
||||
GitBranchWorker brancher = new GitBranchWorker(myProject, myPlatformFacade, myGit, uiHandler);
|
||||
brancher.merge(name, GitBrancher.DeleteOnMergeOption.PROPOSE, myRepositories);
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.intellij.rt.execution.junit.segments.PacketProcessor;
|
||||
import junit.framework.*;
|
||||
import junit.textui.ResultPrinter;
|
||||
import junit.textui.TestRunner;
|
||||
import org.junit.runner.notification.Failure;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
@@ -190,7 +189,12 @@ public class JUnit3IdeaTestRunner extends TestRunner implements IdeaTestRunner {
|
||||
try {
|
||||
final String trace = getTrace(failure);
|
||||
ComparisonFailureData notification = null;
|
||||
if (failure instanceof ComparisonFailure || failure.getClass().getName().equals("org.junit.ComparisonFailure")) {
|
||||
if (failure instanceof FileComparisonFailure) {
|
||||
final FileComparisonFailure comparisonFailure = (FileComparisonFailure)failure;
|
||||
notification = new ComparisonFailureData(comparisonFailure.getExpected(), comparisonFailure.getActual(),
|
||||
comparisonFailure.getFilePath(), comparisonFailure.getActualFilePath());
|
||||
}
|
||||
else if (failure instanceof ComparisonFailure || failure.getClass().getName().equals("org.junit.ComparisonFailure")) {
|
||||
notification = new ComparisonFailureData(ComparisonDetailsExtractor.getExpected(failure), ComparisonDetailsExtractor.getActual(failure));
|
||||
}
|
||||
ComparisonFailureData.registerSMAttributes(notification, trace, failure.getMessage(), attrs, failure);
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -92,9 +93,10 @@ public class EditTaskDialog extends DialogWrapper {
|
||||
else {
|
||||
VcsTaskHandler.TaskInfo[] tasks = handlers[0].getAllExistingTasks();
|
||||
ArrayList<VcsTaskHandler.TaskInfo> infos = new ArrayList<VcsTaskHandler.TaskInfo>(Arrays.asList(tasks));
|
||||
Collections.sort(infos);
|
||||
infos.add(null);
|
||||
myBranch.setModel(new CollectionComboBoxModel<VcsTaskHandler.TaskInfo>(infos));
|
||||
final List<BranchInfo> branches = task.getBranches();
|
||||
final List<BranchInfo> branches = task.getBranches(false);
|
||||
if (!branches.isEmpty()) {
|
||||
VcsTaskHandler.TaskInfo info = ContainerUtil.find(tasks, new Condition<VcsTaskHandler.TaskInfo>() {
|
||||
@Override
|
||||
|
||||
@@ -45,7 +45,6 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
@@ -135,12 +134,7 @@ public class OpenTaskDialog extends DialogWrapper {
|
||||
VcsTaskHandler.TaskInfo[] tasks = handler.getAllExistingTasks();
|
||||
if (tasks.length > 0) {
|
||||
myVcsTaskHandler = handler;
|
||||
Arrays.sort(tasks, new Comparator<VcsTaskHandler.TaskInfo>() {
|
||||
@Override
|
||||
public int compare(VcsTaskHandler.TaskInfo o1, VcsTaskHandler.TaskInfo o2) {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
}
|
||||
});
|
||||
Arrays.sort(tasks);
|
||||
//noinspection unchecked
|
||||
myBranchFrom.setModel(new DefaultComboBoxModel(tasks));
|
||||
myBranchFrom.setEnabled(true);
|
||||
|
||||
Reference in New Issue
Block a user