Skip to content

Remove GetTypeInfo calls #469

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/FastExpressionCompiler.LightExpression/Expression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2909,23 +2909,23 @@ public static bool IsImplicitlyConvertibleTo(this Type source, Type target) =>
[RequiresUnreferencedCode(Trimming.Message)]
internal static PropertyInfo FindProperty(this Type type, string propertyName)
{
var properties = type.GetTypeInfo().DeclaredProperties.AsArray();
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
for (var i = 0; i < properties.Length; i++)
if (properties[i].Name == propertyName)
return properties[i];

return type.GetTypeInfo().BaseType?.FindProperty(propertyName);
return type.BaseType?.FindProperty(propertyName);
}

[RequiresUnreferencedCode(Trimming.Message)]
internal static FieldInfo FindField(this Type type, string fieldName)
{
var fields = type.GetTypeInfo().DeclaredFields.AsArray();
var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
for (var i = 0; i < fields.Length; i++)
if (fields[i].Name == fieldName)
return fields[i];

return type.GetTypeInfo().BaseType?.FindField(fieldName);
return type.BaseType?.FindField(fieldName);
}

internal const BindingFlags InstanceMethods = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
Expand Down
86 changes: 48 additions & 38 deletions src/FastExpressionCompiler/FastExpressionCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2665,7 +2665,7 @@ private static bool TryEmitCoalesceOperator(BinaryExpression expr, IReadOnlyList

private static void EmitDefault(Type type, ILGenerator il)
{
if (!type.GetTypeInfo().IsValueType)
if (!type.IsValueType)
{
il.Demit(OpCodes.Ldnull);
}
Expand Down Expand Up @@ -3798,7 +3798,7 @@ private static void EmitDecimalConstant(decimal value, ILGenerator il)

private static readonly Lazy<ConstructorInfo> _decimalCtor = new Lazy<ConstructorInfo>(() =>
{
foreach (var ctor in typeof(decimal).GetTypeInfo().DeclaredConstructors)
foreach (var ctor in typeof(decimal).GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly))
if (ctor.GetParameters().Length == 5)
return ctor;
return null;
Expand Down Expand Up @@ -3844,7 +3844,7 @@ private static bool EmitNewArrayBounds(NewArrayExpression expr, IReadOnlyList<PE
for (var i = 0; i < boundCount; i++)
if (!TryEmit(bounds.GetArgument(i), paramExprs, il, ref closure, setup, parent))
return false;
il.Demit(OpCodes.Newobj, expr.Type.GetTypeInfo().DeclaredConstructors.GetFirst());
il.Demit(OpCodes.Newobj, expr.Type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly).GetFirst());
}
return true;
}
Expand Down Expand Up @@ -7470,18 +7470,19 @@ static ILGeneratorHacks()
_getNextLocalVarIndex = (i, t) => i.DeclareLocal(t).LocalIndex;

// now let's try to acquire the more efficient less allocating method
var ilGenTypeInfo = typeof(ILGenerator).GetTypeInfo();
var localSignatureField = ilGenTypeInfo.GetDeclaredField("m_localSignature");
var ilGenType = typeof(ILGenerator);
var localSignatureField = ilGenType.GetField("m_localSignature", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
if (localSignatureField == null)
return;

var localCountField = ilGenTypeInfo.GetDeclaredField("m_localCount");
var localCountField = ilGenType.GetField("m_localCount", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
if (localCountField == null)
return;

// looking for the `SignatureHelper.AddArgument(Type argument, bool pinned)`
MethodInfo addArgumentMethod = null;
foreach (var m in typeof(SignatureHelper).GetTypeInfo().GetDeclaredMethods("AddArgument"))
foreach (var m in typeof(SignatureHelper).GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
.Where(_ => _.Name == "AddArgument"))
{
var ps = m.GetParameters();
if (ps.Length == 2 && ps[0].ParameterType == typeof(Type) && ps[1].ParameterType == typeof(bool))
Expand All @@ -7495,7 +7496,7 @@ static ILGeneratorHacks()
return;

// our own helper - always available
var postIncMethod = typeof(ILGeneratorHacks).GetTypeInfo().GetDeclaredMethod(nameof(PostInc));
var postIncMethod = typeof(ILGeneratorHacks).GetMethod(nameof(PostInc), BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly);

var efficientMethod = new DynamicMethod(string.Empty,
typeof(int), new[] { typeof(ExpressionCompiler.ArrayClosure), typeof(ILGenerator), typeof(Type) },
Expand Down Expand Up @@ -7881,9 +7882,9 @@ internal static StringBuilder CreateExpressionString(this Expression e, StringBu
return sb.Append("New(").AppendTypeOf(e.Type, stripNamespace, printType).Append(')');

sb.Append("New( // ").Append(args.Count).Append(" args");
var ctorIndex = x.Constructor.DeclaringType.GetTypeInfo().DeclaredConstructors.AsArray().GetFirstIndex(x.Constructor, default(RefEq<ConstructorInfo>));
var ctorIndex = x.Constructor.DeclaringType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly).GetFirstIndex(x.Constructor, default(RefEq<ConstructorInfo>));
sb.NewLineIndent(lineIndent).AppendTypeOf(x.Type, stripNamespace, printType)
.Append(".GetTypeInfo().DeclaredConstructors.AsArray()[").Append(ctorIndex).Append("],");
.Append(".GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)[").Append(ctorIndex).Append("],");
sb.NewLineIndentArgumentExprs(args, paramsExprs, uniqueExprs, lts, lineIndent, stripNamespace, printType, indentSpaces, notRecognizedToCode);
return sb.Append(')');
}
Expand Down Expand Up @@ -9431,14 +9432,28 @@ member is FieldInfo f
: sb.AppendProperty((PropertyInfo)member, stripNamespace, printType);

internal static StringBuilder AppendField(this StringBuilder sb, FieldInfo field,
bool stripNamespace = false, Func<Type, string, string> printType = null) =>
bool stripNamespace = false, Func<Type, string, string> printType = null)
{
sb.AppendTypeOf(field.DeclaringType, stripNamespace, printType)
.Append(".GetTypeInfo().GetDeclaredField(\"").Append(field.Name).Append("\")");
.Append(".GetField(\"").Append(field.Name);

if (field.IsPublic)
return sb.Append("\", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)");

return sb.Append("\", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)");
}

internal static StringBuilder AppendProperty(this StringBuilder sb, PropertyInfo property,
bool stripNamespace = false, Func<Type, string, string> printType = null) =>
bool stripNamespace = false, Func<Type, string, string> printType = null)
{
sb.AppendTypeOf(property.DeclaringType, stripNamespace, printType)
.Append(".GetTypeInfo().GetDeclaredProperty(\"").Append(property.Name).Append("\")");
.Append(".GetProperty(\"").Append(property.Name);

if (property.PropertyType.IsPublic)
return sb.Append("\", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)");

return sb.Append("\", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)");
}

internal static StringBuilder AppendEnum<TEnum>(this StringBuilder sb, TEnum value,
bool stripNamespace = false, Func<Type, string, string> printType = null) =>
Expand Down Expand Up @@ -9595,7 +9610,7 @@ public static string ToCode(this Type type,
}

var parentCount = 0;
for (var ti = type.GetTypeInfo(); ti.IsNested; ti = ti.DeclaringType.GetTypeInfo())
for (var ti = type; ti.IsNested; ti = ti.DeclaringType)
++parentCount;

Type[] parentTypes = null;
Expand All @@ -9607,13 +9622,13 @@ public static string ToCode(this Type type,
parentTypes[i] = pt;
}

var typeInfo = type.GetTypeInfo();
Type[] typeArgs = null;
var isTypeClosedGeneric = false;

if (type.IsGenericType)
{
isTypeClosedGeneric = !typeInfo.IsGenericTypeDefinition;
typeArgs = isTypeClosedGeneric ? typeInfo.GenericTypeArguments : typeInfo.GenericTypeParameters;
isTypeClosedGeneric = !type.IsGenericTypeDefinition;
typeArgs = isTypeClosedGeneric ? type.GenericTypeArguments : type.GetGenericArguments();
}

var typeArgsConsumedByParentsCount = 0;
Expand All @@ -9632,11 +9647,10 @@ public static string ToCode(this Type type,
}
else
{
var parentTypeInfo = parentType.GetTypeInfo();
Type[] parentTypeArgs = null;
if (parentTypeInfo.IsGenericTypeDefinition)
if (parentType.IsGenericTypeDefinition)
{
parentTypeArgs = parentTypeInfo.GenericTypeParameters;
parentTypeArgs = parentType.GetGenericArguments();

// replace the open parent args with the closed child args,
// and close the parent
Expand All @@ -9662,7 +9676,7 @@ public static string ToCode(this Type type,
}
else
{
parentTypeArgs = parentTypeInfo.GenericTypeArguments;
parentTypeArgs = parentType.GenericTypeArguments;
}

var parentTickIndex = parentType.Name.IndexOf('`');
Expand Down Expand Up @@ -9728,8 +9742,8 @@ public static string ToEnumValueCode(this Type enumType, object x,
return typeStr + "." + string.Join(orTypeDot, flags);
}

private static Type[] GetGenericTypeParametersOrArguments(this TypeInfo typeInfo) =>
typeInfo.IsGenericTypeDefinition ? typeInfo.GenericTypeParameters : typeInfo.GenericTypeArguments;
private static Type[] GetGenericTypeParametersOrArguments(this Type type) =>
type.IsGenericTypeDefinition ? type.GetGenericArguments() : type.GenericTypeArguments;

/// <summary>Custom handler for output the object in valid C#.
/// Note, the `printGenericTypeArgs` is excluded because it cannot be a open-generic object.
Expand Down Expand Up @@ -9775,7 +9789,7 @@ public static string ToArrayInitializerCode(this IEnumerable items, Type itemTyp
}

private static readonly Type[] TypesImplementedByArray =
typeof(object[]).GetInterfaces().Where(t => t.GetTypeInfo().IsGenericType).Select(t => t.GetGenericTypeDefinition()).ToArray();
typeof(object[]).GetInterfaces().Where(t => t.IsGenericType).Select(t => t.GetGenericTypeDefinition()).ToArray();

// todo: @simplify convert to using StringBuilder and simplify usage call-sites, or ADD the method
// todo: @simplify add `addTypeof = false`
Expand Down Expand Up @@ -9821,31 +9835,27 @@ public static string ToCode(this object x,
return "TimeSpan.Parse(" + time.ToString().ToCode() + ")";

var xType = x.GetType();
var xTypeInfo = xType.GetTypeInfo();

// check if item is implemented by array and then use the array initializer only for these types,
// otherwise we may produce the array initializer but it will be incompatible with e.g. `List<T>`
if (xTypeInfo.IsArray ||
xTypeInfo.IsGenericType && TypesImplementedByArray.Contains(xType.GetGenericTypeDefinition()))
if (xType.IsArray ||
xType.IsGenericType && TypesImplementedByArray.Contains(xType.GetGenericTypeDefinition()))
{
var elemType = xTypeInfo.IsArray
? xTypeInfo.GetElementType()
: xTypeInfo.GetGenericTypeParametersOrArguments().GetFirst();
var elemType = xType.IsArray
? xType.GetElementType()
: xType.GetGenericTypeParametersOrArguments().GetFirst();
if (elemType != null && elemType != xType) // avoid self recurring types e.g. `class A : IEnumerable<A>`
return ((IEnumerable)x).ToArrayInitializerCode(elemType, notRecognizedToCode, stripNamespace, printType);
}

// unwrap the Nullable struct
if (xTypeInfo.IsGenericType && xTypeInfo.GetGenericTypeDefinition() == typeof(Nullable<>))
{
xType = xTypeInfo.GetElementType();
xTypeInfo = xType.GetTypeInfo();
}
if (xType.IsGenericType && xType.GetGenericTypeDefinition() == typeof(Nullable<>))
xType = xType.GetElementType();

if (xTypeInfo.IsEnum)
if (xType.IsEnum)
return x.GetType().ToEnumValueCode(x, stripNamespace, printType);

if (xTypeInfo.IsPrimitive) // output the primitive casted to the type
if (xType.IsPrimitive) // output the primitive casted to the type
return "(" + x.GetType().ToCode(true, null) + ")" + x.ToString();

return notRecognizedToCode?.Invoke(x, stripNamespace, printType) ?? x.ToString();
Expand Down