Repository navigation
fix: Hot reload no longer fails to resolve plugin DLLs that only a referenced assembly uses - #3176
Conversation
…tively referenced assembly Cecil resolves the assemblies a publicized copy refers to while it writes the copy, and it only searched the directories of the group assembly's own compile references. Unity's allReferences is not transitive, so a test assembly whose asmdef overrides its references could not resolve a precompiled DLL that only a referenced game assembly lists, and the file failed with "Publicizing referenced assemblies failed". The search directories now come from a breadth-first walk of the referenced assemblies, with the assembly's own references first so a same-named DLL keeps resolving to the same copy. Reference paths seen earlier in the walk are skipped before File.Exists, because the engine references repeat in every assembly. The shim's compile references are unchanged.
…ctories The internals-exposed copies for an introduced-type artifact are written by Cecil too, and their search directories came from the worker's reference list, which holds only the group assembly's own compile references. The artifact compile now receives the directories of every transitively referenced assembly, collected from the group's compilation assembly the same way as for the shim references, so both compiles resolve the same precompiled DLLs.
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configuration
⛔ Files ignored due to path filters (2)
📒 Files selected for processing (6)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 1 remain after this review. 📝 WalkthroughWalkthroughThe change adds breadth-first collection of resolver directories from transitive assembly references. Hot-reload artifact and shim builders use the collected directories. Editor tests cover ordering and transitive resolution, and the documentation records Cecil’s lookup order. ChangesHot-reload resolver directory flow
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix Sequence Diagram(s)sequenceDiagram
participant CompilationAssembly
participant HotReloadResolverSearchDirectories
participant HotReloadIntroducedTypeArtifactReferenceBuilder
participant Cecil
CompilationAssembly->>HotReloadResolverSearchDirectories: Collect reference directories
HotReloadResolverSearchDirectories-->>HotReloadIntroducedTypeArtifactReferenceBuilder: Return ordered directories
HotReloadIntroducedTypeArtifactReferenceBuilder->>Cecil: Resolve exposed-copy references
Merge Risk: ⚪ Minimal · up to No actionable merge-blocking risk is identified; the change is ready for normal merge checks. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to Dependency lookup expands within the existing Unity project workflow without adding a public interface or new execution privileges. No introduced security weakness was demonstrated. Correct reuse of generated files when dependency locations change remains unverified. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The new tests called Collect and the publicizer directly, so putting the old search directories back at either production call site left every test green. One test now builds shim references for a target whose metadata needs an assembly only a transitive reference lists, and another checks that the artifact reference build writes its exposed copies with the directories it is given rather than ones derived from the worker references.
37673bd
into
feature/hot-reload-large-project-feedback
Summary
User Impact
Before: in a project where a game assembly used an Asset Store plugin DLL,
uloop hot-reloadon a file of an EditMode test assembly referencing that game assembly returnedSuccess=false. The file failed with:After: those files hot-reload normally. Nothing changes for files whose own assembly lists the plugin.
Cause
Assembly.allReferences).allReferencesis not transitive: it is the asmdef references plus the assembly's own precompiled references. A test asmdef withoverrideReferences: truedoes not list the game's auto-referenced plugin DLLs, so the plugin's directory was never searched, even though the referenced game assembly lists it.UnityCLILoop.Tests.Editor.HotReloadoverrides its references.ExecuteDynamicCode) lists the code analysis plugin DLLs in a directory the test assembly's own references do not cover.Changes
HotReloadResolverSearchDirectories.Collect(assembly): the search directories are now collected from the assembly and every assembly it references transitively.File.Exists, because the engine references (about 230 per assembly) repeat in every assembly. Measured in this project with the same algorithm: 62–145 ms without the skip, 14–16 ms with it, for closures of 20–51 assemblies. Both found 19 directories. The skip cannot change the result: a path seen earlier either already added its directory or did not exist then either.docs/hot-reload.mddescribes the search order.Verification
New tests
In
HotReloadResolverSearchDirectoriesTests:Collect_IncludesDirectoriesOfTransitivelyReferencedPrecompiledAssemblies: a plugin two references away (Tests → Game → Core → plugin) is reached. It also checks that neither the root's own references nor the direct reference's list the plugin, so the graph needs the full walk.Collect_OrdersOwnReferencesBeforeTransitiveOnes: the root's own reference directory comes before the transitive plugin directory.Collect_ForHotReloadTestAssembly_ReachesTheCodeAnalysisPluginDirectoryOnlyTransitively: on this project's real hot-reload test assembly, its own references do not cover the code analysis plugin directory, and the walk reaches it.GetOrCreatePublicizedCopy_ResolvesAnAssemblyThatOnlyATransitiveReferenceLists: a generated image with a constant of an enum from an assembly that only a transitive reference lists.AssemblyResolutionException.TryBuildShimReferencePaths_PublicizesTheTargetWithTransitiveSearchDirectories: the shim reference build itself, on the same kind of image and graph, returns references instead of the publicize failure.In
HotReloadIntroducedTypeArtifactReferenceBuilderTests:Build_UsesTheResolverSearchDirectoriesItIsGiven: the artifact reference build writes its exposed copies with the directories it is given. With the directories of the worker references, the same build fails with the exposure message.The artifact-side call site is only reachable through PrepareAsync and cannot fail with this project's DLLs, so it is covered by the introduced-type E2E tests for execution, not for the failure.
Unity EditMode (local, filtered)
HotReloadResolverSearchDirectoriesTests|ReferencePublicizerTests|HotReloadShimReferenceBuilderTests|InternalsExposedReferenceTests|HotReloadIntroducedTypeArtifactReferenceBuilderTests|HotReloadIntroducedTypeInitializerE2ETests: 61 tests, 60 passed, 1 skipped. The skipped case needs a platform with two directory separators.HotReloadIntroducedTypeArtifactReferenceBuilderTests|HotReloadIntroducedTypeReferencePathsTests|HotReloadResolverSearchDirectoriesTests|HotReloadIntroducedTypeInitializerE2ETests|HotReloadIntroducedTypeDynamicCodeCompilationE2ETests|HotReloadIntroducedTypeInternalAccessE2ETests: 52 tests, 51 passed, 1 skipped (the same case).HotReloadIntroducedTypeInternalAccessE2ETestscovers the artifact compile with internals exposed.Collectand publicizer tests fail, each for the expected reason (2 missing directories, a missing plugin index, andAssemblyResolutionException).Static checks (local)
uloop compile: 0 errors.uloop compile-check: 0 errors. Its 7 warnings are in unchanged test fixtures.