Skip to content

Extensions: public API for extension syntax in CREF #78738

Open
@jcouv

Description

@jcouv

Background and Motivation

This API allows representing references to extension skeleton members in cref syntax. For example: cref="E.extension{T}(T).M(int)".

Relates to PR #78735
Relates to test plan #76130

Proposed API

namespace Microsoft.CodeAnalysis.CSharp
{
    public enum SyntaxKind : ushort
    {
        ExtensionMemberCref = 8607,
    }
}

namespace Microsoft.CodeAnalysis.CSharp.Syntax
{
    /// <remarks>
    /// <para>This node is associated with the following syntax kinds:</para>
    /// <list type="bullet">
    /// <item><description><see cref="SyntaxKind.ExtensionMemberCref"/></description></item>
    /// </list>
    /// </remarks>
    public sealed partial class ExtensionMemberCrefSyntax : MemberCrefSyntax
    {
        public SyntaxToken ExtensionKeyword { get; }
        public TypeArgumentListSyntax? TypeArgumentList { get; }
        public CrefParameterListSyntax Parameters { get; }
        public SyntaxToken DotToken { get; }
        public MemberCrefSyntax Member { get; }

        public override void Accept(CSharpSyntaxVisitor visitor);
        public override TResult? Accept<TResult>(CSharpSyntaxVisitor<TResult> visitor) where TResult : default;

        public ExtensionMemberCrefSyntax Update(SyntaxToken extensionKeyword, TypeArgumentListSyntax? typeArgumentList, CrefParameterListSyntax parameters, SyntaxToken dotToken, MemberCrefSyntax member);

        public ExtensionMemberCrefSyntax WithExtensionKeyword(SyntaxToken extensionKeyword);
        public ExtensionMemberCrefSyntax WithTypeArgumentList(TypeArgumentListSyntax? typeArgumentList);
        public ExtensionMemberCrefSyntax WithParameters(CrefParameterListSyntax parameters);
        public ExtensionMemberCrefSyntax WithDotToken(SyntaxToken dotToken);
        public ExtensionMemberCrefSyntax WithMember(MemberCrefSyntax member);

        public ExtensionMemberCrefSyntax AddTypeArgumentListArguments(params TypeSyntax[] items);
        public ExtensionMemberCrefSyntax AddParametersParameters(params CrefParameterSyntax[] items);
    }

    public partial class CSharpSyntaxVisitor<TResult>
    {
        /// <summary>Called when the visitor visits a ExtensionMemberCrefSyntax node.</summary>
        public virtual TResult? VisitExtensionMemberCref(ExtensionMemberCrefSyntax node);
    }

    public partial class CSharpSyntaxVisitor
    {
        /// <summary>Called when the visitor visits a ExtensionMemberCrefSyntax node.</summary>
        public virtual void VisitExtensionMemberCref(ExtensionMemberCrefSyntax node);
    }

    public partial class CSharpSyntaxRewriter : CSharpSyntaxVisitor<SyntaxNode?>
    {
        /// <summary>Called when the visitor visits a ExtensionMemberCrefSyntax node.</summary>
        public override SyntaxNode? VisitExtensionMemberCref(ExtensionMemberCrefSyntax node);
    }

    public static partial class SyntaxFactory
    {
        /// <summary>Creates a new ExtensionMemberCrefSyntax instance.</summary>
        public static ExtensionMemberCrefSyntax ExtensionMemberCref(SyntaxToken extensionKeyword, TypeArgumentListSyntax? typeArgumentList, CrefParameterListSyntax parameters, SyntaxToken dotToken, MemberCrefSyntax member);

        /// <summary>Creates a new ExtensionMemberCrefSyntax instance.</summary>
        public static ExtensionMemberCrefSyntax ExtensionMemberCref(TypeArgumentListSyntax? typeArgumentList, CrefParameterListSyntax parameters, MemberCrefSyntax member);

        /// <summary>Creates a new ExtensionMemberCrefSyntax instance.</summary>
        public static ExtensionMemberCrefSyntax ExtensionMemberCref(MemberCrefSyntax member);
    }
}
member_cref
  : conversion_operator_member_cref
+ | extension_member_cref
  | indexer_member_cref
  | name_member_cref
  | operator_member_cref
  ;

+extension_member_cref
+ : 'extension' type_argument_list? cref_parameter_list '.' member_cref
+ ;

Alternatives

The main alternative would be to represent the extension(...) portion as a specialized TypeSyntax instead of a specialized MemberCrefSyntax.

It would be something like:

type
  : array_type
  | function_pointer_type
  | name
  | nullable_type
  | omitted_type_argument
  | pointer_type
  | predefined_type
  | ref_type
  | scoped_type
  | tuple_type
+ | extension_block
  ;

+extension_block
+ : 'extension' type_argument_list? cref_parameter_list
+ ;

Metadata

Metadata

Assignees

Labels

Area-CompilersConcept-APIThis issue involves adding, removing, clarification, or modification of an API.Feature Requestapi-approvedAPI was approved in API review, it can be implementeduntriagedIssues and PRs which have not yet been triaged by a lead

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions