Skip to content

Refactor the sample composer to use CodeWriter instead#3672

Merged
ArcturusZhang merged 45 commits intoAzure:feature/v3from
ArcturusZhang:new-refactor-sample-generator
Sep 14, 2023
Merged

Refactor the sample composer to use CodeWriter instead#3672
ArcturusZhang merged 45 commits intoAzure:feature/v3from
ArcturusZhang:new-refactor-sample-generator

Conversation

@ArcturusZhang
Copy link
Copy Markdown
Member

@ArcturusZhang ArcturusZhang commented Aug 18, 2023

Fixes #3383
Fixes #3337
Fixes #3499
Fixes #3732

Depends on #3711

Possible follow ups:

  1. Manually fix the format in collection initializers since Roslyn has a bug right now: Add an option to apply code formatting to collection initializers dotnet/roslyn#8269 (tracking [Docs] Fix the bad formatting in our generated samples in collection initializations #3732)
  2. refactor some double iterations in the current implementation. They are temporary changes to avoid too many changes in the current regen

Description

How this example writer work now?

This PR separates our previous sample generator into two parts:

  1. makes up mock values. This is done in the new ExampleMockValueBuilder class in AutoRest.CSharp.Common.Input.Examples namespace
  2. consumes the example values (wherever it comes from) and produces C# sample code.

The biggest benefit of this separation is that in the future, if we want to consume the examples in the typespec, we just need an extra thing to deserialize those values into the structures we are having right now in this PR and the rest part introduced in this PR will write them into sample code.

How does the example writer write sample code?

Now the sample writer will write things based on the CSharpType of the property or the parameter regardless what type of the example value is. We must consider this because we would like to let the generator always generates code that could compile properly.
Therefore in this PR, when we are writing the code, we will always check the type of the property or parameter first, and then try to write the value in a value that could compile. If the type or format of the value mismatches, the generator will always generate default there to ensure it could compile properly.

This whole mechanism lives in an extension class of CodeWriter called CodeWriterExampleExtensions.

Refactors around the xml writer

Now our generator uses XDocument to build a xml document instead of using StringBuilder and putting everything manually by ourselves.
When writing the standalone xml document file, the generator will not write the code inside it because we need the sample code to be reduced and formatted by Rolsyn before we put them in the xml file.
Therefore the generator now just writes a test method name to where the sample code should be.

In the GeneratedCodeWorkspace, this PR adds a step after every file has been reduced and formatted to read the generated sample file, and parse it to get the implementation by the test method name we wrote before in the xml file, then replace it with the reduced and formatted code.

Changes on the generated samples

  1. When the RequestContext is required on the signature, we will pass null instead of new RequestContext(). Because we make it required to avoid ambiguous calls between protocol and convenience, null value is still allowed there.
  2. Quite a few example values changed, because now they are centrally generated, therefore for the same parameter or property in protocol method and convenience method, we will always use the same value, previously they are not using the same value therefore we have changes now.
  3. When we are building an anonymous object, we are now using Dictionary<string, object> to avoid the case that we get compilation errors when the property's serialized name has special characters or collides with C# keywords in anonymous objects (see issue [Sample] The sample composer should never change the serialized name of a property #3499 for details)

Issues in anonymous objects

Previously we always use anonymous object as the initialization in the samples for protocol methods which is nice to read for our customers. But unfortunately, as in #3499 , when the serialized name of a property is not a proper identifier in C# (which happens occasionally, such as a property named continue which is a C# keyword, or when a property name has hyphen in it), we no longer could construct it using the anonymous object syntax. When this happens, we have to use a dictionary.

in the implementation, when we could use the anonymous object syntax, we will use it. Only when we cannot, we switch to dictionaries.

Checklist

To ensure a quick review and merge, please ensure:

  • The PR has a understandable title and description explaining the why and what.
  • The PR is opened in draft if not ready for review yet.
    • If opened in draft, please allocate sufficient time (24 hours) after moving out of draft for review
  • The branch is recent enough to not have merge conflicts upon creation.

Ready to Land?

  • Build is completely green
    • Submissions with test failures require tracking issue and approval of a CODEOWNER
  • At least one +1 review by a CODEOWNER
  • All -1 reviews are confirmed resolved by the reviewer
    • Override/Marking reviews stale must be discussed with CODEOWNERS first

@ArcturusZhang ArcturusZhang force-pushed the new-refactor-sample-generator branch from 03f34eb to c6fe04a Compare August 18, 2023 04:02
@ArcturusZhang ArcturusZhang force-pushed the new-refactor-sample-generator branch from a5d807b to 89b38a4 Compare August 23, 2023 03:04
@ArcturusZhang ArcturusZhang force-pushed the new-refactor-sample-generator branch from 9c99a4f to c4d70f4 Compare September 5, 2023 09:26
@ArcturusZhang ArcturusZhang merged commit c908139 into Azure:feature/v3 Sep 14, 2023
@ArcturusZhang ArcturusZhang deleted the new-refactor-sample-generator branch September 14, 2023 06:23
live1206 pushed a commit to live1206/autorest.csharp that referenced this pull request Dec 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants