Replies: 5 comments 7 replies
-
So if it wasn't for file path limits (which is really unfortunate here), those generators should just be using the fully qualified name of the types with the namespace, to avoid the collisions. @chsienki do you know if that was the concern for the runtime generators or this was just an oversight? I don't want to spend a lot of time designing around an "oops" if this was just that. I know famously our API has had no easy way to get a full qualified type name...this might finally be a forcing function. The hint name is used so that way users can see the stable output of a file. If you're running real builds and telling the compiler to output files on disk and you are trying to debug something, it might be handy to be able to open that file in an editor and just let it reload between builds. In the IDE, you can open the output of a generator into a virtual file, and we'll refresh that as we run it; that uses the hint path to know what is the "same" file from one run to the next. We absolutely could do something to automatically differentiate the files like you were with automatically applying suffixes, as you observed there are still determinism problems if the order of calls varies from one run to the next. And even if the order is deterministic, there's still a problem that one disappearing "in the middle" adjusts the suffixes the rest all get, which could be confusing as well. |
Beta Was this translation helpful? Give feedback.
-
Hi - any updates on this? I'm getting reports of this on my source generator: SteveDunn/Vogen#418 |
Beta Was this translation helpful? Give feedback.
-
Incremental source generator implementations that derive hint names from user-provided identifiers are expected to internally process them in a deterministic manner such that the final hint names are not duplicates. An example of this process can be seen here: This pull request can be reviewed commit-by-commit to see how it addresses the potential duplication problem (dotnet/roslyn-analyzers@a1e72641), and then ensures that the result does not impact the overall efficiency of the source generator (dotnet/roslyn-analyzers@9ad38533). |
Beta Was this translation helpful? Give feedback.
-
FWIW I'm tracking this issue as well: JasonBock/Rocks#219. The input I get is the type a user wants to mock. But just using the name of the type isn't sufficient. Even using a FQN (e.g. (Side note: With a I guess my main question is: how do I generate a hint name that will be unique for a given |
Beta Was this translation helpful? Give feedback.
-
[BitX]
public struct TestStruct1 {
public Bit3_0 BF1;
}
[BitX]
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct TestStruct
{
[ByteOffset(0)]
public Bit3_0 BF1;
} I have the same problem, now I need to generate Bit3_0, but the above code doesn't work, |
Beta Was this translation helpful? Give feedback.
-
In the current design of source generators, the
hintName
given toGeneratorExecutionContext.AddSource
/SourceProductionContext.AddSource
must be unique across all outputs of the generator.However, in most cases, the
hintName
is derived from user input (since source generators mainly generate extensions to user-defined code), and it's hard to come up with a source ofhintName
which is meaningful to the user, and is also guaranteed to be unique.The most obvious source of
hintName
is the name of the type being generated, but it's easy for these to be non-unique:Or:
It turns out that even Microsoft-authored source generators fall into this trap: dotnet/runtime#66851.
For non-incremental source generators, one possible workaround is something like:
Given two
hintNames
of "Foo", this will output "Foo" and then "Foo2". However, which file gets called "Foo" and which gets called "Foo2" is (probably) non-deterministic, which breaks the rule thathintNames
are relatively stable. Other options are using GUIDs (again breaking this rule), or appending the hash of the file contents to the hint (which then starts potentially running into path length limits). It's also boilerplate which (almost) every source generator will need to add, just to work around a seemingly arbitrary limitation in the source generator API.With incremental SGs, this gets significantly harder, as naively when we call
SourceProductionContext.AddSource
for one source, we don't know what other sources have been generated and what theirhintNames
are, so it's much harder to make sure that we're not using ahintName
which has already been used elsewhere.The best approach I can come up with is to
.Collect
all of the outputs into a singleIncrementalValueProvider<ImmutableArray<(SourceText, string desiredHintName)>>
or so, then have a single call toIncrementalGeneratorInitializationContext.RegisterSourceOutput
which takes this and does all of the.AddSource
calls for every file your SG needs to output in one go, making sure that none of thehintNames
collide. This seems to somewhat defeat the point of the incremental SG design however, as we need to re-output every generated file on every change (even if we're able to cache the actual content being output).I'm sure there's good reason to require that
hintNames
are unique and to put the burden of ensuring this on the SG author, but it results in a source of bugs which every SG author is going to discover by themselves, and then have to work around. These workarounds are particularly painful for incremental SGs.My request is to relax this restriction. Remove all restrictions on
hintNames
(including allowing duplicate values and invalid characters). If the source generator machinery needs to turn this collection of hints into file names, that can be handled in a suitable way by the source generator machinery itself, using some sensible scheme.Beta Was this translation helpful? Give feedback.
All reactions