Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,8 @@ source on disk. When a run skips a method it had patched before, `Warnings` name
| Method on a `partial` type when another part of the type changed since the last compile and was not passed, or when a file that names the type has syntax errors (passed or not) | Hot reload binds against the compiled type; pass that file with `--files` too, or run `uloop compile`. For a file with syntax errors, fix it and run hot reload again |
| Method on a `partial` type when the other parts could not be checked against the last compile (no source snapshot yet, or more than 50 changed files in the assembly) | Run `uloop compile` |
| Method on a `partial` type whose body names a member no source file of the assembly declares | A part generated at compile time (a source generator's output) is not visible to hot reload; run `uloop compile` |
| Method or getter on a `partial` type whose body uses an `internal` member of a type the reload was not given, by its bare name, as a method passed as a delegate, inside a lambda, local function, query, iterator or async method, in a body where a lambda, local function or query works with the member's result, or in a body patched through a delegating shim | Hot reload reaches such a member only as a field, a property or a method call in the method's own statements, written with its receiver (`this.Name`, `Type.Name`, `value.Name`); qualify a bare name, or run `uloop compile` |
| Method or getter on a `partial` type whose body uses an `internal` member of a type in another assembly (through `InternalsVisibleTo`) | Reported as a name no source file of the `partial` type declares; hot reload does not patch this use from a `partial` type yet. Run `uloop compile` |
| Method on a struct (value type) | Value-type patching is out of scope |
| Generic method, or method on a generic type | Harmony cannot safely patch open generics |
| Explicit interface implementation | Dotted metadata names cannot be expressed as shim identifiers |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,8 @@ source on disk. When a run skips a method it had patched before, `Warnings` name
| Method on a `partial` type when another part of the type changed since the last compile and was not passed, or when a file that names the type has syntax errors (passed or not) | Hot reload binds against the compiled type; pass that file with `--files` too, or run `uloop compile`. For a file with syntax errors, fix it and run hot reload again |
| Method on a `partial` type when the other parts could not be checked against the last compile (no source snapshot yet, or more than 50 changed files in the assembly) | Run `uloop compile` |
| Method on a `partial` type whose body names a member no source file of the assembly declares | A part generated at compile time (a source generator's output) is not visible to hot reload; run `uloop compile` |
| Method or getter on a `partial` type whose body uses an `internal` member of a type the reload was not given, by its bare name, as a method passed as a delegate, inside a lambda, local function, query, iterator or async method, in a body where a lambda, local function or query works with the member's result, or in a body patched through a delegating shim | Hot reload reaches such a member only as a field, a property or a method call in the method's own statements, written with its receiver (`this.Name`, `Type.Name`, `value.Name`); qualify a bare name, or run `uloop compile` |
| Method or getter on a `partial` type whose body uses an `internal` member of a type in another assembly (through `InternalsVisibleTo`) | Reported as a name no source file of the `partial` type declares; hot reload does not patch this use from a `partial` type yet. Run `uloop compile` |
| Method on a struct (value type) | Value-type patching is out of scope |
| Generic method, or method on a generic type | Harmony cannot safely patch open generics |
| Explicit interface implementation | Dotted metadata names cannot be expressed as shim identifiers |
Expand Down
29 changes: 29 additions & 0 deletions Assets/Tests/Editor/HotReload/HotReloadInternalMemberCaller.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Runtime.CompilerServices;

namespace io.github.hatayama.UnityCliLoop.Tests.Editor.HotReload
{
/// <summary>
/// A plain type that calls an internal member of another plain type. The visibility repro tests
/// pass it on its own, next to an edit of a partial type, or as a sibling a run brought back.
/// </summary>
public class HotReloadInternalMemberCaller
{
[MethodImpl(MethodImplOptions.NoInlining)]
public int CallsInternal()
{
return HotReloadInternalMemberHost.InternalStaticValue();
}

[MethodImpl(MethodImplOptions.NoInlining)]
public int PlainValue()
{
return 1;
}

public int CallerProperty
{
[MethodImpl(MethodImplOptions.NoInlining)]
get { return 30; }
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

92 changes: 92 additions & 0 deletions Assets/Tests/Editor/HotReload/HotReloadInternalMemberHost.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using System.Runtime.CompilerServices;

namespace io.github.hatayama.UnityCliLoop.Tests.Editor.HotReload
{
/// <summary>
/// A plain type whose non-public members the visibility repro tests call from edited bodies.
/// No test passes this file to a run, so the worker can only see the type as compiled.
/// </summary>
public class HotReloadInternalMemberHost
{
internal int InternalField = 3;

internal int InternalProperty
{
get { return 4; }
}

internal int InternalSettableProperty { get; set; } = 20;

[MethodImpl(MethodImplOptions.NoInlining)]
internal static int InternalStaticValue()
{
return 1;
}

[MethodImpl(MethodImplOptions.NoInlining)]
internal int InternalInstanceValue()
{
return 2;
}

[MethodImpl(MethodImplOptions.NoInlining)]
protected int ProtectedValue()
{
return 5;
}

[MethodImpl(MethodImplOptions.NoInlining)]
protected internal int ProtectedInternalValue()
{
return 6;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private protected int PrivateProtectedValue()
{
return 7;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static int PrivateStaticValue()
{
return 13;
}

[MethodImpl(MethodImplOptions.NoInlining)]
internal static HotReloadInternalMemberHost InternalSelf()
{
return new HotReloadInternalMemberHost();
}

[MethodImpl(MethodImplOptions.NoInlining)]
internal static HotReloadInternalMemberHost[] InternalHosts()
{
return new HotReloadInternalMemberHost[] { new HotReloadInternalMemberHost() };
}

/// <summary>
/// A type nested in the host, so a test can name an internal member through the nested type.
/// </summary>
public class Nested
{
[MethodImpl(MethodImplOptions.NoInlining)]
internal static int NestedInternalValue()
{
return 11;
}
}
}

/// <summary>
/// An internal type the visibility repro tests name from edited bodies.
/// </summary>
internal static class HotReloadInternalOnlyType
{
[MethodImpl(MethodImplOptions.NoInlining)]
public static int Value()
{
return 8;
}
}
}
11 changes: 11 additions & 0 deletions Assets/Tests/Editor/HotReload/HotReloadInternalMemberHost.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions Assets/Tests/Editor/HotReload/HotReloadPartialDerivedFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace io.github.hatayama.UnityCliLoop.Tests.Editor.HotReload
{
/// <summary>
/// A partial type deriving from <see cref="HotReloadInternalMemberHost"/>, so its edited bodies can
/// reach the protected members of a compiled base type.
/// </summary>
public partial class HotReloadPartialDerivedFixture : HotReloadInternalMemberHost
{
private int _seed = 1000;

[MethodImpl(MethodImplOptions.NoInlining)]
public int DerivedValue()
{
return 9;
}

[MethodImpl(MethodImplOptions.NoInlining)]
public int ClosureValue()
{
Func<int> read = () => 30;
return read();
}

[MethodImpl(MethodImplOptions.NoInlining)]
public int ClosureSeedValue()
{
Func<int> read = () => _seed;
return read();
}

[MethodImpl(MethodImplOptions.NoInlining)]
public IEnumerable<int> IteratorValues()
{
yield return _seed;
}

[MethodImpl(MethodImplOptions.NoInlining)]
public int ClosureSeedPlusValue()
{
Func<int> read = () => this._seed;
return read() + 7;
}

public int DerivedProperty
{
[MethodImpl(MethodImplOptions.NoInlining)]
get { return 40; }
}

[MethodImpl(MethodImplOptions.NoInlining)]
public async System.Threading.Tasks.Task<int> AsyncValue()
{
await System.Threading.Tasks.Task.CompletedTask;
return 50;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#if UNITY_EDITOR
using System.Runtime.CompilerServices;

namespace io.github.hatayama.UnityCliLoop.Tests.Editor.HotReload
{
/// <summary>
/// The other part of <see cref="HotReloadPartialInternalGuardedPeer"/>. The whole file sits in a
/// conditional-compilation block, the way an editor-only or debug-only part usually does.
/// </summary>
public partial class HotReloadPartialInternalGuardedPeer
{
[MethodImpl(MethodImplOptions.NoInlining)]
internal int GuardedPeerInternalValue()
{
return 12;
}
}
}
#endif

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Runtime.CompilerServices;

namespace io.github.hatayama.UnityCliLoop.Tests.Editor.HotReload
{
/// <summary>
/// The other part of <see cref="HotReloadPartialInternalPeer"/>, holding the internal method the
/// visibility repro tests call.
/// </summary>
public partial class HotReloadPartialInternalPeer
{
[MethodImpl(MethodImplOptions.NoInlining)]
internal int PeerInternalValue()
{
return 11;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions Assets/Tests/Editor/HotReload/HotReloadPartialInternalPeer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Runtime.CompilerServices;

namespace io.github.hatayama.UnityCliLoop.Tests.Editor.HotReload
{
/// <summary>
/// The main part of a partial type whose internal method lives in another file. No test passes
/// this file, so the worker sees the type as compiled.
/// </summary>
public partial class HotReloadPartialInternalPeer
{
[MethodImpl(MethodImplOptions.NoInlining)]
public int PeerMain()
{
return 1;
}
}

/// <summary>
/// The main part of a partial type whose internal method lives in a file wrapped in a
/// conditional-compilation block.
/// </summary>
public partial class HotReloadPartialInternalGuardedPeer
{
[MethodImpl(MethodImplOptions.NoInlining)]
public int GuardedPeerMain()
{
return 2;
}
}
}
11 changes: 11 additions & 0 deletions Assets/Tests/Editor/HotReload/HotReloadPartialInternalPeer.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ public int OtherPartOwnMethod()
return PartialTuning - 1;
}

[MethodImpl(MethodImplOptions.NoInlining)]
internal int OtherPartInternalValue()
{
return 12;
}

/// <summary>
/// A type only this part declares, named in a method signature of the edited part.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Linq;
using System.Runtime.CompilerServices;

namespace io.github.hatayama.UnityCliLoop.Tests.Editor.HotReload
Expand Down
Loading
Loading