1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Utilities;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
namespace ICSharpCode.NRefactory6.CSharp
{
class UsingsAndExternAliasesDirectiveComparer : IComparer<SyntaxNode>
{
public static readonly IComparer<SyntaxNode> NormalInstance = new UsingsAndExternAliasesDirectiveComparer(
NameSyntaxComparer.Create(TokenComparer.NormalInstance),
TokenComparer.NormalInstance);
public static readonly IComparer<SyntaxNode> SystemFirstInstance = new UsingsAndExternAliasesDirectiveComparer(
NameSyntaxComparer.Create(TokenComparer.SystemFirstInstance),
TokenComparer.SystemFirstInstance);
private readonly IComparer<NameSyntax> _nameComparer;
private readonly IComparer<SyntaxToken> _tokenComparer;
private UsingsAndExternAliasesDirectiveComparer(
IComparer<NameSyntax> nameComparer,
IComparer<SyntaxToken> tokenComparer)
{
_nameComparer = nameComparer;
_tokenComparer = tokenComparer;
}
public int Compare(SyntaxNode directive1, SyntaxNode directive2)
{
if (directive1 == directive2)
{
return 0;
}
var using1 = directive1 as UsingDirectiveSyntax;
var using2 = directive2 as UsingDirectiveSyntax;
var extern1 = directive1 as ExternAliasDirectiveSyntax;
var extern2 = directive2 as ExternAliasDirectiveSyntax;
var directive1IsExtern = extern1 != null;
var directive2IsExtern = extern2 != null;
var directive1IsNamespace = using1 != null && using1.Alias == null && !using1.StaticKeyword.IsKind(SyntaxKind.StaticKeyword);
var directive2IsNamespace = using2 != null && using2.Alias == null && !using2.StaticKeyword.IsKind(SyntaxKind.StaticKeyword);
var directive1IsUsingStatic = using1 != null && using1.StaticKeyword.IsKind(SyntaxKind.StaticKeyword);
var directive2IsUsingStatic = using2 != null && using2.StaticKeyword.IsKind(SyntaxKind.StaticKeyword);
var directive1IsAlias = using1 != null && using1.Alias != null;
var directive2IsAlias = using2 != null && using2.Alias != null;
// different types of usings get broken up into groups.
// * externs
// * usings
// * using statics
// * aliases
if (directive1IsExtern && !directive2IsExtern)
{
return -1;
}
else if (directive2IsExtern && !directive1IsExtern)
{
return 1;
}
else if (directive1IsNamespace && !directive2IsNamespace)
{
return -1;
}
else if (directive2IsNamespace && !directive1IsNamespace)
{
return 1;
}
else if (directive1IsUsingStatic && !directive2IsUsingStatic)
{
return -1;
}
else if (directive2IsUsingStatic && !directive1IsUsingStatic)
{
return 1;
}
else if (directive1IsAlias && !directive2IsAlias)
{
return -1;
}
else if (directive2IsAlias && !directive1IsAlias)
{
return 1;
}
// ok, it's the same type of using now.
if (directive1IsExtern)
{
// they're externs, sort by the alias
return _tokenComparer.Compare(extern1.Identifier, extern2.Identifier);
}
else if (directive1IsAlias)
{
var aliasComparisonResult = _tokenComparer.Compare(using1.Alias.Name.Identifier, using2.Alias.Name.Identifier);
if (aliasComparisonResult == 0)
{
// They both use the same alias, so compare the names.
return _nameComparer.Compare(using1.Name, using2.Name);
}
else
{
return aliasComparisonResult;
}
}
else
{
return _nameComparer.Compare(using1.Name, using2.Name);
}
}
}
}
|