Skip to content

Commit

Permalink
Various refactorings to share more code with future generators (#67997)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkoritzinsky authored May 12, 2022
1 parent 9fce636 commit e278502
Show file tree
Hide file tree
Showing 37 changed files with 1,367 additions and 1,037 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.ComponentModel;

#if MICROSOFT_INTEROP_SOURCEGENERATION
namespace Microsoft.Interop
#else
namespace System.Runtime.InteropServices.Marshalling
#endif
{
/// <summary>
/// A direction of marshalling data into or out of the managed environment
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;

#if MICROSOFT_INTEROP_SOURCEGENERATION
namespace Microsoft.Interop
#else
namespace System.Runtime.InteropServices.Marshalling
#endif
{
/// <summary>
/// Optional features supported by custom type marshallers.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#if MICROSOFT_INTEROP_SOURCEGENERATION
namespace Microsoft.Interop
#else
namespace System.Runtime.InteropServices.Marshalling
#endif
{
/// <summary>
/// The shape of a custom type marshaller for usage in source-generated interop scenarios.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
//
// Types in this file are used for generated p/invokes
//
#if MICROSOFT_INTEROP_SOURCEGENERATION
namespace Microsoft.Interop
#else
namespace System.Runtime.InteropServices
#endif
{
/// <summary>
/// Specifies how strings should be marshalled for generated p/invokes
/// </summary>
#if SYSTEM_PRIVATE_CORELIB
#if SYSTEM_PRIVATE_CORELIB || MICROSOFT_INTEROP_SOURCEGENERATION
public
#else
internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Collections.Immutable;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using System.Composition;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,10 @@ namespace Microsoft.Interop
{
internal static class Comparers
{
/// <summary>
/// Comparer for the set of all of the generated stubs and diagnostics generated for each of them.
/// </summary>
public static readonly IEqualityComparer<ImmutableArray<(string, ImmutableArray<Diagnostic>)>> GeneratedSourceSet = new ImmutableArraySequenceEqualComparer<(string, ImmutableArray<Diagnostic>)>(new CustomValueTupleElementComparer<string, ImmutableArray<Diagnostic>>(EqualityComparer<string>.Default, new ImmutableArraySequenceEqualComparer<Diagnostic>(EqualityComparer<Diagnostic>.Default)));

/// <summary>
/// Comparer for an individual generated stub source as a string and the generated diagnostics for the stub.
/// </summary>
public static readonly IEqualityComparer<(string, ImmutableArray<Diagnostic>)> GeneratedSource = new CustomValueTupleElementComparer<string, ImmutableArray<Diagnostic>>(EqualityComparer<string>.Default, new ImmutableArraySequenceEqualComparer<Diagnostic>(EqualityComparer<Diagnostic>.Default));

/// <summary>
/// Comparer for an individual generated stub source as a syntax tree and the generated diagnostics for the stub.
/// </summary>
public static readonly IEqualityComparer<(MemberDeclarationSyntax Syntax, ImmutableArray<Diagnostic> Diagnostics)> GeneratedSyntax = new CustomValueTupleElementComparer<MemberDeclarationSyntax, ImmutableArray<Diagnostic>>(SyntaxEquivalentComparer.Instance, new ImmutableArraySequenceEqualComparer<Diagnostic>(EqualityComparer<Diagnostic>.Default));

/// <summary>
/// Comparer for the context used to generate a stub and the original user-provided syntax that triggered stub creation.
/// </summary>
public static readonly IEqualityComparer<(MethodDeclarationSyntax Syntax, LibraryImportGenerator.IncrementalStubGenerationContext StubContext)> CalculatedContextWithSyntax = new CustomValueTupleElementComparer<MethodDeclarationSyntax, LibraryImportGenerator.IncrementalStubGenerationContext>(SyntaxEquivalentComparer.Instance, EqualityComparer<LibraryImportGenerator.IncrementalStubGenerationContext>.Default);
}

/// <summary>
Expand Down Expand Up @@ -61,23 +46,6 @@ public int GetHashCode(ImmutableArray<T> obj)
}
}

internal sealed class SyntaxEquivalentComparer : IEqualityComparer<SyntaxNode>
{
public static readonly SyntaxEquivalentComparer Instance = new();

private SyntaxEquivalentComparer() { }

public bool Equals(SyntaxNode x, SyntaxNode y)
{
return x.IsEquivalentTo(y);
}

public int GetHashCode(SyntaxNode obj)
{
throw new UnreachableException();
}
}

internal sealed class CustomValueTupleElementComparer<T, U> : IEqualityComparer<(T, U)>
{
private readonly IEqualityComparer<T> _item1Comparer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,11 @@ public void ReportConfigurationNotSupported(
/// <summary>
/// Report diagnostic for marshalling of a parameter/return that is not supported
/// </summary>
/// <param name="method">Method with the parameter/return</param>
/// <param name="diagnosticLocations">Method with the parameter/return</param>
/// <param name="info">Type info for the parameter/return</param>
/// <param name="notSupportedDetails">[Optional] Specific reason for lack of support</param>
public void ReportMarshallingNotSupported(
MethodDeclarationSyntax method,
MethodSignatureDiagnosticLocations diagnosticLocations,
TypePositionInfo info,
string? notSupportedDetails,
ImmutableDictionary<string, string> diagnosticProperties)
Expand All @@ -224,15 +224,14 @@ public void ReportMarshallingNotSupported(

if (info.IsManagedReturnPosition)
{
diagnosticLocation = Location.Create(method.SyntaxTree, method.Identifier.Span);
elementName = method.Identifier.ValueText;
diagnosticLocation = diagnosticLocations.FallbackLocation;
elementName = diagnosticLocations.MethodIdentifier;
}
else
{
Debug.Assert(info.ManagedIndex <= method.ParameterList.Parameters.Count);
ParameterSyntax param = method.ParameterList.Parameters[info.ManagedIndex];
diagnosticLocation = Location.Create(param.SyntaxTree, param.Identifier.Span);
elementName = param.Identifier.ValueText;
Debug.Assert(info.ManagedIndex <= diagnosticLocations.ManagedParameterLocations.Length);
diagnosticLocation = diagnosticLocations.ManagedParameterLocations[info.ManagedIndex];
elementName = info.InstanceIdentifier;
}

if (!string.IsNullOrEmpty(notSupportedDetails))
Expand Down Expand Up @@ -322,12 +321,12 @@ public void ReportInvalidMarshallingAttributeInfo(
/// <param name="method">Method with the configuration that cannot be forwarded</param>
/// <param name="name">Configuration name</param>
/// <param name="value">Configuration value</param>
public void ReportCannotForwardToDllImport(MethodDeclarationSyntax method, string name, string? value = null)
public void ReportCannotForwardToDllImport(MethodSignatureDiagnosticLocations method, string name, string? value = null)
{
_diagnostics.Add(
Diagnostic.Create(
CannotForwardToDllImport,
Location.Create(method.SyntaxTree, method.Identifier.Span),
method.FallbackLocation,
value is null ? name : $"{name}={value}"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,11 @@

namespace Microsoft.Interop
{
/// <summary>
/// Flags used to indicate members on LibraryImport attribute.
/// </summary>
[Flags]
public enum LibraryImportMember
{
None = 0,
EntryPoint = 1 << 0,
SetLastError = 1 << 1,
StringMarshalling = 1 << 2,
StringMarshallingCustomType = 1 << 3,
All = ~None
}

/// <summary>
/// LibraryImportAttribute data
/// </summary>
internal sealed record LibraryImportData(string ModuleName)
internal sealed record LibraryImportData(string ModuleName) : InteropAttributeData
{
/// <summary>
/// Value set by the user on the original declaration.
/// </summary>
public LibraryImportMember IsUserDefined { get; init; }
public string? EntryPoint { get; init; }
public bool SetLastError { get; init; }
public StringMarshalling StringMarshalling { get; init; }
public INamedTypeSymbol? StringMarshallingCustomType { get; init; }
public string EntryPoint { get; init; }
}
}
Loading

0 comments on commit e278502

Please sign in to comment.