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;