4
4
//
5
5
6
6
using System ;
7
+ using System . Linq ;
8
+ using System . Collections . Generic ;
9
+ using System . Management . Automation . Language ;
7
10
8
11
namespace Microsoft . PowerShell . EditorServices . Utility
9
12
{
@@ -30,5 +33,122 @@ public static string SafeToString(this object obj)
30
33
31
34
return str ;
32
35
}
36
+
37
+ /// <summary>
38
+ /// Get the maximum of the elements from the given enumerable.
39
+ /// </summary>
40
+ /// <typeparam name="T">Type of object for which the enumerable is defined.</typeparam>
41
+ /// <param name="elements">An enumerable object of type T</param>
42
+ /// <param name="comparer">A comparer for ordering elements of type T. The comparer should handle null values.</param>
43
+ /// <returns>An object of type T. If the enumerable is empty or has all null elements, then the method returns null.</returns>
44
+ public static T MaxElement < T > ( this IEnumerable < T > elements , Func < T , T , int > comparer ) where T : class
45
+ {
46
+ if ( elements == null )
47
+ {
48
+ throw new ArgumentNullException ( nameof ( elements ) ) ;
49
+ }
50
+
51
+ if ( comparer == null )
52
+ {
53
+ throw new ArgumentNullException ( nameof ( comparer ) ) ;
54
+ }
55
+
56
+ if ( ! elements . Any ( ) )
57
+ {
58
+ return null ;
59
+ }
60
+
61
+ var maxElement = elements . First ( ) ;
62
+ foreach ( var element in elements . Skip ( 1 ) )
63
+ {
64
+ if ( element != null && comparer ( element , maxElement ) > 0 )
65
+ {
66
+ maxElement = element ;
67
+ }
68
+ }
69
+
70
+ return maxElement ;
71
+ }
72
+
73
+ /// <summary>
74
+ /// Get the minimum of the elements from the given enumerable.
75
+ /// </summary>
76
+ /// <typeparam name="T">Type of object for which the enumerable is defined.</typeparam>
77
+ /// <param name="elements">An enumerable object of type T</param>
78
+ /// <param name="comparer">A comparer for ordering elements of type T. The comparer should handle null values.</param>
79
+ /// <returns>An object of type T. If the enumerable is empty or has all null elements, then the method returns null.</returns>
80
+ public static T MinElement < T > ( this IEnumerable < T > elements , Func < T , T , int > comparer ) where T : class
81
+ {
82
+ return MaxElement < T > ( elements , ( elementX , elementY ) => - 1 * comparer ( elementX , elementY ) ) ;
83
+ }
84
+
85
+ /// <summary>
86
+ /// Compare extents with respect to their widths.
87
+ ///
88
+ /// Width of an extent is defined as the difference between its EndOffset and StartOffest properties.
89
+ /// </summary>
90
+ /// <param name="extentX">Extent of type IScriptExtent.</param>
91
+ /// <param name="extentY">Extent of type IScriptExtent.</param>
92
+ /// <returns>0 if extentX and extentY are equal in width. 1 if width of extent X is greater than that of extent Y. Otherwise, -1.</returns>
93
+ public static int ExtentWidthComparer ( this IScriptExtent extentX , IScriptExtent extentY )
94
+ {
95
+
96
+ if ( extentX == null && extentY == null )
97
+ {
98
+ return 0 ;
99
+ }
100
+
101
+ if ( extentX != null && extentY == null )
102
+ {
103
+ return 1 ;
104
+ }
105
+
106
+ if ( extentX == null )
107
+ {
108
+ return - 1 ;
109
+ }
110
+
111
+ var extentWidthX = extentX . EndOffset - extentX . StartOffset ;
112
+ var extentWidthY = extentY . EndOffset - extentY . StartOffset ;
113
+ if ( extentWidthX > extentWidthY )
114
+ {
115
+ return 1 ;
116
+ }
117
+ else if ( extentWidthX < extentWidthY )
118
+ {
119
+ return - 1 ;
120
+ }
121
+ else
122
+ {
123
+ return 0 ;
124
+ }
125
+ }
126
+
127
+ /// <summary>
128
+ /// Check if the given coordinates are wholly contained in the instance's extent.
129
+ /// </summary>
130
+ /// <param name="scriptExtent">Extent of type IScriptExtent.</param>
131
+ /// <param name="line">1-based line number.</param>
132
+ /// <param name="column">1-based column number</param>
133
+ /// <returns>True if the coordinates are wholly contained in the instance's extent, otherwise, false.</returns>
134
+ public static bool Contains ( this IScriptExtent scriptExtent , int line , int column )
135
+ {
136
+ if ( scriptExtent . StartLineNumber > line || scriptExtent . EndLineNumber < line )
137
+ {
138
+ return false ;
139
+ }
140
+
141
+ if ( scriptExtent . StartLineNumber == line )
142
+ {
143
+ return scriptExtent . StartColumnNumber <= column ;
144
+ }
145
+
146
+ if ( scriptExtent . EndLineNumber == line )
147
+ {
148
+ return scriptExtent . EndColumnNumber >= column ;
149
+ }
150
+
151
+ return true ;
152
+ }
33
153
}
34
154
}
0 commit comments