Browse Source

System.Activator.CreateInstance<T>() -> new T() transform is only valid if T has new() constraint.

pull/1165/head
Siegfried Pammer 7 years ago
parent
commit
d0683afec4
  1. 6
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs
  2. 14
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.il
  3. 8
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.il
  4. 8
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il
  5. 14
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il
  6. 7
      ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs

6
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs

@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
@ -76,6 +77,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -76,6 +77,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
return new T();
}
public T NotNew<T>()
{
return Activator.CreateInstance<T>();
}
public bool IsNull<T>(T t)
{
return t == null;

14
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.il

@ -237,6 +237,20 @@ @@ -237,6 +237,20 @@
IL_0026: ret
} // end of method Generics::New
.method public hidebysig instance !!T NotNew<T>() cil managed
{
// Code size 11 (0xb)
.maxstack 1
.locals init (!!T V_0)
IL_0000: nop
IL_0001: call !!0 [mscorlib]System.Activator::CreateInstance<!!0>()
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
} // end of method Generics::NotNew
.method public hidebysig instance bool
IsNull<T>(!!T t) cil managed
{

8
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.il

@ -188,6 +188,14 @@ @@ -188,6 +188,14 @@
IL_001f: ret
} // end of method Generics::New
.method public hidebysig instance !!T NotNew<T>() cil managed
{
// Code size 6 (0x6)
.maxstack 8
IL_0000: call !!0 [mscorlib]System.Activator::CreateInstance<!!0>()
IL_0005: ret
} // end of method Generics::NotNew
.method public hidebysig instance bool
IsNull<T>(!!T t) cil managed
{

8
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il

@ -179,6 +179,14 @@ @@ -179,6 +179,14 @@
IL_0005: ret
} // end of method Generics::New
.method public hidebysig instance !!T NotNew<T>() cil managed
{
// Code size 6 (0x6)
.maxstack 8
IL_0000: call !!0 [mscorlib]System.Activator::CreateInstance<!!0>()
IL_0005: ret
} // end of method Generics::NotNew
.method public hidebysig instance bool
IsNull<T>(!!T t) cil managed
{

14
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il

@ -231,6 +231,20 @@ @@ -231,6 +231,20 @@
IL_000a: ret
} // end of method Generics::New
.method public hidebysig instance !!T NotNew<T>() cil managed
{
// Code size 11 (0xb)
.maxstack 1
.locals init (!!T V_0)
IL_0000: nop
IL_0001: call !!0 [mscorlib]System.Activator::CreateInstance<!!0>()
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
} // end of method Generics::NotNew
.method public hidebysig instance bool
IsNull<T>(!!T t) cil managed
{

7
ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs

@ -104,7 +104,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -104,7 +104,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
break;
case "System.Activator.CreateInstance":
if (method.TypeArguments.Count == 1 && arguments.Length == 0 && method.TypeArguments[0].Kind == TypeKind.TypeParameter) {
if (arguments.Length == 0 && method.TypeArguments.Count == 1 && IsInstantiableTypeParameter(method.TypeArguments[0])) {
invocationExpression.ReplaceWith(new ObjectCreateExpression(context.TypeSystemAstBuilder.ConvertType(method.TypeArguments.First())));
}
break;
@ -201,6 +201,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -201,6 +201,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
return;
}
bool IsInstantiableTypeParameter(IType type)
{
return type is ITypeParameter tp && tp.HasDefaultConstructorConstraint;
}
Expression WrapInParens(Expression expression)
{
if (expression is ConditionalExpression)

Loading…
Cancel
Save