Skip to content

Commit c0c6e1c

Browse files
committed
Improved comparison method.
Also fixing import insertion to make sure like has 'import<space>'
1 parent 5d28b0f commit c0c6e1c

File tree

3 files changed

+83
-25
lines changed

3 files changed

+83
-25
lines changed

External/Plugins/ASCompletion/Completion/ASGenerator.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4301,7 +4301,8 @@ public static int InsertImport(MemberModel member, bool fixScrolling)
43014301
string txt;
43024302
int indent = 0;
43034303
int skipIfDef = 0;
4304-
Match mImport;
4304+
Match mImport;
4305+
var importComparer = new CaseSensitiveImportComparer();
43054306
while (line < curLine)
43064307
{
43074308
txt = sci.GetLine(line++).TrimStart();
@@ -4318,15 +4319,14 @@ public static int InsertImport(MemberModel member, bool fixScrolling)
43184319
else continue;
43194320
}
43204321
// insert imports after a package declaration
4321-
else if (txt.StartsWith("import"))
4322+
else if (txt.Length > 6 && txt.StartsWith("import") && txt[6] <= 32)
43224323
{
43234324
packageLine = -1;
43244325
found = true;
43254326
indent = sci.GetLineIndentation(line - 1);
43264327
// insert in alphabetical order
43274328
mImport = ASFileParserRegexes.Import.Match(txt);
4328-
if (mImport.Success &&
4329-
ByImportTypeMemberComparer.CompareImports(mImport.Groups["package"].Value, fullPath) > 0)
4329+
if (mImport.Success && importComparer.Compare(mImport.Groups["package"].Value, fullPath) > 0)
43304330
{
43314331
line--;
43324332
break;

External/Plugins/ASCompletion/Model/MemberModel.cs

Lines changed: 78 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -542,31 +542,89 @@ public int Compare(MemberModel a, MemberModel b)
542542
/// <summary>
543543
/// Compare members based on import name
544544
/// </summary>
545-
public class ByImportTypeMemberComparer : IComparer<MemberModel>
545+
public class CaseSensitiveImportComparer : IComparer<MemberModel>
546546
{
547-
public static Int32 CompareImports(String import1, String import2)
547+
static Int32 GetPackageTypeSeparation(string import)
548+
{
549+
var dot = import.IndexOf('.');
550+
var lastDot = -1;
551+
var max = import.Length - 1;
552+
while (dot > 0 && dot < max)
553+
{
554+
if (Char.IsUpper(import[dot + 1]))
555+
return dot;
556+
lastDot = dot;
557+
dot = import.IndexOf('.', dot + 1);
558+
}
559+
if (dot < 0 || dot >= max) return lastDot;
560+
else if (dot == 0) return -1;
561+
else return dot;
562+
}
563+
564+
public static Int32 CompareImports(string import1, string import2)
548565
{
549-
// Use case-insensitive comparison.
550-
//IComparer cmp = StringComparer.OrdinalIgnoreCase;
551-
// Use case-sensitive comparison.
552566
IComparer cmp = StringComparer.Ordinal;
553-
String[] parts1 = import1.Split('.');
554-
String[] parts2 = import2.Split('.');
555-
int len1 = parts1.Length;
556-
int len2 = parts2.Length;
557-
// If the imports are at the same depth, compare them alphabetically.
558-
if (len1 == len2)
559-
return cmp.Compare(import1, import2);
560-
int minPackageLen = ((len1 <= len2) ? len1 : len2) - 1;
561-
// Alphabetically compare import packages part by part.
562-
for (int i = 0; i < minPackageLen; ++i)
567+
var d1 = GetPackageTypeSeparation(import1);
568+
var d2 = GetPackageTypeSeparation(import2);
569+
// one or both imports do not have a package
570+
if (d1 < 0)
563571
{
564-
int cmpResult = cmp.Compare(parts1[i], parts2[i]);
565-
if (cmpResult != 0)
566-
return cmpResult;
572+
if (d2 > 0) return -1;
573+
else return cmp.Compare(import1, import2);
567574
}
568-
// One of the packages is a sub-package of the other one. Consider the parent package to compare as less than the sub-package.
569-
return len1 - len2;
575+
else if (d2 < 0)
576+
{
577+
if (d1 > 0) return 1;
578+
else return cmp.Compare(import1, import2);
579+
}
580+
// compare package
581+
var pkg1 = import1.Substring(0, d1);
582+
var pkg2 = import2.Substring(0, d2);
583+
var res = cmp.Compare(pkg1, pkg2);
584+
if (res != 0) return res;
585+
// compare type
586+
var tp1 = import1.Substring(d1 + 1);
587+
var tp2 = import2.Substring(d2 + 1);
588+
res = cmp.Compare(tp1, tp2);
589+
return res;
590+
}
591+
592+
#if DEBUG
593+
static void Assert(int res, int expected)
594+
{
595+
System.Diagnostics.Debug.Assert(res == expected, res + " was not expected " + expected);
596+
}
597+
598+
static CaseSensitiveImportComparer()
599+
{
600+
// poor man's unit tests
601+
Assert(GetPackageTypeSeparation("a.b.C"), 3);
602+
Assert(GetPackageTypeSeparation("a.b.c"), 3);
603+
Assert(GetPackageTypeSeparation("a.b.C.D"), 3);
604+
Assert(GetPackageTypeSeparation("a"), -1);
605+
Assert(GetPackageTypeSeparation(".a"), -1);
606+
Assert(GetPackageTypeSeparation("a."), -1);
607+
Assert(GetPackageTypeSeparation("a.b.c."), 3);
608+
609+
Assert(CompareImports("a", "A"), 32);
610+
Assert(CompareImports("a", "b"), -1);
611+
Assert(CompareImports("b", "a"), 1);
612+
Assert(CompareImports("a", "a"), 0);
613+
Assert(CompareImports("a.A", "b"), 1);
614+
Assert(CompareImports("a", "b.B"), -1);
615+
Assert(CompareImports("a.A", "b.A"), -1);
616+
Assert(CompareImports("b.A", "a.A"), 1);
617+
Assert(CompareImports("a.A", "a.A"), 0);
618+
Assert(CompareImports("a.A", "a.B"), -1);
619+
Assert(CompareImports("b.A", "a.A"), 1);
620+
Assert(CompareImports("a.A", "a.a"), -32);
621+
Assert(CompareImports("a.MathReal", "a.Mathematics"), -19);
622+
}
623+
#endif
624+
625+
public Int32 Compare(string import1, string import2)
626+
{
627+
return CompareImports(import1, import2);
570628
}
571629

572630
public Int32 Compare(MemberModel item1, MemberModel item2)

External/Plugins/CodeRefactor/Commands/OrganizeImports.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ private void InsertImports(List<MemberModel> imports, String searchInText, Scint
149149
{
150150
String eol = LineEndDetector.GetNewLineMarker(sci.EOLMode);
151151
Int32 line = imports[0].LineFrom - DeletedImportsCompensation;
152-
imports.Sort(new ByImportTypeMemberComparer());
152+
imports.Sort(new CaseSensitiveImportComparer());
153153
sci.GotoLine(line);
154154
Int32 curLine = 0;
155155
List<String> uniques = this.GetUniqueImports(imports, searchInText, sci.FileName);

0 commit comments

Comments
 (0)