dex3r/GPT-Codemaster

Refactor ClassExtractorCSharp

Opened this issue · 8 comments

dex3r commented

Refactor ClassExtractorCSharp.GetClassContentWithSelectedMethodBodies by dividing it into smaller methods.

Hello, GPT-Codemaster here. I'm starting to work on the issue, give me a moment...

Job progress

Sending request to the AI using Chat interface

System message:

You are an AI system that does programming tasks by reading the issue specification and modifying the existing code by changing it or adding new code to resolve the user request. You minimize changes to the code and make sure not to modify anything that the user has not requested. Do not remove classes, methods, or fields - only add or modify existing ones. You will be doing the work in steps. The results of your work will be automatically put on Github. Always print the whole source, never the 'The rest of the class remains unchanged' comment

User Request:

The user request:
Refactor ClassExtractorCSharp
Refactor ClassExtractorCSharp.GetClassContentWithSelectedMethodBodies by dividing it into smaller methods.


Do this in steps:

  1. From a list of files select ones that will be needed to see or modify to program the user request. You will be shown content of those files. You have a limited memory so you will only see the selected ones.
  2. Modify selected existing files one by one
  3. Create needed new files one by one

Here is a hierarchical view of files in the project::

GithubIssueListener/IInputProvider.cs
GithubIssueListener/ListenerEntryPoint.cs
GithubIssueListener/SolverExceptionNotifier.cs
GithubIssueListener/ISolverExceptionNotifier.cs
GithubIssueListener/IssueSolvingStarter.cs
GithubIssueListener/InputProviderFromEnvironmentVariables.cs
GithubIssueListener/GithubIssueListener.csproj
GithubIssueListener/IssueListenerInput.cs
AiProgrammerTests/AiProgrammerTests.csproj
AiProgrammerTests/DependenciesTest.cs
AiProgrammerTests/ChatMessageRoleTests.cs
AiProgrammerTests/StringExtensionsSubstringSafeTests.cs
AiProgrammerTests/ClassExtractorTests.cs
AiProgrammer/Logging/ISolverProgressLogger.cs
AiProgrammer/Logging/SolverProgressLoggerInIssue.cs
AiProgrammer/Solving/Utils/UnexpectedAiOutputException.cs
AiProgrammer/Solving/GithubIssue/IGithubIssueSolver.cs
AiProgrammer/Solving/GithubIssue/GithubIssueSolverWithMethodSelection.cs
AiProgrammer/Solving/GithubIssue/InIssueNoChangesNotifier.cs
AiProgrammer/Solving/GithubIssue/GithubIssueSolverFileByFile.cs
AiProgrammer/Solving/GithubIssue/IIssueDescriptionProvider.cs
AiProgrammer/Solving/GithubIssue/GithubIssueContextProvider.cs
AiProgrammer/Solving/GithubIssue/IGithubIssueContextProvider.cs
AiProgrammer/Solving/GithubIssue/IssueDescriptionProvider.cs
AiProgrammer/Solving/Steps/Helpers/CurrentStepsHolder.cs
AiProgrammer/Solving/Steps/Helpers/FollowNextStepExecutor.cs
AiProgrammer/Solving/Steps/Helpers/ICurrentStepsHolder.cs
AiProgrammer/Solving/Steps/EntrySteps/StepSolveGithubIssueWithMethodSelection.cs
AiProgrammer/Solving/Steps/EntrySteps/StepSolveGithubIssueFileByFile.cs
AiProgrammer/Solving/Steps/ConcreteSteps/StepNotifyAboutPullRequest.cs
AiProgrammer/Solving/Steps/ConcreteSteps/StepModifyExistingFilesOneByOne.cs
AiProgrammer/Solving/Steps/ConcreteSteps/StepChangeFilesUsingCommands.cs
AiProgrammer/Solving/Steps/ConcreteSteps/StepCreateChangesCommands.cs
AiProgrammer/Solving/Steps/ConcreteSteps/StepCreatePullRequest.cs
AiProgrammer/Solving/Steps/ConcreteSteps/StepSelectMethodsToPreview.cs
AiProgrammer/Solving/Steps/ConcreteSteps/StepCreateNewFilesOneByOne.cs
AiProgrammer/Solving/Steps/ConcreteSteps/StepSelectFilesToPreview.cs
AiProgrammer/Solving/Steps/ISolverStep.cs
AiProgrammer/Solving/Steps/IStepsCollection.cs
AiProgrammer/Solving/Steps/ISolverStepWithSubsteps.cs
AiProgrammer/Solving/Model/FileAndMethodName.cs
AiProgrammer/Solving/Model/GithubIssueContext.cs
AiProgrammer/Solving/Commands/IModifyCodebaseCommand.cs
AiProgrammer/Github/Issues/IIssueUrlParser.cs
AiProgrammer/Github/Issues/IssueUrlParser.cs
AiProgrammer/Github/Model/IssueInfo.cs
AiProgrammer/Github/Model/RepoInfo.cs
AiProgrammer/Github/Model/RepoName.cs
AiProgrammer/Github/Model/RepoOwner.cs
AiProgrammer/Github/PullRequests/PullRequestCreator.cs
AiProgrammer/Github/GithubServices.cs
AiProgrammer/Github/GithubClientProviderForToken.cs
AiProgrammer/Github/GithubContextClientProvider.cs
AiProgrammer/Github/IGithubClientProviderForToken.cs
AiProgrammer/Github/IGithubContextClientProvider.cs
AiProgrammer/Core/CodeStatics.cs
AiProgrammer/CodeProcessing/IClassExtractor.cs
AiProgrammer/CodeProcessing/ClassExtractorCSharp.cs
AiProgrammer/Extensions/StringExtensions.cs
AiProgrammer/IO/FileContent.cs
AiProgrammer/IO/ProjectContentReader.cs
AiProgrammer/IO/IProjectContentReader.cs
AiProgrammer/IO/FilePath.cs
AiProgrammer/AiInterface/ChatCompletions.cs
AiProgrammer/AiInterface/IChat.cs
AiProgrammer/AiInterface/ICompletions.cs
AiProgrammer/AiProgrammer.csproj.DotSettings
AiProgrammer/AiProgrammerServices.cs
AiProgrammer/AiProgrammer.csproj
LICENSE
global.json
.gitignore
AiProgrammer.sln
Readme.md
AiProgrammer.sln.DotSettings


You are currently in step one (1). Please provide a list of files you think will help you the most when solving the problem. List them from most likely to help solve to problem to least likely. Print each path in new line without numerating them. Make sure to always print a full path.
�n

AI Response

AiProgrammer/CodeProcessing/ClassExtractorCSharp.cs

Sending request to the AI using Chat interface

System message:

You are an AI system that does programming tasks by reading the issue specification and modifying the existing code by changing it or adding new code to resolve the user request. You minimize changes to the code and make sure not to modify anything that the user has not requested. Do not remove classes, methods, or fields - only add or modify existing ones. You will be doing the work in steps. The results of your work will be automatically put on Github. Always print the whole source, never the 'The rest of the class remains unchanged' comment

User Request:

The user request:
Refactor ClassExtractorCSharp
Refactor ClassExtractorCSharp.GetClassContentWithSelectedMethodBodies by dividing it into smaller methods.


Do this in steps:

  1. From a list of files select ones that will be needed to see or modify to program the user request. You will be shown content of those files. You have a limited memory so you will only see the selected ones.
  2. Modify selected existing files one by one
  3. Create needed new files one by one

You are currently in step 'Modify selected existing files one by one'

Already reviewed files with your own description of what happened:

Files left to review:

Current file path:
AiProgrammer/CodeProcessing/ClassExtractorCSharp.cs

Current file content:

using System.Text;

namespace AiProgrammer.CodeProcessing;

public class ClassExtractorCSharp : IClassExtractor
{
    public string GetClassContentWithSelectedMethodBodies(string fullFilePath, IReadOnlyList<string> methods)
    {
        return GetClassContentWithSelectedMethodBodies(File.OpenText(fullFilePath), methods);
    }

    //TODO: Longest method generated. Too long, refactor, preferably using AI itself.
    public string GetClassContentWithSelectedMethodBodies(TextReader streamReader, IReadOnlyList<string> methods)
    {
        StringBuilder stringBuilder = new StringBuilder();

        string line;
        int braceCount = 0;
        int insideMethodBraceCount = -1;

        int classStartBraceCount = 0;
        bool isInsideClass = false;
        bool isInsideMethod = false;
        bool nextLineIsNamespace = false;
        bool nextLineIsClass = false;
        bool waitForNamespaceEnd = false;
        bool waitForClassEnd = false;

        void PrintLine(string line)
        {
            stringBuilder.AppendLine(line);
        }

        while ((line = streamReader.ReadLine()) != null)
        {
            if (!line.Contains(";") && !line.Contains("\"")
                                    && (line.Contains(" namespace ") || line.Contains("\tnamespace ") || line.StartsWith("namespace ")))
            {
                PrintLine(line);
                nextLineIsNamespace = true;
                continue;
            }

            if (!line.Contains("\"") &&
                (line.Contains(" class ") || line.Contains("\tclass ")))
            {
                PrintLine(line);
                nextLineIsClass = true;
                isInsideClass = true;
                braceCount++;
                classStartBraceCount = braceCount;
                continue;
            }

            if (nextLineIsNamespace)
            {
                waitForNamespaceEnd = true;
                nextLineIsNamespace = false;
                PrintLine(line);
                continue;
            }

            if (nextLineIsClass)
            {
                waitForClassEnd = true;
                nextLineIsClass = false;
                PrintLine(line);
                continue;
            }

            if (line.Trim().EndsWith("{"))
            {
                braceCount++;

                if (isInsideMethod)
                {
                    insideMethodBraceCount++;
                }
            }

            if (braceCount <= classStartBraceCount)
            {
                PrintLine(line);

                if (!isInsideMethod && methods.Any(method => line.Contains(method)))
                {
                    isInsideMethod = true;
                    insideMethodBraceCount = 0;
                }
            }
            else if (isInsideMethod)
            {
                PrintLine(line);
            }

            if (line.Trim().EndsWith("}"))
            {
                if (braceCount == classStartBraceCount)
                {
                    isInsideClass = false;
                }
                
                braceCount--;

                if (isInsideMethod)
                {
                    insideMethodBraceCount--;

                    if (insideMethodBraceCount == 0)
                    {
                        isInsideMethod = false;
                    }
                }

                if (braceCount == 0)
                {
                    if (waitForClassEnd)
                    {
                        waitForClassEnd = false;
                    }
                    else if (waitForNamespaceEnd)
                    {
                        waitForNamespaceEnd = false;
                    }
                }
            }
        }

        return stringBuilder.ToString();
    }
}

Select one command with this parameters to execute:

  • next_file [Note to yourself of what you saw that can be useful in next steps to solve the issue
    and when changing or creating next files. Make sure to include all needed information as you won't see this file again and won't remember
    what was inside.] - Do not modify this file and go to the next

  • replace_file [(in new line) new content in code block] [short description of what was actually modified and
    why, that can be useful in next steps] - Modify or remove the file by re-writing it's content. Write a short description of what was
    modified, this description will be read only by you when moving to the next file

�n

AI Response

replace_file

using System.Text;
using System.IO;
using System.Collections.Generic;
using System.Linq;

namespace AiProgrammer.CodeProcessing
{
    public class ClassExtractorCSharp : IClassExtractor
    {
        public string GetClassContentWithSelectedMethodBodies(string fullFilePath, IReadOnlyList<string> methods)
        {
            return GetClassContentWithSelectedMethodBodies(File.OpenText(fullFilePath), methods);
        }

        public string GetClassContentWithSelectedMethodBodies(TextReader streamReader, IReadOnlyList<string> methods)
        {
            StringBuilder stringBuilder = new StringBuilder();

            string line;
            int braceCount = 0;
            int insideMethodBraceCount = -1;

            int classStartBraceCount = 0;
            bool isInsideClass = false;
            bool isInsideMethod = false;
            bool nextLineIsNamespace = false;
            bool nextLineIsClass = false;
            bool waitForNamespaceEnd = false;
            bool waitForClassEnd = false;

            void PrintLine(string line)
            {
                stringBuilder.AppendLine(line);
            }

            while ((line = streamReader.ReadLine()) != null)
            {
                if (IsNamespaceDeclaration(line))
                {
                    HandleNamespaceDeclaration(line, ref nextLineIsNamespace);
                    continue;
                }

                if (IsClassDeclaration(line))
                {
                    HandleClassDeclaration(line, ref isInsideClass, ref braceCount, ref classStartBraceCount, ref nextLineIsClass);
                    continue;
                }

                if (nextLineIsNamespace)
                {
                    HandleNextLineNamespace(line, ref waitForNamespaceEnd, ref nextLineIsNamespace);
                    continue;
                }

                if (nextLineIsClass)
                {
                    HandleNextLineClass(line, ref waitForClassEnd, ref nextLineIsClass);
                    continue;
                }

                ProcessLine(line, ref braceCount, ref insideMethodBraceCount, ref isInsideClass, ref isInsideMethod, classStartBraceCount, methods);
            }

            return stringBuilder.ToString();
        }

        private bool IsNamespaceDeclaration(string line)
        {
            return !line.Contains(";") && !line.Contains("\"")
                && (line.Contains(" namespace ") || line.Contains("\tnamespace ") || line.StartsWith("namespace "));
        }

        private void HandleNamespaceDeclaration(string line, ref bool nextLineIsNamespace)
        {
            PrintLine(line);
            nextLineIsNamespace = true;
        }

        private bool IsClassDeclaration(string line)
        {
            return !line.Contains("\"") &&
                (line.Contains(" class ") || line.Contains("\tclass "));
        }

        private void HandleClassDeclaration(string line, ref bool isInsideClass, ref int braceCount, ref int classStartBraceCount, ref bool nextLineIsClass)
        {
            PrintLine(line);
            nextLineIsClass = true;
            isInsideClass = true;
            braceCount++;
            classStartBraceCount = braceCount;
        }

        private void HandleNextLineNamespace(string line, ref bool waitForNamespaceEnd, ref bool nextLineIsNamespace)
        {
            waitForNamespaceEnd = true;
            nextLineIsNamespace = false;
            PrintLine(line);
        }

        private void HandleNextLineClass(string line, ref bool waitForClassEnd, ref bool nextLineIsClass)
        {
            waitForClassEnd = true;
            nextLineIsClass = false;
            PrintLine(line);
        }

        private void ProcessLine(string line, ref int braceCount, ref int insideMethodBraceCount, ref bool isInsideClass, ref bool isInsideMethod, int classStartBraceCount, IReadOnlyList<string> methods)
        {
            if (line.Trim().EndsWith("{"))
            {
                braceCount++;

                if (isInsideMethod)
                {
                    insideMethodBraceCount++;
                }
            }

            if (braceCount <= classStartBraceCount)
            {
                PrintLine(line);

                if (!isInsideMethod && methods.Any(method => line.Contains(method)))
                {
                    isInsideMethod = true;
                    insideMethodBraceCount = 0;
                }
            }
            else if (isInsideMethod)
            {
                PrintLine(line);
            }

            if (line.Trim().EndsWith("}"))
            {
                if (braceCount == classStartBraceCount)
                {
                    isInsideClass = false;
                }

                braceCount--;

                if (isInsideMethod)
                {
                    insideMethodBraceCount--;

                    if (insideMethodBraceCount == 0)
                    {
                        isInsideMethod = false;
                    }
                }

                if (braceCount == 0)
                {
                    if (waitForClassEnd)
                    {
                        waitForClassEnd = false;
                    }
                    else if (waitForNamespaceEnd)
                    {
                        waitForNamespaceEnd = false;
                    }
                }
            }
        }
    }
}

Refactored the GetClassContentWithSelectedMethodBodies method by dividing it into smaller methods.

Sending request to the AI using Chat interface

System message:

You are an AI system that does programming tasks by reading the issue specification and modifying the existing code by changing it or adding new code to resolve the user request. You minimize changes to the code and make sure not to modify anything that the user has not requested. Do not remove classes, methods, or fields - only add or modify existing ones. You will be doing the work in steps. The results of your work will be automatically put on Github. Always print the whole source, never the 'The rest of the class remains unchanged' comment

User Request:

The user request:
Refactor ClassExtractorCSharp
Refactor ClassExtractorCSharp.GetClassContentWithSelectedMethodBodies by dividing it into smaller methods.


Do this in steps:

  1. From a list of files select ones that will be needed to see or modify to program the user request. You will be shown content of those files. You have a limited memory so you will only see the selected ones.
  2. Modify selected existing files one by one
  3. Create needed new files one by one

You are currently in step 'Create needed new files one by one'

Already reviewed files with your own description of what happened:
AiProgrammer/CodeProcessing/ClassExtractorCSharp.cs - modified - Refactored the GetClassContentWithSelectedMethodBodies method by dividing it into smaller methods.

New files you created:

Select one command with parameters to execute:

  • do_not_create_more_files - Use if there is no need to create a new file and move to the next step
  • create_new_file [path] [(in new line)new content in code block] [short description of what was created and why] - Create new file by providing its content. Write a short description of what was created, this description will be read only by you when moving to the next step

�n

AI Response

do_not_create_more_files

Pull Request created: #4