1
1
using System ;
2
2
using System . Collections . Concurrent ;
3
- using System . Diagnostics ;
4
3
using System . IO ;
4
+ using System . Linq ;
5
5
using System . Reflection ;
6
6
using System . Runtime . Loader ;
7
7
using System . Text ;
8
+ using System . Text . Json ;
8
9
using JetBrains . Collections . Viewable ;
9
10
using JetBrains . Lifetimes ;
10
11
using JetBrains . Rd ;
11
12
using JetBrains . Rd . Impl ;
12
13
using JetBrains . Rd . Tasks ;
13
- using JetBrains . Util ;
14
14
using UtBot . Rd ;
15
15
using UtBot . Rd . Generated ;
16
16
using VSharp ;
@@ -46,28 +46,136 @@ public override void WriteLine(string value)
46
46
private static GenerateResults GenerateImpl ( GenerateArguments arguments )
47
47
{
48
48
var ( assemblyPath , projectCsprojPath , solutionFilePath ,
49
- descriptor , generationTimeout , targetFramework ) = arguments ;
49
+ methodDescriptors , generationTimeout , targetFramework ) = arguments ;
50
+
50
51
var assemblyLoadContext = new AssemblyLoadContext ( VSharpProcessName ) ;
51
- using var fs = File . OpenRead ( assemblyPath ) ;
52
- var ass = assemblyLoadContext . LoadFromStream ( fs ) ;
53
- var type = ass . GetType ( descriptor . TypeName , throwOnError : false ) ;
52
+ assemblyLoadContext . Resolving += ( context , name ) =>
53
+ {
54
+ var found = Directory . GetFiles ( new FileInfo ( assemblyPath ) . Directory ? . FullName , $ "{ name . Name } .dll")
55
+ . FirstOrDefault ( ) ;
56
+ if ( found is null )
57
+ {
58
+ return null ;
59
+ }
60
+
61
+ return context . LoadFromAssemblyPath ( found ) ;
62
+ } ;
63
+ var assembly = assemblyLoadContext . LoadFromAssemblyPath ( assemblyPath ) ;
64
+ var methods = methodDescriptors . Select ( d => d . ToMethodInfo ( assembly ) ) . ToList ( ) ;
65
+ var declaringType = methods . Select ( m => m . DeclaringType ) . Distinct ( ) . SingleOrDefault ( ) ;
66
+
67
+ var stat = TestGenerator . Cover ( methods , generationTimeout , verbosity : Verbosity . Info ) ;
68
+
69
+ var testedProject = new FileInfo ( projectCsprojPath ) ;
70
+ var solution = new FileInfo ( solutionFilePath ) ;
71
+
72
+ var ( generatedProject , renderedFiles ) =
73
+ Renderer . Render ( stat . Results ( ) , testedProject , declaringType , solution , targetFramework ) ;
74
+
75
+ return new GenerateResults (
76
+ generatedProject . FullName ,
77
+ renderedFiles ,
78
+ null ,
79
+ ( int ) stat . TestsCount ,
80
+ ( int ) stat . ErrorsCount ) ;
81
+ }
82
+
83
+ private static bool MatchesType ( TypeDescriptor typeDescriptor , Type typ )
84
+ {
85
+ if ( typ . IsGenericMethodParameter )
86
+ {
87
+ return typ . GenericParameterPosition == typeDescriptor . MethodParameterPosition ;
88
+ }
89
+
90
+ if ( typ . IsGenericTypeParameter )
91
+ {
92
+ return typ . GenericParameterPosition == typeDescriptor . TypeParameterPosition ;
93
+ }
94
+
95
+ if ( typ . IsArray )
96
+ {
97
+ return typ . GetArrayRank ( ) == typeDescriptor . ArrayRank &&
98
+ MatchesType ( typeDescriptor . Parameters [ 0 ] , typ . GetElementType ( ) ) ;
99
+ }
100
+
101
+ var name = typ . IsGenericType ? typ . GetGenericTypeDefinition ( ) . FullName : typ . FullName ;
102
+
103
+ if ( name != typeDescriptor . Name )
104
+ {
105
+ Logger . printLogString ( Logger . Error , $ "{ typ . FullName } != { typeDescriptor . Name } ") ;
106
+ return false ;
107
+ }
108
+
109
+ var genericArguments = typ . GetGenericArguments ( ) ;
110
+
111
+ if ( genericArguments . Length != typeDescriptor . Parameters . Count )
112
+ {
113
+ return false ;
114
+ }
115
+
116
+ for ( var i = 0 ; i < genericArguments . Length ; ++ i )
117
+ {
118
+ if ( ! MatchesType ( typeDescriptor . Parameters [ i ] , genericArguments [ i ] ) )
119
+ {
120
+ return false ;
121
+ }
122
+ }
123
+
124
+ return true ;
125
+ }
126
+
127
+ private static bool MatchesMethod ( MethodDescriptor descriptor , MethodInfo methodInfo )
128
+ {
129
+ var targetParameters = descriptor . Parameters . Select ( p => JsonSerializer . Deserialize < TypeDescriptor > ( p ) ) . ToArray ( ) ;
130
+
131
+ if ( methodInfo . Name != descriptor . MethodName )
132
+ {
133
+ return false ;
134
+ }
135
+
136
+ var parameters = methodInfo . GetParameters ( ) ;
137
+
138
+ if ( parameters . Length != targetParameters . Length )
139
+ {
140
+ return false ;
141
+ }
142
+
143
+ for ( var i = 0 ; i < parameters . Length ; ++ i )
144
+ {
145
+ if ( ! MatchesType ( targetParameters [ i ] , parameters [ i ] . ParameterType ) )
146
+ {
147
+ return false ;
148
+ }
149
+ }
150
+
151
+ return true ;
152
+ }
153
+
154
+ private static MethodInfo ToMethodInfo ( this MethodDescriptor descriptor , Assembly assembly )
155
+ {
156
+ var type = assembly . GetType ( descriptor . TypeName , throwOnError : false ) ;
157
+
54
158
if ( type ? . FullName != descriptor . TypeName )
55
- throw new InvalidDataException ( $ "cannot find type - { descriptor . TypeName } ") ;
56
- var methodInfo = type . GetMethod ( descriptor . MethodName ,
57
- BindingFlags . Instance
58
- | BindingFlags . Static
59
- | BindingFlags . Public ) ;
159
+ throw new InvalidDataException ( $ "Cannot find type { descriptor . TypeName } , found: { type ? . Name } ") ;
160
+
161
+ MethodInfo methodInfo ;
162
+ var bindingFlags = BindingFlags . Instance | BindingFlags . Static | BindingFlags . Public ;
163
+
164
+ if ( descriptor . HasNoOverloads )
165
+ {
166
+ methodInfo = type . GetMethod ( descriptor . MethodName , bindingFlags ) ;
167
+ }
168
+ else
169
+ {
170
+ methodInfo = type . GetMethods ( )
171
+ . FirstOrDefault ( m => MatchesMethod ( descriptor , m ) ) ;
172
+ }
173
+
60
174
if ( methodInfo ? . Name != descriptor . MethodName )
61
175
throw new InvalidDataException (
62
- $ "cannot find method - ${ descriptor . MethodName } for type - ${ descriptor . TypeName } ") ;
63
- var stat = TestGenerator . Cover ( methodInfo , generationTimeout , verbosity : Verbosity . Info ) ;
64
- var targetProject = new FileInfo ( projectCsprojPath ) ;
65
- var solution = new FileInfo ( solutionFilePath ) ;
66
- var declaringType = methodInfo . DeclaringType ;
67
- Debug . Assert ( declaringType != null ) ;
68
- var ( generatedProject , renderedFiles ) =
69
- Renderer . Render ( stat . Results ( ) , targetProject , declaringType , assemblyLoadContext , solution , targetFramework ) ;
70
- return new GenerateResults ( true , generatedProject . FullName , renderedFiles . ToArray ( ) , null ) ;
176
+ $ "Cannot find method ${ descriptor . MethodName } for type ${ descriptor . TypeName } ") ;
177
+
178
+ return methodInfo ;
71
179
}
72
180
73
181
public static void Main ( string [ ] args )
@@ -85,7 +193,7 @@ public static void Main(string[] args)
85
193
{
86
194
var vSharpModel = new VSharpModel ( ldef . Lifetime , protocol ) ;
87
195
// Configuring V# logger: messages will be send via RD to UTBot plugin process
88
- Logger . ConfigureWriter ( new SignalWriter ( vSharpModel . Log ) ) ;
196
+ Logger . configureWriter ( new SignalWriter ( vSharpModel . Log ) ) ;
89
197
vSharpModel . Generate . Set ( ( _ , arguments ) =>
90
198
{
91
199
try
@@ -94,7 +202,7 @@ public static void Main(string[] args)
94
202
}
95
203
catch ( Exception e )
96
204
{
97
- return new GenerateResults ( false , "" , EmptyArray < string > . Instance , e . ToString ( ) ) ;
205
+ return new GenerateResults ( null , new ( ) , e . ToString ( ) , 0 , 0 ) ;
98
206
}
99
207
finally
100
208
{
0 commit comments