Skip to content

Commit ca99fc5

Browse files
authored
Add support for .NET Core 3.1.200 (#146)
1 parent ee66e06 commit ca99fc5

35 files changed

+266
-123
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,6 @@ ModelManifest.xml
243243

244244
# FAKE - F# Make
245245
.fake/
246-
tools/**
246+
[Tt]ools/
247247
.idea/
248248
*.dev.props

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ os: osx
55
matrix:
66
include:
77
- dotnet: 2.1.502
8+
env: TARGET=TestCore SCRIPTARGS="netcore=\"netcoreapp2.1\""
9+
- dotnet: 3.1.201
810
env: TARGET=TestCore SCRIPTARGS=
9-
- mono: 5.18.1
11+
- mono: latest
1012
env: TARGET=Test SCRIPTARGS=
1113
git:
1214
submodules: false

Common.props

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
1212
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
1313
<TreatSpecificWarningsAsErrors />
14-
<LibTargetFrameworks Condition ="$(LibTargetFrameworks) == ''">netstandard2.0</LibTargetFrameworks>
15-
<AppTargetFrameworks Condition ="$(AppTargetFrameworks) == ''">net472;netcoreapp2.1</AppTargetFrameworks>
16-
<TestTargetFramework Condition ="$(TestTargetFramework) == ''">net472</TestTargetFramework>
17-
<ToolTargetFramework Condition ="$(ToolTargetFramework) == ''">netcoreapp2.1</ToolTargetFramework>
14+
<LibTargetFrameworks Condition ="$(LibTargetFrameworks) == ''">netstandard2.0;netcoreapp2.1</LibTargetFrameworks>
15+
<AppTargetFrameworks Condition ="$(AppTargetFrameworks) == ''">net472;netcoreapp2.1;netcoreapp3.1</AppTargetFrameworks>
16+
<TestTargetFramework Condition ="$(TestTargetFramework) == ''">netcoreapp3.1</TestTargetFramework>
17+
<ToolTargetFrameworks Condition ="$(ToolTargetFrameworks) == ''">netcoreapp2.1;netcoreapp3.1</ToolTargetFrameworks>
18+
<MicrosoftCodeAnalysisVersion Condition ="$(TargetFramework) == 'netcoreapp2.1'">3.0.0</MicrosoftCodeAnalysisVersion>
19+
<MicrosoftCodeAnalysisVersion Condition ="$(TargetFramework) != 'netcoreapp2.1'">3.7.0</MicrosoftCodeAnalysisVersion>
20+
<DefineConstants Condition ="$(MicrosoftCodeAnalysisVersion) == '3.0.0'">LEGACY</DefineConstants>
1821
</PropertyGroup>
1922
</Project>

Nuget.config

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
<packageSources>
77
<clear />
88
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
9-
<add key="myget.org msbuild nightly" value="https://dotnet.myget.org/F/msbuild/api/v3/index.json" />
10-
<add key="Roslyn" value="https://dotnet.myget.org/F/roslyn/api/v3/index.json" />
9+
<add key="msbuild" value="https://dotnet.myget.org/F/msbuild/api/v3/index.json" />
10+
<add key="roslyn" value="https://dotnet.myget.org/F/roslyn/api/v3/index.json" />
11+
<add key="roslyn-analyzers" value="https://dotnet.myget.org/F/roslyn-analyzers/api/v3/index.json" />
1112
</packageSources>
1213
</configuration>

Source/.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,4 @@ csharp_new_line_before_else = true
7676
csharp_new_line_before_catch = true
7777
csharp_new_line_before_finally = true
7878
csharp_new_line_before_members_in_object_initializers = true
79-
csharp_new_line_before_members_in_anonymous_types = true
79+
csharp_new_line_before_members_in_anonymous_types = true

Source/AsyncGenerator.CommandLine/AsyncGenerator.CommandLine.csproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,33 +26,33 @@
2626
</ItemGroup>
2727

2828
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
29-
<DefineConstants>TRACE;ENV</DefineConstants>
29+
<DefineConstants>$(DefineConstants);TRACE;ENV</DefineConstants>
3030
<PlatformTarget>AnyCPU</PlatformTarget>
3131
</PropertyGroup>
3232

3333
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
34-
<DefineConstants>TRACE;DEBUG;ENV</DefineConstants>
34+
<DefineConstants>$(DefineConstants);TRACE;DEBUG;ENV</DefineConstants>
3535
<PlatformTarget>AnyCPU</PlatformTarget>
3636
</PropertyGroup>
3737

38-
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
38+
<ItemGroup Condition="'$(TargetFramework)' != 'net472'">
3939
<PackageReference Include="log4net" Version="2.0.8" />
4040
<PackageReference Include="Microsoft.Build.Locator" Version="1.2.6" />
41-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.0.0" />
42-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="3.0.0" />
41+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="$(MicrosoftCodeAnalysisVersion)" />
42+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="$(MicrosoftCodeAnalysisVersion)" />
4343
</ItemGroup>
4444

45-
<ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp2.1'">
45+
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
4646
<PackageReference Include="log4net" Version="2.0.8">
4747
<PrivateAssets>all</PrivateAssets>
4848
</PackageReference>
4949
<PackageReference Include="Microsoft.Build.Locator" Version="1.2.6">
5050
<PrivateAssets>all</PrivateAssets>
5151
</PackageReference>
52-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.0.0">
52+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="$(MicrosoftCodeAnalysisVersion)">
5353
<PrivateAssets>all</PrivateAssets>
5454
</PackageReference>
55-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="3.0.0">
55+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="$(MicrosoftCodeAnalysisVersion)">
5656
<PrivateAssets>all</PrivateAssets>
5757
</PackageReference>
5858
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.6.0">

Source/AsyncGenerator.CommandLine/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ static class Program
1919

2020
static Program()
2121
{
22-
#if NETCOREAPP2_1
22+
#if NETCOREAPP
2323
var configPath = EnvironmentHelper.GetConfigurationFilePath();
2424
if (!string.IsNullOrEmpty(configPath))
2525
{
@@ -62,7 +62,7 @@ public static int Main(string[] args)
6262

6363
return 0;
6464
}
65-
#if !NETCOREAPP2_1
65+
#if !NETCOREAPP
6666
// Print inner exceptions for .NET as they are printed in NETCore 2.1: https://github.com/dotnet/coreclr/pull/15688
6767
catch (ReflectionTypeLoadException e) when (e.LoaderExceptions?.Length > 0)
6868
{

Source/AsyncGenerator.Core/AsyncGenerator.Core.csproj

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@
88
<IncludeSymbols>true</IncludeSymbols>
99
<AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>
1010
</PropertyGroup>
11-
1211
<ItemGroup>
13-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.0.0" />
14-
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="3.0.0" />
12+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="$(MicrosoftCodeAnalysisVersion)" />
13+
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="$(MicrosoftCodeAnalysisVersion)" />
1514
</ItemGroup>
16-
1715
</Project>

Source/AsyncGenerator.Core/Extensions/Internal/SymbolExtensions.cs

Lines changed: 98 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ namespace AsyncGenerator.Core.Extensions.Internal
1212
{
1313
internal static class SymbolExtensions
1414
{
15-
private static readonly Func<IMethodSymbol, IEnumerable> GetHiddenMembersFunc;
15+
private static readonly Func<object, IEnumerable> GetHiddenMembersFunc;
16+
#if !LEGACY
17+
private static readonly Func<object, ISymbol> GetPublicSymbolFunc;
18+
private static readonly Func<ISymbol, object> GetInternalSymbolFunc;
19+
#endif
1620

1721
static SymbolExtensions()
1822
{
@@ -22,6 +26,7 @@ static SymbolExtensions()
2226
{
2327
throw new InvalidOperationException($"Type {methodSymbolFullName} does not exist");
2428
}
29+
2530
var overriddenOrHiddenMembersGetter = type.GetProperty("OverriddenOrHiddenMembers", BindingFlags.NonPublic | BindingFlags.Instance)?.GetMethod;
2631
if (overriddenOrHiddenMembersGetter == null)
2732
{
@@ -34,22 +39,92 @@ static SymbolExtensions()
3439
throw new InvalidOperationException($"Property HiddenMembers of type {overriddenOrHiddenMembersGetter.ReturnType} does not exist.");
3540
}
3641

37-
var param1 = Expression.Parameter(typeof(IMethodSymbol), "methodSymbol");
38-
var convertToMethodSymbol = Expression.Convert(param1, type);
39-
var callOverriddenOrHiddenMembersGetter = Expression.Call(convertToMethodSymbol, overriddenOrHiddenMembersGetter);
42+
var symbolParameter = Expression.Parameter(typeof(object));
43+
var callOverriddenOrHiddenMembersGetter = Expression.Call(
44+
Expression.Convert(symbolParameter, type),
45+
overriddenOrHiddenMembersGetter);
4046
var callHiddenMembersGetter = Expression.Call(callOverriddenOrHiddenMembersGetter, hiddenMembersGetter);
4147
var lambdaParams = new List<ParameterExpression>
4248
{
43-
param1
49+
symbolParameter
4450
};
45-
GetHiddenMembersFunc = Expression.Lambda<Func<IMethodSymbol, IEnumerable>>(
51+
GetHiddenMembersFunc = Expression.Lambda<Func<object, IEnumerable>>(
4652
Expression.Convert(callHiddenMembersGetter, typeof(IEnumerable)), lambdaParams)
4753
.Compile();
54+
#if !LEGACY
55+
GetPublicSymbolFunc = CreateGetPublicSymbolFunction();
56+
GetInternalSymbolFunc = CreateGetInternalSymbolFunction();
57+
#endif
58+
}
59+
60+
#if !LEGACY
61+
private static Func<object, ISymbol> CreateGetPublicSymbolFunction()
62+
{
63+
const string symbolInternalFullName = "Microsoft.CodeAnalysis.Symbols.ISymbolInternal, Microsoft.CodeAnalysis";
64+
var symbolInternalType = Type.GetType(symbolInternalFullName);
65+
if (symbolInternalType == null)
66+
{
67+
throw new InvalidOperationException($"Type {symbolInternalFullName} does not exist");
68+
}
69+
70+
var getISymbolMethod = symbolInternalType.GetMethod("GetISymbol");
71+
if (getISymbolMethod == null)
72+
{
73+
throw new InvalidOperationException($"Method GetISymbol of type {symbolInternalFullName} does not exist.");
74+
}
75+
76+
var wrapperParameter = Expression.Parameter(typeof(object));
77+
return Expression.Lambda<Func<object, ISymbol>>(
78+
Expression.Call(
79+
Expression.Convert(wrapperParameter, symbolInternalType),
80+
getISymbolMethod
81+
),
82+
wrapperParameter
83+
).Compile();
84+
}
85+
86+
private static Func<ISymbol, object> CreateGetInternalSymbolFunction()
87+
{
88+
const string publicSymbolFullName = "Microsoft.CodeAnalysis.CSharp.Symbols.PublicModel.Symbol, Microsoft.CodeAnalysis.CSharp";
89+
var publicSymbolType = Type.GetType(publicSymbolFullName);
90+
if (publicSymbolType == null)
91+
{
92+
throw new InvalidOperationException($"Type {publicSymbolFullName} does not exist");
93+
}
94+
95+
var underlyingSymbolProperty = publicSymbolType.GetProperty("UnderlyingSymbol", BindingFlags.NonPublic | BindingFlags.Instance);
96+
if (underlyingSymbolProperty == null)
97+
{
98+
throw new InvalidOperationException($"Property UnderlyingSymbol of type {publicSymbolFullName} does not exist.");
99+
}
100+
101+
var symbolParameter = Expression.Parameter(typeof(ISymbol));
102+
return Expression.Lambda<Func<ISymbol, object>>(
103+
Expression.Property(
104+
Expression.Convert(symbolParameter, publicSymbolType),
105+
underlyingSymbolProperty
106+
),
107+
symbolParameter
108+
).Compile();
48109
}
110+
#endif
49111

50112
internal static IEnumerable<IMethodSymbol> GetHiddenMethods(this IMethodSymbol methodSymbol)
51113
{
114+
#if LEGACY
52115
return GetHiddenMembersFunc(methodSymbol).OfType<IMethodSymbol>();
116+
#else
117+
foreach (var item in GetHiddenMembersFunc(GetInternalSymbolFunc(methodSymbol)))
118+
{
119+
var hiddenMethod = GetPublicSymbolFunc(item) as IMethodSymbol;
120+
if (hiddenMethod == null)
121+
{
122+
continue;
123+
}
124+
125+
yield return hiddenMethod;
126+
}
127+
#endif
53128
}
54129

55130
/// <summary>
@@ -146,6 +221,15 @@ private static bool AreEqual(ImmutableArray<ITypeSymbol> types, ImmutableArray<I
146221
return true;
147222
}
148223

224+
internal static bool EqualTo(this ISymbol symbol, ISymbol symbolToCompare)
225+
{
226+
#if LEGACY
227+
return symbol.Equals(symbolToCompare);
228+
#else
229+
return symbol.Equals(symbolToCompare, SymbolEqualityComparer.Default);
230+
#endif
231+
}
232+
149233
/// <summary>
150234
/// Check if the return type matches, valid cases: <see cref="Void"/> to <see cref="System.Threading.Tasks.Task"/> Task, TResult to <see cref="System.Threading.Tasks.Task{TResult}"/> and
151235
/// also equals return types are ok when there is at least one delegate that can be converted to async (eg. Task.Run(<see cref="Action"/>) and Task.Run(<see cref="Func{Task}"/>))
@@ -156,7 +240,7 @@ private static bool AreEqual(ImmutableArray<ITypeSymbol> types, ImmutableArray<I
156240
internal static bool IsAsyncCandidateForReturnType(this IMethodSymbol syncMethod, IMethodSymbol candidateAsyncMethod)
157241
{
158242
// Original definition is used for matching generic types
159-
if (syncMethod.ReturnType.OriginalDefinition.Equals(candidateAsyncMethod.ReturnType.OriginalDefinition))
243+
if (syncMethod.ReturnType.OriginalDefinition.EqualTo(candidateAsyncMethod.ReturnType.OriginalDefinition))
160244
{
161245
return true;
162246
}
@@ -220,7 +304,7 @@ internal static List<int> GetAsyncDelegateArgumentIndexes(this IMethodSymbol syn
220304
continue;
221305
}
222306
var candidateDelegate = candidateTypeSymbol.DelegateInvokeMethod;
223-
if (origDelegate.Equals(candidateDelegate))
307+
if (origDelegate.EqualTo(candidateDelegate))
224308
{
225309
continue;
226310
}
@@ -239,7 +323,7 @@ internal static List<int> GetAsyncDelegateArgumentIndexes(this IMethodSymbol syn
239323
/// <returns></returns>
240324
internal static bool AreEqual(this ITypeSymbol type, ITypeSymbol toCompare, ITypeSymbol canBeDerivedFromType = null)
241325
{
242-
if (type.Equals(toCompare))
326+
if (type.EqualTo(toCompare))
243327
{
244328
return true;
245329
}
@@ -267,10 +351,10 @@ internal static bool AreEqual(this ITypeSymbol type, ITypeSymbol toCompare, ITyp
267351
return false;
268352
}
269353
}
270-
var equals = typeNamedType.OriginalDefinition.Equals(toCompareNamedType.OriginalDefinition);
354+
var equals = typeNamedType.OriginalDefinition.EqualTo(toCompareNamedType.OriginalDefinition);
271355
if (!equals && canBeDerivedFromType != null)
272356
{
273-
equals = new []{ canBeDerivedFromType }.Concat(canBeDerivedFromType.AllInterfaces).Any(o => toCompareNamedType.OriginalDefinition.Equals(o.OriginalDefinition));
357+
equals = new []{ canBeDerivedFromType }.Concat(canBeDerivedFromType.AllInterfaces).Any(o => toCompareNamedType.OriginalDefinition.EqualTo(o.OriginalDefinition));
274358
}
275359
return equals;
276360
}
@@ -286,22 +370,22 @@ internal static bool InheritsFromOrEquals(this ITypeSymbol type, ITypeSymbol bas
286370
return InheritsFromOrEquals(type, baseType);
287371
}
288372

289-
return type.GetBaseTypesAndThis().Concat(type.AllInterfaces).Any(t => t.Equals(baseType));
373+
return type.GetBaseTypesAndThis().Concat(type.AllInterfaces).Any(t => t.EqualTo(baseType));
290374
}
291375

292376
// Determine if "type" inherits from "baseType", ignoring constructed types and interfaces, dealing
293377
// only with original types.
294378
internal static bool InheritsFromOrEquals(this ITypeSymbol type, ITypeSymbol baseType)
295379
{
296-
return type.GetBaseTypesAndThis().Any(t => t.Equals(baseType));
380+
return type.GetBaseTypesAndThis().Any(t => t.EqualTo(baseType));
297381
}
298382

299383
// Determine if "type" inherits from "baseType", ignoring constructed types, and dealing
300384
// only with original types.
301385
internal static bool InheritsFromOrEqualsIgnoringConstruction(this ITypeSymbol type, ITypeSymbol baseType)
302386
{
303387
var originalBaseType = baseType.OriginalDefinition;
304-
return type.GetBaseTypesAndThis().Any(t => t.OriginalDefinition.Equals(originalBaseType));
388+
return type.GetBaseTypesAndThis().Any(t => t.OriginalDefinition.EqualTo(originalBaseType));
305389
}
306390

307391
internal static IEnumerable<ITypeSymbol> GetBaseTypesAndThis(this ITypeSymbol type)

Source/AsyncGenerator.Core/Extensions/SymbolExtensions.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public static bool IsAsyncCounterpart(this IMethodSymbol syncMethod, ITypeSymbol
4343
syncMethod = syncMethod.ReducedFrom ?? syncMethod;
4444
}
4545

46-
if (syncMethod.OverriddenMethod != null && candidateAsyncMethod.Equals(syncMethod.OverriddenMethod))
46+
if (syncMethod.OverriddenMethod != null && candidateAsyncMethod.EqualTo(syncMethod.OverriddenMethod))
4747
{
4848
return false;
4949
}
@@ -74,7 +74,7 @@ public static bool IsAsyncCounterpart(this IMethodSymbol syncMethod, ITypeSymbol
7474
{
7575
return false;
7676
}
77-
if (param.ConstraintTypes.Where((t, j) => !t.Equals(candidateParam.ConstraintTypes[j])).Any())
77+
if (param.ConstraintTypes.Where((t, j) => !t.EqualTo(candidateParam.ConstraintTypes[j])).Any())
7878
{
7979
return false;
8080
}
@@ -88,7 +88,7 @@ public static bool IsAsyncCounterpart(this IMethodSymbol syncMethod, ITypeSymbol
8888
}
8989
// Both methods can have the same return type only if we have at least one delegate argument that can be async or the ignoreReturnType
9090
// is set to true
91-
var result = ignoreReturnType || !syncMethod.ReturnType.OriginalDefinition.Equals(candidateAsyncMethod.ReturnType.OriginalDefinition);
91+
var result = ignoreReturnType || !syncMethod.ReturnType.OriginalDefinition.EqualTo(candidateAsyncMethod.ReturnType.OriginalDefinition);
9292

9393
for (var i = 0; i < syncMethod.Parameters.Length; i++)
9494
{
@@ -142,7 +142,7 @@ public static bool IsAsyncCounterpart(this IMethodSymbol syncMethod, ITypeSymbol
142142
{
143143
return false;
144144
}
145-
if (origDelegate.Equals(candidateDelegate))
145+
if (origDelegate.EqualTo(candidateDelegate))
146146
{
147147
continue;
148148
}
@@ -192,14 +192,14 @@ public static IEnumerable<IMethodSymbol> GetAsyncCounterparts(this IMethodSymbol
192192
? new[] {rootType}.Concat(rootType.AllInterfaces)
193193
: rootType.GetBaseTypesAndThis();
194194
var asyncCounterparts = types
195-
.SelectMany(o => o.GetMembers().Where(m => asyncName == m.Name || !equalParameters && m.Name == methodSymbol.Name && !methodSymbol.Equals(m)))
195+
.SelectMany(o => o.GetMembers().Where(m => asyncName == m.Name || !equalParameters && m.Name == methodSymbol.Name && !methodSymbol.EqualTo(m)))
196196
.OfType<IMethodSymbol>()
197197
.Where(o => methodSymbol.IsAsyncCounterpart(invokedFromType, o, equalParameters, hasCancellationToken, ignoreReturnType));
198198
// We have to return only unique async counterparts, skip overriden and hidden methods
199199
return FilterOutHiddenAndOverridenMethods(asyncCounterparts);
200200
}
201201

202-
return methodSymbol.ContainingType.GetMembers().Where(m => asyncName == m.Name || !equalParameters && m.Name == methodSymbol.Name && !methodSymbol.Equals(m))
202+
return methodSymbol.ContainingType.GetMembers().Where(m => asyncName == m.Name || !equalParameters && m.Name == methodSymbol.Name && !methodSymbol.EqualTo(m))
203203
.OfType<IMethodSymbol>()
204204
.Where(o => methodSymbol.IsAsyncCounterpart(invokedFromType, o, equalParameters, hasCancellationToken, ignoreReturnType));
205205
}

0 commit comments

Comments
 (0)