summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI/Framework/Content/ContentCache.cs4
-rw-r--r--src/SMAPI/Framework/DeprecationManager.cs2
-rw-r--r--src/SMAPI/Framework/InternalExtensions.cs2
-rw-r--r--src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs167
-rw-r--r--src/SMAPI/Framework/Reflection/ReflectedField.cs (renamed from src/SMAPI/Framework/Reflection/PrivateField.cs)16
-rw-r--r--src/SMAPI/Framework/Reflection/ReflectedMethod.cs (renamed from src/SMAPI/Framework/Reflection/PrivateMethod.cs)16
-rw-r--r--src/SMAPI/Framework/Reflection/ReflectedProperty.cs (renamed from src/SMAPI/Framework/Reflection/PrivateProperty.cs)26
-rw-r--r--src/SMAPI/Framework/Reflection/Reflector.cs106
-rw-r--r--src/SMAPI/Framework/SContentManager.cs6
-rw-r--r--src/SMAPI/Framework/SGame.cs24
-rw-r--r--src/SMAPI/IPrivateField.cs6
-rw-r--r--src/SMAPI/IPrivateMethod.cs6
-rw-r--r--src/SMAPI/IPrivateProperty.cs6
-rw-r--r--src/SMAPI/IReflectedField.cs26
-rw-r--r--src/SMAPI/IReflectedMethod.cs27
-rw-r--r--src/SMAPI/IReflectedProperty.cs26
-rw-r--r--src/SMAPI/IReflectionHelper.cs55
-rw-r--r--src/SMAPI/Program.cs2
-rw-r--r--src/SMAPI/StardewModdingAPI.csproj9
19 files changed, 357 insertions, 175 deletions
diff --git a/src/SMAPI/Framework/Content/ContentCache.cs b/src/SMAPI/Framework/Content/ContentCache.cs
index 10c41d08..4508e641 100644
--- a/src/SMAPI/Framework/Content/ContentCache.cs
+++ b/src/SMAPI/Framework/Content/ContentCache.cs
@@ -57,14 +57,14 @@ namespace StardewModdingAPI.Framework.Content
public ContentCache(LocalizedContentManager contentManager, Reflector reflection, char[] possiblePathSeparators, string preferredPathSeparator)
{
// init
- this.Cache = reflection.GetPrivateField<Dictionary<string, object>>(contentManager, "loadedAssets").GetValue();
+ this.Cache = reflection.GetField<Dictionary<string, object>>(contentManager, "loadedAssets").GetValue();
this.PossiblePathSeparators = possiblePathSeparators;
this.PreferredPathSeparator = preferredPathSeparator;
// get key normalisation logic
if (Constants.TargetPlatform == Platform.Windows)
{
- IPrivateMethod method = reflection.GetPrivateMethod(typeof(TitleContainer), "GetCleanPath");
+ IReflectedMethod method = reflection.GetMethod(typeof(TitleContainer), "GetCleanPath");
this.NormaliseAssetNameForPlatform = path => method.Invoke<string>(path);
}
else
diff --git a/src/SMAPI/Framework/DeprecationManager.cs b/src/SMAPI/Framework/DeprecationManager.cs
index b07c6c7d..20bb0d2d 100644
--- a/src/SMAPI/Framework/DeprecationManager.cs
+++ b/src/SMAPI/Framework/DeprecationManager.cs
@@ -52,7 +52,7 @@ namespace StardewModdingAPI.Framework
return;
// build message
- string message = $"{source ?? "An unknown mod"} uses deprecated code ({nounPhrase}).";
+ string message = $"{source ?? "An unknown mod"} uses deprecated code ({nounPhrase} is deprecated since SMAPI {version}).";
if (source == null)
message += $"{Environment.NewLine}{Environment.StackTrace}";
diff --git a/src/SMAPI/Framework/InternalExtensions.cs b/src/SMAPI/Framework/InternalExtensions.cs
index 3709e05d..f81e05a9 100644
--- a/src/SMAPI/Framework/InternalExtensions.cs
+++ b/src/SMAPI/Framework/InternalExtensions.cs
@@ -125,7 +125,7 @@ namespace StardewModdingAPI.Framework
#endif
// get result
- return reflection.GetPrivateField<bool>(Game1.spriteBatch, fieldName).GetValue();
+ return reflection.GetField<bool>(Game1.spriteBatch, fieldName).GetValue();
}
}
}
diff --git a/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs b/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs
index 8788b142..81453003 100644
--- a/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs
+++ b/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs
@@ -17,6 +17,9 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <summary>The mod name for error messages.</summary>
private readonly string ModName;
+ /// <summary>Manages deprecation warnings.</summary>
+ private readonly DeprecationManager DeprecationManager;
+
/*********
** Public methods
@@ -25,15 +28,88 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="modID">The unique ID of the relevant mod.</param>
/// <param name="modName">The mod name for error messages.</param>
/// <param name="reflector">The underlying reflection helper.</param>
- public ReflectionHelper(string modID, string modName, Reflector reflector)
+ /// <param name="deprecationManager">Manages deprecation warnings.</param>
+ public ReflectionHelper(string modID, string modName, Reflector reflector, DeprecationManager deprecationManager)
: base(modID)
{
this.ModName = modName;
this.Reflector = reflector;
+ this.DeprecationManager = deprecationManager;
+ }
+
+ /// <summary>Get an instance field.</summary>
+ /// <typeparam name="TValue">The field type.</typeparam>
+ /// <param name="obj">The object which has the field.</param>
+ /// <param name="name">The field name.</param>
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ public IReflectedField<TValue> GetField<TValue>(object obj, string name, bool required = true)
+ {
+ return this.AssertAccessAllowed(
+ this.Reflector.GetField<TValue>(obj, name, required)
+ );
+ }
+
+ /// <summary>Get a static field.</summary>
+ /// <typeparam name="TValue">The field type.</typeparam>
+ /// <param name="type">The type which has the field.</param>
+ /// <param name="name">The field name.</param>
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ public IReflectedField<TValue> GetField<TValue>(Type type, string name, bool required = true)
+ {
+ return this.AssertAccessAllowed(
+ this.Reflector.GetField<TValue>(type, name, required)
+ );
+ }
+
+ /// <summary>Get an instance property.</summary>
+ /// <typeparam name="TValue">The property type.</typeparam>
+ /// <param name="obj">The object which has the property.</param>
+ /// <param name="name">The property name.</param>
+ /// <param name="required">Whether to throw an exception if the property is not found.</param>
+ public IReflectedProperty<TValue> GetProperty<TValue>(object obj, string name, bool required = true)
+ {
+ return this.AssertAccessAllowed(
+ this.Reflector.GetProperty<TValue>(obj, name, required)
+ );
+ }
+
+ /// <summary>Get a static property.</summary>
+ /// <typeparam name="TValue">The property type.</typeparam>
+ /// <param name="type">The type which has the property.</param>
+ /// <param name="name">The property name.</param>
+ /// <param name="required">Whether to throw an exception if the property is not found.</param>
+ public IReflectedProperty<TValue> GetProperty<TValue>(Type type, string name, bool required = true)
+ {
+ return this.AssertAccessAllowed(
+ this.Reflector.GetProperty<TValue>(type, name, required)
+ );
+ }
+
+ /// <summary>Get an instance method.</summary>
+ /// <param name="obj">The object which has the method.</param>
+ /// <param name="name">The field name.</param>
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ public IReflectedMethod GetMethod(object obj, string name, bool required = true)
+ {
+ return this.AssertAccessAllowed(
+ this.Reflector.GetMethod(obj, name, required)
+ );
+ }
+
+ /// <summary>Get a static method.</summary>
+ /// <param name="type">The type which has the method.</param>
+ /// <param name="name">The field name.</param>
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ public IReflectedMethod GetMethod(Type type, string name, bool required = true)
+ {
+ return this.AssertAccessAllowed(
+ this.Reflector.GetMethod(type, name, required)
+ );
}
+
/****
- ** Fields
+ ** Obsolete
****/
/// <summary>Get a private instance field.</summary>
/// <typeparam name="TValue">The field type.</typeparam>
@@ -41,11 +117,11 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
/// <returns>Returns the field wrapper, or <c>null</c> if the field doesn't exist and <paramref name="required"/> is <c>false</c>.</returns>
+ [Obsolete]
public IPrivateField<TValue> GetPrivateField<TValue>(object obj, string name, bool required = true)
{
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateField<TValue>(obj, name, required)
- );
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ return (IPrivateField<TValue>)this.GetField<TValue>(obj, name, required);
}
/// <summary>Get a private static field.</summary>
@@ -53,26 +129,23 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="type">The type which has the field.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
+ [Obsolete]
public IPrivateField<TValue> GetPrivateField<TValue>(Type type, string name, bool required = true)
{
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateField<TValue>(type, name, required)
- );
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ return (IPrivateField<TValue>)this.GetField<TValue>(type, name, required);
}
- /****
- ** Properties
- ****/
/// <summary>Get a private instance property.</summary>
/// <typeparam name="TValue">The property type.</typeparam>
/// <param name="obj">The object which has the property.</param>
/// <param name="name">The property name.</param>
/// <param name="required">Whether to throw an exception if the private property is not found.</param>
+ [Obsolete]
public IPrivateProperty<TValue> GetPrivateProperty<TValue>(object obj, string name, bool required = true)
{
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateProperty<TValue>(obj, name, required)
- );
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ return (IPrivateProperty<TValue>)this.GetProperty<TValue>(obj, name, required);
}
/// <summary>Get a private static property.</summary>
@@ -80,17 +153,13 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="type">The type which has the property.</param>
/// <param name="name">The property name.</param>
/// <param name="required">Whether to throw an exception if the private property is not found.</param>
+ [Obsolete]
public IPrivateProperty<TValue> GetPrivateProperty<TValue>(Type type, string name, bool required = true)
{
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateProperty<TValue>(type, name, required)
- );
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ return (IPrivateProperty<TValue>)this.GetProperty<TValue>(type, name, required);
}
- /****
- ** Field values
- ** (shorthand since this is the most common case)
- ****/
/// <summary>Get the value of a private instance field.</summary>
/// <typeparam name="TValue">The field type.</typeparam>
/// <param name="obj">The object which has the field.</param>
@@ -101,9 +170,11 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// This is a shortcut for <see cref="GetPrivateField{TValue}(object,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.
/// When <paramref name="required" /> is false, this will return the default value if reflection fails. If you need to check whether the field exists, use <see cref="GetPrivateField{TValue}(object,string,bool)" /> instead.
/// </remarks>
+ [Obsolete]
public TValue GetPrivateValue<TValue>(object obj, string name, bool required = true)
{
- IPrivateField<TValue> field = this.GetPrivateField<TValue>(obj, name, required);
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ IPrivateField<TValue> field = (IPrivateField<TValue>)this.GetField<TValue>(obj, name, required);
return field != null
? field.GetValue()
: default(TValue);
@@ -119,64 +190,36 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// This is a shortcut for <see cref="GetPrivateField{TValue}(Type,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.
/// When <paramref name="required" /> is false, this will return the default value if reflection fails. If you need to check whether the field exists, use <see cref="GetPrivateField{TValue}(Type,string,bool)" /> instead.
/// </remarks>
+ [Obsolete]
public TValue GetPrivateValue<TValue>(Type type, string name, bool required = true)
{
- IPrivateField<TValue> field = this.GetPrivateField<TValue>(type, name, required);
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ IPrivateField<TValue> field = (IPrivateField<TValue>)this.GetField<TValue>(type, name, required);
return field != null
? field.GetValue()
: default(TValue);
}
- /****
- ** Methods
- ****/
/// <summary>Get a private instance method.</summary>
/// <param name="obj">The object which has the method.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
+ [Obsolete]
public IPrivateMethod GetPrivateMethod(object obj, string name, bool required = true)
{
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateMethod(obj, name, required)
- );
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ return (IPrivateMethod)this.GetMethod(obj, name, required);
}
/// <summary>Get a private static method.</summary>
/// <param name="type">The type which has the method.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
+ [Obsolete]
public IPrivateMethod GetPrivateMethod(Type type, string name, bool required = true)
{
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateMethod(type, name, required)
- );
- }
-
- /****
- ** Methods by signature
- ****/
- /// <summary>Get a private instance method.</summary>
- /// <param name="obj">The object which has the method.</param>
- /// <param name="name">The field name.</param>
- /// <param name="argumentTypes">The argument types of the method signature to find.</param>
- /// <param name="required">Whether to throw an exception if the private field is not found.</param>
- public IPrivateMethod GetPrivateMethod(object obj, string name, Type[] argumentTypes, bool required = true)
- {
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateMethod(obj, name, argumentTypes, required)
- );
- }
-
- /// <summary>Get a private static method.</summary>
- /// <param name="type">The type which has the method.</param>
- /// <param name="name">The field name.</param>
- /// <param name="argumentTypes">The argument types of the method signature to find.</param>
- /// <param name="required">Whether to throw an exception if the private field is not found.</param>
- public IPrivateMethod GetPrivateMethod(Type type, string name, Type[] argumentTypes, bool required = true)
- {
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateMethod(type, name, argumentTypes, required)
- );
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ return (IPrivateMethod)this.GetMethod(type, name, required);
}
@@ -187,7 +230,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <typeparam name="T">The field value type.</typeparam>
/// <param name="field">The field being accessed.</param>
/// <returns>Returns the same field instance for convenience.</returns>
- private IPrivateField<T> AssertAccessAllowed<T>(IPrivateField<T> field)
+ private IReflectedField<T> AssertAccessAllowed<T>(IReflectedField<T> field)
{
this.AssertAccessAllowed(field?.FieldInfo);
return field;
@@ -197,7 +240,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <typeparam name="T">The property value type.</typeparam>
/// <param name="property">The property being accessed.</param>
/// <returns>Returns the same property instance for convenience.</returns>
- private IPrivateProperty<T> AssertAccessAllowed<T>(IPrivateProperty<T> property)
+ private IReflectedProperty<T> AssertAccessAllowed<T>(IReflectedProperty<T> property)
{
this.AssertAccessAllowed(property?.PropertyInfo);
return property;
@@ -206,7 +249,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <summary>Assert that mods can use the reflection helper to access the given member.</summary>
/// <param name="method">The method being accessed.</param>
/// <returns>Returns the same method instance for convenience.</returns>
- private IPrivateMethod AssertAccessAllowed(IPrivateMethod method)
+ private IReflectedMethod AssertAccessAllowed(IReflectedMethod method)
{
this.AssertAccessAllowed(method?.MethodInfo);
return method;
diff --git a/src/SMAPI/Framework/Reflection/PrivateField.cs b/src/SMAPI/Framework/Reflection/ReflectedField.cs
index 0bf45969..ad1557bb 100644
--- a/src/SMAPI/Framework/Reflection/PrivateField.cs
+++ b/src/SMAPI/Framework/Reflection/ReflectedField.cs
@@ -1,11 +1,11 @@
-using System;
+using System;
using System.Reflection;
namespace StardewModdingAPI.Framework.Reflection
{
- /// <summary>A private field obtained through reflection.</summary>
+ /// <summary>A field obtained through reflection.</summary>
/// <typeparam name="TValue">The field value type.</typeparam>
- internal class PrivateField<TValue> : IPrivateField<TValue>
+ internal class ReflectedField<TValue> : IPrivateField<TValue>, IReflectedField<TValue>
{
/*********
** Properties
@@ -37,7 +37,7 @@ namespace StardewModdingAPI.Framework.Reflection
/// <param name="isStatic">Whether the field is static.</param>
/// <exception cref="ArgumentNullException">The <paramref name="parentType"/> or <paramref name="field"/> is null.</exception>
/// <exception cref="ArgumentException">The <paramref name="obj"/> is null for a non-static field, or not null for a static field.</exception>
- public PrivateField(Type parentType, object obj, FieldInfo field, bool isStatic)
+ public ReflectedField(Type parentType, object obj, FieldInfo field, bool isStatic)
{
// validate
if (parentType == null)
@@ -64,11 +64,11 @@ namespace StardewModdingAPI.Framework.Reflection
}
catch (InvalidCastException)
{
- throw new InvalidCastException($"Can't convert the private {this.DisplayName} field from {this.FieldInfo.FieldType.FullName} to {typeof(TValue).FullName}.");
+ throw new InvalidCastException($"Can't convert the {this.DisplayName} field from {this.FieldInfo.FieldType.FullName} to {typeof(TValue).FullName}.");
}
catch (Exception ex)
{
- throw new Exception($"Couldn't get the value of the private {this.DisplayName} field", ex);
+ throw new Exception($"Couldn't get the value of the {this.DisplayName} field", ex);
}
}
@@ -82,11 +82,11 @@ namespace StardewModdingAPI.Framework.Reflection
}
catch (InvalidCastException)
{
- throw new InvalidCastException($"Can't assign the private {this.DisplayName} field a {typeof(TValue).FullName} value, must be compatible with {this.FieldInfo.FieldType.FullName}.");
+ throw new InvalidCastException($"Can't assign the {this.DisplayName} field a {typeof(TValue).FullName} value, must be compatible with {this.FieldInfo.FieldType.FullName}.");
}
catch (Exception ex)
{
- throw new Exception($"Couldn't set the value of the private {this.DisplayName} field", ex);
+ throw new Exception($"Couldn't set the value of the {this.DisplayName} field", ex);
}
}
}
diff --git a/src/SMAPI/Framework/Reflection/PrivateMethod.cs b/src/SMAPI/Framework/Reflection/ReflectedMethod.cs
index ba2374f4..376de869 100644
--- a/src/SMAPI/Framework/Reflection/PrivateMethod.cs
+++ b/src/SMAPI/Framework/Reflection/ReflectedMethod.cs
@@ -3,8 +3,8 @@ using System.Reflection;
namespace StardewModdingAPI.Framework.Reflection
{
- /// <summary>A private method obtained through reflection.</summary>
- internal class PrivateMethod : IPrivateMethod
+ /// <summary>A method obtained through reflection.</summary>
+ internal class ReflectedMethod : IPrivateMethod, IReflectedMethod
{
/*********
** Properties
@@ -33,10 +33,10 @@ namespace StardewModdingAPI.Framework.Reflection
/// <param name="parentType">The type that has the method.</param>
/// <param name="obj">The object that has the instance method(if applicable).</param>
/// <param name="method">The reflection metadata.</param>
- /// <param name="isStatic">Whether the field is static.</param>
+ /// <param name="isStatic">Whether the method is static.</param>
/// <exception cref="ArgumentNullException">The <paramref name="parentType"/> or <paramref name="method"/> is null.</exception>
/// <exception cref="ArgumentException">The <paramref name="obj"/> is null for a non-static method, or not null for a static method.</exception>
- public PrivateMethod(Type parentType, object obj, MethodInfo method, bool isStatic)
+ public ReflectedMethod(Type parentType, object obj, MethodInfo method, bool isStatic)
{
// validate
if (parentType == null)
@@ -67,7 +67,7 @@ namespace StardewModdingAPI.Framework.Reflection
}
catch (Exception ex)
{
- throw new Exception($"Couldn't invoke the private {this.DisplayName} field", ex);
+ throw new Exception($"Couldn't invoke the {this.DisplayName} method", ex);
}
// cast return value
@@ -77,7 +77,7 @@ namespace StardewModdingAPI.Framework.Reflection
}
catch (InvalidCastException)
{
- throw new InvalidCastException($"Can't convert the return value of the private {this.DisplayName} method from {this.MethodInfo.ReturnType.FullName} to {typeof(TValue).FullName}.");
+ throw new InvalidCastException($"Can't convert the return value of the {this.DisplayName} method from {this.MethodInfo.ReturnType.FullName} to {typeof(TValue).FullName}.");
}
}
@@ -92,8 +92,8 @@ namespace StardewModdingAPI.Framework.Reflection
}
catch (Exception ex)
{
- throw new Exception($"Couldn't invoke the private {this.DisplayName} field", ex);
+ throw new Exception($"Couldn't invoke the {this.DisplayName} method", ex);
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/SMAPI/Framework/Reflection/PrivateProperty.cs b/src/SMAPI/Framework/Reflection/ReflectedProperty.cs
index c81f99c7..d6c964c1 100644
--- a/src/SMAPI/Framework/Reflection/PrivateProperty.cs
+++ b/src/SMAPI/Framework/Reflection/ReflectedProperty.cs
@@ -3,9 +3,9 @@ using System.Reflection;
namespace StardewModdingAPI.Framework.Reflection
{
- /// <summary>A private property obtained through reflection.</summary>
+ /// <summary>A property obtained through reflection.</summary>
/// <typeparam name="TValue">The property value type.</typeparam>
- internal class PrivateProperty<TValue> : IPrivateProperty<TValue>
+ internal class ReflectedProperty<TValue> : IPrivateProperty<TValue>, IReflectedProperty<TValue>
{
/*********
** Properties
@@ -31,13 +31,13 @@ namespace StardewModdingAPI.Framework.Reflection
** Public methods
*********/
/// <summary>Construct an instance.</summary>
- /// <param name="parentType">The type that has the field.</param>
- /// <param name="obj">The object that has the instance field (if applicable).</param>
+ /// <param name="parentType">The type that has the property.</param>
+ /// <param name="obj">The object that has the instance property (if applicable).</param>
/// <param name="property">The reflection metadata.</param>
- /// <param name="isStatic">Whether the field is static.</param>
+ /// <param name="isStatic">Whether the property is static.</param>
/// <exception cref="ArgumentNullException">The <paramref name="parentType"/> or <paramref name="property"/> is null.</exception>
- /// <exception cref="ArgumentException">The <paramref name="obj"/> is null for a non-static field, or not null for a static field.</exception>
- public PrivateProperty(Type parentType, object obj, PropertyInfo property, bool isStatic)
+ /// <exception cref="ArgumentException">The <paramref name="obj"/> is null for a non-static property, or not null for a static property.</exception>
+ public ReflectedProperty(Type parentType, object obj, PropertyInfo property, bool isStatic)
{
// validate input
if (parentType == null)
@@ -65,7 +65,7 @@ namespace StardewModdingAPI.Framework.Reflection
public TValue GetValue()
{
if (this.GetMethod == null)
- throw new InvalidOperationException($"The private {this.DisplayName} property has no get method.");
+ throw new InvalidOperationException($"The {this.DisplayName} property has no get method.");
try
{
@@ -73,11 +73,11 @@ namespace StardewModdingAPI.Framework.Reflection
}
catch (InvalidCastException)
{
- throw new InvalidCastException($"Can't convert the private {this.DisplayName} property from {this.PropertyInfo.PropertyType.FullName} to {typeof(TValue).FullName}.");
+ throw new InvalidCastException($"Can't convert the {this.DisplayName} property from {this.PropertyInfo.PropertyType.FullName} to {typeof(TValue).FullName}.");
}
catch (Exception ex)
{
- throw new Exception($"Couldn't get the value of the private {this.DisplayName} property", ex);
+ throw new Exception($"Couldn't get the value of the {this.DisplayName} property", ex);
}
}
@@ -86,7 +86,7 @@ namespace StardewModdingAPI.Framework.Reflection
public void SetValue(TValue value)
{
if (this.SetMethod == null)
- throw new InvalidOperationException($"The private {this.DisplayName} property has no set method.");
+ throw new InvalidOperationException($"The {this.DisplayName} property has no set method.");
try
{
@@ -94,11 +94,11 @@ namespace StardewModdingAPI.Framework.Reflection
}
catch (InvalidCastException)
{
- throw new InvalidCastException($"Can't assign the private {this.DisplayName} property a {typeof(TValue).FullName} value, must be compatible with {this.PropertyInfo.PropertyType.FullName}.");
+ throw new InvalidCastException($"Can't assign the {this.DisplayName} property a {typeof(TValue).FullName} value, must be compatible with {this.PropertyInfo.PropertyType.FullName}.");
}
catch (Exception ex)
{
- throw new Exception($"Couldn't set the value of the private {this.DisplayName} property", ex);
+ throw new Exception($"Couldn't set the value of the {this.DisplayName} property", ex);
}
}
}
diff --git a/src/SMAPI/Framework/Reflection/Reflector.cs b/src/SMAPI/Framework/Reflection/Reflector.cs
index 23a48505..910e3a54 100644
--- a/src/SMAPI/Framework/Reflection/Reflector.cs
+++ b/src/SMAPI/Framework/Reflection/Reflector.cs
@@ -5,7 +5,7 @@ using System.Runtime.Caching;
namespace StardewModdingAPI.Framework.Reflection
{
- /// <summary>Provides helper methods for accessing private game code.</summary>
+ /// <summary>Provides helper methods for accessing inaccessible code.</summary>
/// <remarks>This implementation searches up the type hierarchy, and caches the reflected fields and methods with a sliding expiry (to optimise performance without unnecessary memory usage).</remarks>
internal class Reflector
{
@@ -25,139 +25,139 @@ namespace StardewModdingAPI.Framework.Reflection
/****
** Fields
****/
- /// <summary>Get a private instance field.</summary>
+ /// <summary>Get a instance field.</summary>
/// <typeparam name="TValue">The field type.</typeparam>
/// <param name="obj">The object which has the field.</param>
/// <param name="name">The field name.</param>
- /// <param name="required">Whether to throw an exception if the private field is not found.</param>
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
/// <returns>Returns the field wrapper, or <c>null</c> if the field doesn't exist and <paramref name="required"/> is <c>false</c>.</returns>
- public IPrivateField<TValue> GetPrivateField<TValue>(object obj, string name, bool required = true)
+ public IReflectedField<TValue> GetField<TValue>(object obj, string name, bool required = true)
{
// validate
if (obj == null)
- throw new ArgumentNullException(nameof(obj), "Can't get a private instance field from a null object.");
+ throw new ArgumentNullException(nameof(obj), "Can't get a instance field from a null object.");
// get field from hierarchy
- IPrivateField<TValue> field = this.GetFieldFromHierarchy<TValue>(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+ IReflectedField<TValue> field = this.GetFieldFromHierarchy<TValue>(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
if (required && field == null)
- throw new InvalidOperationException($"The {obj.GetType().FullName} object doesn't have a private '{name}' instance field.");
+ throw new InvalidOperationException($"The {obj.GetType().FullName} object doesn't have a '{name}' instance field.");
return field;
}
- /// <summary>Get a private static field.</summary>
+ /// <summary>Get a static field.</summary>
/// <typeparam name="TValue">The field type.</typeparam>
/// <param name="type">The type which has the field.</param>
/// <param name="name">The field name.</param>
- /// <param name="required">Whether to throw an exception if the private field is not found.</param>
- public IPrivateField<TValue> GetPrivateField<TValue>(Type type, string name, bool required = true)
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ public IReflectedField<TValue> GetField<TValue>(Type type, string name, bool required = true)
{
// get field from hierarchy
- IPrivateField<TValue> field = this.GetFieldFromHierarchy<TValue>(type, null, name, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public);
+ IReflectedField<TValue> field = this.GetFieldFromHierarchy<TValue>(type, null, name, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public);
if (required && field == null)
- throw new InvalidOperationException($"The {type.FullName} object doesn't have a private '{name}' static field.");
+ throw new InvalidOperationException($"The {type.FullName} object doesn't have a '{name}' static field.");
return field;
}
/****
** Properties
****/
- /// <summary>Get a private instance property.</summary>
+ /// <summary>Get a instance property.</summary>
/// <typeparam name="TValue">The property type.</typeparam>
/// <param name="obj">The object which has the property.</param>
/// <param name="name">The property name.</param>
- /// <param name="required">Whether to throw an exception if the private property is not found.</param>
- public IPrivateProperty<TValue> GetPrivateProperty<TValue>(object obj, string name, bool required = true)
+ /// <param name="required">Whether to throw an exception if the property is not found.</param>
+ public IReflectedProperty<TValue> GetProperty<TValue>(object obj, string name, bool required = true)
{
// validate
if (obj == null)
- throw new ArgumentNullException(nameof(obj), "Can't get a private instance property from a null object.");
+ throw new ArgumentNullException(nameof(obj), "Can't get a instance property from a null object.");
// get property from hierarchy
- IPrivateProperty<TValue> property = this.GetPropertyFromHierarchy<TValue>(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+ IReflectedProperty<TValue> property = this.GetPropertyFromHierarchy<TValue>(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
if (required && property == null)
- throw new InvalidOperationException($"The {obj.GetType().FullName} object doesn't have a private '{name}' instance property.");
+ throw new InvalidOperationException($"The {obj.GetType().FullName} object doesn't have a '{name}' instance property.");
return property;
}
- /// <summary>Get a private static property.</summary>
+ /// <summary>Get a static property.</summary>
/// <typeparam name="TValue">The property type.</typeparam>
/// <param name="type">The type which has the property.</param>
/// <param name="name">The property name.</param>
- /// <param name="required">Whether to throw an exception if the private property is not found.</param>
- public IPrivateProperty<TValue> GetPrivateProperty<TValue>(Type type, string name, bool required = true)
+ /// <param name="required">Whether to throw an exception if the property is not found.</param>
+ public IReflectedProperty<TValue> GetProperty<TValue>(Type type, string name, bool required = true)
{
// get field from hierarchy
- IPrivateProperty<TValue> property = this.GetPropertyFromHierarchy<TValue>(type, null, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
+ IReflectedProperty<TValue> property = this.GetPropertyFromHierarchy<TValue>(type, null, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
if (required && property == null)
- throw new InvalidOperationException($"The {type.FullName} object doesn't have a private '{name}' static property.");
+ throw new InvalidOperationException($"The {type.FullName} object doesn't have a '{name}' static property.");
return property;
}
/****
** Methods
****/
- /// <summary>Get a private instance method.</summary>
+ /// <summary>Get a instance method.</summary>
/// <param name="obj">The object which has the method.</param>
/// <param name="name">The field name.</param>
- /// <param name="required">Whether to throw an exception if the private field is not found.</param>
- public IPrivateMethod GetPrivateMethod(object obj, string name, bool required = true)
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ public IReflectedMethod GetMethod(object obj, string name, bool required = true)
{
// validate
if (obj == null)
- throw new ArgumentNullException(nameof(obj), "Can't get a private instance method from a null object.");
+ throw new ArgumentNullException(nameof(obj), "Can't get a instance method from a null object.");
// get method from hierarchy
- IPrivateMethod method = this.GetMethodFromHierarchy(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+ IReflectedMethod method = this.GetMethodFromHierarchy(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
if (required && method == null)
- throw new InvalidOperationException($"The {obj.GetType().FullName} object doesn't have a private '{name}' instance method.");
+ throw new InvalidOperationException($"The {obj.GetType().FullName} object doesn't have a '{name}' instance method.");
return method;
}
- /// <summary>Get a private static method.</summary>
+ /// <summary>Get a static method.</summary>
/// <param name="type">The type which has the method.</param>
/// <param name="name">The field name.</param>
- /// <param name="required">Whether to throw an exception if the private field is not found.</param>
- public IPrivateMethod GetPrivateMethod(Type type, string name, bool required = true)
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ public IReflectedMethod GetMethod(Type type, string name, bool required = true)
{
// get method from hierarchy
- IPrivateMethod method = this.GetMethodFromHierarchy(type, null, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
+ IReflectedMethod method = this.GetMethodFromHierarchy(type, null, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
if (required && method == null)
- throw new InvalidOperationException($"The {type.FullName} object doesn't have a private '{name}' static method.");
+ throw new InvalidOperationException($"The {type.FullName} object doesn't have a '{name}' static method.");
return method;
}
/****
** Methods by signature
****/
- /// <summary>Get a private instance method.</summary>
+ /// <summary>Get a instance method.</summary>
/// <param name="obj">The object which has the method.</param>
/// <param name="name">The field name.</param>
/// <param name="argumentTypes">The argument types of the method signature to find.</param>
- /// <param name="required">Whether to throw an exception if the private field is not found.</param>
- public IPrivateMethod GetPrivateMethod(object obj, string name, Type[] argumentTypes, bool required = true)
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ public IReflectedMethod GetMethod(object obj, string name, Type[] argumentTypes, bool required = true)
{
// validate parent
if (obj == null)
- throw new ArgumentNullException(nameof(obj), "Can't get a private instance method from a null object.");
+ throw new ArgumentNullException(nameof(obj), "Can't get a instance method from a null object.");
// get method from hierarchy
- PrivateMethod method = this.GetMethodFromHierarchy(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, argumentTypes);
+ ReflectedMethod method = this.GetMethodFromHierarchy(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, argumentTypes);
if (required && method == null)
- throw new InvalidOperationException($"The {obj.GetType().FullName} object doesn't have a private '{name}' instance method with that signature.");
+ throw new InvalidOperationException($"The {obj.GetType().FullName} object doesn't have a '{name}' instance method with that signature.");
return method;
}
- /// <summary>Get a private static method.</summary>
+ /// <summary>Get a static method.</summary>
/// <param name="type">The type which has the method.</param>
/// <param name="name">The field name.</param>
/// <param name="argumentTypes">The argument types of the method signature to find.</param>
- /// <param name="required">Whether to throw an exception if the private field is not found.</param>
- public IPrivateMethod GetPrivateMethod(Type type, string name, Type[] argumentTypes, bool required = true)
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ public IReflectedMethod GetMethod(Type type, string name, Type[] argumentTypes, bool required = true)
{
// get field from hierarchy
- PrivateMethod method = this.GetMethodFromHierarchy(type, null, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, argumentTypes);
+ ReflectedMethod method = this.GetMethodFromHierarchy(type, null, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, argumentTypes);
if (required && method == null)
- throw new InvalidOperationException($"The {type.FullName} object doesn't have a private '{name}' static method with that signature.");
+ throw new InvalidOperationException($"The {type.FullName} object doesn't have a '{name}' static method with that signature.");
return method;
}
@@ -171,7 +171,7 @@ namespace StardewModdingAPI.Framework.Reflection
/// <param name="obj">The object which has the field.</param>
/// <param name="name">The field name.</param>
/// <param name="bindingFlags">The reflection binding which flags which indicates what type of field to find.</param>
- private IPrivateField<TValue> GetFieldFromHierarchy<TValue>(Type type, object obj, string name, BindingFlags bindingFlags)
+ private IReflectedField<TValue> GetFieldFromHierarchy<TValue>(Type type, object obj, string name, BindingFlags bindingFlags)
{
bool isStatic = bindingFlags.HasFlag(BindingFlags.Static);
FieldInfo field = this.GetCached<FieldInfo>($"field::{isStatic}::{type.FullName}::{name}", () =>
@@ -183,7 +183,7 @@ namespace StardewModdingAPI.Framework.Reflection
});
return field != null
- ? new PrivateField<TValue>(type, obj, field, isStatic)
+ ? new ReflectedField<TValue>(type, obj, field, isStatic)
: null;
}
@@ -193,7 +193,7 @@ namespace StardewModdingAPI.Framework.Reflection
/// <param name="obj">The object which has the property.</param>
/// <param name="name">The property name.</param>
/// <param name="bindingFlags">The reflection binding which flags which indicates what type of property to find.</param>
- private IPrivateProperty<TValue> GetPropertyFromHierarchy<TValue>(Type type, object obj, string name, BindingFlags bindingFlags)
+ private IReflectedProperty<TValue> GetPropertyFromHierarchy<TValue>(Type type, object obj, string name, BindingFlags bindingFlags)
{
bool isStatic = bindingFlags.HasFlag(BindingFlags.Static);
PropertyInfo property = this.GetCached<PropertyInfo>($"property::{isStatic}::{type.FullName}::{name}", () =>
@@ -205,7 +205,7 @@ namespace StardewModdingAPI.Framework.Reflection
});
return property != null
- ? new PrivateProperty<TValue>(type, obj, property, isStatic)
+ ? new ReflectedProperty<TValue>(type, obj, property, isStatic)
: null;
}
@@ -214,7 +214,7 @@ namespace StardewModdingAPI.Framework.Reflection
/// <param name="obj">The object which has the method.</param>
/// <param name="name">The method name.</param>
/// <param name="bindingFlags">The reflection binding which flags which indicates what type of method to find.</param>
- private IPrivateMethod GetMethodFromHierarchy(Type type, object obj, string name, BindingFlags bindingFlags)
+ private IReflectedMethod GetMethodFromHierarchy(Type type, object obj, string name, BindingFlags bindingFlags)
{
bool isStatic = bindingFlags.HasFlag(BindingFlags.Static);
MethodInfo method = this.GetCached($"method::{isStatic}::{type.FullName}::{name}", () =>
@@ -226,7 +226,7 @@ namespace StardewModdingAPI.Framework.Reflection
});
return method != null
- ? new PrivateMethod(type, obj, method, isStatic: bindingFlags.HasFlag(BindingFlags.Static))
+ ? new ReflectedMethod(type, obj, method, isStatic: bindingFlags.HasFlag(BindingFlags.Static))
: null;
}
@@ -236,7 +236,7 @@ namespace StardewModdingAPI.Framework.Reflection
/// <param name="name">The method name.</param>
/// <param name="bindingFlags">The reflection binding which flags which indicates what type of method to find.</param>
/// <param name="argumentTypes">The argument types of the method signature to find.</param>
- private PrivateMethod GetMethodFromHierarchy(Type type, object obj, string name, BindingFlags bindingFlags, Type[] argumentTypes)
+ private ReflectedMethod GetMethodFromHierarchy(Type type, object obj, string name, BindingFlags bindingFlags, Type[] argumentTypes)
{
bool isStatic = bindingFlags.HasFlag(BindingFlags.Static);
MethodInfo method = this.GetCached($"method::{isStatic}::{type.FullName}::{name}({string.Join(",", argumentTypes.Select(p => p.FullName))})", () =>
@@ -247,7 +247,7 @@ namespace StardewModdingAPI.Framework.Reflection
return methodInfo;
});
return method != null
- ? new PrivateMethod(type, obj, method, isStatic)
+ ? new ReflectedMethod(type, obj, method, isStatic)
: null;
}
diff --git a/src/SMAPI/Framework/SContentManager.cs b/src/SMAPI/Framework/SContentManager.cs
index 524b2d17..1803098d 100644
--- a/src/SMAPI/Framework/SContentManager.cs
+++ b/src/SMAPI/Framework/SContentManager.cs
@@ -45,7 +45,7 @@ namespace StardewModdingAPI.Framework
private readonly ContentCache Cache;
/// <summary>The private <see cref="LocalizedContentManager"/> method which generates the locale portion of an asset name.</summary>
- private readonly IPrivateMethod GetKeyLocale;
+ private readonly IReflectedMethod GetKeyLocale;
/// <summary>The language codes used in asset keys.</summary>
private readonly IDictionary<string, LanguageCode> KeyLocales;
@@ -101,7 +101,7 @@ namespace StardewModdingAPI.Framework
// init
this.Monitor = monitor ?? throw new ArgumentNullException(nameof(monitor));
this.Cache = new ContentCache(this, reflection, SContentManager.PossiblePathSeparators, SContentManager.PreferredPathSeparator);
- this.GetKeyLocale = reflection.GetPrivateMethod(this, "languageCode");
+ this.GetKeyLocale = reflection.GetMethod(this, "languageCode");
this.ModContentPrefix = this.GetAssetNameFromFilePath(Constants.ModPath);
// get asset data
@@ -413,7 +413,7 @@ namespace StardewModdingAPI.Framework
private IDictionary<string, LanguageCode> GetKeyLocales(Reflector reflection)
{
// get the private code field directly to avoid changed-code logic
- IPrivateField<LanguageCode> codeField = reflection.GetPrivateField<LanguageCode>(typeof(LocalizedContentManager), "_currentLangCode");
+ IReflectedField<LanguageCode> codeField = reflection.GetField<LanguageCode>(typeof(LocalizedContentManager), "_currentLangCode");
// remember previous settings
LanguageCode previousCode = codeField.GetValue();
diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs
index 3062b0f6..e9777e0b 100644
--- a/src/SMAPI/Framework/SGame.cs
+++ b/src/SMAPI/Framework/SGame.cs
@@ -133,20 +133,20 @@ namespace StardewModdingAPI.Framework
// ReSharper disable ArrangeStaticMemberQualifier, ArrangeThisQualifier, InconsistentNaming
/// <summary>Used to access private fields and methods.</summary>
- private static List<float> _fpsList => SGame.Reflection.GetPrivateField<List<float>>(typeof(Game1), nameof(_fpsList)).GetValue();
- private static Stopwatch _fpsStopwatch => SGame.Reflection.GetPrivateField<Stopwatch>(typeof(Game1), nameof(SGame._fpsStopwatch)).GetValue();
+ private static List<float> _fpsList => SGame.Reflection.GetField<List<float>>(typeof(Game1), nameof(_fpsList)).GetValue();
+ private static Stopwatch _fpsStopwatch => SGame.Reflection.GetField<Stopwatch>(typeof(Game1), nameof(SGame._fpsStopwatch)).GetValue();
private static float _fps
{
- set => SGame.Reflection.GetPrivateField<float>(typeof(Game1), nameof(_fps)).SetValue(value);
+ set => SGame.Reflection.GetField<float>(typeof(Game1), nameof(_fps)).SetValue(value);
}
- private static Task _newDayTask => SGame.Reflection.GetPrivateField<Task>(typeof(Game1), nameof(_newDayTask)).GetValue();
- private Color bgColor => SGame.Reflection.GetPrivateField<Color>(this, nameof(bgColor)).GetValue();
- public RenderTarget2D screenWrapper => SGame.Reflection.GetPrivateProperty<RenderTarget2D>(this, "screen").GetValue(); // deliberately renamed to avoid an infinite loop
- public BlendState lightingBlend => SGame.Reflection.GetPrivateField<BlendState>(this, nameof(lightingBlend)).GetValue();
- private readonly Action drawFarmBuildings = () => SGame.Reflection.GetPrivateMethod(SGame.Instance, nameof(drawFarmBuildings)).Invoke();
- private readonly Action drawHUD = () => SGame.Reflection.GetPrivateMethod(SGame.Instance, nameof(drawHUD)).Invoke();
- private readonly Action drawDialogueBox = () => SGame.Reflection.GetPrivateMethod(SGame.Instance, nameof(drawDialogueBox)).Invoke();
- private readonly Action renderScreenBuffer = () => SGame.Reflection.GetPrivateMethod(SGame.Instance, nameof(renderScreenBuffer)).Invoke();
+ private static Task _newDayTask => SGame.Reflection.GetField<Task>(typeof(Game1), nameof(_newDayTask)).GetValue();
+ private Color bgColor => SGame.Reflection.GetField<Color>(this, nameof(bgColor)).GetValue();
+ public RenderTarget2D screenWrapper => SGame.Reflection.GetProperty<RenderTarget2D>(this, "screen").GetValue(); // deliberately renamed to avoid an infinite loop
+ public BlendState lightingBlend => SGame.Reflection.GetField<BlendState>(this, nameof(lightingBlend)).GetValue();
+ private readonly Action drawFarmBuildings = () => SGame.Reflection.GetMethod(SGame.Instance, nameof(drawFarmBuildings)).Invoke();
+ private readonly Action drawHUD = () => SGame.Reflection.GetMethod(SGame.Instance, nameof(drawHUD)).Invoke();
+ private readonly Action drawDialogueBox = () => SGame.Reflection.GetMethod(SGame.Instance, nameof(drawDialogueBox)).Invoke();
+ private readonly Action renderScreenBuffer = () => SGame.Reflection.GetMethod(SGame.Instance, nameof(renderScreenBuffer)).Invoke();
// ReSharper restore ArrangeStaticMemberQualifier, ArrangeThisQualifier, InconsistentNaming
@@ -182,7 +182,7 @@ namespace StardewModdingAPI.Framework
this.SContentManager = new SContentManager(this.Content.ServiceProvider, this.Content.RootDirectory, Thread.CurrentThread.CurrentUICulture, null, this.Monitor, reflection);
this.Content = new ContentManagerShim(this.SContentManager, "SGame.Content");
Game1.content = new ContentManagerShim(this.SContentManager, "Game1.content");
- reflection.GetPrivateField<LocalizedContentManager>(typeof(Game1), "_temporaryContent").SetValue(new ContentManagerShim(this.SContentManager, "Game1._temporaryContent")); // regenerate value with new content manager
+ reflection.GetField<LocalizedContentManager>(typeof(Game1), "_temporaryContent").SetValue(new ContentManagerShim(this.SContentManager, "Game1._temporaryContent")); // regenerate value with new content manager
}
/****
diff --git a/src/SMAPI/IPrivateField.cs b/src/SMAPI/IPrivateField.cs
index 3e681c12..512bfdab 100644
--- a/src/SMAPI/IPrivateField.cs
+++ b/src/SMAPI/IPrivateField.cs
@@ -1,9 +1,11 @@
-using System.Reflection;
+using System;
+using System.Reflection;
namespace StardewModdingAPI
{
/// <summary>A private field obtained through reflection.</summary>
/// <typeparam name="TValue">The field value type.</typeparam>
+ [Obsolete("Use " + nameof(IReflectedField<TValue>) + " instead")]
public interface IPrivateField<TValue>
{
/*********
@@ -23,4 +25,4 @@ namespace StardewModdingAPI
//// <param name="value">The value to set.</param>
void SetValue(TValue value);
}
-} \ No newline at end of file
+}
diff --git a/src/SMAPI/IPrivateMethod.cs b/src/SMAPI/IPrivateMethod.cs
index 67fc8b3c..b2fdaaeb 100644
--- a/src/SMAPI/IPrivateMethod.cs
+++ b/src/SMAPI/IPrivateMethod.cs
@@ -1,8 +1,10 @@
-using System.Reflection;
+using System;
+using System.Reflection;
namespace StardewModdingAPI
{
/// <summary>A private method obtained through reflection.</summary>
+ [Obsolete("Use " + nameof(IReflectedMethod) + " instead")]
public interface IPrivateMethod
{
/*********
@@ -24,4 +26,4 @@ namespace StardewModdingAPI
/// <param name="arguments">The method arguments to pass in.</param>
void Invoke(params object[] arguments);
}
-} \ No newline at end of file
+}
diff --git a/src/SMAPI/IPrivateProperty.cs b/src/SMAPI/IPrivateProperty.cs
index 8d67fa7a..a24495dd 100644
--- a/src/SMAPI/IPrivateProperty.cs
+++ b/src/SMAPI/IPrivateProperty.cs
@@ -1,9 +1,11 @@
-using System.Reflection;
+using System;
+using System.Reflection;
namespace StardewModdingAPI
{
/// <summary>A private property obtained through reflection.</summary>
/// <typeparam name="TValue">The property value type.</typeparam>
+ [Obsolete("Use " + nameof(IPrivateProperty<TValue>) + " instead")]
public interface IPrivateProperty<TValue>
{
/*********
@@ -23,4 +25,4 @@ namespace StardewModdingAPI
//// <param name="value">The value to set.</param>
void SetValue(TValue value);
}
-} \ No newline at end of file
+}
diff --git a/src/SMAPI/IReflectedField.cs b/src/SMAPI/IReflectedField.cs
new file mode 100644
index 00000000..43ddad42
--- /dev/null
+++ b/src/SMAPI/IReflectedField.cs
@@ -0,0 +1,26 @@
+using System.Reflection;
+
+namespace StardewModdingAPI
+{
+ /// <summary>A field obtained through reflection.</summary>
+ /// <typeparam name="TValue">The field value type.</typeparam>
+ public interface IReflectedField<TValue>
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The reflection metadata.</summary>
+ FieldInfo FieldInfo { get; }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Get the field value.</summary>
+ TValue GetValue();
+
+ /// <summary>Set the field value.</summary>
+ //// <param name="value">The value to set.</param>
+ void SetValue(TValue value);
+ }
+} \ No newline at end of file
diff --git a/src/SMAPI/IReflectedMethod.cs b/src/SMAPI/IReflectedMethod.cs
new file mode 100644
index 00000000..de83b98c
--- /dev/null
+++ b/src/SMAPI/IReflectedMethod.cs
@@ -0,0 +1,27 @@
+using System.Reflection;
+
+namespace StardewModdingAPI
+{
+ /// <summary>A method obtained through reflection.</summary>
+ public interface IReflectedMethod
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The reflection metadata.</summary>
+ MethodInfo MethodInfo { get; }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Invoke the method.</summary>
+ /// <typeparam name="TValue">The return type.</typeparam>
+ /// <param name="arguments">The method arguments to pass in.</param>
+ TValue Invoke<TValue>(params object[] arguments);
+
+ /// <summary>Invoke the method.</summary>
+ /// <param name="arguments">The method arguments to pass in.</param>
+ void Invoke(params object[] arguments);
+ }
+} \ No newline at end of file
diff --git a/src/SMAPI/IReflectedProperty.cs b/src/SMAPI/IReflectedProperty.cs
new file mode 100644
index 00000000..73ad9f30
--- /dev/null
+++ b/src/SMAPI/IReflectedProperty.cs
@@ -0,0 +1,26 @@
+using System.Reflection;
+
+namespace StardewModdingAPI
+{
+ /// <summary>A property obtained through reflection.</summary>
+ /// <typeparam name="TValue">The property value type.</typeparam>
+ public interface IReflectedProperty<TValue>
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The reflection metadata.</summary>
+ PropertyInfo PropertyInfo { get; }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Get the property value.</summary>
+ TValue GetValue();
+
+ /// <summary>Set the property value.</summary>
+ //// <param name="value">The value to set.</param>
+ void SetValue(TValue value);
+ }
+}
diff --git a/src/SMAPI/IReflectionHelper.cs b/src/SMAPI/IReflectionHelper.cs
index fb2c7861..fcebae42 100644
--- a/src/SMAPI/IReflectionHelper.cs
+++ b/src/SMAPI/IReflectionHelper.cs
@@ -1,18 +1,62 @@
-using System;
+using System;
namespace StardewModdingAPI
{
- /// <summary>Provides an API for accessing private game code.</summary>
+ /// <summary>Provides an API for accessing inaccessible code.</summary>
public interface IReflectionHelper : IModLinked
{
/*********
** Public methods
*********/
+ /// <summary>Get an instance field.</summary>
+ /// <typeparam name="TValue">The field type.</typeparam>
+ /// <param name="obj">The object which has the field.</param>
+ /// <param name="name">The field name.</param>
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ IReflectedField<TValue> GetField<TValue>(object obj, string name, bool required = true);
+
+ /// <summary>Get a static field.</summary>
+ /// <typeparam name="TValue">The field type.</typeparam>
+ /// <param name="type">The type which has the field.</param>
+ /// <param name="name">The field name.</param>
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ IReflectedField<TValue> GetField<TValue>(Type type, string name, bool required = true);
+
+ /// <summary>Get an instance property.</summary>
+ /// <typeparam name="TValue">The property type.</typeparam>
+ /// <param name="obj">The object which has the property.</param>
+ /// <param name="name">The property name.</param>
+ /// <param name="required">Whether to throw an exception if the property is not found.</param>
+ IReflectedProperty<TValue> GetProperty<TValue>(object obj, string name, bool required = true);
+
+ /// <summary>Get a static property.</summary>
+ /// <typeparam name="TValue">The property type.</typeparam>
+ /// <param name="type">The type which has the property.</param>
+ /// <param name="name">The property name.</param>
+ /// <param name="required">Whether to throw an exception if the property is not found.</param>
+ IReflectedProperty<TValue> GetProperty<TValue>(Type type, string name, bool required = true);
+
+ /// <summary>Get an instance method.</summary>
+ /// <param name="obj">The object which has the method.</param>
+ /// <param name="name">The field name.</param>
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ IReflectedMethod GetMethod(object obj, string name, bool required = true);
+
+ /// <summary>Get a static method.</summary>
+ /// <param name="type">The type which has the method.</param>
+ /// <param name="name">The field name.</param>
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ IReflectedMethod GetMethod(Type type, string name, bool required = true);
+
+ /*****
+ ** Obsolete
+ *****/
/// <summary>Get a private instance field.</summary>
/// <typeparam name="TValue">The field type.</typeparam>
/// <param name="obj">The object which has the field.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
+ [Obsolete("Use " + nameof(IReflectionHelper) + "." + nameof(IReflectionHelper.GetField) + " instead")]
IPrivateField<TValue> GetPrivateField<TValue>(object obj, string name, bool required = true);
/// <summary>Get a private static field.</summary>
@@ -20,6 +64,7 @@ namespace StardewModdingAPI
/// <param name="type">The type which has the field.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
+ [Obsolete("Use " + nameof(IReflectionHelper) + "." + nameof(IReflectionHelper.GetField) + " instead")]
IPrivateField<TValue> GetPrivateField<TValue>(Type type, string name, bool required = true);
/// <summary>Get a private instance property.</summary>
@@ -27,6 +72,7 @@ namespace StardewModdingAPI
/// <param name="obj">The object which has the property.</param>
/// <param name="name">The property name.</param>
/// <param name="required">Whether to throw an exception if the private property is not found.</param>
+ [Obsolete("Use " + nameof(IReflectionHelper) + "." + nameof(IReflectionHelper.GetProperty) + " instead")]
IPrivateProperty<TValue> GetPrivateProperty<TValue>(object obj, string name, bool required = true);
/// <summary>Get a private static property.</summary>
@@ -34,6 +80,7 @@ namespace StardewModdingAPI
/// <param name="type">The type which has the property.</param>
/// <param name="name">The property name.</param>
/// <param name="required">Whether to throw an exception if the private property is not found.</param>
+ [Obsolete("Use " + nameof(IReflectionHelper) + "." + nameof(IReflectionHelper.GetProperty) + " instead")]
IPrivateProperty<TValue> GetPrivateProperty<TValue>(Type type, string name, bool required = true);
/// <summary>Get the value of a private instance field.</summary>
@@ -42,6 +89,7 @@ namespace StardewModdingAPI
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
/// <remarks>This is a shortcut for <see cref="GetPrivateField{TValue}(object,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.</remarks>
+ [Obsolete("Use " + nameof(IReflectionHelper) + "." + nameof(IReflectionHelper.GetField) + " or " + nameof(IReflectionHelper) + "." + nameof(IReflectionHelper.GetProperty) + " instead")]
TValue GetPrivateValue<TValue>(object obj, string name, bool required = true);
/// <summary>Get the value of a private static field.</summary>
@@ -50,18 +98,21 @@ namespace StardewModdingAPI
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
/// <remarks>This is a shortcut for <see cref="GetPrivateField{TValue}(Type,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.</remarks>
+ [Obsolete("Use " + nameof(IReflectionHelper) + "." + nameof(IReflectionHelper.GetField) + " or " + nameof(IReflectionHelper) + "." + nameof(IReflectionHelper.GetProperty) + " instead")]
TValue GetPrivateValue<TValue>(Type type, string name, bool required = true);
/// <summary>Get a private instance method.</summary>
/// <param name="obj">The object which has the method.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
+ [Obsolete("Use " + nameof(IReflectionHelper) + "." + nameof(IReflectionHelper.GetMethod) + " instead")]
IPrivateMethod GetPrivateMethod(object obj, string name, bool required = true);
/// <summary>Get a private static method.</summary>
/// <param name="type">The type which has the method.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
+ [Obsolete("Use " + nameof(IReflectionHelper) + "." + nameof(IReflectionHelper.GetMethod) + " instead")]
IPrivateMethod GetPrivateMethod(Type type, string name, bool required = true);
}
}
diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs
index 3ba35e43..7bfb0abd 100644
--- a/src/SMAPI/Program.cs
+++ b/src/SMAPI/Program.cs
@@ -728,7 +728,7 @@ namespace StardewModdingAPI
IMonitor monitor = this.GetSecondaryMonitor(metadata.DisplayName);
ICommandHelper commandHelper = new CommandHelper(manifest.UniqueID, metadata.DisplayName, this.CommandManager);
IContentHelper contentHelper = new ContentHelper(contentManager, metadata.DirectoryPath, manifest.UniqueID, metadata.DisplayName, monitor);
- IReflectionHelper reflectionHelper = new ReflectionHelper(manifest.UniqueID, metadata.DisplayName, this.Reflection);
+ IReflectionHelper reflectionHelper = new ReflectionHelper(manifest.UniqueID, metadata.DisplayName, this.Reflection, this.DeprecationManager);
IModRegistry modRegistryHelper = new ModRegistryHelper(manifest.UniqueID, this.ModRegistry);
ITranslationHelper translationHelper = new TranslationHelper(manifest.UniqueID, manifest.Name, contentManager.GetLocale(), contentManager.GetCurrentLanguage());
diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj
index 380ed733..0db94843 100644
--- a/src/SMAPI/StardewModdingAPI.csproj
+++ b/src/SMAPI/StardewModdingAPI.csproj
@@ -111,6 +111,9 @@
<Compile Include="Framework\Exceptions\SAssemblyLoadFailedException.cs" />
<Compile Include="Framework\ModLoading\AssemblyLoadStatus.cs" />
<Compile Include="Framework\Utilities\ContextHash.cs" />
+ <Compile Include="IReflectedField.cs" />
+ <Compile Include="IReflectedMethod.cs" />
+ <Compile Include="IReflectedProperty.cs" />
<Compile Include="Metadata\CoreAssets.cs" />
<Compile Include="ContentSource.cs" />
<Compile Include="Events\ContentEvents.cs" />
@@ -169,7 +172,7 @@
<Compile Include="Framework\Models\ModStatus.cs" />
<Compile Include="Framework\Models\SConfig.cs" />
<Compile Include="Framework\ModLoading\ModMetadata.cs" />
- <Compile Include="Framework\Reflection\PrivateProperty.cs" />
+ <Compile Include="Framework\Reflection\ReflectedProperty.cs" />
<Compile Include="Framework\RequestExitDelegate.cs" />
<Compile Include="Framework\SContentManager.cs" />
<Compile Include="Framework\Exceptions\SParseException.cs" />
@@ -198,8 +201,8 @@
<Compile Include="Framework\Models\ModDataRecord.cs" />
<Compile Include="Framework\ModLoading\AssemblyLoader.cs" />
<Compile Include="Framework\Reflection\CacheEntry.cs" />
- <Compile Include="Framework\Reflection\PrivateField.cs" />
- <Compile Include="Framework\Reflection\PrivateMethod.cs" />
+ <Compile Include="Framework\Reflection\ReflectedField.cs" />
+ <Compile Include="Framework\Reflection\ReflectedMethod.cs" />
<Compile Include="Framework\Reflection\Reflector.cs" />
<Compile Include="IManifest.cs" />
<Compile Include="IMod.cs" />