pascalabcnet/TreeConverter/TreeRealization/namespaces.cs

708 lines
22 KiB
C#
Raw Normal View History

2015-06-01 22:15:17 +03:00
// Copyright (c) Ivan Bondarev, Stanislav Mihalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
2015-05-14 22:35:07 +03:00
using System;
using System.Collections.Generic;
using PascalABCCompiler.TreeConverter;
namespace PascalABCCompiler.TreeRealization
{
/// <summary>
/// Базовый класс для представления пространств имен.
/// </summary>
[Serializable]
public abstract class namespace_node : definition_node, SemanticTree.INamespaceNode
{
/// <summary>
/// Полное имя пространства имен.
/// </summary>
public abstract string namespace_full_name
{
get;
}
/// <summary>
/// Поиск символа в пространстве имен.
/// </summary>
/// <param name="name">Имя элемента для поиска.</param>
/// <returns>Информация о найденном символе. null, если ни чего не найдено.</returns>
public abstract SymbolInfo find(string name);
/// <summary>
/// Имя пространства имен.
/// </summary>
public abstract string namespace_name
{
get;
}
/// <summary>
/// Метод для обхода дерева посетителем.
/// </summary>
/// <param name="visitor">Класс - посетитель дерева.</param>
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit(this);
}
/// <summary>
/// Обобщенный тип узла.
/// </summary>
public override general_node_type general_node_type
{
get
{
return general_node_type.namespace_node;
}
}
}
/// <summary>
/// Класс, представляющий обычное пространство имен.
/// </summary>
[Serializable]
public class common_namespace_node : namespace_node, SemanticTree.ICommonNamespaceNode
{
/// <summary>
/// Список типов, вложенных в пространство имен.
/// </summary>
private readonly common_type_node_list _types=new common_type_node_list();
//ssyy добавил
/// <summary>
/// Список шаблонных классов, вложенных в пространство имен.
/// </summary>
private readonly template_class_list _templates = new template_class_list();
//\ssyy
//ssyy добавил
/// <summary>
/// Список определённых в пространстве имен синонимов типов.
/// </summary>
private readonly List<type_synonym> _type_synonyms = new List<type_synonym>();
//\ssyy
/// <summary>
/// Список определённых в пространстве имен типов-указателей.
/// </summary>
private readonly List<ref_type_node> _ref_types = new List<ref_type_node>();
/// <summary>
/// Список runtime типов, вложенных в пространство имен.
/// </summary>
private readonly compiled_type_node_list _runtime_types = new compiled_type_node_list();
/// <summary>
/// Список переменных, определенных в прстранстве имен.
/// </summary>
private readonly namespace_variable_list _variables = new namespace_variable_list();
private readonly namespace_event_list _events = new namespace_event_list();
/// <summary>
/// Список меток, определенных в прстранстве имен.
/// </summary>
private readonly List<label_node> _labels = new List<label_node>();
/// <summary>
/// Список функций, определенных в пространстве имен.
/// </summary>
private readonly common_namespace_function_node_list _functions = new common_namespace_function_node_list();
/// <summary>
/// Список констант, определенных в пространстве имен.
/// </summary>
private readonly namespace_constant_definition_list _constants=new namespace_constant_definition_list();
/// <summary>
/// Список пространств имен, вложенных в пространство имен.
/// </summary>
private readonly common_namespace_node_list _namespaces= new common_namespace_node_list();
/// <summary>
/// Пространство имен, в которое вложено это пространство имен.
/// </summary>
private namespace_node _comprehensive_namespace;
/// <summary>
/// Модуль, в котором содержится это пространство имен.
/// При генерации кода, когда возможна ситуация при которой простраство имен расположено в нескольких модулях,
/// этот элемент указывает на один из модулей в котором встретилось это пространство имен.
/// </summary>
private unit_node _cont_unit;
/// <summary>
/// Имя пространства имен.
/// </summary>
private string _name;
/// <summary>
/// Область видимости пространства имен.
/// </summary>
private SymbolTable.Scope _scope;
/// <summary>
/// Расположения заголовка пространства имен.
/// </summary>
private location _loc;
/// <summary>
/// Конструктор узла.
/// </summary>
/// <param name="comprehensive_namespace">Пространство имен, в которое вложено это пространство имен.</param>
/// <param name="cont_unit">Модуль, в котором содержится это пространство имен.</param>
/// <param name="name">Имя пространства имен.</param>
/// <param name="scope">Область видимости пространства имен.</param>
/// <param name="loc">Расположения заголовка пространства имен.</param>
public common_namespace_node(namespace_node comprehensive_namespace, unit_node cont_unit, string name,
SymbolTable.Scope scope, location loc)
{
_comprehensive_namespace = comprehensive_namespace;
_cont_unit = cont_unit;
_name = name;
_scope = scope;
_loc = loc;
}
/// <summary>
/// Клонирует пространство имен.
/// </summary>
/// <returns>Копия пространства иен.</returns>
public common_namespace_node clone()
{
common_namespace_node cnn = new common_namespace_node(this._comprehensive_namespace, this._cont_unit,
this._name, this._scope, this._loc);
cnn.merge_with_namespace(this);
return cnn;
}
/// <summary>
/// Добавляет к текущему пространству имен указанное пространство имен.
/// </summary>
/// <param name="merge_with">Пространство имен для добавления.</param>
public void merge_with_namespace(common_namespace_node merge_with)
{
_types.AddRange(merge_with._types);
//ssyy
_templates.AddRange(merge_with._templates);
_type_synonyms.AddRange(merge_with._type_synonyms);
//\ssyy
_variables.AddRange(merge_with._variables);
_functions.AddRange(merge_with._functions);
_constants.AddRange(merge_with._constants);
_namespaces.AddRange(merge_with._namespaces);
}
private bool _is_main;
public bool is_main
{
get
{
return _is_main;
}
set
{
_is_main = value;
}
}
bool SemanticTree.ICommonNamespaceNode.IsMain
{
get
{
return _is_main;
}
}
/// <summary>
/// Область видимости пространства имен.
/// </summary>
public SymbolTable.Scope scope
{
get
{
return _scope;
}
set
{
_scope = value;
}
}
/// <summary>
/// Расположения заголовка пространства имен.
/// </summary>
public location loc
{
get
{
return _loc;
}
}
/// <summary>
/// Расположения заголовка пространства имен.
/// Используется при обходе дерева посетителем.
/// </summary>
public SemanticTree.ILocation Location
{
get
{
return _loc;
}
}
/// <summary>
/// Имя пространства имен.
/// </summary>
public override string namespace_name
{
get
{
return _name;
}
}
public void SetNamespaceName(string name)
{
_name = name;
}
/// <summary>
/// Пространство имен, в которое вложено это пространство имен.
/// </summary>
public namespace_node comprehensive_namespace
{
get
{
return _comprehensive_namespace;
}
}
/// <summary>
/// Модуль, в котором содержится это пространство имен.
/// При генерации кода, когда возможна ситуация при которой простраство имен расположено в нескольких модулях,
/// этот элемент указывает на один из модулей в котором встретилось это пространство имен.
/// </summary>
public unit_node cont_unit
{
get
{
return _cont_unit;
}
}
/// <summary>
/// Список типов, вложенных в пространство имен.
/// </summary>
public common_type_node_list types
{
get
{
return _types;
}
}
//ssyy добавил
/// <summary>
/// Список шаблонных классов, вложенных в пространство имен.
/// </summary>
public template_class_list templates
{
get
{
return _templates;
}
}
/// <summary>
/// Список определённых в пространстве имен синонимов типов.
/// </summary>
public List<type_synonym> type_synonyms
{
get
{
return _type_synonyms;
}
}
//\ssyy
/// <summary>
/// Список определённых в пространстве имен типов-указателей.
/// </summary>
public List<ref_type_node> ref_types
{
get
{
return _ref_types;
}
}
/// <summary>
/// Список типов, вложенных в пространство имен.
/// </summary>
public compiled_type_node_list runtime_types
{
get
{
return _runtime_types;
}
}
/// <summary>
/// Список пространств имен, вложенных в пространство имен.
/// </summary>
public common_namespace_node_list namespaces
{
get
{
return _namespaces;
}
}
/// <summary>
/// Список переменных, определенных в прстранстве имен.
/// </summary>
public namespace_variable_list variables
{
get
{
return _variables;
}
}
public namespace_event_list events
{
get
{
return _events;
}
}
/// <summary>
/// Список меток, определенных в прстранстве имен.
/// </summary>
public List<label_node> labels
{
get
{
return _labels;
}
}
/// <summary>
/// Список функций, определенных в пространстве имен.
/// </summary>
public common_namespace_function_node_list functions
{
get
{
return _functions;
}
}
/// <summary>
/// Список констант, определенных в пространстве имен.
/// </summary>
public namespace_constant_definition_list constants
{
get
{
return _constants;
}
}
/// <summary>
/// Полное имя пространства имен.
/// </summary>
public override string namespace_full_name
{
get
{
if (_comprehensive_namespace==null)
{
return _name;
}
return (_comprehensive_namespace.namespace_full_name+"."+_name);
}
}
private bool _from_pcu;
public bool from_pcu
{
get
{
return _from_pcu;
}
set
{
_from_pcu = value;
}
}
/// <summary>
/// Поиск символа в этом пространстве имен.
/// </summary>
/// <param name="name">Искомое имя.</param>
/// <returns>Информация о найденом символе. null, если ни чего не найдена.</returns>
public override SymbolInfo find(string name)
{
return _scope.Find(name);//c,cc,c,cc
}
public SymbolInfo findOnlyInNamespace(string name)
{
return _scope.FindOnlyInScope(name);//c,cc,c,cc
}
/// <summary>
/// Тип узла.
/// </summary>
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.common_namespace_node;
}
}
/// <summary>
/// Метод для обхода дерева посетителем.
/// </summary>
/// <param name="visitor">Класс - посетитель дерева.</param>
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit(this);
}
SemanticTree.ICommonNamespaceNode[] SemanticTree.ICommonNamespaceNode.nested_namespaces
{
get
{
return (this._namespaces.ToArray());
}
}
SemanticTree.ICommonTypeNode[] SemanticTree.ICommonNamespaceNode.types
{
get
{
return (this._types.ToArray());
}
}
SemanticTree.ITypeSynonym[] SemanticTree.ICommonNamespaceNode.type_synonims
{
get
{
return this._type_synonyms.ToArray();
}
}
SemanticTree.ITemplateClass[] SemanticTree.ICommonNamespaceNode.templates
{
get
{
return this.templates.ToArray();
}
}
SemanticTree.ICommonNamespaceVariableNode[] SemanticTree.ICommonNamespaceNode.variables
{
get
{
return (this._variables.ToArray());
}
}
SemanticTree.ICommonNamespaceEventNode[] SemanticTree.ICommonNamespaceNode.events
{
get
{
return (this._events.ToArray());
}
}
SemanticTree.ICommonNamespaceFunctionNode[] SemanticTree.ICommonNamespaceNode.functions
{
get
{
return (this._functions.ToArray());
}
}
SemanticTree.INamespaceNode SemanticTree.ICommonNamespaceNode.comprehensive_namespace
{
get
{
return (this._comprehensive_namespace);
}
}
SemanticTree.INamespaceConstantDefinitionNode[] SemanticTree.ICommonNamespaceNode.constants
{
get
{
return (this._constants.ToArray());
}
}
//(ssyy) Флаг, чтобы не проверять второй раз наличие тел всех описанных функций
public bool predefinitions_checked = false;
//(ssyy) Набор типов для сохранения на диск
private common_type_node_list _non_template_types = null;
public common_type_node_list non_template_types
{
get
{
return _non_template_types;
}
}
public void MakeNonTemplateTypesList()
{
_non_template_types = new common_type_node_list();
foreach (common_type_node ctn in _types)
{
if (ctn.original_template == null)
{
_non_template_types.AddElement(ctn);
}
}
}
}
/// <summary>
/// Класс, представляющий пространство имен в откомпилированном коде.
/// </summary>
[Serializable]
public class compiled_namespace_node : namespace_node, SemanticTree.ICompiledNamespaceNode
{
/// <summary>
/// Имя (полное) пространства имен.
/// </summary>
private string _name;
private SymbolTable.TreeConverterSymbolTable _tcst;
/// <summary>
/// Конструктор узла.
/// </summary>
/// <param name="name">Полное имя пространства имен.</param>
public compiled_namespace_node(string name, SymbolTable.TreeConverterSymbolTable tcst)
{
_name=name;
_tcst = tcst;
}
/// <summary>
/// Получение имени пространства имен по его полному имени.
/// </summary>
/// <param name="full_name">Полное имя пространства имен.</param>
/// <returns>Имя пространства имен.</returns>
private string get_namespace_name(string full_name)
{
int last_dot_ind = full_name.LastIndexOf('.');
if (last_dot_ind < 0)
{
return _name;
}
return new string(_name.ToCharArray(last_dot_ind,_name.Length-last_dot_ind));
}
/// <summary>
/// Имя пространства имен (не полное).
/// </summary>
public override string namespace_name
{
get
{
return get_namespace_name(_name);
}
}
/// <summary>
/// Полное имя пространства имен.
/// </summary>
public override string namespace_full_name
{
get
{
return _name;
}
}
/// <summary>
/// Поиск символа в пространстве имен.
/// </summary>
/// <param name="name">Имя для поиска.</param>
/// <returns>Первый элемент списка найденных имен. null если ни чего не найдено.</returns>
public override SymbolInfo find(string name)
{
bool is_ns = NetHelper.NetHelper.IsNetNamespace(_name + "." + name);
SymbolInfo si = null;
if (is_ns == true)
{
compiled_namespace_node cnn = new compiled_namespace_node(_name + "." + name,_tcst);
si = new SymbolInfo(cnn);
}
else
{
//Kolay changed next string. throwOnError=false ignoreCase=true, .
//Type t = Type.GetType(_name+"."+name,false,true);
Type t = NetHelper.NetHelper.FindType(_name + "." + name);
if (t != null)
{
si = new SymbolInfo(compiled_type_node.get_type_node(t,_tcst));
}
else
{
t = NetHelper.NetHelper.FindType(_name+"."+_name);
if (t != null && NetHelper.NetHelper.IsEntryType(t))
{
si = NetHelper.NetHelper.FindName(t,name);
if (si == null)
{
type_node tn = NetHelper.NetHelper.FindCompiledPascalType(_name + "." + name);
if (tn != null)
si = new SymbolInfo(tn);
else
{
template_class tc = NetHelper.NetHelper.FindCompiledTemplateType(_name + "." + name);
if (tc != null)
si = new SymbolInfo(tc);
}
}
}
}
}
return si;
}
/// <summary>
/// Тип узла.
/// </summary>
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.compiled_namespace_node;
}
}
/// <summary>
/// Метод для обхода дерева посетителем.
/// </summary>
/// <param name="visitor">Класс - посетитель дерева.</param>
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit(this);
}
}
}