Repository: dotnet/roslyn
File: src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs (C#)

Code before:
    }

    private static bool ContainsAnonymousType(INamedTypeSymbol type)
    {
        if (type.IsAnonymousType)
            return true;

        foreach (var typeArg in type.GetAllTypeArguments())
        {
            if (ContainsAnonymousType(typeArg))
                return true;
        }

        return false;
    }

    public static string CreateParameterName(this ITypeSymbol type, bool capitalize = false)
    {
        while (true)
        {
            switch (type)
            {
                case IArrayTypeSymbol arrayType:
                    type = arrayType.ElementType;
                    continue;
                case IPointerTypeSymbol:
                case IFunctionPointerTypeSymbol:
                    // Pointer types like "void*" and function pointer types like "delegate*<void>" 
                    // don't have meaningful names, so use the default parameter name
                    return capitalize ? DefaultParameterName.ToPascalCase() : DefaultParameterName;
            }

            break;
        }

        var shortName = GetParameterName(type);
        return capitalize ? shortName.ToPascalCase() : shortName.ToCamelCase();
    }

    private static string GetParameterName(ITypeSymbol? type)
    {
        if (type == null || type.IsAnonymousType() || type.IsTupleType)
        {
            return DefaultParameterName;
        }

        var shortName = type.GetShortName();
        return shortName.Length == 0
            ? DefaultParameterName
            : shortName;
    }

Review comment (suggestion):
@copilot undo the change to pointers. If the user has `Customer*` we want to still make that as if it was just `Customer`. Add tests for this as well and add a 'why, not what's comment for this in the code

Code after:
    }

    private static bool ContainsAnonymousType(INamedTypeSymbol type)
    {
        if (type.IsAnonymousType)
            return true;

        foreach (var typeArg in type.GetAllTypeArguments())
        {
            if (ContainsAnonymousType(typeArg))
                return true;
        }

        return false;
    }

    public static string CreateParameterName(this ITypeSymbol type, bool capitalize = false)
    {
        while (true)
        {
            switch (type)
            {
                case IArrayTypeSymbol arrayType:
                    type = arrayType.ElementType;
                    continue;
                case IPointerTypeSymbol pointerType:
                    // For normal pointers like Customer*, unwrap to get a meaningful name (customer)
                    // rather than using a generic default
                    type = pointerType.PointedAtType;
                    continue;
                case IFunctionPointerTypeSymbol:
                    // Function pointer types like "delegate*<void>" don't have a meaningful underlying type
                    // to generate a name from, so use the default parameter name
                    return capitalize ? DefaultParameterName.ToPascalCase() : DefaultParameterName;
            }

            break;
        }

        var shortName = GetParameterName(type);
        return capitalize ? shortName.ToPascalCase() : shortName.ToCamelCase();
    }

    private static string GetParameterName(ITypeSymbol? type)
    {
        if (type == null || type.IsAnonymousType() || type.IsTupleType)
        {
            return DefaultParameterName;
        }

        var shortName = type.GetShortName();