pascalabcnet/NETGenerator/Helpers.cs
2025-10-11 22:36:05 +03:00

1056 lines
29 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using PascalABCCompiler.SemanticTree;
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections;
using System.Linq;
using System.Collections.Generic;
namespace PascalABCCompiler.NETGenerator {
public class HandlerFactory
{
public static ConstructorInfo ci;
public static Type[] parameters;
public static Type eventHandler;
static HandlerFactory()
{
eventHandler = typeof(System.EventHandler);
parameters = new Type[2]{typeof(object),typeof(IntPtr)};
ci = eventHandler.GetConstructor(parameters);
}
}
public abstract class NodeInfo
{
}
public static class OperatorsNameConvertor
{
private static System.Collections.Generic.Dictionary<string, string> names =
new System.Collections.Generic.Dictionary<string, string>(32);
static OperatorsNameConvertor()
{
names[StringConstants.plus_name]="op_Addition";
names[StringConstants.minus_name]="op_Subtraction";
names[StringConstants.mul_name]="op_Multiply";
names[StringConstants.div_name]="op_Division";
names[StringConstants.and_name]="op_BitwiseAnd";
names[StringConstants.or_name]="op_BitwiseOr";
names[StringConstants.eq_name]="op_Equality";
names[StringConstants.gr_name]="op_GreaterThan";
names[StringConstants.greq_name]="op_GreaterThanOrEqual";
names[StringConstants.sm_name]="op_LessThan";
names[StringConstants.smeq_name]="op_LessThanOrEqual";
names[StringConstants.mod_name]="op_Modulus";
names[StringConstants.not_name]="op_LogicalNot";
names[StringConstants.noteq_name]="op_Inequality";
//op_Implicit
//op_Explicit
names[StringConstants.xor_name]="op_ExclusiveOr";
names[StringConstants.and_name]="op_LogicalAnd";
names[StringConstants.or_name]="op_LogicalOr";
names[StringConstants.assign_name]="op_Assign";
names[StringConstants.shl_name]="op_LeftShift";
names[StringConstants.shr_name]="op_RightShift";
//names["op_SignedRightShift"]=StringConstants.shr_name;
names[StringConstants.shr_name]="op_UnsignedRightShift";
names[StringConstants.eq_name]="op_Equality";
names[StringConstants.multassign_name]="op_MultiplicationAssignment";
names[StringConstants.minusassign_name]="op_SubtractionAssignment";
//names[StringConstants.minusassign_name]="op_ExclusiveOrAssignment";
//op_LeftShiftAssignment
//op_ModulusAssignment
names[StringConstants.plusassign_name]="op_AdditionAssignment";
//op_BitwiseAndAssignment
//op_BitwiseOrAssignment
//op_Comma
names[StringConstants.divassign_name]="op_DivisionAssignment";
//op_Decrement
//op_Increment
//names[StringConstants.minus_name] ="op_UnaryNegation";
//op_UnaryPlus
//op_OnesComplement
}
public static string convert_name(string name)
{
string ret;
if (names.TryGetValue(name, out ret))
{
return ret;
}
return null;
}
}
public class TypeInfo : NodeInfo
{
private Type _tp;
private bool _is_arr=false;//флаг массив ли это
public bool is_set=false;
public bool is_typed_file=false;
public bool is_text_file=false;
public int arr_len;
public ConstructorInfo def_cnstr;//конструктор по умолчанию типа (если он есть)
public FieldInfo arr_fld;//ссылка на поле массива в оболочке над массивом
public MethodInfo clone_meth;//метод копирования в массиве
public MethodInfo init_meth;//метод инициализации
public MethodInfo assign_meth;//метод присваивания значений размерных типов
public ConstructorBuilder static_cnstr;
public MethodBuilder fix_meth;
//временно для событий
public MethodBuilder handl_meth;
public bool has_events=false;//есть ли в типе события
//public Hashtable fields=new Hashtable();//временно
public MethodInfo enumerator_meth;
public TypeInfo() {}
public TypeInfo(Type tp)
{
_tp = tp;
}
public Type tp {
get {
return _tp;
}
set {
_tp = value;
}
}
public bool is_arr {
get
{
return _is_arr;
}
set
{
_is_arr = value;
}
}
}
public class EvntInfo : NodeInfo
{
private EventBuilder _ei;
public EvntInfo(EventBuilder ei)
{
_ei = ei;
}
public EventBuilder ei
{
get {
return _ei;
}
set {
_ei = value;
}
}
}
public class FldInfo : NodeInfo {
private FieldInfo _fi;
public FldInfo() {}
public FldInfo(FieldInfo fi)
{
_fi = fi;
}
public FieldInfo fi
{
get {
return _fi;
}
set {
_fi = value;
}
}
public virtual Type field_type
{
get
{
return fi.FieldType;
}
}
}
public class GenericFldInfo : FldInfo
{
private Type _field_type;
public FieldInfo prev_fi; // передаю чтобы на третьем этапе в NegGenerator.cs (примерно 1586) можно было сконструировать правильный тип. Костыль для #1632
public override Type field_type
{
get
{
return _field_type;
}
}
public GenericFldInfo(FieldInfo fi, Type field_type, FieldInfo prev_fi)
: base(fi)
{
_field_type = field_type;
this.prev_fi = prev_fi;
}
}
public class PropInfo : NodeInfo {
private PropertyInfo _prop;
public PropInfo(PropertyInfo _prop)
{
this._prop = _prop;
}
public PropertyInfo prop
{
get
{
return _prop;
}
}
}
public class ConstrInfo : NodeInfo {
private ConstructorInfo _ci;
public ConstrInfo() {}
public ConstrInfo(ConstructorInfo ci)
{
_ci = ci;
}
public ConstructorInfo ci {
get {
return _ci;
}
set {
_ci = value;
}
}
}
public class MethInfo : NodeInfo {
private MethodInfo _mi;
//private LocalBuilder _ret_val;//переменная для возвр. значения //(ssyy) Нет пользы
private LocalBuilder _frame;//перем, хранящая запись активации
private MethInfo _up_meth;//ссылка на верхний метод
private Frame _disp;//запись активации
private bool _nested=false;//является ли вложенной или содержащей вложенные
private int _num_scope;//номер области видимости
private ConstructorInfo _cnstr;
private bool _stand=false;//для станд. процедур, у которого нет тела в семант. дереве ("New","Dispose")
private bool _is_in_class = false;//является ли он процедурой, влож. в метод
private bool _is_ptr_ret_type = false;
public MethInfo() {}
public MethInfo(MethodInfo mi)
{
_mi = mi;
}
public bool is_ptr_ret_type
{
get
{
return _is_ptr_ret_type;
}
set
{
_is_ptr_ret_type = value;
}
}
public bool is_in_class
{
get
{
return _is_in_class;
}
set
{
_is_in_class = value;
}
}
public bool stand
{
get
{
return _stand;
}
set
{
_stand = value;
}
}
public MethodInfo mi {
get {
return _mi;
}
set {
_mi = value;
}
}
public MethInfo up_meth {
get {
return _up_meth;
}
set {
_up_meth = value;
}
}
public ConstructorInfo cnstr {
get {
return _cnstr;
}
set {
_cnstr = value;
}
}
public int num_scope {
get {
return _num_scope;
}
set {
_num_scope = value;
}
}
public Frame disp {
get {
return _disp;
}
set {
_disp = value;
}
}
public bool nested {
get {
return _nested;
}
set {
_nested = value;
}
}
public LocalBuilder frame {
get {
return _frame;
}
set {
_frame = value;
}
}
//(ssyy) Нет пользы
/*public LocalBuilder ret_val {
get {
return _ret_val;
}
set {
_ret_val = value;
}
}*/
}
public enum VarKind
{
vkLocal, //локальная
vkNonLocal, //нелокальная(содержится в процедуре)
vkGlobal //глобальная переменная (основная программа)
}
public class VarInfo : NodeInfo {
private LocalBuilder _lb;//билдер для переменной
private FieldBuilder _fb;//а вдруг переменная нелокальная
private VarKind _kind;//тип переменной
private MethInfo _meth;//метод, в котором определена переменная
public VarInfo() {}
public VarInfo(LocalBuilder lb)
{
_lb = lb;
_kind = VarKind.vkLocal;
}
public MethInfo meth {
get {
return _meth;
}
set {
_meth = value;
}
}
public FieldBuilder fb {
get {
return _fb;
}
set {
_fb = value;
}
}
public VarKind kind {
get {
return _kind;
}
set {
_kind = value;
}
}
public LocalBuilder lb {
get {
return _lb;
}
set {
_lb = value;
}
}
}
public enum ParamKind {
pkNone,
pkGlobal
}
public class ParamInfo : NodeInfo {
private ParameterBuilder _pb;//билдер для параметра
private FieldBuilder _fb;//вдруг параметр нелокальный
private ParamKind _kind = ParamKind.pkNone;
private MethInfo _meth;//метод, в котор. описан параметр
public ParamInfo() {}
public ParamInfo(ParameterBuilder pb)
{
_pb = pb;
}
public MethInfo meth {
get {
return _meth;
}
set {
_meth = value;
}
}
public ParamKind kind {
get {
return _kind;
}
set {
_kind = value;
}
}
public FieldBuilder fb {
get {
return _fb;
}
set {
_fb = value;
}
}
public ParameterBuilder pb {
get {
return _pb;
}
set {
_pb = value;
}
}
}
public class ConstInfo : NodeInfo {
public FieldBuilder fb;
public ConstInfo(FieldBuilder fb)
{
this.fb = fb;
}
}
//Структура для записи активации процедуры
public class Frame {
public TypeBuilder tb; //класс - запись активации
public FieldBuilder parent; //поле-ссылка на род. запись активации
public ConstructorBuilder cb; //конструктор записи активации
public MethodBuilder mb;
public Frame() {}
}
public class Helper {
public Hashtable defs=new Hashtable();
private HashSet<ICommonTypeNode> processing_types = new HashSet<ICommonTypeNode>();
private MethodInfo arr_mi=null;
private Dictionary<ITypeNode, Type> pas_defs = new Dictionary<ITypeNode, Type>();
private Dictionary<IExpressionNode, LocalBuilder> memoized_exprs = new Dictionary<IExpressionNode, LocalBuilder>();
private Dictionary<TypeBuilder, MethodBuilder> dummy_methods = new Dictionary<TypeBuilder, MethodBuilder>();
public Helper() {}
public void AddDummyMethod(TypeBuilder tb, MethodBuilder mb)
{
dummy_methods[tb] = mb;
}
public MethodBuilder GetDummyMethod(TypeBuilder tb)
{
return dummy_methods[tb];
}
public void AddPascalTypeReference(ITypeNode tn, Type t)
{
pas_defs[tn] = t;
}
public Type GetPascalTypeReference(ITypeNode tn)
{
pas_defs.TryGetValue(tn, out var result);
return result;
}
public ConstInfo AddConstant(IConstantDefinitionNode cnst, FieldBuilder fb)
{
ConstInfo ci = new ConstInfo(fb);
defs[cnst] = ci;
return ci;
}
//добавление локальной переменной
public VarInfo AddVariable(IVAriableDefinitionNode var, LocalBuilder lb)
{
VarInfo vi = new VarInfo(lb);
defs[var] = vi;
return vi;
}
//ssyy
public Label GetLabel(ILabelNode label, ILGenerator il)
{
if (defs.ContainsKey(label))
{
return (Label)(defs[label]);
}
Label lab = il.DefineLabel();
defs.Add(label, lab);
return lab;
}
//\ssyy
//получение локальной переменной
public VarInfo GetVariable(IVAriableDefinitionNode var)
{
return (VarInfo)defs[var];
}
//добавление глоб. переменной
public VarInfo AddGlobalVariable(IVAriableDefinitionNode var, FieldBuilder fb)
{
VarInfo vi = new VarInfo();
defs[var] = vi;
vi.fb = fb;
vi.kind = VarKind.vkGlobal;
return vi;
}
public EvntInfo AddEvent(IEventNode ev, EventBuilder eb)
{
EvntInfo ei = new EvntInfo(eb);
defs[ev] = ei;
return ei;
}
public EvntInfo GetEvent(IEventNode ev)
{
return (EvntInfo)defs[ev];
}
//добавление нелок. переменной
public VarInfo AddNonLocalVariable(IVAriableDefinitionNode var, FieldBuilder fb)
{
VarInfo vi = new VarInfo();
defs[var] = vi;
vi.fb = fb;
vi.kind = VarKind.vkNonLocal;
return vi;
}
//добавление функции (метода)
public MethInfo AddMethod(IFunctionNode func, MethodInfo mi)
{
MethInfo m = new MethInfo(mi);
defs[func] = m;
return m;
}
//добавление функции, вложенной в функцию
public MethInfo AddMethod(IFunctionNode func, MethodInfo mi, MethInfo up)
{
MethInfo m = new MethInfo(mi);
m.up_meth = up;
defs[func] = m;
return m;
}
//получение метода
public MethInfo GetMethod(IFunctionNode func)
{
return (MethInfo)defs[func];
}
//добавление конструктора
public MethInfo AddConstructor(IFunctionNode func, ConstructorInfo ci)
{
//ConstrInfo m = new ConstrInfo(ci);
MethInfo mi = new MethInfo();
mi.cnstr = ci;
defs[func] = mi;
return mi;
}
public PropInfo AddProperty(IPropertyNode prop, PropertyInfo pi)
{
PropInfo pi2 = new PropInfo(pi);
defs[prop] = pi2;
return pi2;
}
public PropInfo GetProperty(IPropertyNode prop)
{
return (PropInfo)defs[prop];
}
//получение конструктора
public MethInfo GetConstructor(IFunctionNode func)
{
MethInfo mi = (MethInfo)defs[func];
return mi;
}
public ConstInfo GetConstant(IConstantDefinitionNode cnst)
{
ConstInfo ci = (ConstInfo)defs[cnst];
return ci;
}
public object GetConstantForExpression(IExpressionNode expr)
{
if (expr is PascalABCCompiler.TreeRealization.null_const_node) // SSM 20/04/21
return expr;
if (expr is IConstantNode)
return (expr as IConstantNode).value;
return null;
}
//добавление параметра
public ParamInfo AddParameter(IParameterNode p, ParameterBuilder pb)
{
ParamInfo pi = new ParamInfo(pb);
defs[p] = pi;
return pi;
}
//добавление нелок. параметра
public ParamInfo AddGlobalParameter(IParameterNode p, FieldBuilder fb)
{
ParamInfo pi = new ParamInfo();
pi.kind = ParamKind.pkGlobal;
pi.fb = fb;
defs[p] = pi;
return pi;
}
//получение параметра
public ParamInfo GetParameter(IParameterNode p)
{
return (ParamInfo)defs[p];
}
//добавление поля
public FldInfo AddField(ICommonClassFieldNode f, FieldInfo fb)
{
FldInfo fi = new FldInfo(fb);
#if DEBUG
/*if (f.name == "XYZW")
{
var y = f.GetHashCode();
} */
#endif
defs[f] = fi;
return fi;
}
public FldInfo AddGenericField(ICommonClassFieldNode f, FieldInfo fb, Type field_type, FieldInfo prev_fi)
{
FldInfo fi = new GenericFldInfo(fb, field_type, prev_fi); // prev_fi - чтобы сконструировать на последнем этапе fi
#if DEBUG
/*if (f.name == "XYZW")
{
var y = f.GetHashCode();
}*/
#endif
defs[f] = fi;
return fi;
}
//получение поля
public FldInfo GetField(ICommonClassFieldNode f)
{
var r = (FldInfo)defs[f];
#if DEBUG
/*if (f.name == "XYZW")
{
var y = f.GetHashCode();
} */
#endif
#if DEBUG
/*if (r == null && f.name == "XYZW")
{
foreach (var k in defs.Keys)
{
if ((k is ICommonClassFieldNode) && (k as ICommonClassFieldNode).name == "XYZW")
return (FldInfo)defs[k];
}
} */
#endif
return r;
}
//добавление типа
public TypeInfo AddType(ITypeNode type, TypeBuilder tb)
{
TypeInfo ti = new TypeInfo(tb);
defs[type] = ti;
return ti;
}
public TypeInfo AddEnum(ITypeNode type, EnumBuilder emb)
{
TypeInfo ti = new TypeInfo(emb);
defs[type] = ti;
return ti;
}
public TypeInfo AddExistingType(ITypeNode type, Type t)
{
TypeInfo ti = new TypeInfo(t);
defs[type] = ti;
return ti;
}
private IFunctionNode find_method(ICommonTypeNode tn, string name)
{
foreach (ICommonMethodNode cmn in tn.methods)
{
if (string.Compare(cmn.name,name,true) == 0) return cmn;
}
return null;
}
private IFunctionNode find_constructor(ICommonTypeNode tn)
{
foreach (ICommonMethodNode cmn in tn.methods)
{
if (cmn.is_constructor) return cmn;
}
return null;
}
private ConstructorInfo find_constructor(Type tn)
{
foreach (ConstructorInfo cmn in tn.GetConstructors())
{
return cmn;
}
return null;
}
private IFunctionNode find_constructor_with_params(ICommonTypeNode tn)
{
foreach (ICommonMethodNode cmn in tn.methods)
{
if (cmn.is_constructor && cmn.parameters.Length == 2) return cmn;
}
return null;
}
private ConstructorInfo find_constructor_with_params(Type t)
{
foreach (ConstructorInfo ci in t.GetConstructors())
{
if (ci.GetParameters().Length == 2)
return ci;
}
return null;
}
private IFunctionNode find_constructor_with_one_param(ICommonTypeNode tn)
{
foreach (ICommonMethodNode cmn in tn.methods)
{
if (cmn.is_constructor && cmn.parameters.Length == 1) return cmn;
}
return null;
}
private ConstructorInfo find_constructor_with_one_param(Type t)
{
foreach (ConstructorInfo ci in t.GetConstructors())
{
if (ci.GetParameters().Length == 1)
return ci;
}
return null;
}
/// <summary>
/// До вызова <c>.CreateType()</c> позволяет определить, был ли тип объявлен в коде, а не в готовой сборке.
/// Generic типы инстанцированные Pascal типами также считаются Pascal типами (пример: <c>IEnumerable&lt;PascalType&gt;</c>)
/// </summary>
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 && t.GetGenericArguments().Any(IsPascalType) )
return true;
if (t.IsArray)
return IsPascalType(t.GetElementType());
return false;
}
public bool IsNumericType(Type t)
{
return t == TypeFactory.ByteType || t == TypeFactory.SByteType || t == TypeFactory.Int16Type || t == TypeFactory.UInt16Type
|| t == TypeFactory.Int32Type || t == TypeFactory.UInt32Type || t == TypeFactory.Int64Type || t == TypeFactory.UInt64Type
|| t == TypeFactory.SingleType || t == TypeFactory.DoubleType;
}
public ICommonTypeNode GetTypeNodeByTypeBuilder(TypeBuilder tb)
{
foreach (object o in defs.Keys)
{
if (o is ICommonTypeNode && this.GetTypeReference(o as ICommonTypeNode).tp == tb)
return o as ICommonTypeNode;
}
return null;
}
public void SetAsProcessing(ICommonTypeNode type)
{
processing_types.Add(type);
}
public bool IsProcessing(ICommonTypeNode type)
{
return processing_types.Contains(type);
}
public void LinkExpressionToLocalBuilder(IExpressionNode expr, LocalBuilder lb)
{
memoized_exprs[expr] = lb;
}
public LocalBuilder GetLocalBuilderForExpression(IExpressionNode expr)
{
memoized_exprs.TryGetValue(expr, out var result);
return result;
}
//получение типа
public TypeInfo GetTypeReference(ITypeNode type)
{
TypeInfo ti = defs[type] as TypeInfo;
if (ti != null)
{
if (type.type_special_kind == type_special_kind.text_file)
ti.is_text_file = true;
if (!ti.is_set && !ti.is_typed_file && !ti.is_text_file)
return ti;
if (ti.clone_meth == null && !ti.is_typed_file && !ti.is_text_file)
{
if (type is ICommonTypeNode)
ti.clone_meth = this.GetMethodBuilder(find_method(type as ICommonTypeNode, "CloneSet"));//ti.tp.GetMethod("Clone");
else
ti.clone_meth = ti.tp.GetMethod("CloneSet");
}
if (ti.def_cnstr == null)
{
//if (type.type_special_kind == type_special_kind.text_file) ti.is_text_file = true;
if (ti.is_set)
{
if (type is ICommonTypeNode)
ti.def_cnstr = this.GetConstructorBuilder(find_constructor_with_params(type as ICommonTypeNode));
else
ti.def_cnstr = find_constructor_with_params(ti.tp);
}
else if (ti.is_typed_file)
{
if (type is ICommonTypeNode)
ti.def_cnstr = this.GetConstructorBuilder(find_constructor_with_one_param(type as ICommonTypeNode));
else
ti.def_cnstr = find_constructor_with_one_param(ti.tp);
}
else
{
if (type is ICommonTypeNode)
ti.def_cnstr = this.GetConstructorBuilder(find_constructor(type as ICommonTypeNode));
else
ti.def_cnstr = find_constructor(ti.tp);
}
}
if (ti.assign_meth == null && !ti.is_typed_file && !ti.is_text_file)
{
if (type is ICommonTypeNode)
ti.assign_meth = this.GetMethodBuilder(find_method(type as ICommonTypeNode, "AssignSetFrom"));
else
ti.assign_meth = ti.tp.GetMethod("AssignSetFrom");
}
return ti;
}
if (type is ICompiledTypeNode) {
ti = new TypeInfo(((ICompiledTypeNode)type).compiled_type);
defs[type] = ti;
return ti;
}
//(ssyy) Ускорил, вставив switch
switch (type.type_special_kind)
{
case type_special_kind.typed_file:
ti = GetTypeReference(type.base_type);
if (ti == null) return null;
ti.is_typed_file = true;
if (ti.def_cnstr == null)
{
if (type.base_type is ICommonTypeNode)
ti.def_cnstr = this.GetConstructorBuilder(find_constructor_with_one_param(type.base_type as ICommonTypeNode));
else
ti.def_cnstr = find_constructor_with_one_param(ti.tp);
}
return ti;
case type_special_kind.set_type:
ti = GetTypeReference(type.base_type);
if (ti == null) return null;
ti.is_set = true;
if (ti.clone_meth == null)
{
if (type.base_type is ICommonTypeNode)
ti.clone_meth = this.GetMethodBuilder(find_method(type.base_type as ICommonTypeNode, "CloneSet"));//ti.tp.GetMethod("Clone");
else
ti.clone_meth = ti.tp.GetMethod("CloneSet");
}
if (ti.assign_meth == null)
{
if (type.base_type is ICommonTypeNode)
ti.assign_meth = this.GetMethodBuilder(find_method(type.base_type as ICommonTypeNode, "AssignSetFrom"));
else
ti.assign_meth = ti.tp.GetMethod("AssignSetFrom");
}
if (ti.def_cnstr == null)
{
if (type.base_type is ICommonTypeNode)
ti.def_cnstr = this.GetConstructorBuilder(find_constructor_with_params(type.base_type as ICommonTypeNode));
else
ti.def_cnstr = find_constructor_with_params(ti.tp);
}
return ti;
case type_special_kind.diap_type:
return GetTypeReference(type.base_type);
case type_special_kind.short_string:
return new TypeInfo(TypeFactory.StringType);
case type_special_kind.array_kind:
TypeInfo tmp = GetTypeReference(type.element_type);
if (tmp == null) return null;
int rank = (type as ICommonTypeNode).rank;
if (rank == 1)
ti = new TypeInfo(tmp.tp.MakeArrayType());
else
ti = new TypeInfo(tmp.tp.MakeArrayType(rank));
//ti.is_arr = true;
defs[type] = ti;
return ti;
}
if (type is IRefTypeNode) {
TypeInfo ref_ti = GetTypeReference(((IRefTypeNode)type).pointed_type);
if (ref_ti == null) return null;
//(ssyy) Лучше использовать MakePointerType
ti = new TypeInfo(ref_ti.tp.MakePointerType());
defs[type] = ti;
return ti;
}
return null;
}
public MethodBuilder GetMethodBuilder(IFunctionNode meth)
{
MethInfo mi = defs[meth] as MethInfo;
if (mi != null)
return mi.mi as MethodBuilder;
return null;
}
public ConstructorBuilder GetConstructorBuilder(IFunctionNode meth)
{
MethInfo ci = defs[meth] as MethInfo;
if (ci != null)
return ci.cnstr as ConstructorBuilder;
return null;
}
//получение метода создания массива
public MethodInfo GetArrayInstance()
{
if (arr_mi != null) return arr_mi;
arr_mi = typeof(System.Array).GetMethod("CreateInstance",new Type[2]{typeof(System.Type),typeof(int)});
return arr_mi;
}
//добавление фиктивного метода (если метод содерж. вложенные, создается заглушка)
//т. е. метод не добавл. в таблицу
public MethInfo AddFictiveMethod(IFunctionNode func, MethodBuilder mi)
{
MethInfo m = new MethInfo(mi);
//defs[func] = m;
return m;
}
}
}