Skip to content

Unconditionally generate C# classes with nullable reference types #3945

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

0xced
Copy link
Contributor

@0xced 0xced commented Dec 21, 2023

Fixes #3944

@0xced 0xced requested a review from a team as a code owner December 21, 2023 22:50
@0xced 0xced force-pushed the unconditional-csharp-nrt branch from b750fa2 to e418974 Compare December 22, 2023 14:19
Copy link
Member

@baywet baywet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

holding until we get to a consensus on the issue

@0xced 0xced force-pushed the unconditional-csharp-nrt branch 2 times, most recently from 8cf210a to 4be3916 Compare January 17, 2024 10:44
@0xced 0xced force-pushed the unconditional-csharp-nrt branch from 4be3916 to 08b7bb6 Compare January 24, 2024 16:12
@0xced 0xced force-pushed the unconditional-csharp-nrt branch from 08b7bb6 to fe5f97c Compare March 7, 2024 19:16
@0xced 0xced force-pushed the unconditional-csharp-nrt branch from fe5f97c to 71c94d3 Compare March 8, 2024 19:46
@0xced 0xced force-pushed the unconditional-csharp-nrt branch 6 times, most recently from 6e4a216 to 3881847 Compare June 4, 2024 15:42
@0xced 0xced force-pushed the unconditional-csharp-nrt branch from 3881847 to 761d7e6 Compare June 6, 2024 15:08
@0xced 0xced force-pushed the unconditional-csharp-nrt branch from 761d7e6 to 7676d1a Compare June 11, 2024 13:18
@petriashev
Copy link

Waiting for this in kiota.
Too much noise

@dersia
Copy link

dersia commented Feb 10, 2025

what is this still waiting for?

@Odonno
Copy link

Odonno commented Mar 12, 2025

I am not sure what consensus is needed. Not wanted to look particularly disrespectful but having a strongly typed generated client should be common sense. Can we accelerate on this issue?

@Cyberzim
Copy link

Cyberzim commented Jun 2, 2025

@baywet
It's been over a year now. Why has this not reached a verdict yet? I really like the Kiota tool for C#, but the conditional code is making the generated code hard to read.

For now, I have created this bash script for cleaning up the output of Kiota in case anyone else needs it.

#!/bin/bash
# Script for cleaning up .cs files generated by Kiota.
# Basically, this is a workaround for https://github.com/microsoft/kiota/pull/3945 to make the code a bit more readable.

target_dir="${1:-.}"
echo "Processing .cs files in: $target_dir"

# Counters for reporting
total_files=0
modified_files=0

# Process all .cs files recursively
while read -r file; do
    total_files=$((total_files + 1))

    # Create a temporary file for processing
    temp_file=$(mktemp)

    # State variables for tracking position in the file
    has_nullable_directive=0
    in_if_block=0
    in_nullable_code=0
    in_else_block=0
    line_count=0
    in_using_section=0

    # Process the file line by line
    while IFS= read -r line || [[ -n "$line" ]]; do
        line_count=$((line_count + 1))

        if [[ $line =~ ^[[:space:]]*using[[:space:]]+ ]]; then
            # Using section
            in_using_section=1
            echo "$line" >> "$temp_file"
            continue
        elif [[ $in_using_section -eq 1 && has_nullable_directive -eq 0 ]]; then
            # Add nullable directive after using section
            echo "#nullable enable" >> "$temp_file"
            has_nullable_directive=1
            echo "$line" >> "$temp_file"
            continue
        elif [[ $in_if_block -eq 0 && $line =~ ^[[:space:]]*#if[[:space:]]+NETSTANDARD2_1_OR_GREATER[[:space:]]+\|\|[[:space:]]+NETCOREAPP3_1_OR_GREATER ]]; then
            # Found the start of a conditional block
            in_if_block=1
            continue
        elif [[ $in_if_block -eq 1 && $line =~ ^[[:space:]]*#nullable[[:space:]]+enable ]]; then
            # Found the nullable enable directive
            in_nullable_code=1
            continue
        elif [[ $in_nullable_code -eq 1 && $line =~ ^[[:space:]]*#nullable[[:space:]]+restore ]]; then
            # End of nullable code section
            in_nullable_code=0
            continue
        elif [[ $in_if_block -eq 1 && $in_nullable_code -eq 0 && $line =~ ^[[:space:]]*#else ]]; then
            # Found the else block - skip everything until endif
            in_else_block=1
            continue
        elif [[ ($in_if_block -eq 1 || $in_else_block -eq 1) && $line =~ ^[[:space:]]*#endif ]]; then
            # End of conditional block
            in_if_block=0
            in_else_block=0
            continue
        elif [[ $in_nullable_code -eq 1 ]]; then
            # Inside nullable code - keep this line
            echo "$line" >> "$temp_file"
        elif [[ $in_else_block -eq 1 ]]; then
            # Inside else block - skip this line
            continue
        else
            # Regular line - write to temp file
            echo "$line" >> "$temp_file"
        fi
    done < "$file"

    # Check if file was modified
    if ! cmp -s "$file" "$temp_file"; then
        modified_files=$((modified_files + 1))
        mv "$temp_file" "$file"
        echo "Modified: $file"
    else
        rm "$temp_file"
    fi
done < <(find "$target_dir" -type f -name "*.cs")

echo "Completed processing $total_files files. Modified $modified_files files."

Note: Use at your own risk. I have tested it on the Keycloak Admin REST API client generated by Kiota, and it seems to work well.

@Odonno
Copy link

Odonno commented Jun 2, 2025

@baywet It's been over a year now. Why has this not reached a verdict yet? I really like the Kiota tool for C#, but the conditional code is making the generated code hard to read.

For now, I have created this bash script for cleaning up the output of Kiota in case anyone else needs it.

#!/bin/bash
# Script for cleaning up .cs files generated by Kiota.
# Basically, this is a workaround for https://github.com/microsoft/kiota/pull/3945 to make the code a bit more readable.

target_dir="${1:-.}"
echo "Processing .cs files in: $target_dir"

# Counters for reporting
total_files=0
modified_files=0

# Process all .cs files recursively
while read -r file; do
    total_files=$((total_files + 1))

    # Create a temporary file for processing
    temp_file=$(mktemp)

    # State variables for tracking position in the file
    has_nullable_directive=0
    in_if_block=0
    in_nullable_code=0
    in_else_block=0
    line_count=0
    in_using_section=0

    # Process the file line by line
    while IFS= read -r line || [[ -n "$line" ]]; do
        line_count=$((line_count + 1))

        if [[ $line =~ ^[[:space:]]*using[[:space:]]+ ]]; then
            # Using section
            in_using_section=1
            echo "$line" >> "$temp_file"
            continue
        elif [[ $in_using_section -eq 1 && has_nullable_directive -eq 0 ]]; then
            # Add nullable directive after using section
            echo "#nullable enable" >> "$temp_file"
            has_nullable_directive=1
            echo "$line" >> "$temp_file"
            continue
        elif [[ $in_if_block -eq 0 && $line =~ ^[[:space:]]*#if[[:space:]]+NETSTANDARD2_1_OR_GREATER[[:space:]]+\|\|[[:space:]]+NETCOREAPP3_1_OR_GREATER ]]; then
            # Found the start of a conditional block
            in_if_block=1
            continue
        elif [[ $in_if_block -eq 1 && $line =~ ^[[:space:]]*#nullable[[:space:]]+enable ]]; then
            # Found the nullable enable directive
            in_nullable_code=1
            continue
        elif [[ $in_nullable_code -eq 1 && $line =~ ^[[:space:]]*#nullable[[:space:]]+restore ]]; then
            # End of nullable code section
            in_nullable_code=0
            continue
        elif [[ $in_if_block -eq 1 && $in_nullable_code -eq 0 && $line =~ ^[[:space:]]*#else ]]; then
            # Found the else block - skip everything until endif
            in_else_block=1
            continue
        elif [[ ($in_if_block -eq 1 || $in_else_block -eq 1) && $line =~ ^[[:space:]]*#endif ]]; then
            # End of conditional block
            in_if_block=0
            in_else_block=0
            continue
        elif [[ $in_nullable_code -eq 1 ]]; then
            # Inside nullable code - keep this line
            echo "$line" >> "$temp_file"
        elif [[ $in_else_block -eq 1 ]]; then
            # Inside else block - skip this line
            continue
        else
            # Regular line - write to temp file
            echo "$line" >> "$temp_file"
        fi
    done < "$file"

    # Check if file was modified
    if ! cmp -s "$file" "$temp_file"; then
        modified_files=$((modified_files + 1))
        mv "$temp_file" "$file"
        echo "Modified: $file"
    else
        rm "$temp_file"
    fi
done < <(find "$target_dir" -type f -name "*.cs")

echo "Completed processing $total_files files. Modified $modified_files files."

Note: Use at your own risk. I have tested it on the Keycloak Admin REST API client generated by Kiota, and it seems to work well.

Got to write a dumbed .csx script too. Guess I could move to dotnet shebang now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: New📃
Development

Successfully merging this pull request may close these issues.

Kiota should unconditionally generate C# classes with nullable reference types
6 participants