| File: IncrementalMethodStubGenerationContext.cs | Web Access |
| Project: src\runtime\src\libraries\System.Runtime.InteropServices\gen\ComInterfaceGenerator\ComInterfaceGenerator.csproj (Microsoft.Interop.ComInterfaceGenerator) |
// 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.Diagnostics; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.Interop { internal abstract record GeneratedMethodContextBase(ManagedTypeInfo OriginalDefiningType, SequenceEqualImmutableArray<DiagnosticInfo> Diagnostics); internal enum StubMemberKind { Method, PropertyGetter, PropertySetter, IndexerGetter, IndexerSetter, } internal static class StubMemberKindExtensions { /// <summary> /// Returns true if <paramref name="kind"/> represents any property or indexer accessor /// (<see cref="StubMemberKind.PropertyGetter"/>, <see cref="StubMemberKind.PropertySetter"/>, /// <see cref="StubMemberKind.IndexerGetter"/>, or <see cref="StubMemberKind.IndexerSetter"/>). /// </summary> public static bool IsPropertyOrIndexerAccessor(this StubMemberKind kind) => kind is StubMemberKind.PropertyGetter or StubMemberKind.PropertySetter or StubMemberKind.IndexerGetter or StubMemberKind.IndexerSetter; /// <summary> /// Returns true if <paramref name="kind"/> represents the setter half of either a property /// or an indexer. /// </summary> public static bool IsAccessorSetter(this StubMemberKind kind) => kind is StubMemberKind.PropertySetter or StubMemberKind.IndexerSetter; /// <summary> /// Returns true if <paramref name="kind"/> represents either accessor of an indexer /// (as opposed to an ordinary property). /// </summary> public static bool IsIndexerAccessor(this StubMemberKind kind) => kind is StubMemberKind.IndexerGetter or StubMemberKind.IndexerSetter; } internal record IncrementalMethodStubGenerationContext( SignatureContext SignatureContext, ISignatureDiagnosticLocations DiagnosticLocation, SequenceEqualImmutableArray<FunctionPointerUnmanagedCallingConventionSyntax> CallingConvention, VirtualMethodIndexData VtableIndexData, MarshallingInfo ExceptionMarshallingInfo, EnvironmentFlags EnvironmentFlags, ManagedTypeInfo TypeKeyOwner, ManagedTypeInfo DeclaringType, SequenceEqualImmutableArray<DiagnosticInfo> Diagnostics, MarshallingInfo ManagedThisMarshallingInfo, StubMemberKind MemberKind) : GeneratedMethodContextBase(DeclaringType, Diagnostics) { private const string GetterPrefix = "get_"; private const string SetterPrefix = "set_"; /// <summary> /// Returns true if <paramref name="name"/> matches the Roslyn naming convention for a /// property accessor method (<c>get_X</c> or <c>set_X</c>). Centralizes the convention so /// callers do not embed the prefix literals directly. /// </summary> public static bool IsPropertyAccessorName(string name) => name.StartsWith(GetterPrefix, StringComparison.Ordinal) || name.StartsWith(SetterPrefix, StringComparison.Ordinal); /// <summary> /// Strips the <c>get_</c>/<c>set_</c> prefix from <paramref name="accessorName"/> to recover /// the underlying property name. Caller is responsible for ensuring the input is an /// accessor-shaped name (validated via <see cref="IsPropertyAccessorName"/>). /// </summary> public static string GetPropertyNameFromAccessor(string accessorName) { Debug.Assert(IsPropertyAccessorName(accessorName)); // GetterPrefix and SetterPrefix are the same length; either constant works here. return accessorName.Substring(GetterPrefix.Length); } } internal sealed record SourceAvailableIncrementalMethodStubGenerationContext( SignatureContext SignatureContext, ContainingSyntaxContext ContainingSyntaxContext, ContainingSyntax StubMethodSyntaxTemplate, ISignatureDiagnosticLocations DiagnosticLocation, SequenceEqualImmutableArray<FunctionPointerUnmanagedCallingConventionSyntax> CallingConvention, VirtualMethodIndexData VtableIndexData, MarshallingInfo ExceptionMarshallingInfo, EnvironmentFlags EnvironmentFlags, ManagedTypeInfo TypeKeyOwner, ManagedTypeInfo DeclaringType, SequenceEqualImmutableArray<DiagnosticInfo> Diagnostics, MarshallingInfo ManagedThisMarshallingInfo, StubMemberKind MemberKind) : IncrementalMethodStubGenerationContext( SignatureContext, DiagnosticLocation, CallingConvention, VtableIndexData, ExceptionMarshallingInfo, EnvironmentFlags, TypeKeyOwner, DeclaringType, Diagnostics, ManagedThisMarshallingInfo, MemberKind) { /// <summary> /// The user-visible name of the member this stub targets, suitable for use as an identifier in /// generated source. For an ordinary method this is the method's name; for a property accessor /// this is the property's name (e.g. <c>Foo</c> for accessor <c>get_Foo</c>, stripping the /// Roslyn-internal <c>get_</c> / <c>set_</c> prefix). /// </summary> public string TemplateName { get { string templateName = StubMethodSyntaxTemplate.Identifier.Text; if (MemberKind.IsPropertyOrIndexerAccessor()) { return GetPropertyNameFromAccessor(templateName); } return templateName; } } } }