Skip to content

Commit 2181c75

Browse files
maca88hazzik
authored andcommitted
fixed some tests
1 parent 133ff1e commit 2181c75

File tree

9 files changed

+179
-35
lines changed

9 files changed

+179
-35
lines changed

src/NHibernate.AsyncGenerator/MethodInfo.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,19 @@ public MethodInfo(TypeInfo typeInfo, IMethodSymbol symbol, MethodDeclarationSynt
3636

3737
public HashSet<IMethodSymbol> ExternalDependencies { get; } = new HashSet<IMethodSymbol>();
3838

39+
// async methods that have the same parameters and name and are external
40+
public HashSet<IMethodSymbol> ExternalAsyncMethods { get; } = new HashSet<IMethodSymbol>();
41+
42+
public bool HasRequiredExternalMethods
43+
{
44+
get
45+
{
46+
return ExternalDependencies.Select(o => o.ContainingType.GetFullName())
47+
.Except(ExternalAsyncMethods.Select(o => o.ContainingType.GetFullName()))
48+
.Any();
49+
}
50+
}
51+
3952
/// <summary>
4053
/// When true the method will be ignored when generating async members
4154
/// </summary>
@@ -57,7 +70,7 @@ public bool HasReferences
5770

5871
public bool IsRequired
5972
{
60-
get { return ExternalDependencies.Any() || GetAllDependencies().Any(o => o.ExternalDependencies.Any())/* || Dependencies.Any(o => o.Ignore)*/; }
73+
get { return HasRequiredExternalMethods || GetAllDependencies().Any(o => o.HasRequiredExternalMethods); }
6174
}
6275

6376
public bool Candidate { get; set; }
@@ -211,12 +224,18 @@ public MethodReferenceResult AnalyzeMethodReference(ReferenceLocation reference)
211224
return o.Span == reference.Location.SourceSpan;
212225
});
213226
var docInfo = TypeInfo.NamespaceInfo.DocumentInfo;
227+
var config = docInfo.ProjectInfo.Configuration;
214228
var methodSymbol = (IMethodSymbol) docInfo.SemanticModel.GetSymbolInfo(nameNode).Symbol;
215229
var result = new MethodReferenceResult(reference, nameNode, methodSymbol)
216230
{
217231
CanBeAsync = true,
218232
DeclaredWithinSameType = TypeInfo.Symbol.GetFullName() == methodSymbol.ContainingType.GetFullName()
219233
};
234+
if (!config.CanConvertReferenceFunc(methodSymbol))
235+
{
236+
result.Ignore = true;
237+
return result;
238+
}
220239

221240
var currNode = nameNode.Parent;
222241
var ascend = true;

src/NHibernate.AsyncGenerator/MethodReferenceResult.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public MethodReferenceResult(ReferenceLocation reference, SimpleNameSyntax refer
2424

2525
public IMethodSymbol Symbol { get; }
2626

27+
public bool Ignore { get; set; }
28+
2729
public bool CanBeAsync { get; internal set; }
2830

2931
public bool DeclaredWithinSameType { get; internal set; }

src/NHibernate.AsyncGenerator/Program.cs

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ public ProjectConfiguration(string name)
209209
/// </summary>
210210
public Func<Document, bool> CanScanDocumentFunc { get; set; } = m => true;
211211

212+
/// <summary>
213+
/// Predicate for reference selection
214+
/// </summary>
215+
public Func<IMethodSymbol, bool> CanConvertReferenceFunc { get; set; } = m => true;
216+
212217
/// <summary>
213218
/// A custom method that will be called when for a method there is not an async counterpart with same parameters
214219
/// </summary>
@@ -294,12 +299,14 @@ static void Main(string[] args)
294299
}
295300
return false;
296301
},*/
297-
298-
302+
CanConvertReferenceFunc = m =>
303+
{
304+
return m.ContainingNamespace.ToString() != "System.IO";
305+
},
299306
//CanScanDocumentFunc = doc =>
300307
//{
301-
// //return doc.FilePath.EndsWith(@"Interceptor\StatefulInterceptor.cs");
302-
// return doc.FilePath.EndsWith(@"NHSpecificTest\NH1882\TestCollectionInitializingDuringFlush.cs"); //||
308+
// return doc.FilePath.EndsWith(@"Linq\QueryTimeoutTests.cs");
309+
// //return doc.FilePath.EndsWith(@"NHSpecificTest\NH1882\TestCollectionInitializingDuringFlush.cs"); //||
303310
// //doc.FilePath.EndsWith(@"TestCase.cs");
304311
//},
305312
FindAsyncCounterpart = symbol =>
@@ -320,20 +327,24 @@ static void Main(string[] args)
320327
},
321328
TypeTransformationFunc = type =>
322329
{
323-
if (type.GetAttributes().Any(o => o.AttributeClass.Name == "TestFixtureAttribute") || type.Name == "TestCase")
330+
if (type.Name == "LinqReadonlyTestsContext")
331+
{
332+
return TypeTransformation.None;
333+
}
334+
if (type.GetAttributes().Any(o => o.AttributeClass.Name == "TestFixtureAttribute") || type.Name == "TestCase")
335+
{
336+
return TypeTransformation.NewType;
337+
}
338+
var baseType = type.BaseType;
339+
while (baseType != null)
340+
{
341+
if (baseType.Name == "TestCase")
324342
{
325343
return TypeTransformation.NewType;
326344
}
327-
var baseType = type.BaseType;
328-
while (baseType != null)
329-
{
330-
if (baseType.Name == "TestCase")
331-
{
332-
return TypeTransformation.NewType;
333-
}
334-
baseType = baseType.BaseType;
335-
}
336-
return TypeTransformation.Partial;
345+
baseType = baseType.BaseType;
346+
}
347+
return TypeTransformation.Partial;
337348
}
338349
}
339350
},

src/NHibernate.AsyncGenerator/ProjectInfo.cs

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,8 @@ private class MethodSymbolInfo
399399

400400
public HashSet<IMethodSymbol> InterfaceMethods { get; set; }
401401

402+
public HashSet<IMethodSymbol> AsyncInterfaceMethods { get; set; }
403+
402404
public HashSet<IMethodSymbol> OverriddenMethods { get; set; }
403405

404406
public IMethodSymbol BaseOverriddenMethod { get; set; }
@@ -531,17 +533,27 @@ private MethodSymbolInfo AnalyzeMethodSymbol(IMethodSymbol methodSymbol, bool me
531533
}
532534

533535
var interfaceMethods = new HashSet<IMethodSymbol>();
536+
var asyncMethods = new HashSet<IMethodSymbol>();
534537
// check if explicitly implements external interfaces
535538
if (methodSymbol.MethodKind == MethodKind.ExplicitInterfaceImplementation)
536539
{
537540
foreach (var interfaceMember in methodSymbol.ExplicitInterfaceImplementations)
538541
{
539542
var syntax = interfaceMember.DeclaringSyntaxReferences.SingleOrDefault();
540-
if (syntax == null || methodSymbol.ContainingAssembly.Name != interfaceMember.ContainingAssembly.Name)
543+
if (methodSymbol.ContainingAssembly.Name != interfaceMember.ContainingAssembly.Name)
541544
{
542-
Logger.Warn(
543-
$"Method {methodSymbol} implements an external interface {interfaceMember} and cannot be made async");
544-
return MethodSymbolInfo.Invalid;
545+
// check if the member has an async counterpart that is not implemented in the current type (missing member)
546+
var asyncConterPart = interfaceMember.ContainingType.GetMembers()
547+
.OfType<IMethodSymbol>()
548+
.Where(o => o.Name == methodSymbol.Name + "Async")
549+
.SingleOrDefault(o => o.HaveSameParameters(methodSymbol));
550+
if (asyncConterPart == null)
551+
{
552+
Logger.Warn(
553+
$"Method {methodSymbol} implements an external interface {interfaceMember} and cannot be made async");
554+
return MethodSymbolInfo.Invalid;
555+
}
556+
asyncMethods.Add(asyncConterPart);
545557
}
546558
if (memorize && !AnalyzedMethodSymbols.Contains(interfaceMember.OriginalDefinition))
547559
{
@@ -566,9 +578,18 @@ private MethodSymbolInfo AnalyzeMethodSymbol(IMethodSymbol methodSymbol, bool me
566578
var syntax = interfaceMember.DeclaringSyntaxReferences.SingleOrDefault();
567579
if (syntax == null || methodSymbol.ContainingAssembly.Name != interfaceMember.ContainingAssembly.Name)
568580
{
569-
Logger.Warn(
570-
$"Method {methodSymbol} implements an external interface {interfaceMember} and cannot be made async");
571-
return MethodSymbolInfo.Invalid;
581+
// check if the member has an async counterpart that is not implemented in the current type (missing member)
582+
var asyncConterPart = interfaceMember.ContainingType.GetMembers()
583+
.OfType<IMethodSymbol>()
584+
.Where(o => o.Name == methodSymbol.Name + "Async")
585+
.SingleOrDefault(o => o.HaveSameParameters(methodSymbol));
586+
if (asyncConterPart == null)
587+
{
588+
Logger.Warn(
589+
$"Method {methodSymbol} implements an external interface {interfaceMember} and cannot be made async");
590+
return MethodSymbolInfo.Invalid;
591+
}
592+
asyncMethods.Add(asyncConterPart);
572593
}
573594
if (memorize && !AnalyzedMethodSymbols.Contains(interfaceMember.OriginalDefinition))
574595
{
@@ -587,10 +608,26 @@ private MethodSymbolInfo AnalyzeMethodSymbol(IMethodSymbol methodSymbol, bool me
587608
while (overridenMethod != null)
588609
{
589610
var syntax = overridenMethod.DeclaringSyntaxReferences.SingleOrDefault();
590-
if (syntax == null || methodSymbol.ContainingAssembly.Name != overridenMethod.ContainingAssembly.Name)
591-
{
592-
Logger.Warn($"Method {methodSymbol} overrides an external method {overridenMethod} and cannot be made async");
593-
return MethodSymbolInfo.Invalid;
611+
if (methodSymbol.ContainingAssembly.Name != overridenMethod.ContainingAssembly.Name)
612+
{
613+
// check if the member has an async counterpart that is not implemented in the current type (missing member)
614+
var asyncConterPart = overridenMethod.ContainingType.GetMembers()
615+
.OfType<IMethodSymbol>()
616+
.Where(o => o.Name == methodSymbol.Name + "Async" && !o.IsSealed)
617+
.SingleOrDefault(o => o.HaveSameParameters(methodSymbol));
618+
if (asyncConterPart == null)
619+
{
620+
if (!asyncMethods.Any() ||
621+
(asyncMethods.Any() && !overridenMethod.IsOverride && !overridenMethod.IsVirtual))
622+
{
623+
Logger.Warn($"Method {methodSymbol} overrides an external method {overridenMethod} and cannot be made async");
624+
return MethodSymbolInfo.Invalid;
625+
}
626+
}
627+
else
628+
{
629+
asyncMethods.Add(asyncConterPart);
630+
}
594631
}
595632
if (memorize && !AnalyzedMethodSymbols.Contains(overridenMethod.OriginalDefinition))
596633
{
@@ -627,6 +664,7 @@ private MethodSymbolInfo AnalyzeMethodSymbol(IMethodSymbol methodSymbol, bool me
627664
{
628665
IsValid = true,
629666
MethodSymbol = methodSymbol,
667+
AsyncInterfaceMethods = asyncMethods,
630668
InterfaceMethods = interfaceMethods,
631669
BaseOverriddenMethod = overridenMethod?.OriginalDefinition,
632670
OverriddenMethods = overrrides,
@@ -647,6 +685,10 @@ private async Task ProcessMethodSymbolInfo(MethodSymbolInfo methodSymbolInfo, Do
647685
_processedMethodSymbolInfos.Add(methodSymbolInfo);
648686

649687
var mainMethodInfo = methodDocInfo.GetOrCreateMethodInfo(methodSymbolInfo.MethodSymbol);
688+
foreach (var asyncMethod in methodSymbolInfo.AsyncInterfaceMethods)
689+
{
690+
mainMethodInfo.ExternalAsyncMethods.Add(asyncMethod);
691+
}
650692

651693
DocumentInfo docInfo;
652694
SyntaxReference syntax;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#if NET_4_5
2+
using System;
3+
using System.Collections;
4+
using System.Collections.Generic;
5+
using System.Data;
6+
using System.Data.Common;
7+
using NHibernate.Connection;
8+
using System.Threading.Tasks;
9+
10+
namespace NHibernate.Test
11+
{
12+
[System.CodeDom.Compiler.GeneratedCode("AsyncGenerator", "1.0.0")]
13+
public partial class DebugConnectionProvider : DriverConnectionProvider
14+
{
15+
public override async Task<DbConnection> GetConnectionAsync()
16+
{
17+
try
18+
{
19+
DbConnection connection = await (base.GetConnectionAsync());
20+
lock (lockObject)
21+
{
22+
connections.Add(connection);
23+
}
24+
return connection;
25+
}
26+
catch (Exception e)
27+
{
28+
throw new HibernateException("Could not open connection to: " + ConnectionString, e);
29+
}
30+
}
31+
}
32+
}
33+
#endif
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#if NET_4_5
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using NHibernate.Event;
5+
using NHibernate.Event.Default;
6+
using NHibernate.Impl;
7+
using System.Threading.Tasks;
8+
9+
namespace NHibernate.Test.Events.Collections
10+
{
11+
[System.CodeDom.Compiler.GeneratedCode("AsyncGenerator", "1.0.0")]
12+
public partial class CollectionListeners
13+
{
14+
[System.CodeDom.Compiler.GeneratedCode("AsyncGenerator", "1.0.0")]
15+
public partial class InitializeCollectionListener : DefaultInitializeCollectionEventListener, IListener
16+
{
17+
public override async Task OnInitializeCollectionAsync(InitializeCollectionEvent @event)
18+
{
19+
await (base.OnInitializeCollectionAsync(@event));
20+
AddEvent(@event, this);
21+
}
22+
}
23+
}
24+
}
25+
#endif

src/NHibernate.Test/Async/NHSpecificTest/NH2065/Fixture.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ public async Task GetGoodErrorForDirtyReassociatedCollectionAsync()
5858
{
5959
await (s.LockAsync(person, LockMode.None));
6060
}
61-
});
61+
}
62+
63+
);
6264
Assert.That(ex.Message, Is.EqualTo("reassociated object has dirty collection: NHibernate.Test.NHSpecificTest.NH2065.Person.Children"));
6365
}
6466
}

src/NHibernate.Test/DebugConnectionProvider.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Data;
44
using System.Data.Common;
55
using System.Linq;
6+
using System.Runtime.CompilerServices;
67
using NHibernate.Connection;
78

89
namespace NHibernate.Test
@@ -14,13 +15,15 @@ namespace NHibernate.Test
1415
public partial class DebugConnectionProvider : DriverConnectionProvider
1516
{
1617
private ConcurrentDictionary<DbConnection, byte> connections = new ConcurrentDictionary<DbConnection, byte>();
18+
private readonly object lockObject = new object();
1719

1820
public override DbConnection GetConnection()
1921
{
2022
try
2123
{
2224
var connection = base.GetConnection();
2325
connections.TryAdd(connection, 0);
26+
}
2427
return connection;
2528
}
2629
catch (Exception e)
@@ -31,26 +34,31 @@ public override DbConnection GetConnection()
3134

3235
public override void CloseConnection(DbConnection conn)
3336
{
34-
base.CloseConnection(conn);
37+
lock (lockObject)
38+
{
39+
base.CloseConnection(conn);
3540
byte _;
3641
connections.TryRemove(conn, out _);
42+
}
3743
}
3844

3945
public bool HasOpenConnections
4046
{
4147
get
4248
{
43-
// Disposing of an ISession does not call CloseConnection (should it???)
44-
// so a Diposed of ISession will leave an DbConnection in the list but
45-
// the DbConnection will be closed (atleast with MsSql it works this way).
49+
// Disposing of an ISession does not call CloseConnection (should it???)
50+
// so a Diposed of ISession will leave an DbConnection in the list but
51+
// the DbConnection will be closed (atleast with MsSql it works this way).
4652
return connections.Keys.Any(conn => conn.State != ConnectionState.Closed);
47-
}
48-
}
53+
}
54+
}
4955

5056
public void CloseAllConnections()
5157
{
52-
while (connections.Count != 0)
58+
lock (lockObject)
5359
{
60+
while (connections.Count != 0)
61+
{
5462
foreach (var conn in connections.Keys.ToArray())
5563
{
5664
CloseConnection(conn);

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@
198198
<Compile Include="Async\Criteria\Lambda\SubqueryFixture.cs" />
199199
<Compile Include="Async\Criteria\Lambda\SubQueryIntegrationFixture.cs" />
200200
<Compile Include="Async\Criteria\ProjectionsTest.cs" />
201+
<Compile Include="Async\DebugConnectionProvider.cs" />
201202
<Compile Include="Async\Deletetransient\DeleteTransientEntityTest.cs" />
202203
<Compile Include="Async\DialectTest\DB2DialectFixture.cs" />
203204
<Compile Include="Async\DialectTest\DialectFixture.cs" />
@@ -254,6 +255,7 @@
254255
<Compile Include="Async\Events\Collections\Association\Unidirectional\ManyToMany\UnidirectionalManyToManyBagCollectionEventFixture.cs" />
255256
<Compile Include="Async\Events\Collections\Association\Unidirectional\OneToMany\UnidirectionalOneToManyBagCollectionEventFixture.cs" />
256257
<Compile Include="Async\Events\Collections\Association\Unidirectional\OneToMany\UnidirectionalOneToManySetCollectionEventFixture.cs" />
258+
<Compile Include="Async\Events\Collections\CollectionListeners.cs" />
257259
<Compile Include="Async\Events\Collections\Values\ValuesBagCollectionEventFixture.cs" />
258260
<Compile Include="Async\Events\DisposableListenersTest.cs" />
259261
<Compile Include="Async\Events\PostEvents\PostUpdateFixture.cs" />

0 commit comments

Comments
 (0)