2020-12-20 08:36:11 +01:00
|
|
|
// Copyright (c) Umbraco.
|
|
|
|
|
// See LICENSE for more details.
|
|
|
|
|
|
2018-10-25 15:29:29 +02:00
|
|
|
using System.Collections.Generic;
|
2020-05-03 15:51:46 +01:00
|
|
|
using System.Linq;
|
2017-09-29 15:50:30 +02:00
|
|
|
using System.Reflection;
|
2024-03-01 12:51:21 +01:00
|
|
|
using System.Text.Json.Serialization;
|
2017-09-27 21:16:09 +02:00
|
|
|
using NUnit.Framework;
|
2021-02-09 10:22:42 +01:00
|
|
|
using Umbraco.Cms.Core;
|
2021-02-15 13:14:07 +01:00
|
|
|
using Umbraco.Extensions;
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core;
|
|
|
|
|
|
|
|
|
|
[TestFixture]
|
|
|
|
|
public class ReflectionUtilitiesTests
|
2017-09-27 21:16:09 +02:00
|
|
|
{
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitCtorEmits()
|
2017-09-27 21:16:09 +02:00
|
|
|
{
|
2022-06-21 08:09:38 +02:00
|
|
|
var ctor1 = ReflectionUtilities.EmitConstructor<Func<Class1>>();
|
|
|
|
|
Assert.IsInstanceOf<Class1>(ctor1());
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var ctor2 = ReflectionUtilities.EmitConstructor<Func<object>>(declaring: typeof(Class1));
|
|
|
|
|
Assert.IsInstanceOf<Class1>(ctor2());
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var ctor3 = ReflectionUtilities.EmitConstructor<Func<int, Class3>>();
|
|
|
|
|
Assert.IsInstanceOf<Class3>(ctor3(42));
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var ctor4 = ReflectionUtilities.EmitConstructor<Func<int, object>>(declaring: typeof(Class3));
|
|
|
|
|
Assert.IsInstanceOf<Class3>(ctor4(42));
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitCtorEmitsFromInfo()
|
|
|
|
|
{
|
|
|
|
|
var ctorInfo = typeof(Class1).GetConstructor(
|
|
|
|
|
BindingFlags.Public | BindingFlags.Instance,
|
|
|
|
|
null,
|
|
|
|
|
CallingConventions.Any,
|
|
|
|
|
Array.Empty<Type>(),
|
|
|
|
|
null);
|
|
|
|
|
var ctor1 = ReflectionUtilities.EmitConstructor<Func<Class1>>(ctorInfo);
|
|
|
|
|
Assert.IsInstanceOf<Class1>(ctor1());
|
|
|
|
|
|
|
|
|
|
ctorInfo = typeof(Class1).GetConstructor(
|
|
|
|
|
BindingFlags.Public | BindingFlags.Instance,
|
|
|
|
|
null,
|
|
|
|
|
CallingConventions.Any,
|
|
|
|
|
new[]
|
|
|
|
|
{
|
|
|
|
|
typeof(int),
|
|
|
|
|
},
|
|
|
|
|
null);
|
|
|
|
|
var ctor3 = ReflectionUtilities.EmitConstructor<Func<int, object>>(ctorInfo);
|
|
|
|
|
Assert.IsInstanceOf<Class1>(ctor3(42));
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
Assert.Throws<ArgumentException>(() => ReflectionUtilities.EmitConstructor<Func<string, object>>(ctorInfo));
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitCtorEmitsPrivateCtor()
|
|
|
|
|
{
|
|
|
|
|
var ctor = ReflectionUtilities.EmitConstructor<Func<string, Class3>>();
|
|
|
|
|
Assert.IsInstanceOf<Class3>(ctor("foo"));
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitCtorThrowsIfNotFound() =>
|
|
|
|
|
Assert.Throws<InvalidOperationException>(() => ReflectionUtilities.EmitConstructor<Func<bool, Class3>>());
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitCtorThrowsIfInvalid()
|
|
|
|
|
{
|
|
|
|
|
var ctorInfo = typeof(Class1).GetConstructor(
|
|
|
|
|
BindingFlags.Public | BindingFlags.Instance,
|
|
|
|
|
null,
|
|
|
|
|
CallingConventions.Any,
|
|
|
|
|
Array.Empty<Type>(),
|
|
|
|
|
null);
|
|
|
|
|
Assert.Throws<ArgumentException>(() => ReflectionUtilities.EmitConstructor<Func<Class2>>(ctorInfo));
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitCtorReturnsNull() =>
|
|
|
|
|
Assert.IsNull(ReflectionUtilities.EmitConstructor<Func<bool, Class3>>(false));
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodEmitsInstance()
|
|
|
|
|
{
|
|
|
|
|
var class1 = new Class1();
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var method1 = ReflectionUtilities.EmitMethod<Action<Class1>>("Method1");
|
|
|
|
|
method1(class1);
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var method2 = ReflectionUtilities.EmitMethod<Action<Class1, int>>("Method2");
|
|
|
|
|
method2(class1, 42);
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var method3 = ReflectionUtilities.EmitMethod<Func<Class1, int>>("Method3");
|
|
|
|
|
Assert.AreEqual(42, method3(class1));
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var method4 = ReflectionUtilities.EmitMethod<Func<Class1, string, int>>("Method4");
|
|
|
|
|
Assert.AreEqual(42, method4(class1, "42"));
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodEmitsStatic()
|
|
|
|
|
{
|
|
|
|
|
var method1 = ReflectionUtilities.EmitMethod<Class1, Action>("SMethod1");
|
|
|
|
|
method1();
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var method2 = ReflectionUtilities.EmitMethod<Class1, Action<int>>("SMethod2");
|
|
|
|
|
method2(42);
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var method3 = ReflectionUtilities.EmitMethod<Class1, Func<int>>("SMethod3");
|
|
|
|
|
Assert.AreEqual(42, method3());
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var method4 = ReflectionUtilities.EmitMethod<Class1, Func<string, int>>("SMethod4");
|
|
|
|
|
Assert.AreEqual(42, method4("42"));
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodEmitsStaticStatic()
|
|
|
|
|
{
|
|
|
|
|
var method = ReflectionUtilities.EmitMethod<Action>(typeof(StaticClass1), "Method");
|
|
|
|
|
method();
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodEmitsFromInfo()
|
|
|
|
|
{
|
|
|
|
|
var class1 = new Class1();
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var methodInfo = typeof(Class1).GetMethod("Method1", BindingFlags.Instance | BindingFlags.Public);
|
|
|
|
|
var method1 = ReflectionUtilities.EmitMethod<Action<Class1>>(methodInfo);
|
|
|
|
|
method1(class1);
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
methodInfo = typeof(Class1).GetMethod(
|
|
|
|
|
"Method2",
|
|
|
|
|
BindingFlags.Instance | BindingFlags.Public,
|
|
|
|
|
null,
|
|
|
|
|
new[]
|
|
|
|
|
{
|
|
|
|
|
typeof(int),
|
|
|
|
|
},
|
|
|
|
|
null);
|
|
|
|
|
var method2 = ReflectionUtilities.EmitMethod<Action<Class1, int>>(methodInfo);
|
|
|
|
|
method2(class1, 42);
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(Class1).GetMethod("Method3", BindingFlags.Instance | BindingFlags.Public);
|
|
|
|
|
var method3 = ReflectionUtilities.EmitMethod<Func<Class1, int>>(methodInfo);
|
|
|
|
|
Assert.AreEqual(42, method3(class1));
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(Class1).GetMethod(
|
|
|
|
|
"Method4",
|
|
|
|
|
BindingFlags.Instance | BindingFlags.Public,
|
|
|
|
|
null,
|
|
|
|
|
new[]
|
|
|
|
|
{
|
|
|
|
|
typeof(string),
|
|
|
|
|
},
|
|
|
|
|
null);
|
|
|
|
|
var method4 = ReflectionUtilities.EmitMethod<Func<Class1, string, int>>(methodInfo);
|
|
|
|
|
Assert.AreEqual(42, method4(class1, "42"));
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(Class1).GetMethod("SMethod1", BindingFlags.Static | BindingFlags.Public);
|
|
|
|
|
var smethod1 = ReflectionUtilities.EmitMethod<Action>(methodInfo);
|
|
|
|
|
smethod1();
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(Class1).GetMethod("SMethod2", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(int) }, null);
|
|
|
|
|
var smethod2 = ReflectionUtilities.EmitMethod<Action<int>>(methodInfo);
|
|
|
|
|
smethod2(42);
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(Class1).GetMethod("SMethod3", BindingFlags.Static | BindingFlags.Public);
|
|
|
|
|
var smethod3 = ReflectionUtilities.EmitMethod<Func<int>>(methodInfo);
|
|
|
|
|
Assert.AreEqual(42, smethod3());
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(Class1).GetMethod(
|
|
|
|
|
"SMethod4",
|
|
|
|
|
BindingFlags.Static | BindingFlags.Public,
|
|
|
|
|
null,
|
|
|
|
|
new[] { typeof(string) },
|
|
|
|
|
null);
|
|
|
|
|
var smethod4 = ReflectionUtilities.EmitMethod<Func<string, int>>(methodInfo);
|
|
|
|
|
Assert.AreEqual(42, smethod4("42"));
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(StaticClass1).GetMethod("Method", BindingFlags.Static | BindingFlags.Public);
|
|
|
|
|
var method = ReflectionUtilities.EmitMethod<Action>(methodInfo);
|
|
|
|
|
method();
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodEmitsPrivateMethod()
|
|
|
|
|
{
|
|
|
|
|
var class1 = new Class1();
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var method1 = ReflectionUtilities.EmitMethod<Action<Class1>>("MethodP1");
|
|
|
|
|
method1(class1);
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var method2 = ReflectionUtilities.EmitMethod<Class1, Action>("SMethodP1");
|
|
|
|
|
method2();
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodThrowsIfNotFound()
|
|
|
|
|
{
|
|
|
|
|
Assert.Throws<InvalidOperationException>(() => ReflectionUtilities.EmitMethod<Action<Class1>>("ZZZ"));
|
|
|
|
|
Assert.Throws<InvalidOperationException>(() =>
|
|
|
|
|
ReflectionUtilities.EmitMethod<Action<Class1, int, int>>("Method1"));
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodThrowsIfInvalid()
|
|
|
|
|
{
|
|
|
|
|
var methodInfo = typeof(Class1).GetMethod("Method1", BindingFlags.Instance | BindingFlags.Public);
|
|
|
|
|
Assert.Throws<ArgumentException>(() => ReflectionUtilities.EmitMethod<Action<Class1, int, int>>(methodInfo));
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodReturnsNull()
|
|
|
|
|
{
|
|
|
|
|
Assert.IsNull(ReflectionUtilities.EmitMethod<Action<Class1>>("ZZZ", false));
|
|
|
|
|
Assert.IsNull(ReflectionUtilities.EmitMethod<Action<Class1, int, int>>("Method1", false));
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitPropertyEmits()
|
|
|
|
|
{
|
|
|
|
|
var class1 = new Class1();
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var getter1 = ReflectionUtilities.EmitPropertyGetter<Class1, int>("Value1");
|
|
|
|
|
Assert.AreEqual(42, getter1(class1));
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var getter2 = ReflectionUtilities.EmitPropertyGetter<Class1, int>("Value3");
|
|
|
|
|
Assert.AreEqual(42, getter2(class1));
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var setter1 = ReflectionUtilities.EmitPropertySetter<Class1, int>("Value2");
|
|
|
|
|
setter1(class1, 42);
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var setter2 = ReflectionUtilities.EmitPropertySetter<Class1, int>("Value3");
|
|
|
|
|
setter2(class1, 42);
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
(var getter3, var setter3) = ReflectionUtilities.EmitPropertyGetterAndSetter<Class1, int>("Value3");
|
|
|
|
|
Assert.AreEqual(42, getter3(class1));
|
|
|
|
|
setter3(class1, 42);
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitPropertyEmitsFromInfo()
|
|
|
|
|
{
|
|
|
|
|
var class1 = new Class1();
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var propertyInfo = typeof(Class1).GetProperty("Value1");
|
|
|
|
|
var getter1 = ReflectionUtilities.EmitPropertyGetter<Class1, int>(propertyInfo);
|
|
|
|
|
Assert.AreEqual(42, getter1(class1));
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
propertyInfo = typeof(Class1).GetProperty("Value3");
|
|
|
|
|
var getter2 = ReflectionUtilities.EmitPropertyGetter<Class1, int>(propertyInfo);
|
|
|
|
|
Assert.AreEqual(42, getter2(class1));
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
propertyInfo = typeof(Class1).GetProperty("Value2");
|
|
|
|
|
var setter1 = ReflectionUtilities.EmitPropertySetter<Class1, int>(propertyInfo);
|
|
|
|
|
setter1(class1, 42);
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
propertyInfo = typeof(Class1).GetProperty("Value3");
|
|
|
|
|
var setter2 = ReflectionUtilities.EmitPropertySetter<Class1, int>(propertyInfo);
|
|
|
|
|
setter2(class1, 42);
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
(var getter3, var setter3) = ReflectionUtilities.EmitPropertyGetterAndSetter<Class1, int>(propertyInfo);
|
|
|
|
|
Assert.AreEqual(42, getter3(class1));
|
|
|
|
|
setter3(class1, 42);
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitPropertyEmitsPrivateProperty()
|
|
|
|
|
{
|
|
|
|
|
var class1 = new Class1();
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var getter1 = ReflectionUtilities.EmitPropertyGetter<Class1, int>("ValueP1");
|
|
|
|
|
Assert.AreEqual(42, getter1(class1));
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitPropertyThrowsIfNotFound()
|
|
|
|
|
{
|
|
|
|
|
Assert.Throws<InvalidOperationException>(() => ReflectionUtilities.EmitPropertyGetter<Class1, int>("Zalue1"));
|
|
|
|
|
Assert.Throws<InvalidOperationException>(() => ReflectionUtilities.EmitPropertyGetter<Class1, int>("Value2"));
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var propertyInfo = typeof(Class1).GetProperty("Value1");
|
|
|
|
|
Assert.Throws<ArgumentException>(() => ReflectionUtilities.EmitPropertySetter<Class1, int>(propertyInfo));
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitPropertyThrowsIfInvalid() =>
|
|
|
|
|
Assert.Throws<ArgumentException>(() => ReflectionUtilities.EmitPropertyGetter<Class1, string>("Value1"));
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitPropertyReturnsNull()
|
|
|
|
|
{
|
|
|
|
|
Assert.IsNull(ReflectionUtilities.EmitPropertyGetter<Class1, int>("Zalue1", false));
|
|
|
|
|
Assert.IsNull(ReflectionUtilities.EmitPropertyGetter<Class1, int>("Value2", false));
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void PropertySetterCanCastUnsafeValue()
|
|
|
|
|
{
|
|
|
|
|
// test that we can emit property setters that cast from eg 'object'
|
|
|
|
|
var type4 = typeof(Class4);
|
|
|
|
|
var propInt4 = type4.GetProperty("IntValue");
|
|
|
|
|
var propString4 = type4.GetProperty("StringValue");
|
|
|
|
|
var propClassA4 = type4.GetProperty("ClassAValue");
|
|
|
|
|
|
|
|
|
|
var object4 = new Class4();
|
|
|
|
|
var object2A = new Class2A();
|
|
|
|
|
|
|
|
|
|
// works with a string property
|
|
|
|
|
Assert.IsNotNull(propString4);
|
|
|
|
|
var setterString4 = ReflectionUtilities.EmitPropertySetterUnsafe<Class4, object>(propString4);
|
|
|
|
|
Assert.IsNotNull(setterString4);
|
|
|
|
|
setterString4(object4, "foo");
|
|
|
|
|
Assert.IsNotNull(object4.StringValue);
|
|
|
|
|
Assert.AreEqual("foo", object4.StringValue);
|
|
|
|
|
|
|
|
|
|
// unsafe is... unsafe
|
|
|
|
|
Assert.Throws<InvalidCastException>(() => setterString4(object4, new Class2()));
|
|
|
|
|
|
|
|
|
|
// works with a reference property
|
|
|
|
|
Assert.IsNotNull(propClassA4);
|
|
|
|
|
var setterClassA4 = ReflectionUtilities.EmitPropertySetterUnsafe<Class4, object>(propClassA4);
|
|
|
|
|
Assert.IsNotNull(setterClassA4);
|
|
|
|
|
setterClassA4(object4, object2A);
|
|
|
|
|
Assert.IsNotNull(object4.ClassAValue);
|
|
|
|
|
Assert.AreEqual(object2A, object4.ClassAValue);
|
|
|
|
|
|
|
|
|
|
// works with a boxed value type
|
|
|
|
|
Assert.IsNotNull(propInt4);
|
|
|
|
|
var setterInt4 = ReflectionUtilities.EmitPropertySetterUnsafe<Class4, object>(propInt4);
|
|
|
|
|
Assert.IsNotNull(setterInt4);
|
|
|
|
|
|
|
|
|
|
setterInt4(object4, 42);
|
|
|
|
|
Assert.AreEqual(42, object4.IntValue);
|
|
|
|
|
|
2023-01-18 12:28:54 +01:00
|
|
|
// TODO: the code below runs fine with ReSharper test running within VisualStudio
|
2022-06-21 08:09:38 +02:00
|
|
|
// but it crashes when running via vstest.console.exe - unless some settings are required?
|
|
|
|
|
|
|
|
|
|
// converting works
|
|
|
|
|
setterInt4(object4, 42.0);
|
|
|
|
|
Assert.AreEqual(42, object4.IntValue);
|
|
|
|
|
|
|
|
|
|
// unsafe is... unsafe
|
|
|
|
|
Assert.Throws<FormatException>(() => setterInt4(object4, "foo"));
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void PropertySetterCanCastObject()
|
|
|
|
|
{
|
|
|
|
|
// Class5 inherits from Class4 and ClassValue is defined on Class4
|
|
|
|
|
var type5 = typeof(Class5);
|
|
|
|
|
var propClass4 = type5.GetProperty("ClassValue");
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var object2 = new Class2();
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// can cast the object type from Class5 to Class4
|
|
|
|
|
var setterClass4 = ReflectionUtilities.EmitPropertySetter<Class5, Class2>(propClass4);
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var object4 = new Class5();
|
|
|
|
|
setterClass4(object4, object2);
|
|
|
|
|
Assert.IsNotNull(object4.ClassValue);
|
|
|
|
|
Assert.AreSame(object2, object4.ClassValue);
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void PropertySetterCanCastUnsafeObject()
|
|
|
|
|
{
|
|
|
|
|
var type5 = typeof(Class5);
|
|
|
|
|
var propClass4 = type5.GetProperty("ClassValue");
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var object2 = new Class2();
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// can cast the object type from object to Class4
|
|
|
|
|
var setterClass4 = ReflectionUtilities.EmitPropertySetterUnsafe<object, Class2>(propClass4);
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var object4 = new Class5();
|
|
|
|
|
setterClass4(object4, object2);
|
|
|
|
|
Assert.IsNotNull(object4.ClassValue);
|
|
|
|
|
Assert.AreSame(object2, object4.ClassValue);
|
|
|
|
|
}
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void PropertyGetterCanCastValue()
|
|
|
|
|
{
|
|
|
|
|
var type4 = typeof(Class4);
|
|
|
|
|
var propClassA4 = type4.GetProperty("ClassAValue");
|
|
|
|
|
var propInt4 = type4.GetProperty("IntValue");
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var object2A = new Class2A();
|
|
|
|
|
var object4 = new Class4 { ClassAValue = object2A, IntValue = 159 };
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// can cast the return type from Class2A to Class2
|
|
|
|
|
var getterClassA4 = ReflectionUtilities.EmitPropertyGetter<Class4, Class2>(propClassA4);
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var valueClass4A = getterClassA4(object4);
|
|
|
|
|
Assert.IsNotNull(valueClass4A);
|
|
|
|
|
Assert.AreSame(object2A, valueClass4A);
|
2018-03-01 14:50:42 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// cannot cast the return type from Class2A to Class3!
|
|
|
|
|
Assert.Throws<ArgumentException>(()
|
|
|
|
|
=> ReflectionUtilities.EmitPropertyGetter<Class4, Class3>(propClassA4));
|
2018-03-01 14:50:42 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// can cast and box the return type from int to object
|
|
|
|
|
var getterInt4 = ReflectionUtilities.EmitPropertyGetter<Class4, object>(propInt4);
|
2018-03-01 14:50:42 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var valueInt4 = getterInt4(object4);
|
|
|
|
|
Assert.IsTrue(valueInt4 is int);
|
|
|
|
|
Assert.AreEqual(159, valueInt4);
|
2018-03-01 14:50:42 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// cannot cast the return type from int to Class3!
|
|
|
|
|
Assert.Throws<ArgumentException>(()
|
|
|
|
|
=> ReflectionUtilities.EmitPropertyGetter<Class4, Class3>(propInt4));
|
|
|
|
|
}
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void PropertyGetterCanCastObject()
|
|
|
|
|
{
|
|
|
|
|
var type5 = typeof(Class5);
|
|
|
|
|
var propClass4 = type5.GetProperty("ClassValue");
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var object2 = new Class2();
|
|
|
|
|
var object4 = new Class5 { ClassValue = object2 };
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// can cast the object type from Class5 to Class4
|
|
|
|
|
var getterClass4 = ReflectionUtilities.EmitPropertyGetter<Class5, Class2>(propClass4);
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var valueClass4 = getterClass4(object4);
|
|
|
|
|
Assert.IsNotNull(valueClass4);
|
|
|
|
|
Assert.AreSame(object2, valueClass4);
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// cannot cast the object type from Class3 to Class4!
|
|
|
|
|
Assert.Throws<ArgumentException>(()
|
|
|
|
|
=> ReflectionUtilities.EmitPropertyGetter<Class3, Class2>(propClass4));
|
|
|
|
|
}
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitPropertyCastGetterEmits()
|
|
|
|
|
{
|
|
|
|
|
// test that we can emit property getters that cast the returned value to 'object'
|
|
|
|
|
// test simple class
|
|
|
|
|
var type4 = typeof(Class4);
|
|
|
|
|
|
|
|
|
|
var object4 = new Class4 { IntValue = 1, StringValue = "foo", ClassValue = new Class2() };
|
|
|
|
|
|
|
|
|
|
// works with a string property
|
|
|
|
|
var propString4 = type4.GetProperty("StringValue");
|
|
|
|
|
Assert.IsNotNull(propString4);
|
|
|
|
|
var getterString4 = ReflectionUtilities.EmitPropertyGetter<Class4, object>(propString4);
|
|
|
|
|
Assert.IsNotNull(getterString4);
|
|
|
|
|
var valueString4 = getterString4(object4);
|
|
|
|
|
Assert.IsNotNull(valueString4);
|
|
|
|
|
Assert.AreEqual("foo", valueString4);
|
|
|
|
|
|
|
|
|
|
// works with a reference property
|
|
|
|
|
var propClass4 = type4.GetProperty("ClassValue");
|
|
|
|
|
Assert.IsNotNull(propClass4);
|
|
|
|
|
var getterClass4 = ReflectionUtilities.EmitPropertyGetter<Class4, object>(propClass4);
|
|
|
|
|
Assert.IsNotNull(getterClass4);
|
|
|
|
|
var valueClass4 = getterClass4(object4);
|
|
|
|
|
Assert.IsNotNull(valueClass4);
|
|
|
|
|
Assert.IsInstanceOf<Class2>(valueClass4);
|
|
|
|
|
|
|
|
|
|
// works with a value type property
|
|
|
|
|
var propInt4 = type4.GetProperty("IntValue");
|
|
|
|
|
Assert.IsNotNull(propInt4);
|
|
|
|
|
|
|
|
|
|
// ... if explicitly getting a value type
|
|
|
|
|
var getterInt4T = ReflectionUtilities.EmitPropertyGetter<Class4, int>(propInt4);
|
|
|
|
|
Assert.IsNotNull(getterInt4T);
|
|
|
|
|
var valueInt4T = getterInt4T(object4);
|
|
|
|
|
Assert.AreEqual(1, valueInt4T);
|
|
|
|
|
|
|
|
|
|
// ... if using a compiled getter
|
|
|
|
|
var valueInt4D = GetIntValue(object4);
|
|
|
|
|
Assert.IsNotNull(valueInt4D);
|
|
|
|
|
Assert.IsTrue(valueInt4D is int);
|
|
|
|
|
Assert.AreEqual(1, valueInt4D);
|
|
|
|
|
|
|
|
|
|
// ... if getting a non-value type (emit adds a box)
|
|
|
|
|
var getterInt4 = ReflectionUtilities.EmitPropertyGetter<Class4, object>(propInt4);
|
|
|
|
|
Assert.IsNotNull(getterInt4);
|
|
|
|
|
var valueInt4 = getterInt4(object4);
|
|
|
|
|
Assert.IsNotNull(valueInt4);
|
|
|
|
|
Assert.IsTrue(valueInt4 is int);
|
|
|
|
|
Assert.AreEqual(1, valueInt4);
|
|
|
|
|
|
|
|
|
|
var getters4 = type4
|
|
|
|
|
.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)
|
|
|
|
|
.ToDictionary(x => x.Name, x => (object)ReflectionUtilities.EmitPropertyGetter<Class4, object>(x));
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Getting object4 values...");
|
|
|
|
|
var values4 = getters4.ToDictionary(kvp => kvp.Key, kvp => ((Func<Class4, object>)kvp.Value)(object4));
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Writing object4 values...");
|
|
|
|
|
foreach ((var name, var value) in values4)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"{name}: {value}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Assert.AreEqual(4, values4.Count);
|
|
|
|
|
Assert.AreEqual("foo", values4["StringValue"]);
|
|
|
|
|
Assert.IsInstanceOf<Class2>(values4["ClassValue"]);
|
|
|
|
|
Assert.AreEqual(1, values4["IntValue"]);
|
|
|
|
|
|
|
|
|
|
// test hierarchy
|
|
|
|
|
var type5 = typeof(Class5);
|
|
|
|
|
|
|
|
|
|
var getters5 = type5
|
|
|
|
|
.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)
|
|
|
|
|
.ToDictionary(x => x.Name, x => (object)ReflectionUtilities.EmitPropertyGetter<Class5, object>(x));
|
|
|
|
|
|
|
|
|
|
var object5 = new Class5
|
|
|
|
|
{
|
|
|
|
|
IntValue = 1,
|
|
|
|
|
IntValue2 = 1,
|
|
|
|
|
StringValue = "foo",
|
|
|
|
|
StringValue2 = "foo",
|
|
|
|
|
ClassValue = new Class2(),
|
|
|
|
|
ClassValue2 = new Class2(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Getting object5 values...");
|
|
|
|
|
var values5 = getters5.ToDictionary(kvp => kvp.Key, kvp => ((Func<Class5, object>)kvp.Value)(object5));
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Writing object5 values...");
|
|
|
|
|
foreach ((var name, var value) in values5)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"{name}: {value}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Assert.AreEqual(7, values5.Count);
|
|
|
|
|
Assert.AreEqual("foo", values5["StringValue"]);
|
|
|
|
|
Assert.IsInstanceOf<Class2>(values5["ClassValue"]);
|
|
|
|
|
Assert.AreEqual(1, values5["IntValue"]);
|
|
|
|
|
Assert.AreEqual("foo", values5["StringValue2"]);
|
|
|
|
|
Assert.IsInstanceOf<Class2>(values5["ClassValue2"]);
|
|
|
|
|
Assert.AreEqual(1, values5["IntValue2"]);
|
|
|
|
|
|
|
|
|
|
// test object extensions
|
|
|
|
|
Console.WriteLine("Getting object5D values...");
|
|
|
|
|
var values5D = ObjectJsonExtensions.ToObjectDictionary(object5);
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Writing object5D values...");
|
|
|
|
|
foreach ((var name, var value) in values5)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"{name}: {value}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Assert.AreEqual(7, values5.Count);
|
|
|
|
|
Assert.AreEqual("foo", values5D["StringValue"]);
|
|
|
|
|
Assert.IsInstanceOf<Class2>(values5D["ClassValue"]);
|
|
|
|
|
Assert.AreEqual(1, values5D["IntValue"]);
|
|
|
|
|
Assert.AreEqual("foo", values5D["StringValue2"]);
|
|
|
|
|
Assert.IsInstanceOf<Class2>(values5D["ClassValue2"]);
|
|
|
|
|
Assert.AreEqual(1, values5D["intValue2"]); // JsonProperty changes property name
|
|
|
|
|
}
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitFieldGetterSetterEmits()
|
|
|
|
|
{
|
|
|
|
|
var getter1 = ReflectionUtilities.EmitFieldGetter<Class1, int>("Field1");
|
|
|
|
|
var getter2 = ReflectionUtilities.EmitFieldGetter<Class1, int>("Field2");
|
|
|
|
|
var c = new Class1();
|
|
|
|
|
Assert.AreEqual(33, getter1(c));
|
|
|
|
|
Assert.AreEqual(66, getter2(c));
|
|
|
|
|
|
|
|
|
|
var setter2 = ReflectionUtilities.EmitFieldSetter<Class1, int>("Field2");
|
|
|
|
|
setter2(c, 99);
|
|
|
|
|
Assert.AreEqual(99, getter2(c));
|
|
|
|
|
|
|
|
|
|
// works on readonly fields!
|
|
|
|
|
(var getter3, var setter3) = ReflectionUtilities.EmitFieldGetterAndSetter<Class1, int>("Field3");
|
|
|
|
|
Assert.AreEqual(22, getter3(c));
|
|
|
|
|
setter3(c, 44);
|
|
|
|
|
Assert.AreEqual(44, getter3(c));
|
|
|
|
|
}
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2023-01-18 12:28:54 +01:00
|
|
|
// TODO: missing tests specifying 'returned' on method, property
|
2022-06-21 08:09:38 +02:00
|
|
|
[Test]
|
|
|
|
|
public void DeconstructAnonymousType()
|
|
|
|
|
{
|
|
|
|
|
var o = new { a = 1, b = "hello" };
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
var getters = new Dictionary<string, Func<object, object>>();
|
|
|
|
|
foreach (var prop in o.GetType().GetProperties())
|
2018-02-02 19:43:03 +01:00
|
|
|
{
|
2022-06-21 08:09:38 +02:00
|
|
|
getters[prop.Name] = ReflectionUtilities.EmitMethodUnsafe<Func<object, object>>(prop.GetMethod);
|
|
|
|
|
}
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
Assert.AreEqual(2, getters.Count);
|
|
|
|
|
Assert.IsTrue(getters.ContainsKey("a"));
|
|
|
|
|
Assert.IsTrue(getters.ContainsKey("b"));
|
|
|
|
|
Assert.AreEqual(1, getters["a"](o));
|
|
|
|
|
Assert.AreEqual("hello", getters["b"](o));
|
|
|
|
|
}
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// these functions can be examined in eg DotPeek to understand IL works
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// box [mscorlib]System.Int32
|
|
|
|
|
public object GetIntValue(Class4 object4) => object4.IntValue;
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// unbox.any [mscorlib]System.Int32
|
|
|
|
|
public void SetIntValue(Class4 object4, object i) => object4.IntValue = (int)i;
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// castclass [mscorlib]System.String
|
|
|
|
|
public void SetStringValue(Class4 object4, object s) => object4.StringValue = (string)s;
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// conv.i4
|
|
|
|
|
public void SetIntValue(Class4 object4, double d) => object4.IntValue = (int)d;
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// unbox.any [mscorlib]System.Double
|
|
|
|
|
// conv.i4
|
|
|
|
|
public void SetIntValue2(Class4 object4, object d) => object4.IntValue = (int)(double)d;
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public void SetIntValue3(Class4 object4, object v)
|
|
|
|
|
{
|
|
|
|
|
if (v is int i)
|
|
|
|
|
{
|
|
|
|
|
object4.IntValue = i;
|
2018-02-02 19:43:03 +01:00
|
|
|
}
|
2022-06-21 08:09:38 +02:00
|
|
|
else
|
2018-05-29 18:30:37 +02:00
|
|
|
{
|
2022-06-21 08:09:38 +02:00
|
|
|
object4.IntValue = Convert.ToInt32(v);
|
2018-05-29 18:30:37 +02:00
|
|
|
}
|
2022-06-21 08:09:38 +02:00
|
|
|
}
|
2018-05-29 18:30:37 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public void SetIntValue4(Class4 object4, object v)
|
|
|
|
|
{
|
|
|
|
|
if (v is int i)
|
2018-10-25 15:29:29 +02:00
|
|
|
{
|
2022-06-21 08:09:38 +02:00
|
|
|
object4.IntValue = i;
|
2018-10-25 15:29:29 +02:00
|
|
|
}
|
2022-06-21 08:09:38 +02:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
object4.IntValue = (int)Convert.ChangeType(v, typeof(int));
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-10-25 15:29:29 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// get field
|
|
|
|
|
public int GetIntField(Class1 object1) => object1.Field1;
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
// set field
|
|
|
|
|
public void SetIntField(Class1 object1, int i) => object1.Field1 = i;
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public static class StaticClass1
|
|
|
|
|
{
|
|
|
|
|
public static void Method()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public class Class1
|
|
|
|
|
{
|
|
|
|
|
public readonly int Field3 = 22;
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public int Field1 = 33;
|
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
|
|
|
#pragma warning disable SA1306 // Field names should begin with lower-case letter
|
2022-06-21 08:09:38 +02:00
|
|
|
private readonly int Field2 = 66;
|
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
|
|
|
#pragma warning restore SA1306 // Field names should begin with lower-case letter
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public Class1()
|
2018-06-07 14:29:31 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public Class1(int i)
|
2018-06-07 14:29:31 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public int Value1 => 42;
|
2018-05-29 18:30:37 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public int Value2
|
2017-09-29 15:50:30 +02:00
|
|
|
{
|
2022-06-21 08:09:38 +02:00
|
|
|
set { }
|
2017-09-27 21:16:09 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public int Value3
|
2017-09-29 15:50:30 +02:00
|
|
|
{
|
2022-06-21 08:09:38 +02:00
|
|
|
get => 42;
|
|
|
|
|
set { }
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
private int ValueP1 => 42;
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public void Method1()
|
|
|
|
|
{
|
|
|
|
|
}
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public void Method2(int i)
|
|
|
|
|
{
|
|
|
|
|
}
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public int Method3() => 42;
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public int Method4(string s) => int.Parse(s);
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public string Method5() => "foo";
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public static void SMethod1()
|
|
|
|
|
{
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public static void SMethod2(int i)
|
|
|
|
|
{
|
|
|
|
|
}
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public static int SMethod3() => 42;
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public static int SMethod4(string s) => int.Parse(s);
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
private void MethodP1()
|
|
|
|
|
{
|
2017-09-29 15:50:30 +02:00
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
private static void SMethodP1()
|
2020-12-20 08:36:11 +01:00
|
|
|
{
|
|
|
|
|
}
|
2022-06-21 08:09:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class Class2
|
|
|
|
|
{
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public class Class2A : Class2
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class Class3
|
|
|
|
|
{
|
|
|
|
|
public Class3(int i)
|
2020-12-20 08:36:11 +01:00
|
|
|
{
|
|
|
|
|
}
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
private Class3(string s)
|
2017-09-29 15:50:30 +02:00
|
|
|
{
|
|
|
|
|
}
|
2022-06-21 08:09:38 +02:00
|
|
|
}
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public class Class4
|
|
|
|
|
{
|
|
|
|
|
public int IntValue { get; set; }
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public string StringValue { get; set; }
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public Class2 ClassValue { get; set; }
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public Class2A ClassAValue { get; set; }
|
|
|
|
|
}
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public class Class5 : Class4
|
|
|
|
|
{
|
2024-03-01 12:51:21 +01:00
|
|
|
[JsonPropertyName("intValue2")]
|
2022-06-21 08:09:38 +02:00
|
|
|
public int IntValue2 { get; set; }
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public string StringValue2 { get; set; }
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2022-06-21 08:09:38 +02:00
|
|
|
public Class2 ClassValue2 { get; set; }
|
2017-09-27 21:16:09 +02:00
|
|
|
}
|
|
|
|
|
}
|