@@ -17,17 +17,17 @@ namespace Semmle.BuildAnalyser
17
17
internal partial class FileContent
18
18
{
19
19
private readonly ProgressMonitor progressMonitor ;
20
- private readonly TemporaryDirectory packageDirectory ;
20
+ private readonly IUnsafeFileReader unsafeFileReader ;
21
21
private readonly Func < IEnumerable < string > > getFiles ;
22
+ private readonly Func < HashSet < string > > getAlreadyDownloadedPackages ;
22
23
private readonly HashSet < string > notYetDownloadedPackages = new HashSet < string > ( ) ;
23
-
24
- private bool IsInitialized { get ; set ; } = false ;
24
+ private Initializer Initialize { get ; init ; }
25
25
26
26
public HashSet < string > NotYetDownloadedPackages
27
27
{
28
28
get
29
29
{
30
- Initialize ( ) ;
30
+ Initialize . Run ( ) ;
31
31
return notYetDownloadedPackages ;
32
32
}
33
33
}
@@ -45,18 +45,30 @@ public bool UseAspNetDlls
45
45
{
46
46
get
47
47
{
48
- Initialize ( ) ;
48
+ Initialize . Run ( ) ;
49
49
return useAspNetDlls ;
50
50
}
51
51
}
52
52
53
- public FileContent ( TemporaryDirectory packageDirectory , ProgressMonitor progressMonitor , Func < IEnumerable < string > > getFiles )
53
+ internal FileContent ( Func < HashSet < string > > getAlreadyDownloadedPackages ,
54
+ ProgressMonitor progressMonitor ,
55
+ Func < IEnumerable < string > > getFiles ,
56
+ IUnsafeFileReader unsafeFileReader )
54
57
{
58
+ this . getAlreadyDownloadedPackages = getAlreadyDownloadedPackages ;
55
59
this . progressMonitor = progressMonitor ;
56
- this . packageDirectory = packageDirectory ;
57
60
this . getFiles = getFiles ;
61
+ this . unsafeFileReader = unsafeFileReader ;
62
+ Initialize = new Initializer ( DoInitialize ) ;
58
63
}
59
64
65
+
66
+ public FileContent ( TemporaryDirectory packageDirectory , ProgressMonitor progressMonitor , Func < IEnumerable < string > > getFiles ) : this ( ( ) => Directory . GetDirectories ( packageDirectory . DirInfo . FullName )
67
+ . Select ( d => Path . GetFileName ( d )
68
+ . ToLowerInvariant ( ) )
69
+ . ToHashSet ( ) , progressMonitor , getFiles , new UnsafeFileReader ( ) )
70
+ { }
71
+
60
72
private static string GetGroup ( ReadOnlySpan < char > input , ValueMatch valueMatch , string groupPrefix )
61
73
{
62
74
var match = input . Slice ( valueMatch . Index , valueMatch . Length ) ;
@@ -87,21 +99,14 @@ private static bool IsGroupMatch(ReadOnlySpan<char> line, Regex regex, string gr
87
99
return false ;
88
100
}
89
101
90
- private void Initialize ( )
102
+ private void DoInitialize ( )
91
103
{
92
- if ( IsInitialized )
93
- {
94
- return ;
95
- }
96
-
97
- var alreadyDownloadedPackages = Directory . GetDirectories ( packageDirectory . DirInfo . FullName ) . Select ( d => Path . GetFileName ( d ) . ToLowerInvariant ( ) ) . ToHashSet ( ) ;
104
+ var alreadyDownloadedPackages = getAlreadyDownloadedPackages ( ) ;
98
105
foreach ( var file in getFiles ( ) )
99
106
{
100
107
try
101
108
{
102
- using var sr = new StreamReader ( file ) ;
103
- ReadOnlySpan < char > line ;
104
- while ( ( line = sr . ReadLine ( ) ) != null )
109
+ foreach ( ReadOnlySpan < char > line in unsafeFileReader . ReadLines ( file ) )
105
110
{
106
111
107
112
// Find the not yet downloaded packages.
@@ -122,15 +127,13 @@ private void Initialize()
122
127
IsGroupMatch ( line , ProjectSdk ( ) , "Sdk" , "Microsoft.NET.Sdk.Web" ) ||
123
128
IsGroupMatch ( line , FrameworkReference ( ) , "Include" , "Microsoft.AspNetCore.App" ) ;
124
129
}
125
-
126
130
}
127
131
}
128
132
catch ( Exception ex )
129
133
{
130
134
progressMonitor . FailedToReadFile ( file , ex ) ;
131
135
}
132
136
}
133
- IsInitialized = true ;
134
137
}
135
138
136
139
[ GeneratedRegex ( "<PackageReference.*\\ sInclude=\" (.*?)\" .*/?>" , RegexOptions . IgnoreCase | RegexOptions . Compiled | RegexOptions . Singleline ) ]
@@ -142,4 +145,22 @@ private void Initialize()
142
145
[ GeneratedRegex ( "<(.*\\ s)?Project.*\\ sSdk=\" (.*?)\" .*/?>" , RegexOptions . IgnoreCase | RegexOptions . Compiled | RegexOptions . Singleline ) ]
143
146
private static partial Regex ProjectSdk ( ) ;
144
147
}
148
+ }
149
+
150
+ internal interface IUnsafeFileReader
151
+ {
152
+ IEnumerable < string > ReadLines ( string file ) ;
153
+ }
154
+
155
+ internal class UnsafeFileReader : IUnsafeFileReader
156
+ {
157
+ public IEnumerable < string > ReadLines ( string file )
158
+ {
159
+ using var sr = new StreamReader ( file ) ;
160
+ string ? line ;
161
+ while ( ( line = sr . ReadLine ( ) ) != null )
162
+ {
163
+ yield return line ;
164
+ }
165
+ }
145
166
}
0 commit comments