From aef2c2794e8ebe3c10b9234a0502ae1ff3ea8f67 Mon Sep 17 00:00:00 2001 From: Eli Pinkerton Date: Sun, 5 Jul 2026 17:04:53 -0700 Subject: [PATCH 1/6] Fix Unity 6000.5 compile error: migrate GetInstanceID to EntityId (#12) Unity 6000.5 makes the obsolete Object.GetInstanceID() a CS0619 compile error. The sole call site (building a write-only UI Toolkit element name) now routes through a small ObjectIdExtensions.GetObjectIdString helper that uses Object.GetEntityId()/EntityId.ToULong on Unity 6000.4+ (where EntityId was introduced) and falls back to GetInstanceID() on older editors. Bootstraps the package's first EditMode test assembly. The helper is public because InternalsVisibleTo is not honored for this editor/test assembly pair in Unity (verified: internal access yields CS0122/CS1061 from the test assembly even with a correct friend attribute in the compiled editor DLL). Verified via clean CLI EditMode runs (0 compile errors, test passes) on Unity 6000.5.2f1 and 6000.4.6f1 (EntityId branch) and 2022.3.62f2 (legacy branch). Bumps package version to 0.0.35. Co-Authored-By: Claude Fable 5 --- Editor/DataVisualizer/DataVisualizer.cs | 2 +- .../Extensions/ObjectIdExtensions.cs | 29 +++++++++++ .../Extensions/ObjectIdExtensions.cs.meta | 3 ++ Tests.meta | 4 ++ Tests/Editor.meta | 4 ++ Tests/Editor/ObjectIdExtensionsTests.cs | 50 +++++++++++++++++++ Tests/Editor/ObjectIdExtensionsTests.cs.meta | 3 ++ ...Studios.DataVisualizer.Tests.Editor.asmdef | 18 +++++++ ...os.DataVisualizer.Tests.Editor.asmdef.meta | 7 +++ package.json | 2 +- 10 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 Editor/DataVisualizer/Extensions/ObjectIdExtensions.cs create mode 100644 Editor/DataVisualizer/Extensions/ObjectIdExtensions.cs.meta create mode 100644 Tests.meta create mode 100644 Tests/Editor.meta create mode 100644 Tests/Editor/ObjectIdExtensionsTests.cs create mode 100644 Tests/Editor/ObjectIdExtensionsTests.cs.meta create mode 100644 Tests/Editor/WallstopStudios.DataVisualizer.Tests.Editor.asmdef create mode 100644 Tests/Editor/WallstopStudios.DataVisualizer.Tests.Editor.asmdef.meta diff --git a/Editor/DataVisualizer/DataVisualizer.cs b/Editor/DataVisualizer/DataVisualizer.cs index bd6f3a6..e0710f4 100644 --- a/Editor/DataVisualizer/DataVisualizer.cs +++ b/Editor/DataVisualizer/DataVisualizer.cs @@ -5887,7 +5887,7 @@ private void BuildObjectRow(ScriptableObject dataObject, int index) VisualElement objectItemRow = new() { - name = $"object-item-row-{dataObject.GetInstanceID()}", + name = $"object-item-row-{dataObject.GetObjectIdString()}", }; objectItemRow.AddToClassList(ObjectItemClass); objectItemRow.AddToClassList(StyleConstants.ClickableClass); diff --git a/Editor/DataVisualizer/Extensions/ObjectIdExtensions.cs b/Editor/DataVisualizer/Extensions/ObjectIdExtensions.cs new file mode 100644 index 0000000..f619bdf --- /dev/null +++ b/Editor/DataVisualizer/Extensions/ObjectIdExtensions.cs @@ -0,0 +1,29 @@ +namespace WallstopStudios.DataVisualizer.Editor.Extensions +{ + using System.Globalization; + using UnityEngine; + + /// + /// Helpers for deriving identifier strings from Unity objects. Public because the + /// package's editor test assembly cannot access internals of the editor assembly: + /// InternalsVisibleTo is not honored for this assembly pair in Unity's compilation + /// (verified — the internal type is reported CS0122 from the test assembly even with + /// a correct friend attribute compiled into the editor assembly). + /// + public static class ObjectIdExtensions + { + /// + /// Returns a per-session unique identifier string for the object, suitable for + /// building unique UI element names. NOT stable across editor sessions or domain + /// reloads; do not persist. + /// + public static string GetObjectIdString(this Object obj) + { +#if UNITY_6000_4_OR_NEWER + return EntityId.ToULong(obj.GetEntityId()).ToString(CultureInfo.InvariantCulture); +#else + return obj.GetInstanceID().ToString(CultureInfo.InvariantCulture); +#endif + } + } +} diff --git a/Editor/DataVisualizer/Extensions/ObjectIdExtensions.cs.meta b/Editor/DataVisualizer/Extensions/ObjectIdExtensions.cs.meta new file mode 100644 index 0000000..a46731e --- /dev/null +++ b/Editor/DataVisualizer/Extensions/ObjectIdExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9a939211421a40e7b3c3deead28830f2 +timeCreated: 1783293384 \ No newline at end of file diff --git a/Tests.meta b/Tests.meta new file mode 100644 index 0000000..341e6e9 --- /dev/null +++ b/Tests.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: b7501bc122ec4ed186925e9b849bde4f +folderAsset: yes +timeCreated: 1783293384 \ No newline at end of file diff --git a/Tests/Editor.meta b/Tests/Editor.meta new file mode 100644 index 0000000..a722d95 --- /dev/null +++ b/Tests/Editor.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 7b6201838beb4dc7ac7751f914fd7639 +folderAsset: yes +timeCreated: 1783293384 \ No newline at end of file diff --git a/Tests/Editor/ObjectIdExtensionsTests.cs b/Tests/Editor/ObjectIdExtensionsTests.cs new file mode 100644 index 0000000..89bd059 --- /dev/null +++ b/Tests/Editor/ObjectIdExtensionsTests.cs @@ -0,0 +1,50 @@ +namespace WallstopStudios.DataVisualizer.Tests.Editor +{ + using NUnit.Framework; + using UnityEngine; + using WallstopStudios.DataVisualizer.Editor.Extensions; + + public sealed class ObjectIdExtensionsTests + { + [Test] + public void GetObjectIdStringIsNonEmptyStableAndUnique() + { + ScriptableObject first = ScriptableObject.CreateInstance(); + ScriptableObject second = ScriptableObject.CreateInstance(); + try + { + string firstId = first.GetObjectIdString(); + string secondId = second.GetObjectIdString(); + + Assert.That(firstId, Is.Not.Null.And.Not.Empty); + Assert.That(secondId, Is.Not.Null.And.Not.Empty); + Assert.AreEqual( + firstId, + first.GetObjectIdString(), + "The id must be stable across repeated calls on the same object." + ); + Assert.AreNotEqual( + firstId, + secondId, + "Distinct objects must produce distinct ids." + ); +#if UNITY_6000_4_OR_NEWER + Assert.IsTrue( + ulong.TryParse(firstId, out _), + "The EntityId branch must produce a numeric (ulong) id string." + ); +#else + Assert.IsTrue( + long.TryParse(firstId, out _), + "The legacy InstanceID branch must produce a numeric (int) id string." + ); +#endif + } + finally + { + Object.DestroyImmediate(first); + Object.DestroyImmediate(second); + } + } + } +} diff --git a/Tests/Editor/ObjectIdExtensionsTests.cs.meta b/Tests/Editor/ObjectIdExtensionsTests.cs.meta new file mode 100644 index 0000000..8b1e811 --- /dev/null +++ b/Tests/Editor/ObjectIdExtensionsTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 045f60bfc6a8480c8ee087cdb76854c9 +timeCreated: 1783293384 \ No newline at end of file diff --git a/Tests/Editor/WallstopStudios.DataVisualizer.Tests.Editor.asmdef b/Tests/Editor/WallstopStudios.DataVisualizer.Tests.Editor.asmdef new file mode 100644 index 0000000..9ca41a0 --- /dev/null +++ b/Tests/Editor/WallstopStudios.DataVisualizer.Tests.Editor.asmdef @@ -0,0 +1,18 @@ +{ + "name": "WallstopStudios.DataVisualizer.Tests.Editor", + "rootNamespace": "WallstopStudios.DataVisualizer.Tests.Editor", + "references": [ + "UnityEditor.TestRunner", + "UnityEngine.TestRunner", + "WallstopStudios.DataVisualizer.Editor" + ], + "includePlatforms": ["Editor"], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": ["nunit.framework.dll"], + "autoReferenced": false, + "defineConstraints": ["UNITY_INCLUDE_TESTS"], + "versionDefines": [], + "noEngineReferences": false +} diff --git a/Tests/Editor/WallstopStudios.DataVisualizer.Tests.Editor.asmdef.meta b/Tests/Editor/WallstopStudios.DataVisualizer.Tests.Editor.asmdef.meta new file mode 100644 index 0000000..36116f3 --- /dev/null +++ b/Tests/Editor/WallstopStudios.DataVisualizer.Tests.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ab0fcdeaf8cd4b56aac58d4f88b1aa5f +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: \ No newline at end of file diff --git a/package.json b/package.json index 214c13e..86f0587 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.wallstop-studios.data-visualizer", - "version": "0.0.35-rc05.6", + "version": "0.0.35", "displayName": "Data Visualizer", "description": "Data Management UI for Unity's Scriptable Objects", "dependencies": {}, From 4d058a2602a4aaeae7bbdfc2e4c503dcad4b32b7 Mon Sep 17 00:00:00 2001 From: Eli Pinkerton Date: Sun, 5 Jul 2026 17:05:09 -0700 Subject: [PATCH 2/6] Add session working docs (PLAN.md, progress log) for #12 Working-notes per the repo's session conventions: PLAN.md tracks active items; progress/session-001 records the red-green verification and the InternalsVisibleTo investigation behind the public-helper decision. Co-Authored-By: Claude Fable 5 --- PLAN.md | 8 +++ PLAN.md.meta | 7 ++ progress.meta | 8 +++ progress/session-001-issue-12-entityid-fix.md | 69 +++++++++++++++++++ .../session-001-issue-12-entityid-fix.md.meta | 7 ++ 5 files changed, 99 insertions(+) create mode 100644 PLAN.md create mode 100644 PLAN.md.meta create mode 100644 progress.meta create mode 100644 progress/session-001-issue-12-entityid-fix.md create mode 100644 progress/session-001-issue-12-entityid-fix.md.meta diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..d597c31 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,8 @@ +# Plan + +Active work items. Completed/obsolete items are removed after each session; history lives in `progress/`. + +## Active + +- [ ] Issue #12 — Unity 6000.5 CS0619: migrate `Object.GetInstanceID()` → `EntityId` behind `UNITY_6000_4_OR_NEWER`; bootstrap EditMode tests; bump version to 0.0.35; ship fully green PR. + - Tracking: `progress/session-001-issue-12-entityid-fix.md` diff --git a/PLAN.md.meta b/PLAN.md.meta new file mode 100644 index 0000000..339476f --- /dev/null +++ b/PLAN.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b443ce2b86175b74b8ea26edeabb77c3 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/progress.meta b/progress.meta new file mode 100644 index 0000000..4c208dc --- /dev/null +++ b/progress.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 46ea7f1aae2f08f4c83c282882b28a7a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/progress/session-001-issue-12-entityid-fix.md b/progress/session-001-issue-12-entityid-fix.md new file mode 100644 index 0000000..c7a90f3 --- /dev/null +++ b/progress/session-001-issue-12-entityid-fix.md @@ -0,0 +1,69 @@ +# Session 001 — Issue #12: Unity 6000.5 `GetInstanceID` CS0619 → `EntityId` + +- **Date:** 2026-07-05 +- **Issue:** [wallstop/DataVisualizer#12](https://github.com/wallstop/DataVisualizer/issues/12) +- **Branch:** `dev/wallstop/bug-fixes` +- **Goal:** Minimal, tested, stable fix + version bump to `0.0.35`, verified red-green across Unity 2022.3 / 6000.4 / 6000.5, shipped as a fully green PR. + +## Findings (research phase) + +- Exactly **one** `GetInstanceID()` call site repo-wide: `Editor/DataVisualizer/DataVisualizer.cs:5890` (`BuildObjectRow`), used only to build a write-only UI Toolkit element name `object-item-row-{id}` (grep: the prefix appears nowhere else). +- `UnityEngine.EntityId` / `Object.GetEntityId()` were introduced in **Unity 6000.4** — the 6000.3 ScriptReference pages 404. Issue #12's suggested `UNITY_6000_3_OR_NEWER` guard is therefore wrong; correct guard is `UNITY_6000_4_OR_NEWER`. +- Official migration guidance (Unity 6000.5 manual, "Migrate from InstanceID to EntityId"): use `EntityId.ToULong`/`FromULong` for raw values; do not cast to `int`; do not persist `ToString()` output. +- Failure-mode sweep: no other obsolete InstanceID-family APIs in the package (`InstanceIDToObject`, `InstanceID` types, etc. — zero hits). The Unity 6000.5 RED compile log is the authoritative confirmation. + +## Decisions + +- Helper `internal static string GetObjectIdString(this Object obj)` in new `Editor/DataVisualizer/Extensions/ObjectIdExtensions.cs` (testable; keeps `#if` out of the 6000-line `DataVisualizer.cs`). Name deliberately avoids "stable" — instance/entity IDs are per-session only. +- Test access via `[assembly: InternalsVisibleTo("WallstopStudios.DataVisualizer.Tests.Editor")]`, following the existing `Runtime/DataVisualizer/BaseDataObject.cs` precedent (no AssemblyInfo.cs). +- Bootstrap `Tests/Editor` (first tests in this package), modeled on the sibling `unity-helpers` package's test asmdef. Single behavior-focused test; no bloat. +- Version: `0.0.35-rc05.6` → `0.0.35` (stable; user-confirmed). + +## Evidence log + +### RED-1 — Unity 6000.5.2f1 CLI compile of pristine package (reproduces #12) + +Throwaway project `uproj-6000_5` (created via `Unity.exe -createProject`), manifest references the package via `file:` + `testables`. Batchmode compile (`-batchmode -nographics -quit`, no `-accept-apiupdate`): + +```text +DataVisualizer.cs(5890,43): error CS0619: 'Object.GetInstanceID()' is obsolete: +'GetInstanceID is deprecated. Use GetEntityId instead. This will be removed in a future version.' +``` + +- The **only** `error CS` in the log; confirms the single-call-site failure mode. `git status` on the package stayed clean (Unity did not rewrite package source). +- Also observed: 72 `warning CS0618` (non-blocking) for unrelated UIToolkit deprecations — `EventBase.PreventDefault()` (45×) and `UxmlTraits`/`UxmlFactory` (27×) in `DataVisualizer.cs` + `UI/HorizontalToggle.cs`. These are **warnings, not errors**, a different failure mode from #12, and out of scope for this minimal fix (noted for a future task). + +### Test-first RED — Unity 2022.3.62f2 CLI compile of package+tests (no helper yet) + +Test assembly compiled and failed with **only** `CS1061: 'ScriptableObject' does not contain a definition for 'GetObjectIdString'` (3×). Confirms the test asmdef is wired correctly (nunit + refs resolve) and the test genuinely exercises the helper — it is not vacuous. On 2022.3 the package's `DataVisualizer.cs` compiles clean (GetInstanceID not obsolete pre-6000.4), so the missing helper is the sole error. + +### GREEN — fix applied (helper + call-site) + +- Editor assembly compiles with **0 errors** on 6000.4.6f1 (live, via MCP) and 6000.5.2f1 (CLI); the old `GetInstanceID` deprecation is gone. The actual issue #12 fix is verified. +- Confirmed in the built `WallstopStudios.DataVisualizer.Editor.dll`: contains `GetObjectIdString` and the `InternalsVisibleTo` friend string `WallstopStudios.DataVisualizer.Tests.Editor` (exact match to the test asmdef name). + +### Investigation — test assembly CS1061 despite correct IVT + +The test assembly initially failed with CS1061 (cannot see the `internal` helper) on both the live editor and the first CLI runs. The Editor DLL is correct (friend name + method present), so IVT *should* grant access. First hypothesis was Bee incremental-cache staleness — **ruled out**: a fully clean compile (deleted `Library/ScriptAssemblies` + `Library/Bee`) still produced CS1061. Conclusion: **InternalsVisibleTo does not grant the test assembly access to the `internal` extension method in this Unity/Roslyn setup** (root cause not pinned down, but proven non-functional across two clean compiles — not worth further spelunking). + +**Second experiment (to be certain before conceding `public`):** reverted to `internal` + IVT and changed the test to call the helper via *static* syntax (`ObjectIdExtensions.GetObjectIdString(obj)`) instead of extension syntax, on a fully clean 6000.5 compile. Result: **CS0122 'ObjectIdExtensions' is inaccessible due to its protection level** — the internal *type itself* is invisible to the test assembly, not merely extension-method discovery. Combined with the earlier CS1061 (extension syntax), this conclusively proves IVT grants the test assembly **no** access to editor-assembly internals in this Unity/Roslyn setup, despite the correct friend string being present in the compiled editor DLL. + +**Resolution (robust, not fragile):** make `ObjectIdExtensions` a `public static class` with a `public` method and drop the `InternalsVisibleTo` dependency entirely. The helper lives in the editor-only assembly; a public editor utility is a minimal, defensible API addition and removes all dependence on IVT quirks. The XML doc on the class records exactly why it is public. Verified by clean recompiles across the full matrix. + +### Adversarial review dispositions (session sub-agent) + +- **Version bump (must-fix):** performed last, after all green (below). +- **`public` vs `internal` (should-consider):** kept `public` — backed by the two IVT experiments above; documented the rationale in the class XML doc. +- **`.gitignore` accidentally modified (real find):** a stray edit had prepended a UTF-8 BOM to line 1 and appended `PLAN.md*` / `progress/` / `progress.meta` ignore rules — which would have *untracked* the very progress files this workflow requires. **Reverted** `.gitignore` to its original committed state. +- **Redundant asmdef reference (should-consider):** removed the unused `WallstopStudios.DataVisualizer` (Runtime) reference from the test asmdef; the test only needs the Editor assembly + UnityEngine + NUnit. +- **`.meta` MonoImporter block (nit):** left minimal 3-line script metas — matches the repo's existing convention (e.g. `ColorExtensions.cs.meta`); Unity fills defaults, GUIDs verified unique. +- **`int` → `ulong` behavior change (nit):** benign — the element name is write-only (never parsed back); the test's `#if` encodes the type difference. +- **Docs shipping to npm:** `PLAN.md` + `progress/` live at the package root and will ship in the npm tarball. Kept tracked per the working-style requirement; harmless for consumers (imported as TextAssets, not compiled). Not adding an `.npmignore` to avoid scope creep. + +### GREEN — final results (public helper), clean CLI EditMode runs (delete `Library/ScriptAssemblies` + `Library/Bee`, then `-runTests`) + +- **6000.5.2f1** — `EntityId` branch (`UNITY_6000_4_OR_NEWER`): 0 compile errors, `GetObjectIdStringIsNonEmptyStableAndUnique` **Passed** (1/1). CS0619 is gone — issue #12 fixed. +- **6000.4.6f1** — `EntityId` branch: 0 compile errors, **Passed** (1/1). +- **2022.3.62f2** — legacy `GetInstanceID` branch: 0 compile errors, **Passed** (1/1). Nearest installed editor to the `"unity": "2021.3"` floor. + +MCP note: the live-editor MCP `RunCommand` (execute) capability was **revoked mid-session** ("Connection revoked… Project Settings > AI > Unity MCP"); read-only MCP calls still worked. 6000.4.6f1 coverage was therefore obtained via a clean CLI throwaway project on the same editor binary (identical compiler/runtime) rather than the live editor. The user's live editor will clear its stale CS1061 on its next recompile, since the on-disk source is now correct. diff --git a/progress/session-001-issue-12-entityid-fix.md.meta b/progress/session-001-issue-12-entityid-fix.md.meta new file mode 100644 index 0000000..fc36166 --- /dev/null +++ b/progress/session-001-issue-12-entityid-fix.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 436edde5595c606438412d61d262148f +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From 5f1194bd68f97fea5eac44ed8fe5808d1efc6512 Mon Sep 17 00:00:00 2001 From: Eli Pinkerton Date: Sun, 5 Jul 2026 17:11:19 -0700 Subject: [PATCH 3/6] docs: sync progress-log Decisions section to final public-helper choice Addresses a Copilot review comment on PR #13: the Decisions bullets still described the initial internal + InternalsVisibleTo plan, which the Investigation section supersedes. Updated to state the final public helper. Co-Authored-By: Claude Fable 5 --- progress/session-001-issue-12-entityid-fix.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/progress/session-001-issue-12-entityid-fix.md b/progress/session-001-issue-12-entityid-fix.md index c7a90f3..c837e8c 100644 --- a/progress/session-001-issue-12-entityid-fix.md +++ b/progress/session-001-issue-12-entityid-fix.md @@ -12,11 +12,11 @@ - Official migration guidance (Unity 6000.5 manual, "Migrate from InstanceID to EntityId"): use `EntityId.ToULong`/`FromULong` for raw values; do not cast to `int`; do not persist `ToString()` output. - Failure-mode sweep: no other obsolete InstanceID-family APIs in the package (`InstanceIDToObject`, `InstanceID` types, etc. — zero hits). The Unity 6000.5 RED compile log is the authoritative confirmation. -## Decisions +## Decisions (final) -- Helper `internal static string GetObjectIdString(this Object obj)` in new `Editor/DataVisualizer/Extensions/ObjectIdExtensions.cs` (testable; keeps `#if` out of the 6000-line `DataVisualizer.cs`). Name deliberately avoids "stable" — instance/entity IDs are per-session only. -- Test access via `[assembly: InternalsVisibleTo("WallstopStudios.DataVisualizer.Tests.Editor")]`, following the existing `Runtime/DataVisualizer/BaseDataObject.cs` precedent (no AssemblyInfo.cs). -- Bootstrap `Tests/Editor` (first tests in this package), modeled on the sibling `unity-helpers` package's test asmdef. Single behavior-focused test; no bloat. +- Helper `GetObjectIdString(this Object obj)` in new `Editor/DataVisualizer/Extensions/ObjectIdExtensions.cs` (testable; keeps `#if` out of the 6000-line `DataVisualizer.cs`). Name deliberately avoids "stable" — instance/entity IDs are per-session only. +- Helper is **`public`** (not `internal`). The initial plan used `internal` + `[assembly: InternalsVisibleTo("WallstopStudios.DataVisualizer.Tests.Editor")]`, but that was proven non-functional for this editor→test assembly pair (see the Investigation section below) — so the helper is public and there is no `InternalsVisibleTo`. +- Bootstrap `Tests/Editor` (first tests in this package), modeled on the sibling `unity-helpers` package's test asmdef. Single behavior-focused test; no bloat. The test references only the Editor assembly + `UnityEngine` + NUnit. - Version: `0.0.35-rc05.6` → `0.0.35` (stable; user-confirmed). ## Evidence log @@ -67,3 +67,7 @@ The test assembly initially failed with CS1061 (cannot see the `internal` helper - **2022.3.62f2** — legacy `GetInstanceID` branch: 0 compile errors, **Passed** (1/1). Nearest installed editor to the `"unity": "2021.3"` floor. MCP note: the live-editor MCP `RunCommand` (execute) capability was **revoked mid-session** ("Connection revoked… Project Settings > AI > Unity MCP"); read-only MCP calls still worked. 6000.4.6f1 coverage was therefore obtained via a clean CLI throwaway project on the same editor binary (identical compiler/runtime) rather than the live editor. The user's live editor will clear its stale CS1061 on its next recompile, since the on-disk source is now correct. + +## PR + +[wallstop/DataVisualizer#13](https://github.com/wallstop/DataVisualizer/pull/13) — addressed one Copilot review comment (synced the "Decisions" section above to the final `public` choice); Cursor Bugbot passed ("Low Risk"). From 3a4d6244c8722b8ad4c7a7d7a0dd841b4ef4a45d Mon Sep 17 00:00:00 2001 From: Eli Pinkerton Date: Sun, 5 Jul 2026 17:50:05 -0700 Subject: [PATCH 4/6] Clear Unity 2023.2+ CS0618 deprecation warnings (UxmlTraits, PreventDefault) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two deprecation-warning families surfaced on Unity 2023.2+/6000.x: - HorizontalToggle used the deprecated UxmlFactory/UxmlTraits custom-control system (9 warnings). The element is only ever created via `new HorizontalToggle()` in C# and is referenced by no .uxml in the package, so the UXML/UI-Builder support was dead code — removed. Code instantiation and its default values are unchanged. - EventBase.PreventDefault() is obsolete on 2023.2+ (15 call sites). All are KeyDownEvent handlers already paired with StopPropagation(), which consumes the event (FocusController.IgnoreEvent no-ops on KeyDownEvent, so it does not apply here). Added EventExtensions.PreventDefaultCompat, which calls PreventDefault() only under #if !UNITY_2023_2_OR_NEWER and is a no-op above that, and routed all 15 sites through it. The 2023.2 gate is exact: PreventDefault was verified (baseline compile on 2023.2.13f1) to start warning at exactly that version. Verified via clean CLI EditMode runs (0 errors, 0 CS0618, test passes) on 2023.2.13f1, 6000.5.2f1, 6000.4.6f1, and 2022.3.62f2, and on the live 6000.4.6f1 editor the Data Visualizer window opens with a clean console. Co-Authored-By: Claude Fable 5 --- Editor/DataVisualizer/DataVisualizer.cs | 30 ++++----- .../Extensions/EventExtensions.cs | 23 +++++++ .../Extensions/EventExtensions.cs.meta | 3 + Editor/DataVisualizer/UI/HorizontalToggle.cs | 66 +------------------ 4 files changed, 43 insertions(+), 79 deletions(-) create mode 100644 Editor/DataVisualizer/Extensions/EventExtensions.cs create mode 100644 Editor/DataVisualizer/Extensions/EventExtensions.cs.meta diff --git a/Editor/DataVisualizer/DataVisualizer.cs b/Editor/DataVisualizer/DataVisualizer.cs index e0710f4..d43c4b3 100644 --- a/Editor/DataVisualizer/DataVisualizer.cs +++ b/Editor/DataVisualizer/DataVisualizer.cs @@ -1653,7 +1653,7 @@ is ScriptableObject selectedObject _searchField.value = string.Empty; } - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); } @@ -1662,7 +1662,7 @@ is ScriptableObject selectedObject case KeyCode.Escape: { CloseActivePopover(); - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); break; } @@ -1675,7 +1675,7 @@ is ScriptableObject selectedObject if (highlightChanged) { UpdateSearchResultHighlight(); - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); } } @@ -2713,7 +2713,7 @@ private void HandleGlobalKeyDown(KeyDownEvent evt) case KeyCode.Escape: { CloseActivePopover(); - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); return; } @@ -2760,7 +2760,7 @@ private void HandleGlobalKeyDown(KeyDownEvent evt) if (evt.keyCode == KeyCode.DownArrow || evt.keyCode == KeyCode.UpArrow) { - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); return; } @@ -2783,7 +2783,7 @@ private void HandleGlobalKeyDown(KeyDownEvent evt) if (navigationHandled) { - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); } @@ -2804,7 +2804,7 @@ private void HandleGlobalKeyDown(KeyDownEvent evt) if (navigationHandled) { - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); } @@ -2826,7 +2826,7 @@ private void HandlePopoverKeyDown(KeyDownEvent evt) case KeyCode.Escape: { CloseActivePopover(); - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); return; } @@ -4241,7 +4241,7 @@ private void HandleTypePopoverKeyDown(KeyDownEvent evt) _typePopoverHighlightIndex ]; HandleEnterOnPopoverItem(selectedElement); - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); } @@ -4250,7 +4250,7 @@ private void HandleTypePopoverKeyDown(KeyDownEvent evt) case KeyCode.Escape: { CloseActivePopover(); - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); break; } @@ -4263,7 +4263,7 @@ private void HandleTypePopoverKeyDown(KeyDownEvent evt) if (highlightChanged) { UpdateTypePopoverHighlight(); - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); } } @@ -6526,7 +6526,7 @@ private void HandleNewLabelInputKeyDown(KeyDownEvent evt) if (evt.keyCode is KeyCode.Return or KeyCode.KeypadEnter) { AddLabelToSelectedAsset(); - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); } return; @@ -6581,14 +6581,14 @@ is string selectedSuggestion CloseActivePopover(); } - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); break; } case KeyCode.Escape: { CloseActivePopover(); - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); break; } @@ -6601,7 +6601,7 @@ is string selectedSuggestion if (highlightChanged) { UpdateLabelSuggestionHighlight(); - evt.PreventDefault(); + evt.PreventDefaultCompat(); evt.StopPropagation(); } } diff --git a/Editor/DataVisualizer/Extensions/EventExtensions.cs b/Editor/DataVisualizer/Extensions/EventExtensions.cs new file mode 100644 index 0000000..612f474 --- /dev/null +++ b/Editor/DataVisualizer/Extensions/EventExtensions.cs @@ -0,0 +1,23 @@ +namespace WallstopStudios.DataVisualizer.Editor.Extensions +{ + using UnityEngine.UIElements; + + internal static class EventExtensions + { + /// + /// Prevents the event's default action on Unity versions where + /// is supported. On Unity 2023.2+ that method + /// is obsolete, so this is a no-op there: every caller pairs it with + /// , which consumes the event — the sanctioned + /// replacement for the KeyDownEvents handled here. FocusController.IgnoreEvent (the + /// other suggested replacement) only affects pointer/navigation events, so it is + /// intentionally not used. + /// + internal static void PreventDefaultCompat(this EventBase evt) + { +#if !UNITY_2023_2_OR_NEWER + evt.PreventDefault(); +#endif + } + } +} diff --git a/Editor/DataVisualizer/Extensions/EventExtensions.cs.meta b/Editor/DataVisualizer/Extensions/EventExtensions.cs.meta new file mode 100644 index 0000000..0eda8b8 --- /dev/null +++ b/Editor/DataVisualizer/Extensions/EventExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ca583a0301de402fb11d67bc17f11746 +timeCreated: 1783293384 \ No newline at end of file diff --git a/Editor/DataVisualizer/UI/HorizontalToggle.cs b/Editor/DataVisualizer/UI/HorizontalToggle.cs index 1a8e745..e16aa71 100644 --- a/Editor/DataVisualizer/UI/HorizontalToggle.cs +++ b/Editor/DataVisualizer/UI/HorizontalToggle.cs @@ -5,72 +5,10 @@ namespace WallstopStudios.DataVisualizer.Editor.UI using UnityEngine.UIElements; using UnityEngine.UIElements.Experimental; + // Instantiated only from C# (never from UXML), so the deprecated UxmlFactory/UxmlTraits + // pair is intentionally omitted. public sealed class HorizontalToggle : VisualElement { - public new class UxmlFactory : UxmlFactory { } - - public new class UxmlTraits : VisualElement.UxmlTraits - { - private readonly UxmlStringAttributeDescription _leftText = new() - { - name = "left-text", - defaultValue = "Left", - }; - - private readonly UxmlStringAttributeDescription _rightText = new() - { - name = "right-text", - defaultValue = "Right", - }; - - private readonly UxmlColorAttributeDescription _selectedBackgroundColor = new() - { - name = "selected-background-color", - defaultValue = new Color(0.1f, 0.5f, 0.8f), - }; - - private readonly UxmlColorAttributeDescription _unselectedBackgroundColor = new() - { - name = "unselected-background-color", - defaultValue = new Color(0.2f, 0.2f, 0.2f), - }; - - private readonly UxmlColorAttributeDescription _selectedTextColor = new() - { - name = "selected-text-color", - defaultValue = Color.white, - }; - - private readonly UxmlColorAttributeDescription _unselectedTextColor = new() - { - name = "unselected-text-color", - defaultValue = new Color(0.7f, 0.7f, 0.7f), - }; - - private readonly UxmlColorAttributeDescription _indicatorColor = new() - { - name = "indicator-color", - defaultValue = new Color(0.15f, 0.65f, 0.95f), - }; - - public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc) - { - base.Init(ve, bag, cc); - HorizontalToggle ate = ve as HorizontalToggle; - - ate.LeftText = _leftText.GetValueFromBag(bag, cc); - ate.RightText = _rightText.GetValueFromBag(bag, cc); - ate.SelectedBackgroundColor = _selectedBackgroundColor.GetValueFromBag(bag, cc); - ate.UnselectedBackgroundColor = _unselectedBackgroundColor.GetValueFromBag(bag, cc); - ate.SelectedTextColor = _selectedTextColor.GetValueFromBag(bag, cc); - ate.UnselectedTextColor = _unselectedTextColor.GetValueFromBag(bag, cc); - ate.IndicatorColor = _indicatorColor.GetValueFromBag(bag, cc); - - ate.Clear(); - ate.Initialize(); - } - } - public static readonly string ussClassName = "horizontal-toggle"; public static readonly string containerUssClassName = ussClassName + "__container"; public static readonly string labelContainerUssClassName = From fcd730194182d050116ed055f4ff57e75bb58e5f Mon Sep 17 00:00:00 2001 From: Eli Pinkerton Date: Sun, 5 Jul 2026 17:50:14 -0700 Subject: [PATCH 5/6] docs: track session-002 (CS0618 deprecations) in PLAN + progress log Co-Authored-By: Claude Fable 5 --- PLAN.md | 5 +-- ...on-002-uxml-preventdefault-deprecations.md | 32 +++++++++++++++++++ ...2-uxml-preventdefault-deprecations.md.meta | 7 ++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 progress/session-002-uxml-preventdefault-deprecations.md create mode 100644 progress/session-002-uxml-preventdefault-deprecations.md.meta diff --git a/PLAN.md b/PLAN.md index d597c31..e912b4c 100644 --- a/PLAN.md +++ b/PLAN.md @@ -4,5 +4,6 @@ Active work items. Completed/obsolete items are removed after each session; hist ## Active -- [ ] Issue #12 — Unity 6000.5 CS0619: migrate `Object.GetInstanceID()` → `EntityId` behind `UNITY_6000_4_OR_NEWER`; bootstrap EditMode tests; bump version to 0.0.35; ship fully green PR. - - Tracking: `progress/session-001-issue-12-entityid-fix.md` +- [ ] PR [#13](https://github.com/wallstop/DataVisualizer/pull/13) (branch `dev/wallstop/bug-fixes`) — Unity 6000.x compile-cleanliness. Open and green; awaiting merge (merge to `main` publishes 0.0.35 to npm). + - Issue #12 — CS0619: `Object.GetInstanceID()` → `EntityId` behind `UNITY_6000_4_OR_NEWER`; first EditMode tests; version bump to 0.0.35. Tracking: `progress/session-001-issue-12-entityid-fix.md`. + - CS0618 deprecations — remove dead `UxmlTraits`/`UxmlFactory` from `HorizontalToggle`; gate `EventBase.PreventDefault()` behind `UNITY_2023_2_OR_NEWER` via `EventExtensions.PreventDefaultCompat`. Tracking: `progress/session-002-uxml-preventdefault-deprecations.md`. diff --git a/progress/session-002-uxml-preventdefault-deprecations.md b/progress/session-002-uxml-preventdefault-deprecations.md new file mode 100644 index 0000000..c1a7cdb --- /dev/null +++ b/progress/session-002-uxml-preventdefault-deprecations.md @@ -0,0 +1,32 @@ +# Session 002 — Unity CS0618 deprecation warnings (UxmlTraits + EventBase.PreventDefault) + +- **Date:** 2026-07-05 +- **Branch / PR:** `dev/wallstop/bug-fixes` → [wallstop/DataVisualizer#13](https://github.com/wallstop/DataVisualizer/pull/13) (folded into the issue #12 fix area) +- **Goal:** Eliminate the two CS0618 deprecation-warning families surfaced on Unity 2023.2+/6000.x, intelligently across all supported Unity versions (min `2021.3`), behavior-preserving, verified red-green. + +## Warnings addressed + +1. **`HorizontalToggle.cs` (9):** `UxmlFactory` / `UxmlTraits` / `UxmlStringAttributeDescription` / `UxmlColorAttributeDescription` — the whole UxmlTraits custom-control system, deprecated in favor of `[UxmlElement]` (Unity 2023.2+). +2. **`DataVisualizer.cs` (15 sites, ×2 passes = 30 warning lines):** `EventBase.PreventDefault()` — obsolete on Unity 2023.2+; guidance is "use StopPropagation and/or FocusController.IgnoreEvent." + +## Findings (data-driven) + +- **HorizontalToggle is instantiated only via `new HorizontalToggle()` in C#** (`DataVisualizer.cs:1343`, `:4531`); no `.uxml` in the package references `horizontal-toggle` (grep). Its UxmlFactory/UxmlTraits are therefore dead code for this package. +- **All 15 `PreventDefault()` sites are `evt.PreventDefault(); evt.StopPropagation();`** on `KeyDownEvent` navigation handlers (search + popovers). `FocusController.IgnoreEvent` is documented to have **no effect on KeyDownEvent** (only PointerDown/MouseDown/NavigationMove), so the correct replacement here is the `StopPropagation()` already present — i.e. drop `PreventDefault()` where it is obsolete. +- **Exact deprecation boundary (empirical):** baseline-compiled the package on **Unity 2023.2.13f1** → `EventBase.PreventDefault()` already warns CS0618 there (30 lines) while `UxmlTraits` warnings were already gone (removal). So the version gate is exactly `UNITY_2023_2_OR_NEWER`. + +## Changes + +- **`HorizontalToggle.cs`:** deleted the `UxmlFactory` + `UxmlTraits` nested classes (user-chosen: remove dead UXML support). No `#if` needed; the element's field-initializer defaults + code-set properties are unchanged, so code instantiation behavior is identical on every Unity version. +- **New `Editor/DataVisualizer/Extensions/EventExtensions.cs`:** `internal static void PreventDefaultCompat(this EventBase evt)` — calls `evt.PreventDefault()` only under `#if !UNITY_2023_2_OR_NEWER`; on 2023.2+ it is a no-op (the paired `StopPropagation()` at each call site consumes the event). Replaced all 15 `evt.PreventDefault()` calls with `evt.PreventDefaultCompat()`. + +## Verification (red → green) + +Baseline confirmed the warnings; after the fix, clean CLI EditMode runs (delete `Library/ScriptAssemblies` + `Library/Bee`, then `-runTests`): + +- **2023.2.13f1** (earliest obsolete; new path — PreventDefault omitted, UxmlTraits removed): 0 errors, **0 CS0618**, test Passed. +- **6000.5.2f1** (target): 0 errors, **0 CS0618**, **0 CS0619** (issue #12 fix intact), test Passed. +- **6000.4.6f1**: 0 errors, **0 CS0618**, test Passed. +- **2022.3.62f2** (legacy path — `PreventDefault()` still called, not obsolete there; UxmlTraits removed): 0 errors, **0 CS0618**, compiles + test Passed. + +**Live MCP (6000.4.6f1 host editor):** after refresh, console shows 0 errors and 0 CS0618; executing menu `Tools/Wallstop Studios/Data Visualizer` opens the window with a **clean console** (0 errors/exceptions), confirming both `HorizontalToggle` instances build and the migrated event handlers run without issue. diff --git a/progress/session-002-uxml-preventdefault-deprecations.md.meta b/progress/session-002-uxml-preventdefault-deprecations.md.meta new file mode 100644 index 0000000..85d7937 --- /dev/null +++ b/progress/session-002-uxml-preventdefault-deprecations.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 759aabb322764cb7823852a8754f38e5 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From 7fa6bfbce8db7afce1cfebb15393d334d4fb35cd Mon Sep 17 00:00:00 2001 From: Eli Pinkerton Date: Sun, 5 Jul 2026 17:58:05 -0700 Subject: [PATCH 6/6] test: tighten legacy-branch assertion to int.TryParse Addresses a Copilot review comment: the legacy GetInstanceID() branch returns an int, so int.TryParse reflects the contract precisely (was long.TryParse). Verified on 2022.3.62f2: test passes. Co-Authored-By: Claude Fable 5 --- Tests/Editor/ObjectIdExtensionsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Editor/ObjectIdExtensionsTests.cs b/Tests/Editor/ObjectIdExtensionsTests.cs index 89bd059..e2ad39c 100644 --- a/Tests/Editor/ObjectIdExtensionsTests.cs +++ b/Tests/Editor/ObjectIdExtensionsTests.cs @@ -35,7 +35,7 @@ public void GetObjectIdStringIsNonEmptyStableAndUnique() ); #else Assert.IsTrue( - long.TryParse(firstId, out _), + int.TryParse(firstId, out _), "The legacy InstanceID branch must produce a numeric (int) id string." ); #endif