Skip to content

[API Proposal]: TypeName.MakeSimpleTypeName(AssemblyNameInfo) to avoid type name reparsing #106022

Closed
@adamsitnik

Description

@adamsitnik

Background and motivation

In #102263, we have approved a set of APIs for creating new TypeName instances without reparsing the input again.

I took a stab at it in #103713 and realized that I can not use the approved TypeName.CreateSimpleTypeName because it expects unescaped input. It's also supposed to escape such input (#102263 (comment)). In order to find out whether it needs to escape the input, it needs to reparse the input (search for multiple characters that need to be escaped). It's exactly what I need to avoid in NRBF, so I need a new method.

API Proposal

namespace System.Reflection.Metadata;

public partial class TypeName
{      
    public TypeName MakeSZArrayTypeName();
    public TypeName MakeArrayTypeName(int rank);
    public TypeName MakePointerTypeName();
    public TypeName MakeByRefTypeName();
    public TypeName MakeGenericTypeName(ImmutableArray<TypeName> typeArguments);
+   public TypeName MakeSimpleTypeName(AssemblyNameInfo? assemblyInfo);

    public static TypeName CreateSimpleTypeName(
        string metadataName,
        TypeName? declaringType = null,
        AssemblyNameInfo? assemblyInfo = null);
}

API Usage

static TypeName WithAssemblyName(this TypeName typeName, AssemblyNameInfo assemblyName)
{
    if (!typeName.IsSimple)
    {
        if (typeName.IsArray)
        {
            TypeName newElementType = typeName.GetElementType().WithAssemblyName(assemblyName);

            return typeName.IsSZArray
                ? newElementType.MakeSZArrayTypeName()
                : newElementType.MakeArrayTypeName(typeName.GetArrayRank());
        }
        else if (typeName.IsConstructedGenericType)
        {
            TypeName newGenericTypeDefinition = typeName.GetGenericTypeDefinition().WithAssemblyName(assemblyName);

            // We don't change the assembly name of generic arguments on purpose.
            return newGenericTypeDefinition.MakeGenericTypeName(typeName.GetGenericArguments());
        }
        else
        {
            // BinaryFormatter can not serialize pointers or references.
            ThrowHelper.ThrowInvalidTypeName(typeName.FullName);
        }
    }

    return typeName.MakeSimpleTypeName(assemblyName);
}

Alternative Designs

No response

Risks

Having two methods with similar names: MakeSimpleTypeName and CreateSimpleTypeName may be confusing to the end users.

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-System.Reflection.Metadatabinaryformatter-migrationIssues related to the removal of BinaryFormatter and migrations away from itblockingMarks issues that we want to fast track in order to unblock other important workin-prThere is an active PR which will close this issue when it is merged

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions