Skip to content

Unstable compareTo between FunctionCompletion and AbstractCompletion #88

@siggemannen

Description

@siggemannen

Hello, i think there's a bug in the compareTo method of FunctionCompletion-class.
Very seldom, i'm getting an exception when sorting my completions:

        java.lang.IllegalArgumentException: Comparison method violates its general contract!
	at java.util.ComparableTimSort.mergeHi(ComparableTimSort.java:866)

The problem is that FunctionCompletion.compareTo uses String.compareTo but AbstractCompletion uses String.compareToIgnoreCase.

I have reduced the problem to following code. I compare function "O" with function "f" and basic string "h".
O < f according to FunctionCompletion (ascii compare), and f < h according to AbstractCompletion, but O > h according to AbstractCompletion (case insensitive). This breaks the sort contract.

My suggestion is to change the compareTo in FunctionCompletion to use compareToIgnoreCase.

package com.sigge.completion;

import org.fife.ui.autocomplete.BasicCompletion;
import org.fife.ui.autocomplete.FunctionCompletion;
import org.junit.Test;

public class CompletionCompareTest
{
    @Test
    public void test_compare()
    {
        FunctionCompletion O = new FunctionCompletion(null, "O", "String");
        FunctionCompletion f = new FunctionCompletion(null, "f", "string");
        BasicCompletion h = new BasicCompletion(null, "h");

        int compareTo = O.compareTo(f);
        int compareTo23 = f.compareTo(h);
        int compareTo13 = O.compareTo(h);
        if (compareTo < 0 && compareTo23 < 0 && compareTo13 > 0)
        {
            throw new RuntimeException("Unstable completion between: " + O + ", " + f + ", " + h);
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions