Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Source Generator generates code multiple times

Discussion in 'Editor & General Support' started by thepunkoff, May 18, 2022.

  1. thepunkoff

    thepunkoff

    Joined:
    Apr 29, 2019
    Posts:
    4
    I was able to make my source generator work in Unity 2021.3, but there's one problem - it generates code multiple times - once per each unity assembly.

    This is how it looks like in Rider 2022.1:
    upload_2022-5-18_22-16-28.png

    In spite of those conflicts, the compiler is able to chose one of them for each generated file. So my game is working and using the generated classes.
    But Rider can't offer proper intellisense, because it sees a lot of similar files.

    The way I imported my generator is kind of a workaround/. I'm going to show the steps from the beginning:

    My generator makes use of System.Text.Json v5.0.2 (!), not the latest one, not the 6.0.0-preview (which the docs recommend - even if such a version doesn't actually exist, but that's another topic).
    It consumes the json file passed to it, and generates classes from it, using the AdditionalFiles property.
    var jsonFile = context.AdditionalFiles.SingleOrDefault(x => x.Path.EndsWith(".json"));


    1) I'm building my project in Rider 2022.1. This is the project file:
    upload_2022-5-18_22-23-1.png
    So, the two assemblies to make the generator be an actual generator, and one json assembly.

    2) Next, I'm copying the built libraries to Assets/MyGenerator
    These are the files:
    upload_2022-5-18_22-25-24.png
    Well, this bunch of libraries is the three libraries I refer to in the project, and their dependencies.|

    3) I click on the generator dll to configure it (just like in the docs):
    upload_2022-5-18_22-29-49.png
    Nothing works. Unity can't find the generated code:

    Assets\Game\Test.cs(4,24): error CS0234: The type or namespace name 'ArticySharp' does not exist in the namespace 'WhateverSoftware' (are you missing an assembly reference?)
    Assets\Game\Test.cs(14,17): error CS0246: The type or namespace name 'ArticyFlow' could not be found (are you missing a using directive or an assembly reference?)


    So this is the workaround using Additional Compiler Arguments:

    4) First, make the compiler see my json in Unity (/additionalfile:"Assets/myFile.json")
    Unity starts to print errors like these:

    WhateverSoftware.ArticySharp.Generator\WhateverSoftware.ArticySharp.Generator.ArticyJsonSourceGenerator\ArticyFlow.g.cs(6,19): error CS0234: The type or namespace name 'Json' does not exist in the namespace 'System.Text' (are you missing an assembly reference?)
    WhateverSoftware.ArticySharp.Generator\WhateverSoftware.ArticySharp.Generator.ArticyJsonSourceGenerator\ArticyFlow.g.cs(59,105): error CS0246: The type or namespace name 'JsonProperty' could not be found (are you missing a using directive or an assembly reference?)


    5) Next, I make the compiler see the Json library (/reference:"Assets/ArticySharp/System.Text.Json.dll")

    And... It compiles! With suspicious warnings...:
    WhateverSoftware.ArticySharp.Generator\WhateverSoftware.ArticySharp.Generator.ArticyJsonSourceGenerator\Character.g.cs(4,30): warning CS0436: The type 'Entity' in 'WhateverSoftware.ArticySharp.Generator\WhateverSoftware.ArticySharp.Generator.ArticyJsonSourceGenerator\Entity.g.cs' conflicts with the imported type 'Entity' in 'Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'WhateverSoftware.ArticySharp.Generator\WhateverSoftware.ArticySharp.Generator.ArticyJsonSourceGenerator\Entity.g.cs'.
    WhateverSoftware.ArticySharp.Generator\WhateverSoftware.ArticySharp.Generator.ArticyJsonSourceGenerator\Transformation.g.cs(11,16): warning CS0436: The type 'Point' in 'WhateverSoftware.ArticySharp.Generator\WhateverSoftware.ArticySharp.Generator.ArticyJsonSourceGenerator\Point.g.cs' conflicts with the imported type 'Point' in 'Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'WhateverSoftware.ArticySharp.Generator\WhateverSoftware.ArticySharp.Generator.ArticyJsonSourceGenerator\Point.g.cs'.

    And so on and so on....

    You've already seen how it looks like in the IDE. It seems, the compiler somehow runs once for each existing Unity script assembly. And I can't get rid of those extra files.

    My next step was to try some asmdef magic.
    I created a separate folder Assets/Game and put my test script there.
    And... magic! Now it looks like this:
    upload_2022-5-18_22-44-8.png

    Sooo it's obviously running code generation for each library my Test.cs script is referencing. Its header:

    using UnityEngine;
    using UnityEngine.TextCore.Text;
    using UnityEngine.UI;
    ...


    This smells like a bug. It already did, when I touched the additional compiler arguments.

    So, what do I do? How to make source generator run only once?
     
    MixamiDev likes this.
  2. jduffy_unity

    jduffy_unity

    Joined:
    May 14, 2019
    Posts:
    4
    The generator will run for every project/assembly in the solution. Make the generated class assembly/internal scoped. Every assembly will still get a copy of the generated class but it will fix the warnings.
     
  3. Xisor

    Xisor

    Joined:
    Jan 30, 2016
    Posts:
    8
    Workarounded that issue with
    Code (CSharp):
    1. if (context.Compilation.AssemblyName != "Assembly-CSharp") return;
    in the generators body
     
    lnm95 and MixamiDev like this.