From ef795bbb6498898c077c5c5517fc94cbf84dcfec Mon Sep 17 00:00:00 2001 From: samuraiGH <87191377+samuraiGH@users.noreply.github.com> Date: Thu, 3 Jul 2025 20:39:09 +0300 Subject: [PATCH] renaming method and adding comments (#3312) --- NETGenerator/Helpers.cs | 18 ++++++++++++------ NETGenerator/NETGenerator.cs | 10 +++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/NETGenerator/Helpers.cs b/NETGenerator/Helpers.cs index 411f80c17..0aacf2788 100644 --- a/NETGenerator/Helpers.cs +++ b/NETGenerator/Helpers.cs @@ -5,6 +5,7 @@ using System; using System.Reflection; using System.Reflection.Emit; using System.Collections; +using System.Linq; namespace PascalABCCompiler.NETGenerator { @@ -836,16 +837,21 @@ namespace PascalABCCompiler.NETGenerator { return null; } - public bool IsConstructedGenericType(Type t) + /// + /// До вызова .CreateType() позволяет определить, был ли тип объявлен в коде, а не в готовой сборке. + /// Generic типы инстанцированные Pascal типами также считаются Pascal типами (пример: IEnumerable<PascalType>) + /// + public bool IsPascalType(Type t) { if (t is TypeBuilder || t is GenericTypeParameterBuilder || t is EnumBuilder || t.GetType().FullName == "System.Reflection.Emit.TypeBuilderInstantiation") return true; - if (t.IsGenericType) - foreach (Type gt in t.GetGenericArguments()) - if (IsConstructedGenericType(gt)) - return true; + + if ( t.IsGenericType && t.GetGenericArguments().Any(IsPascalType) ) + return true; + if (t.IsArray) - return IsConstructedGenericType(t.GetElementType()); + return IsPascalType(t.GetElementType()); + return false; } diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index f8b0cc3d7..21cf0054a 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -3922,7 +3922,7 @@ namespace PascalABCCompiler.NETGenerator PushIntConst(il, i - 2 - rank); ILGenerator ilb = this.il; - if (ti != null && ti.tp.IsValueType && !TypeFactory.IsStandType(ti.tp) && (helper.IsConstructedGenericType(ti.tp) || ti.tp.IsGenericType || !ti.tp.IsEnum)) + if (ti != null && ti.tp.IsValueType && !TypeFactory.IsStandType(ti.tp) && (helper.IsPascalType(ti.tp) || ti.tp.IsGenericType || !ti.tp.IsEnum)) if (!(ti.tp is EnumBuilder)) il.Emit(OpCodes.Ldelema, ti.tp); if (_arr_type.is_nullable_type && exprs[i] is INullConstantNode) @@ -4643,7 +4643,7 @@ namespace PascalABCCompiler.NETGenerator this.il = ilb; } - if (ti != null && ti.tp.IsValueType && !TypeFactory.IsStandType(ti.tp) && lb.LocalType.GetElementType().IsValueType && (helper.IsConstructedGenericType(ti.tp) || ti.tp.IsGenericType || !ti.tp.IsEnum)) + if (ti != null && ti.tp.IsValueType && !TypeFactory.IsStandType(ti.tp) && lb.LocalType.GetElementType().IsValueType && (helper.IsPascalType(ti.tp) || ti.tp.IsGenericType || !ti.tp.IsEnum)) { if (!(ti.tp is EnumBuilder)) il.Emit(OpCodes.Ldelema, ti.tp); @@ -11663,7 +11663,7 @@ namespace PascalABCCompiler.NETGenerator // если элемент перечисления объявлен в коде // или типоаргумент элемента перечисления объявлен в коде // например IEnumerable, array of MyType - if (helper.IsConstructedGenericType(elementType)) + if (helper.IsPascalType(elementType)) { enumer_mi = TypeBuilder.GetMethod( TypeFactory.IEnumerableGenericType.MakeGenericType(elementType), @@ -11712,7 +11712,7 @@ namespace PascalABCCompiler.NETGenerator MethodInfo get_current_meth = enumer_mi.ReturnType.GetMethod("get_Current"); if (enumer_mi.ReturnType.IsGenericType && !enumer_mi.ReturnType.IsGenericTypeDefinition) { - if (helper.IsConstructedGenericType(return_type)) + if (helper.IsPascalType(return_type)) get_current_meth = TypeBuilder.GetMethod(return_type, enumer_mi.ReturnType.GetGenericTypeDefinition().GetMethod("get_Current")); else get_current_meth = return_type.GetMethod("get_Current"); @@ -11781,7 +11781,7 @@ namespace PascalABCCompiler.NETGenerator il.BeginFinallyBlock(); //il.MarkLabel(br_lbl); bool is_disposable = false; - if (helper.IsConstructedGenericType(return_type)) + if (helper.IsPascalType(return_type)) { if (enumer_mi.ReturnType.GetGenericTypeDefinition().GetMethod("Dispose") != null) is_disposable = true;