Welcome to mirror list, hosted at ThFree Co, Russian Federation.

UsingsAndExternAliasesDirectiveComparer.cs « Util « CSharpBinding « addins « src « main - github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: f7f3c623a8a513944f5bbd81fa2533393985f2a9 (plain)
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);
			}
		}
	}
}