// 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 System;
using System.IO;
using System.Collections;
using System.Reflection;
using TreeConverter;
using PascalABCCompiler.TreeConverter;
using PascalABCCompiler.TreeRealization;
using System.Collections.Generic;
using System.Linq;
namespace PascalABCCompiler.PCU
{
public class PCUConsts
{
public const byte template_meth = 250;
public const byte template_field = 249;
public const byte template_prop = 248;
public const byte generic_meth = 240;
public const byte generic_ctor = 239;
public const byte generic_field = 238;
public const byte generic_prop = 237;
public const byte generic_param_ctor = 236;
public const byte common_method_generic = 230;
public const byte compiled_method_generic = 229;
public const byte common_namespace_generic = 228;
public const int method_instance_as_compiled_function_node = -1;
}
//класс, хранящий информацию об имени интерфейсной сущности и ее смещении в модуле
public class NameRef {
public string name;//имя сущности
public TreeConverter.access_level access_level;//модификатор видимости
public symbol_kind symbol_kind = symbol_kind.sk_none;
public int offset;//смещение в модуле
public byte special_scope=0;//говорит о том что этот символ добавляется не в пространсво имен модуля
public int index;//не сериализуется
public semantic_node_type semantic_node_type;
public bool virtual_slot;
public bool is_static;
public NameRef(string name, int index, TreeConverter.access_level access_level, semantic_node_type semantic_node_type)
{
this.name = name;
this.index = index;//4
this.access_level = access_level;//1
this.semantic_node_type = semantic_node_type;
}
public NameRef(string name, int index)
{
this.name = name;
this.index = index;
this.access_level = TreeConverter.access_level.al_none;
}
public int Size
{
get { return (System.Text.UTF8Encoding.UTF8.GetByteCount(name) + 1) + 1 + 4 + 1 + 1 + 1 + 1 + 1; }
}
}
public class ClassInfo
{
public int names_pos;
public int def_prop_off;
public int base_class_off;
public int interf_impl_off;
public NameRef[] names;
public ClassInfo(int names_pos, int def_prop_off, int base_class_off, int interf_impl_off, NameRef[] names)
{
this.names_pos = names_pos;
this.def_prop_off = def_prop_off;
this.base_class_off = base_class_off;
this.interf_impl_off = interf_impl_off;
this.names = names;
}
}
//вид импортируемой сущности
public enum ImportKind {
Common,
DotNet
}
//
public enum TypeKind
{
Array=2,
Pointer=3,
UnsizedArray=4,
BoundedArray=5,
TemplateInstance = 6,
GenericInstance = 7,
ShortString = 8,
GenericParameterOfType = 9,
GenericParameterOfFunction = 10,
GenericParameterOfMethod = 11,
LambdaAnyType = 12
}
public enum GenericParamKind
{
None=0,
Class=1,
Value=2
}
//класс, описывающий импортируемую сущность
public class ImportedEntity {
public ImportKind flag; //откуда импортируется сущность (сборка или PCU)
public int num_unit;//
public int offset;//для PCU - смещение в модуле, содержащем сущность, для .NET - MetadataToken сущности
public int index;//индекс записи в списке импортируемых сущностей (не сериализуется)
public int GetSize()
{
return 9;
}
public static int GetClassSize()
{
return 9;
}
}
public enum DotNetKind
{
Field,
Method,
Constructor,
Type,
Property
}
public class DotAdditInfo
{
public int offset;
}
public class DotNetNameRef
{
public DotNetKind kind;
public string name;
public DotAdditInfo[] addit;
}
///
/// Класс, описывающий заголовок PCU-файла
///
public class PCUFile {
public static char[] Header = new char[3] { 'P', 'C', 'U'};
public static Int16 SupportedVersion = PCUFileFormatVersion.Version;
public Int16 Version;
public static int CRCOffset = 3 + 2;
public Int64 CRC;
public bool UseRtlDll;
public bool IncludeDebugInfo;
public string SourceFileName;
public NameRef[] names; //список имен интерфейсной части модуля
public string[] incl_modules; //список подключаемых модулей
public string[] used_namespaces;
public string[] ref_assemblies; //список подключаемых сборок
public DotNetNameRef[] dotnet_names;
//public AssemblyRef[] ref_assemblies;
public ImportedEntity[] imp_entitles; //список импортируемых сущностей
public List compiler_directives; //список директив
//ssyy
public NameRef[] implementation_names;
public int interface_uses_count; //Количество модулей из incl_modules, относящихся к секции interface
//public List interface_type_synonyms;
//public List implementation_type_synonyms;
public int interface_synonyms_offset;
public int implementation_synonyms_offset;
//public string[] implementation_incl_modules;
//\ssyy
public PCUFile() {}
}
///
/// Класс, создающий PCU-модуль
///
public class PCUWriter {
private BinaryWriter bw;
private MemoryStream ms;
private string name;//имя модуля
public string FileName;//имя файла модуля
private PCUFile pcu_file = new PCUFile(); //заголовок PCU
private CompilationUnit unit;
private common_unit_node cun; //текущий сериализуемый unit
private Dictionary members = new Dictionary(); //таблица для хранения смещений сущностей модуля
private Dictionary name_pool = new Dictionary();//таблица для связывания имени сущности с ее описанием
//ssyy
private Dictionary impl_name_pool = new Dictionary();//то же для implementation - части
//\ssyy
private List imp_entitles = new List();//список импортируемых сущностей, заполняется в процессе
private List ref_assemblies = new List();//список подключаемых сборок, заполняется в процессе
private Dictionary assm_refs = new Dictionary();//таблица для привязывания сборки
private Dictionary func_codes = new Dictionary();//таблица, хранящая смещения тел методов в PCU
private Dictionary used_units = new Dictionary();
private Dictionary ext_members = new Dictionary();//таблица, привязывающая импорт. сущность с записью в списке имп. сущ-тей
private common_namespace_node cur_cnn;//текущее пространство имен
private bool is_interface = true;//переводим ли интерфейсную часть
//глобальная таблица для хранения смещений сущностей
private static Dictionary gl_members = new Dictionary();
private Dictionary function_references = new Dictionary();
private Dictionary type_references = new Dictionary();
//глобальная таблица, привязывающая импортируемую сущность, смещение которой пока неизвестно с PCUWriter
private static Dictionary> not_comp_members = new Dictionary>();
private static void add_not_comp_members(definition_node dn, PCUWriter pw)
{
if (not_comp_members.ContainsKey(dn))
{
not_comp_members[dn].Add(pw);
}
else
{
List l=new List();
l.Add(pw);
not_comp_members.Add(dn, l);
}
}
//локальная таблица, привязывающая импортируемую сущность с записью в таблице импортируемых сущностей
private Dictionary ext_offsets = new Dictionary();
private PCUReader pcu_reader = null; //требуется, если например требуется перекомпилировать модули PCU с циклическими связями
private Dictionary class_info = new Dictionary();
private int InitializationMethodOffset = 0;
private int FinalizationMethodOffset = 0;
internal static List AllWriters=new List();
private Compiler compiler;
public delegate void ChangeStateDelegate(object Sender, PCUReaderWriterState State, object obj);
public event ChangeStateDelegate ChangeState;
//ivan
private List dot_net_name_list = new List();
private Hashtable tokens = new Hashtable();
//ivan
public PCUWriter(Compiler compiler, ChangeStateDelegate changeState)
{
ChangeState += changeState;
this.compiler = compiler;
AllWriters.Add(this);
}
public static void Clear()
{
gl_members.Clear();
not_comp_members.Clear();
foreach (PCUWriter pw in AllWriters)
if (pw.ext_offsets.Count > 0)
;//ошибка?
AllWriters.Clear();
}
//процедура сохранения модуля на диск
public void SaveSemanticTree(CompilationUnit Unit, string TargetFileName, bool IncludeDebugInfo)
{
pcu_file.IncludeDebugInfo = IncludeDebugInfo;
pcu_file.UseRtlDll = compiler.CompilerOptions.UseDllForSystemUnits;
unit = Unit; cun = (common_unit_node)unit.SemanticTree;
this.FileName = TargetFileName;
string program_folder=System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(TargetFileName));
name = System.IO.Path.GetFileName(TargetFileName);
//name = name.Substring(0,name.LastIndexOf('.'))+".pcu";
//FileStream fs = new FileStream(name,FileMode.Create,FileAccess.ReadWrite);
ChangeState(this, PCUReaderWriterState.BeginSaveTree, TargetFileName);
pcu_file.compiler_directives = cun.compiler_directives;
if (Path.GetDirectoryName(TargetFileName).ToLower() == Path.GetDirectoryName(Unit.SyntaxTree.file_name).ToLower())
pcu_file.SourceFileName = Path.GetFileName(Unit.SyntaxTree.file_name);
else
pcu_file.SourceFileName = Unit.SyntaxTree.file_name;
ms = new MemoryStream();
bw = new BinaryWriter(ms);
//if (Unit.InterfaceUsedUnits.Count > 0) Console.WriteLine("{0} {1}",name,Unit.InterfaceUsedUnits[0].namespaces[0].namespace_name);
cur_cnn = cun.namespaces[0];
//(ssyy) формируем список нешаблонных классов
cur_cnn.MakeNonTemplateTypesList();
GetUsedUnits();//заполняем список полключаемых модулей
GetCountOfMembers();//заполняем список имен интерфейсных сущностей
WriteUnit();//пишем имя interface_namespace
cur_cnn = cun.namespaces[1];
//(ssyy) формируем список нешаблонных классов
cur_cnn.MakeNonTemplateTypesList();
GetCountOfImplementationMembers();//(ssyy) заполняем список имен сущностей реализации
WriteUnit();//пишем имя implementation_namespace
SaveOffsetForAttribute(cun.namespaces[0]);
bw.Write(0);//attributes;
cur_cnn = cun.namespaces[0];
//bw.Write((byte)0);
//bw.Write((byte)0);
//ssyy
VisitTemplateClasses();//сериализуем шаблонные классы
//\ssyy
VisitTypeDefinitions();//сериализуем описания типов интерфейсной части
//ssyy
pcu_file.interface_synonyms_offset = (int)bw.BaseStream.Position;
VisitTypeSynonyms();
//\ssyy
cur_cnn = cun.namespaces[1];
is_interface = false;
//ssyy
VisitLabelDeclarations(cur_cnn.labels); //сериализуем метки
type_entity_index = 0;
VisitTemplateClasses();//сериализуем шаблонные классы
//\ssyy
VisitTypeDefinitions();//сериализуем описания типов имплемент. части
//ssyy
pcu_file.implementation_synonyms_offset = (int)bw.BaseStream.Position;
VisitTypeSynonyms();
//\ssyy
cur_cnn = cun.namespaces[0];
is_interface = true;
foreach (common_type_node ctn in cur_cnn.non_template_types)
{
VisitTypeMemberDefinition(ctn);
}
cur_cnn = cun.namespaces[1];
is_interface = false;
foreach (common_type_node ctn in cur_cnn.non_template_types)
{
VisitTypeMemberDefinition(ctn);
}
cur_cnn = cun.namespaces[0];
is_interface = true;
VisitConstantDefinitions();//сериализуем константы
VisitVariableDefinitions();//сериализуем переменные
VisitFunctionDefinitions();//сериализуем функции
VisitRefTypeDefinitions();
VisitEventDefinitions();
cur_cnn = cun.namespaces[1];
is_interface = false;
entity_index = 0;
//имплементационная часть
VisitConstantDefinitions();
VisitVariableDefinitions();
VisitFunctionDefinitions();
VisitRefTypeDefinitions();
VisitEventDefinitions();
cur_cnn = cun.namespaces[0];
//сериализуем тела функций
foreach (common_namespace_function_node cnfn in cur_cnn.functions)
{
VisitFunctionImplementation(cnfn);
}
//сериализуем тела методов и конструкторов типа
foreach (common_type_node ctn in cur_cnn.non_template_types)
{
VisitTypeImplementation(ctn);
}
cur_cnn = cun.namespaces[1];
//имплементационная часть
foreach (common_namespace_function_node cnfn in cur_cnn.functions)
VisitFunctionImplementation(cnfn);
foreach (common_type_node ctn in cur_cnn.non_template_types)
{
VisitTypeImplementation(ctn);
}
WriteVariablePositions();
WriteConstantPositions();
AddAttributes();
WriteInitExpressions();
WriteFunctionReferences();
WriteTypeReferences();
//сохранение интерфейсной и имплементац. частей модуля
if (ext_offsets.Count != 0)
{
List dnl = new List(ext_offsets.Keys);
foreach (definition_node wdn in dnl)
{
if (wdn is wrapped_definition_node)
AddOffsetForMembers(wdn, (wdn as wrapped_definition_node).offset);
else
if (wdn is wrapped_common_type_node)
AddOffsetForMembers(wdn, (wdn as wrapped_common_type_node).offset);
else
if (PCUReader.AllReadOrWritedDefinitionNodesOffsets.ContainsKey(wdn))
AddOffsetForMembers(wdn, PCUReader.AllReadOrWritedDefinitionNodesOffsets[wdn]);
}
}
}
//запись шапки PCU на диск
private void WritePCUHeader(BinaryWriter fbw)
{
pcu_file.ref_assemblies = new string[ref_assemblies.Count];
for (int i=0; i> attr_dict = new Dictionary>();
private void SaveOffsetForAttribute(definition_node dn)
{
if (!attr_dict.ContainsKey(dn))
{
attr_dict[dn] = new List();
}
attr_dict[dn].Add((int)bw.BaseStream.Position);
}
private void AddAttributes()
{
foreach (definition_node dn in attr_dict.Keys)
{
SaveAttributes(dn.attributes,attr_dict[dn]);
}
}
private void WriteCRC32InHeader(byte[] buf, BinaryWriter bw)
{
/*Crc32 CRC32 = new Crc32();
CRC32.Update(buf);
bw.Seek(PCUFile.CRCOffset, SeekOrigin.Begin);
bw.Write(CRC32.Value);*/
bw.Write((Int64)0);
}
// запись PCU на диск
internal void CloseWriter()
{
FileStream fs = new FileStream(FileName, FileMode.Create, FileAccess.ReadWrite);
BinaryWriter fbw = new BinaryWriter(fs);
WritePCUHeader(fbw);
byte[] buf = new byte[bw.BaseStream.Length];
bw.Seek(0, SeekOrigin.Begin);
bw.BaseStream.Read(buf, 0, buf.Length);
fbw.Write(buf);
WriteCRC32InHeader(buf, fbw);
bw.Close();
ms.Close();
fbw.Close();
fs.Close();
if (pcu_reader != null)
pcu_reader.OpenUnit();
ChangeState(this, PCUReaderWriterState.EndSaveTree, FileName);
}
internal void RemoveSelf()
{
AllWriters.Remove(this);
}
public void AddPCUToOpen(PCUReader pr)
{
pcu_reader = pr;
}
//сохранен ли PCU на диск
public bool IsSaved()
{
return ext_offsets.Count == 0;
}
private Dictionary> exprs_cache = new Dictionary>();
private void SaveExpressionAndOffset(expression_node expr)
{
List lst = null;
if (!exprs_cache.ContainsKey(expr))
{
lst = new List();
exprs_cache[expr] = lst;
}
else lst = exprs_cache[expr];
lst.Add((int)bw.BaseStream.Position);
//System.Diagnostics.Debug.WriteLine((int)bw.BaseStream.Position);
}
private void FixupExpressionPosition(expression_node expr)
{
List poses = exprs_cache[expr];
//System.Diagnostics.Debug.WriteLine(pos);
foreach (int pos in poses)
{
int tmp = (int)bw.BaseStream.Position;
bw.Seek(pos,SeekOrigin.Begin);
bw.Write(tmp);
bw.Seek(tmp,SeekOrigin.Begin);
}
}
private void WriteInitExpressions()
{
foreach (expression_node expr in exprs_cache.Keys)
{
FixupExpressionPosition(expr);
VisitExpression(expr);
}
}
private void WriteFunctionReferences()
{
foreach (int off in function_references.Keys)
{
common_namespace_function_node cnfn = function_references[off];
int pos = (int)bw.BaseStream.Position;
bw.Seek(off, SeekOrigin.Begin);
WriteFunctionReference(cnfn);
bw.Seek(pos, SeekOrigin.Begin);
}
}
private void WriteTypeReferences()
{
foreach (int off in type_references.Keys)
{
common_type_node ctn = type_references[off];
int pos = (int)bw.BaseStream.Position;
bw.Seek(off, SeekOrigin.Begin);
WriteTypeReference(ctn);
bw.Seek(pos, SeekOrigin.Begin);
}
}
//получения индекса сборки в списке подключаемых сборок
private int GetAssemblyToken(Assembly a)
{
int pos = 0;
if (assm_refs.TryGetValue(a, out pos))
{
return pos;
}
int num = ref_assemblies.Count;
ref_assemblies.Add(a.FullName);
assm_refs[a]=num;
return num;
}
//получение смещения сущности в модуле
private int GetMemberOffset(definition_node dn)
{
int off = members[dn];
return members[dn];
}
//получения индекса в таблице интерфейсных имен
private int GetNameIndex(definition_node dn)
{
return name_pool[dn].index;
}
private int GetUnitReference(namespace_node nn)
{
return members[nn];
}
//получение смещения в другом модуле
private int GetExternalOffset(definition_node dn)
{
int off = -1;
if (!gl_members.TryGetValue(dn, out off))
{
add_not_comp_members(dn, this);
ext_offsets[dn] = imp_entitles.Count;
}
return off;
}
//сериализована ли сущность
private bool IsDefined(definition_node dn)
{
return members.ContainsKey(dn);
}
//добавить внешнюю сущность
public static void AddExternalMember(definition_node dn, int offset)
{
gl_members[dn] = offset;
}
private int entity_index=0;
private int type_entity_index = 0;
//сохранить смещение сущности в таблицах и в списке интерфейсных имен
private int SavePositionAndConstPool(definition_node dn)
{
int pos = (int)bw.BaseStream.Position;
members[dn] = pos;
if (name_pool.ContainsKey(dn))
{
name_pool[dn].offset = pos;
if (dn is common_namespace_function_node)
if ((dn as common_namespace_function_node).is_overload)
name_pool[dn].symbol_kind = symbol_kind.sk_overload_function;
}
gl_members[dn] = pos;
List pwl = null;
//если какой-то модуль ждет смещения от этой сущности, сообщаем ему
if (not_comp_members.TryGetValue(dn, out pwl))
foreach(PCUWriter pw in pwl)
pw.AddOffsetForMembers(dn, pos);
PCUReader.AddReadOrWritedDefinitionNode(dn, pos);
return pos;
}
//то же самое, но только для членов класса (это лишнее можно объединить)
/* private int SavePositionAndConstPoolInType(definition_node dn)
{
int pos = (int)bw.BaseStream.Position;
members[dn] = pos;
name_pool[dn].offset = pos;
gl_members[dn] = pos;
PCUWriter pw = null;
if (not_comp_members.TryGetValue(dn,out pw))
pw.AddOffsetForMembers(dn,pos);
return pos;
}*/
//просто сохраняем смещение сущности
private int SavePosition(definition_node dn)
{
int pos = (int)bw.BaseStream.Position;
members[dn] = pos;
gl_members[dn] = pos;
return pos;
}
//(ssyy) сохраняем смещение сущности (для implementation)
private int SavePositionAndImplementationPool(definition_node dn)
{
int pos = (int)bw.BaseStream.Position;
members[dn] = pos;
impl_name_pool[dn].offset = pos;
gl_members[dn] = pos;
return pos;
}
//связываем сущность со смещением, по которому находится тело методов
private void SaveCodeReference(function_node fn)
{
func_codes[fn] = (int)bw.BaseStream.Position;
}
//сообщаем функции смещение, по которому расположен ее код
private void FixupCode(function_node fn)
{
int tmp = (int)bw.BaseStream.Position;
int pos = func_codes[fn];
bw.Seek(pos,SeekOrigin.Begin);
bw.Write(tmp);
bw.Seek(tmp,SeekOrigin.Begin);
}
//заполнение списка интерфейсных имен модуля
private void GetCountOfMembers()
{
int num = cur_cnn.constants.Count + cur_cnn.functions.Count + cur_cnn.non_template_types.Count + cur_cnn.runtime_types.Count + cur_cnn.variables.Count + cur_cnn.templates.Count + cur_cnn.ref_types.Count + cur_cnn.events.Count;
pcu_file.names = new NameRef[num];
FillNames(pcu_file.names, name_pool);
}
//ssyy
private void GetCountOfImplementationMembers()
{
int num = cur_cnn.constants.Count + cur_cnn.functions.Count + cur_cnn.non_template_types.Count + cur_cnn.runtime_types.Count + cur_cnn.variables.Count + cur_cnn.templates.Count + cur_cnn.ref_types.Count + cur_cnn.events.Count;
pcu_file.implementation_names = new NameRef[num];
FillNames(pcu_file.implementation_names, impl_name_pool);
}
//\ssyy
private string GetSynonimName(common_namespace_node cnn, compiled_type_node ctn)
{
for (int i = 0; i < cnn.type_synonyms.Count; i++)
{
if (cnn.type_synonyms[i].original_type == ctn) return cnn.type_synonyms[i].name;
}
return ctn.name;
}
//ssyy
private void FillNames(NameRef[] name_array, Dictionary pools)
{
int j = 0, i = 0;
for (i = j; i < cur_cnn.constants.Count + j; i++)
{
name_array[i] = new NameRef(cur_cnn.constants[i - j].name, i);
pools[cur_cnn.constants[i - j]] = name_array[i];
}
j = i;
for (i = j; i < cur_cnn.templates.Count + j; i++)
{
name_array[i] = new NameRef(cur_cnn.templates[i - j].name, i);
pools[cur_cnn.templates[i - j]] = name_array[i];
}
j = i;
for (i = j; i < cur_cnn.functions.Count + j; i++)
{
name_array[i] = new NameRef(cur_cnn.functions[i - j].name, i);
if (cur_cnn.functions[i - j].ConnectedToType != null)
{
name_array[i].special_scope = 1;
if (cur_cnn.functions[i - j].return_value_type != null)
name_array[i].symbol_kind = symbol_kind.sk_overload_function;
else
name_array[i].symbol_kind = symbol_kind.sk_overload_procedure;
}
pools[cur_cnn.functions[i - j]] = name_array[i];
}
j = i;
for (i = j; i < cur_cnn.non_template_types.Count + j; i++)
{
name_array[i] = new NameRef(cur_cnn.non_template_types[i - j].name, i);
pools[cur_cnn.non_template_types[i - j]] = name_array[i];
}
j = i;
for (i = j; i < cur_cnn.runtime_types.Count + j; i++)
{
name_array[i] = new NameRef(GetSynonimName(cur_cnn,cur_cnn.runtime_types[i - j]), i);
//name_array[i] = new NameRef(cur_cnn.runtime_types[i - j].name, i);
pools[cur_cnn.runtime_types[i - j]] = name_array[i];
}
j = i;
for (i = j; i < cur_cnn.ref_types.Count + j; i++)
{
name_array[i] = new NameRef(cur_cnn.ref_types[i - j].name, i);
pools[cur_cnn.ref_types[i - j]] = name_array[i];
}
j = i;
for (i = j; i < cur_cnn.variables.Count + j; i++)
{
name_array[i] = new NameRef(cur_cnn.variables[i - j].name, i);
pools[cur_cnn.variables[i - j]] = name_array[i];
}
j = i;
for (i = j; i < cur_cnn.events.Count + j; i++)
{
name_array[i] = new NameRef(cur_cnn.events[i - j].name, i);
pools[cur_cnn.events[i - j]] = name_array[i];
}
}
//\ssyy
private void AddIndirectUsedUnitsForType(type_node tn, Dictionary ns_dict, bool interf)
{
if (tn is common_type_node)
{
common_namespace_node comp_cnn = (tn as common_type_node).comprehensive_namespace;
if (tn is common_generic_instance_type_node)
comp_cnn = (tn as common_generic_instance_type_node).common_original_generic.comprehensive_namespace;
if (comp_cnn != null && !ns_dict.ContainsKey(comp_cnn) && unit.SemanticTree != comp_cnn.cont_unit)
{
var path = Compiler.GetUnitPath(unit, compiler.UnitsLogicallySortedList.Find(u => u.SemanticTree == comp_cnn.cont_unit));
if (interf)
unit.InterfaceUsedUnits.AddElement(comp_cnn.cont_unit, path);
else
unit.ImplementationUsedUnits.AddElement(comp_cnn.cont_unit, path);
ns_dict[comp_cnn] = true;
}
if (tn.base_type is common_type_node)
AddIndirectUsedUnitsForType(tn.base_type, ns_dict, interf);
}
}
private void AddIndirectUsedUnitsForFunction(common_namespace_function_node cnfn, Dictionary ns_dict, bool interf)
{
common_namespace_node comp_cnn = cnfn.namespace_node;
if (comp_cnn != null && !ns_dict.ContainsKey(comp_cnn) && unit.SemanticTree != comp_cnn.cont_unit)
{
var path = Compiler.GetUnitPath(unit, compiler.UnitsLogicallySortedList.Find(u => u.SemanticTree == comp_cnn.cont_unit));
if (interf)
unit.InterfaceUsedUnits.AddElement(comp_cnn.cont_unit, path);
else
unit.ImplementationUsedUnits.AddElement(comp_cnn.cont_unit, path);
ns_dict[comp_cnn] = true;
}
}
private void AddIndirectUsedUnitsInStatement(statement_node stmt, Dictionary ns_dict, bool interf)
{
if (stmt == null)
return;
if (stmt is statements_list)
{
statements_list stmt_list = stmt as statements_list;
foreach (local_block_variable lv in stmt_list.local_variables)
{
AddIndirectUsedUnitsForType(lv.type, ns_dict, interf);
}
foreach (statement_node st in stmt_list.statements)
AddIndirectUsedUnitsInStatement(st, ns_dict, interf);
}
else if (stmt is common_static_method_call)
{
common_static_method_call csmc = stmt as common_static_method_call;
AddIndirectUsedUnitsForType(csmc.common_type, ns_dict, interf);
}
else if (stmt is common_method_call)
{
common_method_call cmc = stmt as common_method_call;
AddIndirectUsedUnitsForType(cmc.function_node.cont_type, ns_dict, interf);
}
else if (stmt is common_namespace_function_call)
{
common_namespace_function_call cnfc = stmt as common_namespace_function_call;
if (cnfc.function_node.ConnectedToType != null)
AddIndirectUsedUnitsForFunction(cnfc.function_node, ns_dict, interf);
}
else if (stmt is if_node)
{
if_node node = stmt as if_node;
AddIndirectUsedUnitsInStatement(node.condition, ns_dict, interf);
AddIndirectUsedUnitsInStatement(node.then_body, ns_dict, interf);
AddIndirectUsedUnitsInStatement(node.else_body, ns_dict, interf);
}
else if (stmt is while_node)
{
while_node node = stmt as while_node;
AddIndirectUsedUnitsInStatement(node.condition, ns_dict, interf);
AddIndirectUsedUnitsInStatement(node.body, ns_dict, interf);
}
else if (stmt is repeat_node)
{
repeat_node node = stmt as repeat_node;
AddIndirectUsedUnitsInStatement(node.condition, ns_dict, interf);
AddIndirectUsedUnitsInStatement(node.body, ns_dict, interf);
}
else if (stmt is lock_statement)
{
lock_statement node = stmt as lock_statement;
AddIndirectUsedUnitsInStatement(node.lock_object, ns_dict, interf);
AddIndirectUsedUnitsInStatement(node.body, ns_dict, interf);
}
else if (stmt is foreach_node)
{
foreach_node node = stmt as foreach_node;
AddIndirectUsedUnitsInStatement(node.in_what, ns_dict, interf);
AddIndirectUsedUnitsInStatement(node.what_do, ns_dict, interf);
}
else if (stmt is for_node)
{
for_node node = stmt as for_node;
AddIndirectUsedUnitsInStatement(node.init_while_expr, ns_dict, interf);
AddIndirectUsedUnitsInStatement(node.while_expr, ns_dict, interf);
}
else if (stmt is try_block)
{
try_block node = stmt as try_block;
AddIndirectUsedUnitsInStatement(node.try_statements, ns_dict, interf);
foreach (var eh in node.filters)
AddIndirectUsedUnitsInStatement(eh.exception_handler, ns_dict, interf);
AddIndirectUsedUnitsInStatement(node.finally_statements, ns_dict, interf);
}
else if (stmt is throw_statement_node)
{
throw_statement_node node = stmt as throw_statement_node;
AddIndirectUsedUnitsInStatement(node.excpetion, ns_dict, interf);
}
if (stmt is base_function_call)
{
base_function_call bfc = stmt as base_function_call;
foreach (var expr in bfc.parameters)
{
AddIndirectUsedUnitsInStatement(expr, ns_dict, interf);
}
}
}
private void AddIndirectUsedUnitsInVariables(IEnumerable variables, Dictionary ns_dict, bool interf) where T: var_definition_node
{
if (variables == null)
return;
foreach (var lv in variables)
{
AddIndirectUsedUnitsForType(lv.type, ns_dict, interf);
}
}
private void AddIndirectInteraceUsedUnits()
{
if (cun.namespaces.Count == 0)
return;
Dictionary interf_ns_dict = new Dictionary();
common_unit_node unt = null;
for (int j = 0; j < unit.InterfaceUsedUnits.Count; j++)
{
unt = unit.InterfaceUsedUnits[j] as common_unit_node;
if (unt == null) continue;
foreach (common_namespace_node ns in unt.namespaces)
{
interf_ns_dict[ns] = true;
}
}
common_namespace_node cnn = cun.namespaces[0];
foreach (type_synonym ts in cnn.type_synonyms)
AddIndirectUsedUnitsForType(ts.original_type, interf_ns_dict, true);
foreach (common_type_node ctn in cnn.types)
{
if (ctn.base_type != null)
AddIndirectUsedUnitsForType(ctn.base_type, interf_ns_dict, true);
foreach (common_method_node cmn in ctn.methods)
{
if (cmn.is_constructor && cmn.function_code != null && cmn.function_code.location == null)
{
foreach (common_parameter cp in cmn.parameters)
{
AddIndirectUsedUnitsForType(cp.type, interf_ns_dict, true);
}
}
AddIndirectUsedUnitsInVariables(cmn.var_definition_nodes_list, interf_ns_dict, true);
AddIndirectUsedUnitsInStatement(cmn.function_code, interf_ns_dict, true);
if (cmn.return_value_type != null)
AddIndirectUsedUnitsForType(cmn.return_value_type, interf_ns_dict, true);
}
AddIndirectUsedUnitsInVariables(ctn.fields, interf_ns_dict, true);
}
foreach (common_namespace_function_node cnfn in cnn.functions)
{
AddIndirectUsedUnitsInVariables(cnfn.var_definition_nodes_list, interf_ns_dict, true);
AddIndirectUsedUnitsInStatement(cnfn.function_code, interf_ns_dict, true);
if (cnfn.return_value_type != null)
AddIndirectUsedUnitsForType(cnfn.return_value_type, interf_ns_dict, true);
}
AddIndirectUsedUnitsInVariables(cnn.variables, interf_ns_dict, true);
if (cun.main_function != null)
AddIndirectUsedUnitsInStatement(cun.main_function.function_code, interf_ns_dict, true);
if (cun.finalization_method != null)
AddIndirectUsedUnitsInStatement(cun.finalization_method.function_code, interf_ns_dict, true);
}
private void AddIndirectImplementationUsedUnits()
{
if (cun.namespaces.Count < 2)
return;
common_unit_node unt = null;
Dictionary impl_ns_dict = new Dictionary();
for (int j = 0; j < unit.ImplementationUsedUnits.Count; j++)
{
unt = unit.ImplementationUsedUnits[j] as common_unit_node;
if (unt == null) continue;
foreach (common_namespace_node ns in unt.namespaces)
{
impl_ns_dict[ns] = true;
}
}
common_namespace_node cnn = cun.namespaces[1];
foreach (type_synonym ts in cnn.type_synonyms)
AddIndirectUsedUnitsForType(ts.original_type, impl_ns_dict, true);
foreach (common_type_node ctn in cnn.types)
{
if (ctn.base_type != null)
AddIndirectUsedUnitsForType(ctn.base_type, impl_ns_dict, true);
foreach (common_method_node cmn in ctn.methods)
{
if (cmn.is_constructor && cmn.function_code != null && cmn.function_code.location == null)
{
foreach (common_parameter cp in cmn.parameters)
{
AddIndirectUsedUnitsForType(cp.type, impl_ns_dict, false);
}
}
AddIndirectUsedUnitsInVariables(cmn.var_definition_nodes_list, impl_ns_dict, false);
AddIndirectUsedUnitsInStatement(cmn.function_code, impl_ns_dict, false);
if (cmn.return_value_type != null)
AddIndirectUsedUnitsForType(cmn.return_value_type, impl_ns_dict, false);
}
AddIndirectUsedUnitsInVariables(ctn.fields, impl_ns_dict, false);
}
foreach (common_namespace_function_node cnfn in cnn.functions)
{
AddIndirectUsedUnitsInVariables(cnfn.var_definition_nodes_list, impl_ns_dict, false);
AddIndirectUsedUnitsInStatement(cnfn.function_code, impl_ns_dict, true);
if (cnfn.return_value_type != null)
AddIndirectUsedUnitsForType(cnfn.return_value_type, impl_ns_dict, true);
}
AddIndirectUsedUnitsInVariables(cnn.variables, impl_ns_dict, true);
}
//заполнение списка подключаемых модулей
private void GetUsedUnits()
{
AddIndirectInteraceUsedUnits();
AddIndirectImplementationUsedUnits();
var c1 = unit.InterfaceUsedUnits.unit_uses_paths.Count;
var c2 = unit.ImplementationUsedUnits.unit_uses_paths.Count;
pcu_file.interface_uses_count = c1;
var incl_modules = new List(c1 + c2);
foreach (var used_unit in unit.InterfaceUsedUnits.OfType())
{
// Каждый модуль, зачем то, подключён сам к себе
// Конечно, записи в unit_uses_paths для такого подключения - нет
if (unit.SemanticTree == used_unit) continue;
// AddIndirectInteraceUsedUnits может добавлять один и тот же модуль несколько раз
if (used_units.ContainsKey(used_unit)) continue;
// раньше вместо пути модуля - брало имя его первого пространства имён
// и сразу стояла эта проверка. Если будет тут вылетать - наверное надо заменить throw на continue
if (used_unit.namespaces.Count == 0) throw new InvalidOperationException();
this.used_units.Add(used_unit, used_units.Count);
incl_modules.Add(unit.InterfaceUsedUnits.unit_uses_paths[used_unit]);
}
foreach (var used_unit in unit.ImplementationUsedUnits.OfType())
{
if (unit.SemanticTree == used_unit) continue;
if (used_units.ContainsKey(used_unit)) continue;
if (used_unit.namespaces.Count == 0) throw new InvalidOperationException();
this.used_units.Add(used_unit, used_units.Count);
incl_modules.Add(unit.ImplementationUsedUnits.unit_uses_paths[used_unit]);
}
used_units.Add(unit.SemanticTree as common_unit_node, -1);
pcu_file.incl_modules = incl_modules.ToArray();
pcu_file.used_namespaces = cun.used_namespaces.ToArray();
}
//получения индекса модуля в списке подключ. модулей
private int GetUnitToken(common_namespace_node ns)
{
return used_units[ns.cont_unit as common_unit_node];
}
private int GetTokenForNetEntity(FieldInfo val)
{
int off=0;
object o = tokens[val];
if (o != null) return (int)o;
DotNetNameRef dnnr = new DotNetNameRef();
dnnr.kind = DotNetKind.Field;
dnnr.name = val.Name;
dnnr.addit = new DotAdditInfo[0];
off = dot_net_name_list.Count;
tokens.Add(val, dot_net_name_list.Count);
dot_net_name_list.Add(dnnr);
return off;
}
private int GetTokenForNetEntity(MethodInfo val)
{
int off = 0;
//if (tokens.TryGetValue(val, out off)) return off;
object o = tokens[val];
if (o != null) return (int)o;
DotNetNameRef dnnr = new DotNetNameRef();
dnnr.kind = DotNetKind.Method;
dnnr.name = val.Name;
//if (val.GetParameters() != null)
//{
ParameterInfo[] prms = val.GetParameters();
if (prms != null)
{
if (val.Name != "op_Explicit")
dnnr.addit = new DotAdditInfo[prms.Length];
else dnnr.addit = new DotAdditInfo[prms.Length+1];
for (int i = 0; i < prms.Length; i++)
{
dnnr.addit[i] = new DotAdditInfo();
dnnr.addit[i].offset = GetTokenForNetEntity(prms[i].ParameterType);
}
if (val.Name == "op_Explicit")
{
dnnr.addit[prms.Length] = new DotAdditInfo();
dnnr.addit[prms.Length].offset = GetTokenForNetEntity(val.ReturnType);
}
}
else dnnr.addit = new DotAdditInfo[0];
//}
off = dot_net_name_list.Count;
tokens.Add(val, dot_net_name_list.Count);
dot_net_name_list.Add(dnnr);
return off;
}
private int GetTokenForNetEntity(ConstructorInfo val)
{
int off = 0;
//if (tokens.TryGetValue(val, out off)) return off;
object o = tokens[val];
if (o != null) return (int)o;
DotNetNameRef dnnr = new DotNetNameRef();
dnnr.kind = DotNetKind.Constructor;
dnnr.name = ".ctor";
//if (val.GetParameters() != null)
//{
ParameterInfo[] prms = val.GetParameters();
if (prms != null)
{
dnnr.addit = new DotAdditInfo[prms.Length];
for (int i = 0; i < prms.Length; i++)
{
dnnr.addit[i] = new DotAdditInfo();
dnnr.addit[i].offset = GetTokenForNetEntity(prms[i].ParameterType);
}
}
else dnnr.addit = new DotAdditInfo[0];
//}
off = dot_net_name_list.Count;
tokens.Add(val, dot_net_name_list.Count);
dot_net_name_list.Add(dnnr);
return off;
}
private int GetTokenForNetEntity(PropertyInfo val)
{
int off = 0;
//if (tokens.TryGetValue(val, out off)) return off;
object o = tokens[val];
if (o != null) return (int)o;
DotNetNameRef dnnr = new DotNetNameRef();
dnnr.kind = DotNetKind.Property;
dnnr.name = val.Name;
//if (val.GetParameters() != null)
//{
/*ParameterInfo[] prms = val.GetIndexParameters();
if (prms != null)
{
dnnr.addit = new DotAdditInfo[prms.Length];
for (int i = 0; i < prms.Length; i++)
{
dnnr.addit[i] = new DotAdditInfo();
dnnr.addit[i].offset = GetTokenForNetEntity(prms[i].ParameterType);
}
}
else*/
dnnr.addit = new DotAdditInfo[0];
//}
off = dot_net_name_list.Count;
tokens.Add(val, dot_net_name_list.Count);
dot_net_name_list.Add(dnnr);
return off;
}
private int GetTokenForNetEntity(Type val)
{
int off = 0;
//if (tokens.TryGetValue(val, out off)) return off;
object o = tokens[val];
if (o != null) return (int)o;
DotNetNameRef dnnr = new DotNetNameRef();
dnnr.kind = DotNetKind.Type;
if (val.FullName != null)
{
//(ssyy) для инстанций generic-ов пишем имя оригинала
if (val.IsGenericType && !val.IsGenericTypeDefinition)
dnnr.name = val.GetGenericTypeDefinition().FullName;
else
dnnr.name = val.FullName;
}
else if (val.IsGenericType && !val.IsGenericTypeDefinition)
dnnr.name = val.GetGenericTypeDefinition().FullName;
else
dnnr.name = val.Name;
// if (val.IsGenericType)
//{
Type[] tt = (val.IsGenericTypeDefinition)?
new Type[0]
:
val.GetGenericArguments();
dnnr.addit = new DotAdditInfo[tt.Length];
for (int i = 0; i < tt.Length; i++)
{
dnnr.addit[i] = new DotAdditInfo();
dnnr.addit[i].offset = GetTokenForNetEntity(tt[i]);
}
//}
off = dot_net_name_list.Count;
tokens.Add(val, dot_net_name_list.Count);
dot_net_name_list.Add(dnnr);
return off;
}
//получения ссылки на тип
private int GetTypeReference(type_node tn, ref byte is_def)
{
//если это откомпилир. тип
if (tn.semantic_node_type == semantic_node_type.compiled_type_node)
{
is_def = 0;
compiled_type_node ctn = (compiled_type_node)tn;
ImportedEntity ie = null;
if (ext_members.TryGetValue(ctn,out ie))
{
return ie.index*ie.GetSize();
}
//заполняем структуру в списке импортируемых сущностей
ie = new ImportedEntity();
ie.index = imp_entitles.Count;
ie.flag = ImportKind.DotNet;
ie.num_unit = GetAssemblyToken(ctn.compiled_type.Assembly);
//ie.offset = (int)ctn.compiled_type.MetadataToken;//токен для типа (уникален в сборке)
ie.offset = GetTokenForNetEntity(ctn.compiled_type);
int offset = imp_entitles.Count*ie.GetSize();
imp_entitles.Add(ie);//добавляем структуру
ext_members[ctn] = ie;
return offset;//возвращаем смещение относительно начала списка импорт. сущ-тей
}
else
{
int off = 0;
if (members.TryGetValue(tn, out off)) //если этот тип описан в этом модуле
{
is_def = 1;
return off;//возвращаем его смещение
}
//иначе он описан в другом модуле
is_def = 0;
ImportedEntity ie = null;
if (ext_members.TryGetValue(tn, out ie))
{
return ie.index * ie.GetSize();
}
common_type_node ctn = (common_type_node)tn;
ie = new ImportedEntity();
ie.flag = ImportKind.Common;
ie.num_unit = GetUnitToken(ctn.comprehensive_namespace);//получаем модуль
ie.offset = GetExternalOffset(ctn);//получаем смещение в другом модуле
int offset = imp_entitles.Count*ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[ctn] = ie;
return offset;
}
}
//ssyy
private int GetTemplateTypeReference(template_class tc, ref byte is_def)
{
int off = 0;
if (members.TryGetValue(tc, out off)) //если этот тип описан в этом модуле
{
is_def = 1;
return off;//возвращаем его смещение
}
//иначе он описан в другом модуле
is_def = 0;
ImportedEntity ie = null;
if (ext_members.TryGetValue(tc, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.Common;
ie.num_unit = GetUnitToken(tc.cnn);//получаем модуль
ie.offset = GetExternalOffset(tc);//получаем смещение в другом модуле
int offset = imp_entitles.Count * ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[tc] = ie;
return offset;
}
//\ssyy
//получения ссылки на откомпилированный тип
private int GetCompiledTypeReference(compiled_type_node ctn)
{
ImportedEntity ie = null;
if (ext_members.TryGetValue(ctn, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.index = imp_entitles.Count;
ie.flag = ImportKind.DotNet;
ie.num_unit = GetAssemblyToken(ctn.compiled_type.Assembly);
//ie.offset = (int)ctn.compiled_type.MetadataToken;
ie.offset = GetTokenForNetEntity(ctn.compiled_type);
int offset = imp_entitles.Count*ie.GetSize();
imp_entitles.Add(ie);
ext_members[ctn] = ie;
return offset;
}
//получение ссылки на тип, описанный в другом модуле
private int GetExtTypeReference(common_type_node ctn)
{
ImportedEntity ie = null;
if (ext_members.TryGetValue(ctn, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.Common;
ie.num_unit = GetUnitToken(ctn.comprehensive_namespace);
ie.offset = GetExternalOffset(ctn);
int offset = imp_entitles.Count*ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[ctn] = ie;
return offset;
}
//запись ссылки на тип
//флаг|смещение
private void WriteTypeReference(type_node type)
{
if (type == null)
{
bw.Write((System.Byte)255);
return;
}
//если это массив
if (type.semantic_node_type == semantic_node_type.simple_array)
{
WriteArrayType((simple_array)type);
return;
}
//если это указатель
//Наверно также надо сохранять Pointer,
// пока он востанавливается из таблицы nethelper.special_types
if (type.semantic_node_type == semantic_node_type.ref_type_node)
{
WritePointerType((ref_type_node)type);
return;
}
if (type.semantic_node_type == semantic_node_type.short_string)
{
WriteShortStringType((short_string_type_node)type);
return;
}
internal_interface ii=type.get_internal_interface(internal_interface_kind.unsized_array_interface);
//(ssyy) 18.05.2008 Убрал проверку на compiled_type_node
if (ii != null) //&& type.element_type is compiled_type_node)
{
array_internal_interface aii=(array_internal_interface)ii;
WriteUnsizedArrayType(type,aii);
return;
}
//Пишем параметр generic-типа
if (type.is_generic_parameter)
{
WriteGenericParameter(type as common_type_node);
return;
}
//Пишем инстанцию generic-типа
generic_instance_type_node gitn = type as generic_instance_type_node;
if (gitn != null)
{
WriteGenericTypeInstance(gitn);
return;
}
//Пишем инстанцию шаблонного класса
common_type_node c_t_n = type as common_type_node;
if (c_t_n != null && c_t_n.original_template != null)
{
WriteTemplateInstance(c_t_n);
return;
}
if (type is lambda_any_type_node)
{
bw.Write((byte)TypeKind.LambdaAnyType);
return;
}
byte is_def = 0;
int offset = GetTypeReference(type, ref is_def);
bw.Write(is_def); //пишем флаг импортируемый ли это тип или нет
bw.Write(offset); // сохраняем его смещение (это либо смещение в самом модуле, либо в списке импорт. сущностей)
}
private void WriteTypeReferenceWithDelay(common_type_node type)
{
if (!type_references.ContainsKey((int)bw.BaseStream.Position))
type_references.Add((int)bw.BaseStream.Position, type);
bw.Write((byte)0);
bw.Write(0);
}
private void WriteTypeList(List types)
{
bw.Write(types.Count);
foreach (type_node t_n in types)
{
WriteTypeReference(t_n);
}
}
//(ssyy) Сохранение инстанции шаблонного класса
private void WriteTemplateInstance(common_type_node cnode)
{
bw.Write((byte)TypeKind.TemplateInstance);
//Записать ссылку на шаблонный класс
WriteTemplateClassReference(cnode.original_template);
WriteTypeList(cnode.original_template.GetParamsList(cnode));
}
//(ssyy) Сохранение инстанции generic-класса
private void WriteGenericTypeInstance(generic_instance_type_node gitn)
{
bw.Write((byte)TypeKind.GenericInstance);
//Пишем ссылку на описание generic-типа
WriteTypeReference(gitn.original_generic);
WriteTypeList(gitn.instance_params);
}
private void WriteGenericNamespaceFunctionReference(generic_namespace_function_instance_node func)
{
bw.Write((byte)PCUConsts.common_namespace_generic);
WriteFunctionReference(func.original_function as common_namespace_function_node);
WriteTypeList(func.instance_params);
}
private void WriteGenericMethodReference(function_node meth)
{
common_method_node cnode = meth.original_function as common_method_node;
if (cnode != null)
{
bw.Write((byte)PCUConsts.common_method_generic);
WriteMethodReference(cnode);
}
else
{
compiled_function_node comp = meth.original_function as compiled_function_node;
bw.Write((byte)PCUConsts.compiled_method_generic);
WriteCompiledMethod(comp);
}
WriteTypeList(meth.get_generic_params_list());
}
//(ssyy) Сохранение параметров generic-типов
private void WriteGenericParameter(common_type_node type)
{
if (type.generic_type_container != null)
{
bw.Write((byte)TypeKind.GenericParameterOfType);
//Пишем ссылку на generic-тип, содержащий данный параметр
if (type.generic_type_container is common_type_node)
WriteTypeReferenceWithDelay(type.generic_type_container as common_type_node);
else
WriteTypeReference(type.generic_type_container as type_node);
}
else
{
common_method_node cnode = type.generic_function_container as common_method_node;
if (cnode != null)
{
bw.Write((byte)TypeKind.GenericParameterOfMethod);
WriteMethodReference(cnode);
}
else
{
common_namespace_function_node cnfn = type.generic_function_container as common_namespace_function_node;
bw.Write((byte)TypeKind.GenericParameterOfFunction);
WriteFunctionReferenceWithDelay(cnfn);
}
}
bw.Write(type.generic_param_index);
}
//сохранение типа-массив
private void WriteArrayType(simple_array type)
{
int offset = (int)bw.BaseStream.Position;
bw.Write((byte)TypeKind.Array);
WriteTypeReference(type.element_type);
bw.Write(type.length);
members[type] = offset;//это для нашего модуля
//ext_members[type] = offset;//это для других модулей
//VisitPropertyDefinition(type.default_property_node, offset);
}
//сохранение типа-указатель
private void WritePointerType(ref_type_node type)
{
bw.Write((byte)TypeKind.Pointer);
WriteTypeReference(type.pointed_type);
}
private void WriteShortStringType(short_string_type_node type)
{
bw.Write((byte)TypeKind.ShortString);
bw.Write(type.Length);
}
private void WriteBoundedArray(bounded_array_interface bai)
{
bw.Write((byte)TypeKind.BoundedArray);
VisitExpression(bai.ordinal_type_interface.lower_value);
VisitExpression(bai.ordinal_type_interface.upper_value);
WriteTypeReference(bai.element_type);
}
private void WriteUnsizedArrayType(type_node type,array_internal_interface aii)
{
bw.Write((byte)TypeKind.UnsizedArray);
WriteDebugInfo((type as SemanticTree.ILocated).Location);
WriteTypeReference(aii.element_type);
bw.Write(aii.rank);
}
//получение ссылки на функцию
private int GetFunctionReference(common_namespace_function_node fn, ref byte is_def)
{
int off = 0;
if (members.TryGetValue(fn, out off)) //если этот тип описан в этом модуле
{
is_def = 1;
return off;//возвращаем его смещение
}
is_def = 0;
ImportedEntity ie = null;
if (ext_members.TryGetValue(fn, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.Common;
ie.num_unit = GetUnitToken(fn.namespace_node);
ie.offset = GetExternalOffset(fn);
int offset = imp_entitles.Count*ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[fn] = ie;
return offset;
}
//получение ссылки на откомпилированный метод
private int GetCompiledMethod(compiled_function_node cfn)
{
ImportedEntity ie = null;
if (ext_members.TryGetValue(cfn, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.DotNet;
ie.num_unit = GetCompiledTypeReference(cfn.cont_type);
//ie.offset = (int)cfn.method_info.MetadataToken;
ie.offset = GetTokenForNetEntity(cfn.method_info);
int offset = imp_entitles.Count*ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[cfn] = ie;
return offset;
}
//получение ссылки на откомпилированный конструктор
private int GetCompiledConstructor(compiled_constructor_node ccn)
{
ImportedEntity ie = null;
if (ext_members.TryGetValue(ccn, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.DotNet;
ie.num_unit = GetCompiledTypeReference(ccn.compiled_type);
//ie.offset = (int)ccn.constructor_info.MetadataToken;
ie.offset = GetTokenForNetEntity(ccn.constructor_info);
int offset = imp_entitles.Count*ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[ccn] = ie;
return offset;
}
//получение ссылки на откомпилированное свойство
private int GetCompiledProperty(compiled_property_node cpn)
{
ImportedEntity ie = null;
if (ext_members.TryGetValue(cpn, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.DotNet;
ie.num_unit = GetCompiledTypeReference(cpn.compiled_comprehensive_type);
//ie.offset = (int)ccn.constructor_info.MetadataToken;
ie.offset = GetTokenForNetEntity(cpn.property_info);
int offset = imp_entitles.Count * ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[cpn] = ie;
return offset;
}
private void WriteFunctionReferenceWithDelay(common_namespace_function_node fn)
{
function_references.Add((int)bw.BaseStream.Position, fn);
bw.Write((byte)0);
bw.Write(0);
}
//сохранение ссылки на функцию
private void WriteFunctionReference(common_namespace_function_node fn)
{
generic_namespace_function_instance_node gi = fn as generic_namespace_function_instance_node;
if (gi != null)
{
WriteGenericNamespaceFunctionReference(gi);
return;
}
byte is_def = 0;
int offset=0;
if (fn.SpecialFunctionKind == SemanticTree.SpecialFunctionKind.None)
offset = GetFunctionReference(fn, ref is_def);
else
is_def = 2;
bw.Write(is_def);
if (fn.SpecialFunctionKind == SemanticTree.SpecialFunctionKind.None)
bw.Write(offset);
else
bw.Write((byte)fn.SpecialFunctionKind);
}
//сохранение ссылки на откомпилированный метод
private void WriteCompiledMethod(compiled_function_node cfn)
{
if (cfn.is_generic_function_instance)
{
bw.Write(PCUConsts.method_instance_as_compiled_function_node);
WriteGenericMethodReference(cfn);
return;
}
bw.Write(GetCompiledMethod(cfn));
}
private void WriteCompiledConstructor(compiled_constructor_node ccn)
{
bw.Write(GetCompiledConstructor(ccn));
}
private void WriteCompiledProperty(compiled_property_node cpn)
{
bw.Write(GetCompiledProperty(cpn));
}
private int GetVariableReference(namespace_variable nv, ref byte is_def)
{
int off = 0;
if (members.TryGetValue(nv, out off)) //если этот тип описан в этом модуле
{
is_def = 1;
return off;//возвращаем его смещение
}
if (!used_units.ContainsKey(nv.namespace_node.cont_unit as common_unit_node))
{
is_def = 1;
return -1;
}
is_def = 0;
ImportedEntity ie = null;
if (ext_members.TryGetValue(nv, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.Common;
ie.num_unit = GetUnitToken(nv.namespace_node);
ie.offset = GetExternalOffset(nv);
int offset = imp_entitles.Count*ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[nv] = ie;
return offset;
}
private int GetConstantReference(namespace_constant_definition nv, ref byte is_def)
{
int off = 0;
if (members.TryGetValue(nv, out off)) //если этот тип описан в этом модуле
{
is_def = 1;
return off;//возвращаем его смещение
}
if (!used_units.ContainsKey(nv.comprehensive_namespace.cont_unit as common_unit_node))
{
is_def = 1;
return -1;
}
is_def = 0;
ImportedEntity ie = null;
if (ext_members.TryGetValue(nv, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.Common;
ie.num_unit = GetUnitToken(nv.comprehensive_namespace);
ie.offset = GetExternalOffset(nv);
int offset = imp_entitles.Count*ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[nv] = ie;
return offset;
}
private int GetCompiledVariable(compiled_variable_definition cvd)
{
ImportedEntity ie = null;
if (ext_members.TryGetValue(cvd, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.DotNet;
ie.num_unit = GetCompiledTypeReference(cvd.cont_type);
//ie.offset = (int)cvd.compiled_field.MetadataToken;
ie.offset = GetTokenForNetEntity(cvd.compiled_field);
ie.index = imp_entitles.Count;
int offset = imp_entitles.Count*ie.GetSize();
imp_entitles.Add(ie);
ext_members[cvd] = ie;
return offset;
}
private Hashtable var_positions = new Hashtable();
private Hashtable const_positions = new Hashtable();
private void SaveVariableReferencePosition(namespace_variable nv)
{
List offs = (List)var_positions[nv];
if (offs == null)
{
offs = new List();
var_positions[nv] = offs;
}
offs.Add((int)bw.BaseStream.Position);
}
private void SaveConstantReferencePosition(namespace_constant_definition nv)
{
List offs = (List)const_positions[nv];
if (offs == null)
{
offs = new List();
const_positions[nv] = offs;
}
offs.Add((int)bw.BaseStream.Position);
}
private void WriteVariablePositions()
{
int tmp = (int)bw.BaseStream.Position;
foreach (namespace_variable nv in var_positions.Keys)
{
List offs = (List)var_positions[nv];
byte is_def = 0;
for (int i = 0; i < offs.Count; i++)
{
bw.Seek(offs[i], SeekOrigin.Begin);
bw.Write(GetVariableReference(nv,ref is_def));
}
}
bw.BaseStream.Position = tmp;
}
private void WriteConstantPositions()
{
int tmp = (int)bw.BaseStream.Position;
foreach (namespace_constant_definition nv in const_positions.Keys)
{
List offs = (List)const_positions[nv];
byte is_def = 0;
for (int i = 0; i < offs.Count; i++)
{
bw.Seek(offs[i], SeekOrigin.Begin);
bw.Write(GetConstantReference(nv,ref is_def));
}
}
bw.BaseStream.Position = tmp;
}
private void WriteVariableReference(namespace_variable nv)
{
byte is_def = 0;
int offset = GetVariableReference(nv, ref is_def);
bw.Write(is_def);
if (offset == -1) SaveVariableReferencePosition(nv);
bw.Write(offset);
}
private void WriteConstantReference(namespace_constant_definition nv)
{
byte is_def = 0;
int offset = GetConstantReference(nv, ref is_def);
bw.Write(is_def);
if (offset == -1) SaveConstantReferencePosition(nv);
bw.Write(offset);
}
private void WriteCompiledVariable(compiled_variable_definition cvd)
{
bw.Write(GetCompiledVariable(cvd));
}
private int GetEventReference(event_node ev, ref byte is_def)
{
if (ev.semantic_node_type == semantic_node_type.compiled_event)
{
is_def = 2;
compiled_event cev = (compiled_event)ev;
ImportedEntity ie = null;
if (ext_members.TryGetValue(cev, out ie))
{
return ie.index * ie.GetSize();
}
//заполняем структуру в списке импортируемых сущностей
ie = new ImportedEntity();
ie.index = imp_entitles.Count;
ie.flag = ImportKind.DotNet;
ie.num_unit = GetAssemblyToken(cev.event_info.DeclaringType.Assembly);
//ie.offset = (int)ctn.compiled_type.MetadataToken;//токен для типа (уникален в сборке)
ie.offset = GetTokenForNetEntity(cev.event_info.DeclaringType);
int offset = imp_entitles.Count * ie.GetSize();
imp_entitles.Add(ie);//добавляем структуру
ext_members[cev] = ie;
return offset;//возвращаем смещение относительно начала списка импорт. сущ-тей
}
else if (ev.semantic_node_type == semantic_node_type.common_namespace_event)
{
int off = 0;
if (members.TryGetValue(ev, out off)) //если этот тип описан в этом модуле
{
is_def = 4;
return off;//возвращаем его смещение
}
is_def = 3;
ImportedEntity ie = null;
if (ext_members.TryGetValue(ev, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.Common;
ie.num_unit = GetUnitReference((ev as common_namespace_event).namespace_node);
ie.offset = GetExternalOffset(ev);
int offset = imp_entitles.Count * ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[ev] = ie;
return offset;
}
else
{
int off = 0;
if (members.TryGetValue(ev, out off)) //если этот тип описан в этом модуле
{
is_def = 1;
return off;//возвращаем его смещение
}
is_def = 0;
ImportedEntity ie = null;
if (ext_members.TryGetValue(ev, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.Common;
ie.num_unit = GetExtTypeReference((ev as common_event).cont_type);
ie.offset = GetExternalOffset(ev);
int offset = imp_entitles.Count * ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[ev] = ie;
return offset;
}
}
private int GetFieldReference(class_field field, ref byte is_def)
{
int off = 0;
if (members.TryGetValue(field, out off)) //если этот тип описан в этом модуле
{
is_def = 1;
return off;//возвращаем его смещение
}
is_def = 0;
ImportedEntity ie = null;
if (ext_members.TryGetValue(field, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.Common;
ie.num_unit = GetExtTypeReference(field.cont_type);
ie.offset = GetExternalOffset(field);
int offset = imp_entitles.Count*ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[field] = ie;
return offset;
}
private void WriteFieldReference(class_field field)
{
generic_instance_type_node gitn = field.cont_type as generic_instance_type_node;
if (gitn != null)
{
bw.Write(PCUConsts.generic_field);
WriteGenericTypeInstance(gitn);
if (gitn is compiled_generic_instance_type_node)
{
WriteCompiledVariable(
gitn.get_member_definition(field) as compiled_variable_definition
);
}
else
{
WriteFieldReference(gitn.get_member_definition(field) as class_field);
}
return;
}
common_type_node ctnode = field.comperehensive_type as common_type_node;
if (ctnode != null && ctnode.original_template != null)
{
bw.Write(PCUConsts.template_field); //т.е. пишем на место is_def
WriteTemplateInstance(ctnode);
bw.Write(ctnode.fields.IndexOf(field));
return;
}
byte is_def = 0;
int offset = GetFieldReference(field, ref is_def);
bw.Write(is_def);
bw.Write(offset);
}
private int GetMethodReference(common_method_node meth, ref byte is_def)
{
int off = 0;
if (members.TryGetValue(meth, out off)) //если этот тип описан в этом модуле
{
is_def = 1;
return off;//возвращаем его смещение
}
is_def = 0;
ImportedEntity ie = null;
if (ext_members.TryGetValue(meth, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.Common;
ie.num_unit = GetExtTypeReference(meth.cont_type);
ie.offset = GetExternalOffset(meth);
int offset = imp_entitles.Count*ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[meth] = ie;
return offset;
}
private void WriteEventReference(event_node ev)
{
byte is_def = 0;
int offset = GetEventReference(ev, ref is_def);
bw.Write(is_def);
bw.Write(offset);
}
private void WriteMethodReference(common_method_node meth)
{
if (meth.comperehensive_type.is_generic_parameter)
{
bw.Write(PCUConsts.generic_param_ctor);
WriteGenericParameter(meth.comperehensive_type as common_type_node);
return;
}
generic_method_instance_node gmin = meth as generic_method_instance_node;
if (gmin != null)
{
WriteGenericMethodReference(gmin);
return;
}
generic_instance_type_node gitn = meth.comperehensive_type as generic_instance_type_node;
if (gitn != null)
{
if (gitn is common_generic_instance_type_node)
{
bw.Write(PCUConsts.generic_meth);
WriteGenericTypeInstance(gitn);
WriteMethodReference(gitn.get_member_definition(meth) as common_method_node);
return;
}
if (meth.is_constructor)
{
bw.Write(PCUConsts.generic_ctor);
WriteGenericTypeInstance(gitn);
WriteCompiledConstructor(
gitn.get_member_definition(meth) as compiled_constructor_node
);
return;
}
bw.Write(PCUConsts.generic_meth);
WriteGenericTypeInstance(gitn);
WriteCompiledMethod(
gitn.get_member_definition(meth) as compiled_function_node
);
return;
}
common_type_node ctnode = meth.comperehensive_type as common_type_node;
if (ctnode != null && ctnode.original_template != null)
{
bw.Write(PCUConsts.template_meth); //т.е. пишем на место is_def
WriteTemplateInstance(ctnode);
bw.Write(ctnode.methods.IndexOf(meth));
return;
}
//generic_namespace_function_instance_node gnfin = meth as generic_namespace_function_instance_node;
//if (gnfin != null)
//{
// WriteGenericNamespaceFunctionReference(gnfin);
// return;
//}
byte is_def = 0;
int offset = GetMethodReference(meth, ref is_def);
bw.Write(is_def);
bw.Write(offset);
}
private void WriteTemplateClassReference(template_class tc)
{
byte is_def = 0;
int t_offset = GetTemplateTypeReference(tc, ref is_def);
bw.Write(is_def); //пишем флаг импортируемый ли это тип или нет
bw.Write(t_offset); // сохраняем его смещение (это либо смещение в самом модуле, либо в списке импорт. сущностей)
}
private int GetPropertyReference(common_property_node prop, ref byte is_def)
{
int off = 0;
if (members.TryGetValue(prop, out off)) //если этот тип описан в этом модуле
{
is_def = 1;
return off;//возвращаем его смещение
}
is_def = 0;
ImportedEntity ie = null;
if (ext_members.TryGetValue(prop, out ie))
{
return ie.index * ie.GetSize();
}
ie = new ImportedEntity();
ie.flag = ImportKind.Common;
ie.num_unit = GetExtTypeReference(prop.common_comprehensive_type);
ie.offset = GetExternalOffset(prop);
int offset = imp_entitles.Count * ie.GetSize();
ie.index = imp_entitles.Count;
imp_entitles.Add(ie);
ext_members[prop] = ie;
return offset;
}
private void WriteMethodReference(function_node fn)
{
if (fn is common_method_node)
{
bw.Write((byte)0);
WriteMethodReference(fn as common_method_node);
}
else if (fn is compiled_constructor_node)
{
bw.Write((byte)1);
bw.Write(GetCompiledConstructor(fn as compiled_constructor_node));
}
else if (fn is compiled_function_node)
{
bw.Write((byte)2);
bw.Write(GetCompiledMethod(fn as compiled_function_node));
}
}
private void WritePropertyReference(property_node pn)
{
if (pn is common_property_node)
{
bw.Write((byte)0);
WritePropertyReference(pn as common_property_node);
}
else if (pn is compiled_property_node)
{
bw.Write((byte)1);
bw.Write(GetCompiledProperty(pn as compiled_property_node));
}
}
private void WriteFieldReference(var_definition_node vdn)
{
if (vdn is class_field)
{
bw.Write((byte)0);
WriteFieldReference(vdn as class_field);
}
else if (vdn is compiled_variable_definition)
{
bw.Write((byte)1);
bw.Write(GetCompiledVariable(vdn as compiled_variable_definition));
}
}
private void WritePropertyReference(common_property_node prop)
{
//ssyy
generic_instance_type_node gitn = prop.common_comprehensive_type as generic_instance_type_node;
if (gitn != null)
{
bw.Write(PCUConsts.generic_prop);
WriteGenericTypeInstance(gitn);
if (gitn is compiled_generic_instance_type_node)
{
WriteCompiledProperty(
gitn.get_member_definition(prop) as compiled_property_node
);
}
else
{
WritePropertyReference(gitn.get_member_definition(prop) as common_property_node);
}
return;
}
common_type_node ctnode = prop.common_comprehensive_type as common_type_node;
if (ctnode != null && ctnode.original_template != null)
{
bw.Write(PCUConsts.template_prop); //т.е. пишем на место is_def
WriteTemplateInstance(ctnode);
bw.Write(ctnode.properties.IndexOf(prop));
return;
}
//\ssyy
byte is_def = 0;
int offset = GetPropertyReference(prop, ref is_def);
bw.Write(is_def);
bw.Write(offset);
}
//сохранение пространства имен
private void WriteUnit()
{
SavePosition(cur_cnn);
bw.Write(cur_cnn.namespace_name);
WriteDebugInfo(cur_cnn.Location);
}
//сохранение констант
private void VisitConstantDefinitions()
{
bw.Write(cur_cnn.constants.Count);
for (int i = 0; i < cur_cnn.constants.Count; i++)
VisitConstantDefinition(cur_cnn.constants[i]);
}
//сохранение указателей на тип
private void VisitRefTypeDefinitions()
{
bw.Write(cur_cnn.ref_types.Count);
for (int i = 0; i < cur_cnn.ref_types.Count; i++)
VisitRefTypeDefinition(cur_cnn.ref_types[i]);
}
private void VisitRefTypeDefinition(ref_type_node node)
{
if (is_interface == true)
SavePositionAndConstPool(node);
else
SavePositionAndImplementationPool(node);
bw.Write((byte)node.semantic_node_type);
bw.Write(is_interface);
if (is_interface == true)
bw.Write(GetNameIndex(node));
else
bw.Write(node.name);
//bw.Write(GetUnitReference(node.comprehensive_namespace));
WriteTypeReference(node.pointed_type);
WriteDebugInfo(node.loc);
}
//сохранение константы
private void VisitConstantDefinition(namespace_constant_definition cnst)
{
if (is_interface == true)
SavePositionAndConstPool(cnst);
else
SavePositionAndImplementationPool(cnst);
bw.Write((byte)cnst.semantic_node_type);
bw.Write(is_interface);
if (is_interface == true)
bw.Write(GetNameIndex(cnst));
else
bw.Write(cnst.name);
bw.Write(GetUnitReference(cnst.comprehensive_namespace));
WriteTypeReference(cnst.type);
SaveExpressionAndOffset(cnst.const_value);
bw.Write(0);
//VisitExpression(cnst.const_value);
WriteDebugInfo(cnst.loc);
}
//сохранение переменных модуля
private void VisitVariableDefinitions()
{
bw.Write(cur_cnn.variables.Count);
for (int i=0; i labels)
{
bw.Write(labels.Count);
foreach (label_node ln in labels)
{
VisitLabelDeclaration(ln);
}
}
//сохранение шаблонных классов
private void VisitTemplateClasses()
{
bw.Write(cur_cnn.templates.Count);
for (int i = 0; i < cur_cnn.templates.Count; i++)
VisitTemplateClassDefinition(cur_cnn.templates[i]);
}
//сохранение синонимов типов
private void VisitTypeSynonyms()
{
bw.Write(cur_cnn.type_synonyms.Count);
for (int i = 0; i < cur_cnn.type_synonyms.Count; i++)
VisitTypeSynonym(cur_cnn.type_synonyms[i]);
}
private void SaveAttributes(attributes_list attrs, List offs)
{
int tmp = (int)bw.BaseStream.Position;
for (int i=0; i tpars)
{
foreach (common_type_node par in tpars)
{
//class - value
if (par.is_class)
{
bw.Write((byte)GenericParamKind.Class);
}
else
{
if (par.is_value)
{
bw.Write((byte)GenericParamKind.Value);
}
else
{
bw.Write((byte)GenericParamKind.None);
}
}
//предок
WriteTypeReference(par.base_type);
//интерфейсы
WriteImplementingInterfaces(par);
//конструктор по умолчанию
if (par.methods.Count > 0)
{
bw.Write((byte)1);
}
else
{
bw.Write((byte)0);
}
//if (CanWriteObject(par.runtime_initialization_marker))
//{
// WriteFieldReference(par.runtime_initialization_marker);
//}
}
}
private int GetSizeOfReference(type_node tn)
{
if (tn == null)
return sizeof(byte);
if (tn.is_generic_parameter)
{
return sizeof(byte) + GetSizeOfReference(tn.generic_type_container as type_node) + sizeof(int);
}
generic_instance_type_node gitn = tn as generic_instance_type_node;
if (gitn != null)
{
int rez = sizeof(byte) + GetSizeOfReference(gitn.original_generic) + sizeof(int);
foreach (type_node par in gitn.instance_params)
{
rez += GetSizeOfReference(par);
}
return rez;
}
internal_interface ii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface);
if (ii != null)
{
return sizeof(byte) + 4 * 4 + GetSizeOfReference(tn.element_type) + 4;
}
return sizeof(byte) + sizeof(int);
}
private void VisitTypeDefinition(common_type_node type)
{
int offset = 0;
if (class_info.ContainsKey(type))
return;
if (is_interface == true) offset = SavePositionAndConstPool(type);
else offset = SavePositionAndImplementationPool(type);
bw.Write((byte)type.semantic_node_type);
bw.Write(is_interface);
bw.Write(type_entity_index++);
if (is_interface == true)
bw.Write(GetNameIndex(type));
else
bw.Write(type.name);
if (type.IsInterface)
{
bw.Write((byte)1);
}
else
{
bw.Write((byte)0);
}
if (type.is_class)
{
bw.Write((byte)1);
}
else
{
bw.Write((byte)0);
}
if (type.IsDelegate)
{
bw.Write((byte)1);
}
else
{
bw.Write((byte)0);
}
//Является ли тип описанием дженерика
if (type.is_generic_type_definition)
{
bw.Write((byte)1);
//Число типов-параметров
bw.Write(type.generic_params.Count);
//Имена параметров
foreach (common_type_node par in type.generic_params)
{
bw.Write(par.name);
}
}
else
{
bw.Write((byte)0);
}
bw.Write((byte)type.type_special_kind);
int base_class_off = (int)bw.BaseStream.Position;
bw.Seek(GetSizeOfReference(type.base_type), SeekOrigin.Current);
bw.Write(type.internal_is_value);
//Пишем поддерживаемые интерфейсы
//eto nepravilno!!! a vdrug bazovye interfejsy eshe ne projdeny.
//WriteImplementingInterfaces(type);
int interface_impl_off = (int)bw.BaseStream.Position;
int seek_off = sizeof(int);
for (int k = 0; k < type.ImplementingInterfaces.Count; k++)
seek_off += GetSizeOfReference(type.ImplementingInterfaces[k] as TreeRealization.type_node);
bw.Seek(seek_off, SeekOrigin.Current);
bw.Write((byte)type.type_access_level);
bw.Write(type.IsSealed);
bw.Write(type.IsAbstract);
bw.Write(type.IsStatic);
bw.Write(type.IsPartial);
if (type.type_special_kind == SemanticTree.type_special_kind.diap_type)
{
ordinal_type_interface oti = type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface;
VisitExpression(oti.lower_value);
VisitExpression(oti.upper_value);
}
if (type.is_generic_type_definition)
{
//Ограничители параметров
WriteTypeParamsEliminations(type.generic_params);
}
if (CanWriteObject(type.element_type))
WriteTypeReference(type.element_type);
bw.Write(GetUnitReference(type.comprehensive_namespace));
SaveOffsetForAttribute(type);
bw.Write(0);//attributes;
if (type.default_property != null)
bw.Write((byte)1);
else
bw.Write((byte)0);
int def_prop_off = (int)bw.BaseStream.Position;
if (type.default_property != null)
bw.Write(0);//default_property
WriteDebugInfo(type.loc);
//заполнение списка имен членов этого класса
int num = type.const_defs.Count + type.fields.Count + type.properties.Count + type.methods.Count + type.events.Count;
NameRef[] names = new NameRef[num];
int pos = (int)bw.BaseStream.Position;
int int_size = System.Runtime.InteropServices.Marshal.SizeOf(typeof(int));
int size = int_size;
int i = 0, j = 0;
for (i = j; i < type.const_defs.Count + j; i++)
{
names[i] = new NameRef(type.const_defs[i - j].name, i);
name_pool[type.const_defs[i - j]] = names[i];
size += names[i].Size;
}
j = i;
for (i = j; i < type.fields.Count + j; i++)
{
names[i] = new NameRef(type.fields[i - j].name, i, convert_field_access_level(type.fields[i - j].field_access_level), type.fields[i - j].semantic_node_type);
name_pool[type.fields[i - j]] = names[i];
names[i].is_static = type.fields[i - j].polymorphic_state == SemanticTree.polymorphic_state.ps_static;
size += names[i].Size;
}
j = i;
for (i = j; i < type.properties.Count + j; i++)
{
names[i] = new NameRef(type.properties[i - j].name, i, convert_field_access_level(type.properties[i - j].field_access_level), type.properties[i - j].semantic_node_type);
name_pool[type.properties[i - j]] = names[i];
names[i].is_static = type.properties[i - j].polymorphic_state == SemanticTree.polymorphic_state.ps_static;
size += names[i].Size;
}
j = i;
for (i = j; i < type.methods.Count + j; i++)
{
names[i] = new NameRef(type.methods[i - j].name, i, convert_field_access_level(type.methods[i - j].field_access_level), type.methods[i - j].semantic_node_type);
name_pool[type.methods[i - j]] = names[i];
if (type.methods[i - j].is_overload)
names[i].symbol_kind = symbol_kind.sk_overload_function;
names[i].virtual_slot = type.methods[i - j].newslot_awaited || type.methods[i - j].polymorphic_state == SemanticTree.polymorphic_state.ps_virtual || type.methods[i - j].polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract || type.methods[i - j].is_constructor;
names[i].is_static = type.methods[i - j].polymorphic_state == SemanticTree.polymorphic_state.ps_static && !type.methods[i - j].is_constructor;
size += names[i].Size;
}
j = i;
for (i = j; i < type.events.Count + j; i++)
{
names[i] = new NameRef(type.events[i - j].name, i, convert_field_access_level(type.events[i - j].field_access_level), type.events[i - j].semantic_node_type);
name_pool[type.events[i - j]] = names[i];
size += names[i].Size;
}
bw.BaseStream.Seek(size, SeekOrigin.Current);
/*VisitConstantInTypeDefinitions(type);
VisitFieldDefinitions(type);
VisitMethodDefinitions(type);
VisitPropertyDefinitions(type);
int tmp = (int)bw.BaseStream.Position;
if (type.default_property != null)
{
bw.Seek(def_prop_off, SeekOrigin.Begin);
bw.Write(GetMemberOffset(type.default_property));
bw.Seek(tmp, SeekOrigin.Begin);
}
bw.BaseStream.Seek(pos,SeekOrigin.Begin);
bw.Write(names.Length);
for (i=0; i") != -1)
{
VisitStatement(new empty_statement(null));
}
else
{
VisitStatement(meth.function_code);
}
if (meth.overrided_method != null)
WriteMethodReference(meth.overrided_method);
//}
}
//(ssyy) Может быть, соединить следующие 2 метода в один?
private void VisitFunctionImplementation(common_namespace_function_node func)
{
foreach (common_in_function_function_node nested in func.functions_nodes_list)
VisitNestedFunctionImplementation(nested);
//(ssyy) метки
VisitLabelDeclarations(func.label_nodes_list);
FixupCode(func);
if (func.name.IndexOf("") != -1)
VisitStatement(new empty_statement(null));
else
VisitStatement(func.function_code);
}
private void VisitNestedFunctionImplementation(common_in_function_function_node func)
{
foreach (common_in_function_function_node nested in func.functions_nodes_list)
VisitNestedFunctionImplementation(nested);
//(ssyy) метки
VisitLabelDeclarations(func.label_nodes_list);
FixupCode(func);
VisitStatement(func.function_code);
}
private void VisitFunctionConstant(function_constant_definition cnst)
{
SavePosition(cnst);
bw.Write(cnst.name);
SaveExpressionAndOffset(cnst.const_value);
bw.Write(0);
//VisitExpression((expression_node)cnst.const_value);
}
//сохранение лок. переменной
private void VisitLocalVariable(local_variable var)
{
SavePosition(var);
//bw.Write((byte)var.semantic_node_type);
bw.Write(var.name);
WriteTypeReference(var.type);
bw.Write(var.is_used_as_unlocal);
if (CanWriteObject(var.inital_value))
{
SaveExpressionAndOffset(var.inital_value);
bw.Write(0);
//VisitExpression((expression_node)var.inital_value);
}
}
//сохранение параметра
private void VisitParameter(common_parameter p)
{
SavePosition(p);
bw.Write((byte)p.semantic_node_type);
if (p.name == null)
bw.Write("");
else
bw.Write(p.name);
WriteTypeReference(p.type);
bw.Write((byte)p.concrete_parameter_type);
bw.Write(p.is_used_as_unlocal);
bw.Write(p.is_params);
if (CanWriteObject(p.default_value))
{
SaveExpressionAndOffset(p.default_value);
bw.Write(0);
//VisitExpression((expression_node)var.inital_value);
}
SaveOffsetForAttribute(p);
bw.Write(0);//attributes;
}
//сохранение вложенной функций
private void VisitNestedFunctionDefinition(common_in_function_function_node func)
{
SavePosition(func);
bw.Write((byte)func.semantic_node_type);
bw.Write(func.name);
if (func.return_value_type == null) bw.Write((byte)0);
else
{
bw.Write((byte)1);
WriteTypeReference(func.return_value_type);
VisitLocalVariable(func.return_variable);
}
bw.Write(func.parameters.Count);
foreach (common_parameter p in func.parameters)
VisitParameter(p);
bw.Write(0);
bw.Write(func.is_forward);
bw.Write(func.is_overload);
bw.Write(func.num_of_default_variables);
bw.Write(func.num_of_for_cycles);
bw.Write(func.var_definition_nodes_list.Count);
foreach (local_variable var in func.var_definition_nodes_list)
if (var != func.return_variable) VisitLocalVariable(var);
bw.Write(func.constants.Count);
foreach (function_constant_definition cnst in func.constants)
VisitFunctionConstant(cnst);
bw.Write(func.functions_nodes.Length);
foreach (common_in_function_function_node nest_func in func.functions_nodes_list)
VisitNestedFunctionDefinition(nest_func);
WriteDebugInfo(func.loc);
SaveCodeReference(func);
bw.Write(0);
}
//сохранение отлад. информации
private void WriteDebugInfo(SemanticTree.ILocation loc)
{
WriteDebugInfo(bw,loc);
}
//сохранение отлад. информации
private void WriteDebugInfo(BinaryWriter bw,SemanticTree.ILocation loc)
{
if (pcu_file.IncludeDebugInfo)
{
if (loc != null)
{
bw.Write(loc.begin_line_num);
bw.Write(loc.begin_column_num);
bw.Write(loc.end_line_num);
bw.Write(loc.end_column_num);
}
else
{
bw.Write((int)-1);
bw.Write((int)-1);
bw.Write((int)-1);
bw.Write((int)-1);
}
}
}
private bool CanWriteObject(object obj)
{
if (obj == null)
bw.Write((byte)0);
else
bw.Write((byte)1);
return obj != null;
}
private void VisitTryBlock(try_block tryblock)
{
VisitStatement(tryblock.try_statements);
if (CanWriteObject(tryblock.finally_statements))
VisitStatement(tryblock.finally_statements);
bw.Write(tryblock.filters.Count);
foreach (exception_filter ef in tryblock.filters)
{
if (CanWriteObject(ef.filter_type))
WriteTypeReference(ef.filter_type);
if (CanWriteObject(ef.exception_var))
{
VisitLocalBlockVariable(ef.exception_var.var);
VisitLocalBlockVariableReference(ef.exception_var);
}
VisitStatement(ef.exception_handler);
WriteDebugInfo(ef.location);
}
}
private void VisitStatement(statement_node sn)
{
if (sn is expression_node)
{
VisitExpression((expression_node)sn);
WriteDebugInfo(sn.location);
return;
}
bw.Write((byte)sn.semantic_node_type);
switch (sn.semantic_node_type) {
case semantic_node_type.if_node : VisitIf((if_node)sn); break;
case semantic_node_type.while_node : VisitWhile((while_node)sn); break;
case semantic_node_type.repeat_node : VisitRepeat((repeat_node)sn); break;
case semantic_node_type.for_node : VisitFor((for_node)sn); break;
case semantic_node_type.statements_list : VisitStatementList((statements_list)sn); break;
case semantic_node_type.empty_statement : VisitEmpty((empty_statement)sn); break;
case semantic_node_type.return_node : VisitReturnNode((return_node)sn); break;
case semantic_node_type.switch_node : VisitSwitchNode((switch_node)sn); break;
case semantic_node_type.external_statement_node: VisitExternalStatementNode((external_statement)sn); break;
case semantic_node_type.throw_statement: VisitThrow((throw_statement_node)sn); break;
case semantic_node_type.runtime_statement: VisitRuntimeStatement((runtime_statement)sn); break;
case semantic_node_type.try_block: VisitTryBlock((try_block)sn); break;
case semantic_node_type.labeled_statement: VisitLabeledStatement((labeled_statement)sn); break;
case semantic_node_type.goto_statement: VisitGoto((goto_statement)sn); break;
case semantic_node_type.foreach_node: VisitForeach((foreach_node)sn); break;
case semantic_node_type.lock_statement: VisitLock((lock_statement)sn); break;
case semantic_node_type.rethrow_statement: VisitRethrow((rethrow_statement_node)sn); break;
case semantic_node_type.pinvoke_node : VisitPInvokeStatement((pinvoke_statement)sn); break;
}
WriteDebugInfo(sn.location);
}
private void VisitForeachBreak(foreach_break_node sn)
{
}
private void VisitForeachContinue(foreach_continue_node sn)
{
}
private void VisitRethrow(rethrow_statement_node sn)
{
}
private void VisitForeach(foreach_node fn)
{
//VisitVariableDefinition(fn.ident);
bw.Write(GetMemberOffset(fn.ident));
VisitExpression(fn.in_what);
VisitStatement(fn.what_do);
}
private void VisitLock(lock_statement node)
{
VisitExpression(node.lock_object);
VisitStatement(node.body);
}
private void VisitLabeledStatement(labeled_statement ls)
{
bw.Write(members[ls.label]);
WriteDebugInfo(ls.location);
VisitStatement(ls.statement);
}
private void VisitGoto(goto_statement gs)
{
bw.Write(members[gs.label]);
WriteDebugInfo(gs.location);
}
private void VisitThrow(throw_statement_node stmt)
{
VisitExpression(stmt.excpetion);
}
private void VisitIf(if_node stmt)
{
VisitExpression(stmt.condition);
VisitStatement(stmt.then_body);
if (stmt.else_body != null)
{
bw.Write((byte)1);
VisitStatement(stmt.else_body);
}
else
{
bw.Write((byte)0);
}
}
private void VisitWhile(while_node stmt)
{
VisitExpression(stmt.condition);
VisitStatement(stmt.body);
}
private void VisitRepeat(repeat_node stmt)
{
VisitStatement(stmt.body);
VisitExpression(stmt.condition);
}
private void VisitFor(for_node stmt)
{
if(CanWriteObject(stmt.initialization_statement))
VisitStatement(stmt.initialization_statement);
VisitExpression(stmt.while_expr);
if (CanWriteObject(stmt.init_while_expr))
VisitExpression(stmt.init_while_expr);
VisitStatement(stmt.increment_statement);
VisitStatement(stmt.body);
bw.Write(stmt.bool_cycle);
}
private void VisitSwitchNode(switch_node stmt)
{
VisitExpression(stmt.condition);
bw.Write(stmt.case_variants.Count);
foreach (case_variant_node cvn in stmt.case_variants)
VisitCaseVariantNode(cvn);
if (stmt.default_statement != null)
{
bw.Write((byte)1);
VisitStatement(stmt.default_statement);
}
else
bw.Write((byte)0);
}
private void VisitCaseVariantNode(case_variant_node cvn)
{
bw.Write(cvn.case_constants.Count);
foreach (constant_node cnst in cvn.case_constants)
VisitExpression(cnst);
bw.Write(cvn.case_ranges.Count);
foreach (case_range_node crn in cvn.case_ranges)
{
VisitExpression(crn.lower_bound);
VisitExpression(crn.high_bound);
}
VisitStatement(cvn.case_statement);
}
private void VisitRuntimeStatement(runtime_statement rts)
{
bw.Write(((int)(rts.runtime_statement_type)));
}
private void VisitExternalStatementNode(external_statement stmt)
{
bw.Write(stmt.module_name);
bw.Write(stmt.name);
}
private void VisitPInvokeStatement(pinvoke_statement stmt)
{
}
private void VisitStatementList(statements_list stmt)
{
bw.Write(stmt.local_variables.Count);
foreach (local_block_variable lv in stmt.local_variables)
VisitLocalBlockVariable(lv);
bw.Write(stmt.statements.Count);
foreach (statement_node sn in stmt.statements)
VisitStatement(sn);
WriteDebugInfo(stmt.LeftLogicalBracketLocation);
WriteDebugInfo(stmt.RightLogicalBracketLocation);
}
private void VisitLocalBlockVariable(local_block_variable lv)
{
SavePosition(lv);
bw.Write(lv.name);
WriteTypeReference(lv.type);
if(CanWriteObject(lv.inital_value))
{
SaveExpressionAndOffset(lv.inital_value);
bw.Write(0);
//VisitExpression(lv.inital_value);
}
WriteDebugInfo(lv.loc);
}
private void VisitEmpty(empty_statement stmt)
{
}
private void VisitIsNode(is_node node)
{
VisitExpression(node.left);
WriteTypeReference(node.right);
}
private void VisitAsNode(as_node node)
{
VisitExpression(node.left);
WriteTypeReference(node.right);
}
private void VisitTypeOfOperator(typeof_operator node)
{
WriteTypeReference(node.oftype);
}
private void VisitSizeOfOperator(sizeof_operator node)
{
WriteTypeReference(node.oftype);
}
private void VisitArrayConst(array_const node)
{
bw.Write(node.element_values.Count);
foreach (constant_node cn in node.element_values)
VisitExpression(cn);
WriteTypeReference(node.type);
}
private void VisitArrayInitializer(array_initializer node)
{
bw.Write(node.element_values.Count);
foreach (expression_node en in node.element_values)
VisitExpression(en);
WriteTypeReference(node.type);
}
private void VisitRecordConst(record_constant node)
{
bw.Write(node.field_values.Count);
foreach (constant_node cn in node.field_values)
VisitExpression(cn);
WriteTypeReference(node.type);
}
private void VisitQuestionColonExpression(question_colon_expression node)
{
VisitExpression(node.internal_condition);
VisitExpression(node.internal_ret_if_true);
VisitExpression(node.internal_ret_if_false);
}
private void VisitDoubleQuestionColonExpression(double_question_colon_expression node)
{
VisitExpression(node.internal_condition);
VisitExpression(node.internal_ret_if_null);
}
private void VisitStatementsExpressionNode(statements_expression_node node)
{
bw.Write(node.internal_statements.Count);
foreach (statement_node stmt in node.internal_statements)
VisitStatement(stmt);
VisitExpression(node.internal_expression);
}
private void VisitFloatConst(float_const_node node)
{
bw.Write((Single)node.constant_value);
}
private void VisitCompiledStaticMethodCallNodeAsConstant(compiled_static_method_call_as_constant node)
{
VisitCompiledStaticMethodCall(node.method_call);
}
private void VisitCommonStaticMethodCallNodeAsConstant(common_static_method_call_as_constant node)
{
VisitCommonStaticMethodCall(node.method_call);
}
private void VisitCompiledConstructorCallAsConstant(compiled_constructor_call_as_constant node)
{
VisitCompiledConstructorCall(node.method_call);
}
private void VisitSizeOfOperatorAsConstant(sizeof_operator_as_constant node)
{
VisitSizeOfOperator(node.sizeof_operator);
}
private void VisitCommonNamespaceFunctionCallNodeAsConstant(common_namespace_function_call_as_constant node)
{
VisitCommonNamespaceFunctionCall(node.method_call);
WriteTypeReference(node.type);
}
private void VisitExpression(expression_node en)
{
bw.Write((byte)en.semantic_node_type);
//WriteDebugInfo(en.location);
switch (en.semantic_node_type) {
case semantic_node_type.exit_procedure:
/*ничего писать не надо*/ break;
case semantic_node_type.typeof_operator:
VisitTypeOfOperator((typeof_operator)en); break;
case semantic_node_type.statement_expression_node:
VisitStatementsExpressionNode((statements_expression_node)en); break;
case semantic_node_type.question_colon_expression:
VisitQuestionColonExpression((question_colon_expression)en); break;
case semantic_node_type.double_question_colon_expression:
VisitDoubleQuestionColonExpression((double_question_colon_expression)en); break;
case semantic_node_type.sizeof_operator:
VisitSizeOfOperator((sizeof_operator)en); break;
case semantic_node_type.is_node:
VisitIsNode((is_node)en); break;
case semantic_node_type.as_node:
VisitAsNode((as_node)en); break;
case semantic_node_type.compiled_static_method_call_node_as_constant:
VisitCompiledStaticMethodCallNodeAsConstant((compiled_static_method_call_as_constant)en); break;
case semantic_node_type.common_static_method_call_node_as_constant:
VisitCommonStaticMethodCallNodeAsConstant((common_static_method_call_as_constant)en); break;
case semantic_node_type.common_namespace_function_call_node_as_constant:
VisitCommonNamespaceFunctionCallNodeAsConstant((common_namespace_function_call_as_constant)en); break;
case semantic_node_type.compiled_constructor_call_as_constant:
VisitCompiledConstructorCallAsConstant((compiled_constructor_call_as_constant)en); break;
case semantic_node_type.sizeof_operator_as_constant:
VisitSizeOfOperatorAsConstant((sizeof_operator_as_constant)en); break;
case semantic_node_type.array_const:
VisitArrayConst((array_const)en); break;
case semantic_node_type.record_const:
VisitRecordConst((record_constant)en); break;
case semantic_node_type.float_const_node:
VisitFloatConst((float_const_node)en);break;
case semantic_node_type.byte_const_node:
VisitByteConstNode((byte_const_node)en); break;
case semantic_node_type.int_const_node:
VisitIntConstNode((int_const_node)en); break;
case semantic_node_type.sbyte_const_node:
VisitSByteConstNode((sbyte_const_node)en); break;
case semantic_node_type.short_const_node:
VisitShortConstNode((short_const_node)en); break;
case semantic_node_type.ushort_const_node:
VisitUShortConstNode((ushort_const_node)en); break;
case semantic_node_type.uint_const_node:
VisitUIntConstNode((uint_const_node)en); break;
case semantic_node_type.ulong_const_node:
VisitULongConstNode((ulong_const_node)en); break;
case semantic_node_type.long_const_node:
VisitLongConstNode((long_const_node)en); break;
case semantic_node_type.double_const_node:
VisitDoubleConstNode((double_const_node)en); break;
case semantic_node_type.char_const_node :
VisitCharConstNode((char_const_node)en); break;
case semantic_node_type.bool_const_node :
VisitBoolConstNode((bool_const_node)en); break;
case semantic_node_type.string_const_node :
VisitStringConstNode((string_const_node)en); break;
case semantic_node_type.local_variable_reference :
VisitLocalVariableReference((local_variable_reference)en); break;
case semantic_node_type.local_block_variable_reference:
VisitLocalBlockVariableReference((local_block_variable_reference)en); break;
case semantic_node_type.namespace_variable_reference:
VisitNamespaceVariableReference((namespace_variable_reference)en); break;
case semantic_node_type.basic_function_call :
VisitBasicFunctionCall((basic_function_call)en); break;
case semantic_node_type.common_parameter_reference :
VisitCommonParameterReference((common_parameter_reference)en); break;
case semantic_node_type.common_namespace_function_call :
VisitCommonNamespaceFunctionCall((common_namespace_function_call)en); break;
case semantic_node_type.common_in_function_function_call :
VisitCommonInFuncFuncCall((common_in_function_function_call)en); break;
case semantic_node_type.while_break_node:
VisitWhileBreakNode((while_break_node)en); break;
case semantic_node_type.while_continue_node:
VisitWhileContinueNode((while_continue_node)en); break;
case semantic_node_type.for_break_node:
VisitForBreakNode((for_break_node)en); break;
case semantic_node_type.for_continue_node:
VisitForContinueNode((for_continue_node)en); break;
case semantic_node_type.repeat_break_node:
VisitRepeatBreakNode((repeat_break_node)en); break;
case semantic_node_type.repeat_continue_node:
VisitRepeatContinueNode((repeat_continue_node)en); break;
case semantic_node_type.compiled_static_method_call:
VisitCompiledStaticMethodCall((compiled_static_method_call)en); break;
case semantic_node_type.class_field_reference:
VisitClassFieldReference((class_field_reference)en); break;
case semantic_node_type.deref_node:
VisitDerefNode((dereference_node)en); break;
case semantic_node_type.common_method_call:
VisitCommonMethodCall((common_method_call)en); break;
case semantic_node_type.compiled_function_call:
VisitCompiledFunctionCall((compiled_function_call)en); break;
case semantic_node_type.get_addr_node:
VisitGetAddrNode((get_addr_node)en); break;
case semantic_node_type.common_constructor_call:
VisitCommonConstructorCall((common_constructor_call)en); break;
case semantic_node_type.compiled_constructor_call:
VisitCompiledConstructorCall((compiled_constructor_call)en); break;
case semantic_node_type.compiled_variable_reference:
VisitCompiledVariableReference((compiled_variable_reference)en); break;
case semantic_node_type.static_compiled_variable_reference:
VisitStaticCompiledVariableReference((static_compiled_variable_reference)en); break;
case semantic_node_type.static_class_field_reference:
VisitStaticClassFieldReference((static_class_field_reference)en); break;
case semantic_node_type.non_static_property_reference:
VisitNonStaticPropertyReference((non_static_property_reference)en); break;
case semantic_node_type.simple_array_indexing:
VisitSimpleArrayIndexing((simple_array_indexing)en); break;
case semantic_node_type.this_node:
VisitThisNode((this_node)en); break;
case semantic_node_type.null_const_node:
VisitNullConstNode((null_const_node)en); break;
case semantic_node_type.enum_const:
VisitEnumConstNode((enum_const_node)en); break;
case semantic_node_type.foreach_break_node:
VisitForeachBreak((foreach_break_node)en); break;
case semantic_node_type.foreach_continue_node:
VisitForeachContinue((foreach_continue_node)en); break;
case semantic_node_type.namespace_constant_reference:
VisitNamespaceConstantReference((namespace_constant_reference)en); break;
case semantic_node_type.function_constant_reference:
VisitFunctionConstantReference((function_constant_reference)en); break;
case semantic_node_type.common_constructor_call_as_constant:
VisitCommonConstructorCallAsConstant((common_constructor_call_as_constant)en); break;
case semantic_node_type.basic_function_call_node_as_constant:
VisitBasicFunctionCallAsConstant((basic_function_call_as_constant)en); break;
case semantic_node_type.default_operator_node_as_constant:
VisitDefaultOperatorAsConstant((default_operator_node_as_constant)en); break;
case semantic_node_type.array_initializer:
VisitArrayInitializer((array_initializer)en); break;
case semantic_node_type.record_initializer:
VisitRecordInitializer((record_initializer)en); break;
case semantic_node_type.common_static_method_call:
VisitCommonStaticMethodCall((common_static_method_call)en); break;
case semantic_node_type.default_operator:
VisitDefaultOperator((default_operator_node)en); break;
case semantic_node_type.compiled_static_field_reference_as_constant:
VisitCompiledStaticFieldReferenceAsConstant((compiled_static_field_reference_as_constant)en); break;
case semantic_node_type.nonstatic_event_reference:
VisitNonStaticEventReference((nonstatic_event_reference)en); break;
case semantic_node_type.static_event_reference:
VisitStaticEventReference((static_event_reference)en); break;
default : throw new Exception("Unknown expression");
}
}
private void VisitStaticEventReference(static_event_reference en)
{
WriteEventReference(en.en);
}
private void VisitNonStaticEventReference(nonstatic_event_reference en)
{
VisitExpression(en.obj);
WriteEventReference(en.en as common_event);
}
private void VisitCompiledStaticFieldReferenceAsConstant(compiled_static_field_reference_as_constant en)
{
VisitStaticCompiledVariableReference(en.field_reference);
}
private void VisitDefaultOperator(default_operator_node expr)
{
WriteTypeReference(expr.type);
}
private void VisitRecordInitializer(record_initializer expr)
{
bw.Write(expr.field_values.Count);
foreach (expression_node en in expr.field_values)
VisitExpression(en);
WriteTypeReference(expr.type);
}
private void VisitCommonConstructorCallAsConstant(common_constructor_call_as_constant expr)
{
VisitCommonConstructorCall(expr.constructor_call);
}
private void VisitBasicFunctionCallAsConstant(basic_function_call_as_constant expr)
{
VisitBasicFunctionCall(expr.method_call);
}
private void VisitDefaultOperatorAsConstant(default_operator_node_as_constant expr)
{
VisitDefaultOperator(expr.default_operator);
}
private void VisitNamespaceConstantReference(namespace_constant_reference expr)
{
WriteConstantReference(expr.constant);
}
private void VisitFunctionConstantReference(function_constant_reference expr)
{
bw.Write(GetMemberOffset(expr.constant));
}
private void VisitNullConstNode(null_const_node expr)
{
if (expr.type != null && !(expr.type is null_type_node) && !(expr.type is delegated_methods))
{
bw.Write((byte)1);
WriteTypeReference(expr.type);
}
else
{
bw.Write((byte)0);
}
}
private void VisitEnumConstNode(enum_const_node en)
{
bw.Write(en.constant_value);
WriteTypeReference(en.type);
}
private void VisitByteConstNode(byte_const_node expr)
{
bw.Write(expr.constant_value);
}
private void VisitIntConstNode(int_const_node expr)
{
bw.Write(expr.constant_value);
}
private void VisitSByteConstNode(sbyte_const_node expr)
{
bw.Write(expr.constant_value);
}
private void VisitShortConstNode(short_const_node expr)
{
bw.Write(expr.constant_value);
}
private void VisitUShortConstNode(ushort_const_node expr)
{
bw.Write(expr.constant_value);
}
private void VisitUIntConstNode(uint_const_node expr)
{
bw.Write(expr.constant_value);
}
private void VisitULongConstNode(ulong_const_node expr)
{
bw.Write(expr.constant_value);
}
private void VisitLongConstNode(long_const_node expr)
{
bw.Write(expr.constant_value);
}
private void VisitDoubleConstNode(double_const_node expr)
{
bw.Write(expr.constant_value);
}
private void VisitCharConstNode(char_const_node expr)
{
bw.Write(expr.constant_value);
}
private void VisitBoolConstNode(bool_const_node expr)
{
bw.Write(expr.constant_value);
}
private void VisitStringConstNode(string_const_node expr)
{
bw.Write(expr.constant_value);
}
private void VisitLocalVariableReference(local_variable_reference expr)
{
bw.Write(GetMemberOffset(expr.var));
//bw.Write(expr.static_depth);
}
private void VisitLocalBlockVariableReference(local_block_variable_reference expr)
{
bw.Write(GetMemberOffset(expr.var));
//bw.Write(expr.static_depth);
}
private void VisitNamespaceVariableReference(namespace_variable_reference expr)
{
WriteVariableReference(expr.var);
}
private void VisitCommonParameterReference(common_parameter_reference expr)
{
bw.Write(GetMemberOffset(expr.par));
}
private void VisitBasicFunctionCall(basic_function_call expr)
{
bw.Write((System.Int16)expr.function_node.basic_function_type);
WriteTypeReference(expr.ret_type);
if (expr.conversion_type is delegated_methods)
WriteTypeReference(null);
else
WriteTypeReference(expr.conversion_type);
bw.Write(expr.parameters.Count);
for (int i=0; i