// 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) using System; using System.Collections.Generic; using PascalABCCompiler.TreeConverter; using PascalABCCompiler.TreeRealization; using System.Linq; namespace PascalABCCompiler.TreeRealization { /// /// Базовый класс для представления пространств имен. /// [Serializable] public abstract class namespace_node : definition_node, SemanticTree.INamespaceNode { /// /// Полное имя пространства имен. /// public abstract string namespace_full_name { get; } /// /// Поиск символа в пространстве имен. /// /// Имя элемента для поиска. /// Информация о найденном символе. null, если ни чего не найдено. public abstract List find(string name); public abstract List findOnlyInNamespace(string name); /// /// Имя пространства имен. /// public abstract string namespace_name { get; } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } /// /// Обобщенный тип узла. /// public override general_node_type general_node_type { get { return general_node_type.namespace_node; } } } /// /// Класс, представляющий обычное пространство имен. /// [Serializable] public class common_namespace_node : namespace_node, SemanticTree.ICommonNamespaceNode { public override string ToString() { if(is_main) return "main"; if (namespace_full_name == "") return GetType().Name; return namespace_full_name; } /// /// Список типов, вложенных в пространство имен. /// private readonly common_type_node_list _types=new common_type_node_list(); //ssyy добавил /// /// Список шаблонных классов, вложенных в пространство имен. /// private readonly template_class_list _templates = new template_class_list(); //\ssyy //ssyy добавил /// /// Список определённых в пространстве имен синонимов типов. /// private readonly List _type_synonyms = new List(); //\ssyy /// /// Список определённых в пространстве имен типов-указателей. /// private readonly List _ref_types = new List(); /// /// Список runtime типов, вложенных в пространство имен. /// private readonly compiled_type_node_list _runtime_types = new compiled_type_node_list(); /// /// Список переменных, определенных в прстранстве имен. /// private readonly namespace_variable_list _variables = new namespace_variable_list(); private readonly namespace_event_list _events = new namespace_event_list(); /// /// Список меток, определенных в прстранстве имен. /// private readonly List _labels = new List(); /// /// Список функций, определенных в пространстве имен. /// private readonly common_namespace_function_node_list _functions = new common_namespace_function_node_list(); /// /// Список констант, определенных в пространстве имен. /// private readonly namespace_constant_definition_list _constants=new namespace_constant_definition_list(); /// /// Список пространств имен, вложенных в пространство имен. /// private readonly common_namespace_node_list _namespaces= new common_namespace_node_list(); /// /// Пространство имен, в которое вложено это пространство имен. /// private namespace_node _comprehensive_namespace; /// /// Модуль, в котором содержится это пространство имен. /// При генерации кода, когда возможна ситуация при которой простраство имен расположено в нескольких модулях, /// этот элемент указывает на один из модулей в котором встретилось это пространство имен. /// private unit_node _cont_unit; /// /// Имя пространства имен. /// private string _name; /// /// Область видимости пространства имен. /// private SymbolTable.Scope _scope; /// /// Расположения заголовка пространства имен. /// private location _loc; /// /// Конструктор узла. /// /// Пространство имен, в которое вложено это пространство имен. /// Модуль, в котором содержится это пространство имен. /// Имя пространства имен. /// Область видимости пространства имен. /// Расположения заголовка пространства имен. 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; } /// /// Клонирует пространство имен. /// /// Копия пространства иен. 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; } /// /// Добавляет к текущему пространству имен указанное пространство имен. /// /// Пространство имен для добавления. 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; } } /// /// Область видимости пространства имен. /// public SymbolTable.Scope scope { get { return _scope; } set { _scope = value; } } /// /// Расположения заголовка пространства имен. /// public location loc { get { return _loc; } } /// /// Расположения заголовка пространства имен. /// Используется при обходе дерева посетителем. /// public SemanticTree.ILocation Location { get { return _loc; } } /// /// Имя пространства имен. /// public override string namespace_name { get { return _name; } } public void SetNamespaceName(string name) { _name = name; } /// /// Пространство имен, в которое вложено это пространство имен. /// public namespace_node comprehensive_namespace { get { return _comprehensive_namespace; } } /// /// Модуль, в котором содержится это пространство имен. /// При генерации кода, когда возможна ситуация при которой простраство имен расположено в нескольких модулях, /// этот элемент указывает на один из модулей в котором встретилось это пространство имен. /// public unit_node cont_unit { get { return _cont_unit; } } /// /// Список типов, вложенных в пространство имен. /// public common_type_node_list types { get { return _types; } } //ssyy добавил /// /// Список шаблонных классов, вложенных в пространство имен. /// public template_class_list templates { get { return _templates; } } /// /// Список определённых в пространстве имен синонимов типов. /// public List type_synonyms { get { return _type_synonyms; } } //\ssyy /// /// Список определённых в пространстве имен типов-указателей. /// public List ref_types { get { return _ref_types; } } /// /// Список типов, вложенных в пространство имен. /// public compiled_type_node_list runtime_types { get { return _runtime_types; } } /// /// Список пространств имен, вложенных в пространство имен. /// public common_namespace_node_list namespaces { get { return _namespaces; } } /// /// Список переменных, определенных в прстранстве имен. /// public namespace_variable_list variables { get { return _variables; } } public namespace_event_list events { get { return _events; } } /// /// Список меток, определенных в прстранстве имен. /// public List labels { get { return _labels; } } /// /// Список функций, определенных в пространстве имен. /// public common_namespace_function_node_list functions { get { return _functions; } } /// /// Список констант, определенных в пространстве имен. /// public namespace_constant_definition_list constants { get { return _constants; } } /// /// Полное имя пространства имен. /// 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; } } /// /// Поиск символа в этом пространстве имен. /// /// Искомое имя. /// Информация о найденом символе. null, если ни чего не найдена. public override List find(string name) { return _scope.Find(name);//c,cc,c,cc } public SymbolInfo findFirstOnlyInNamespace(string name) { var temp = _scope.FindOnlyInScope(name);//c,cc,c,cc return temp?.First(); } public override List findOnlyInNamespace(string name) { List si_list = _scope.FindOnlyInScope(name);//c,cc,c,cc return si_list; } /// /// Тип узла. /// public override semantic_node_type semantic_node_type { get { return semantic_node_type.common_namespace_node; } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. 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); } } } } /// /// Класс, представляющий пространство имен в откомпилированном коде. /// [Serializable] public class compiled_namespace_node : namespace_node, SemanticTree.ICompiledNamespaceNode { /// /// Имя (полное) пространства имен. /// private string _name; private common_namespace_node _common_namespace; private SymbolTable.Scope _scope; private SymbolTable.TreeConverterSymbolTable _tcst; /// /// Конструктор узла. /// /// Полное имя пространства имен. public compiled_namespace_node(string name, SymbolTable.TreeConverterSymbolTable tcst) { _name=name; _tcst = tcst; using_namespace_list unl = new using_namespace_list(); unl.AddElement(new using_namespace(_name)); _scope = new NetHelper.NetScope(unl, _tcst); } /// /// Получение имени пространства имен по его полному имени. /// /// Полное имя пространства имен. /// Имя пространства имен. 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)); } private static Dictionary compiled_namespaces = new Dictionary(); public static compiled_namespace_node get_compiled_namespace(string full_name, SymbolTable.TreeConverterSymbolTable tcst) { compiled_namespace_node cnn = null; if (!compiled_namespaces.TryGetValue(full_name, out cnn)) { cnn = new compiled_namespace_node(full_name, tcst); compiled_namespaces.Add(full_name, cnn); } cnn._tcst = tcst; return cnn; } public SymbolTable.TreeConverterSymbolTable SymbolTable { get { return _tcst; } } public SymbolTable.Scope scope { get { return _scope; } } /// /// Имя пространства имен (не полное). /// public override string namespace_name { get { return get_namespace_name(_name); } } /// /// Полное имя пространства имен. /// public override string namespace_full_name { get { return _name; } } public common_namespace_node common_namespace { get { return _common_namespace; } set { _common_namespace = value; } } public override List findOnlyInNamespace(string name) { return find(name); } /// /// Поиск символа в пространстве имен. /// /// Имя для поиска. /// Первый элемент списка найденных имен. null если ни чего не найдено. public override List find(string name) { bool is_ns = NetHelper.NetHelper.IsNetNamespace(_name + "." + name); List sil = null; if (is_ns) { compiled_namespace_node cnn = compiled_namespace_node.get_compiled_namespace(_name + "." + name, _tcst); sil = new List { new SymbolInfo(cnn) }; } else { //Kolay changed next string. throwOnError=false ignoreCase=true, . //Type t = Type.GetType(_name+"."+name,false,true); if (common_namespace != null) { sil = common_namespace.scope.FindOnlyInScope(name); if (sil != null) return sil; } Type t = NetHelper.NetHelper.FindType(_name + "." + name); if (t != null) { sil = new List { new SymbolInfo(compiled_type_node.get_type_node(t, _tcst)) }; } else { t = NetHelper.NetHelper.FindType(_name+"."+_name); if (t != null && NetHelper.NetHelper.IsEntryType(t)) { sil = NetHelper.NetHelper.FindName(t,name); if (sil == null) { type_node tn = NetHelper.NetHelper.FindCompiledPascalType(_name + "." + name); if (tn != null) sil = new List { new SymbolInfo(tn) }; else { template_class tc = NetHelper.NetHelper.FindCompiledTemplateType(_name + "." + name); if (tc != null) sil = new List { new SymbolInfo(tc) }; } } } } } return sil; } /// /// Тип узла. /// public override semantic_node_type semantic_node_type { get { return semantic_node_type.compiled_namespace_node; } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } } } namespace PascalABCCompiler.SyntaxTree { public class syntax_namespace_node : base_syntax_namespace_node { PascalABCCompiler.TreeRealization.unit_node_list _referenced_units; public syntax_namespace_node(string name):base(name) { } public unit_node_list referenced_units { get => _referenced_units; set => _referenced_units = value; } } }