// 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; namespace PascalABCCompiler.TreeRealization { /// /// Базовый класс для свойств классов. /// [Serializable] public abstract class property_node : definition_node, SemanticTree.IPropertyNode { /// /// Список параметров свойства. /// private parameter_list _parametres = new parameter_list(); /// /// Вид объекта. /// public abstract SemanticTree.node_kind node_kind { get; } /// /// Имя свойства. /// public abstract string name { get; } /// /// Тип, который содержит это свойство. /// public abstract type_node comprehensive_type { get; } /// /// Тип свойства. /// public abstract type_node property_type { get; } /// /// Уровень доступа к свойству. /// public abstract SemanticTree.field_access_level field_access_level { get; } /// /// Тип свойства (виртуальное, статическое или обычное). /// public virtual SemanticTree.polymorphic_state polymorphic_state { get { return SemanticTree.polymorphic_state.ps_common; } set { } } /// /// Список параметров свойства. /// public parameter_list parameters { get { return _parametres; } } /// /// Функция, которая возвращает значение свойства. /// public abstract function_node get_function { get; } /// /// Функция, которая устанавливает значение свойства. /// public abstract function_node set_function { get; } /// /// Обобщенный тип узла. /// public override general_node_type general_node_type { get { return general_node_type.property_node; } } SemanticTree.IParameterNode[] SemanticTree.IPropertyNode.parameters { get { return (_parametres.ToArray()); } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } SemanticTree.IFunctionNode SemanticTree.IPropertyNode.get_function { get { return this.get_function; } } SemanticTree.IFunctionNode SemanticTree.IPropertyNode.set_function { get { return this.set_function; } } SemanticTree.ITypeNode SemanticTree.IPropertyNode.property_type { get { return this.property_type; } } SemanticTree.ITypeNode SemanticTree.IPropertyNode.comprehensive_type { get { return this.comprehensive_type; } } } /// /// Свойство, определенное в обычном классе. /// [Serializable] public class common_property_node : property_node, SemanticTree.ICommonPropertyNode { /// /// Тип, в котором определено свойство. /// private common_type_node _comprehensive_type; /// /// Тип свойства. /// private type_node _property_type; /// /// Акцессор get свойства. /// private function_node _get_function; /// /// Акцессор set свойства. /// private function_node _set_function; /// /// Имя свойства. /// private string _name; /// /// Уровень доступа к свойству. /// private SemanticTree.field_access_level _field_access_level; /// /// Тип свойства (виртуальное, статическое или обычное). /// private SemanticTree.polymorphic_state _polymorphic_state; /// /// Расположение свойства. /// private location _loc; public common_property_node(string name, common_type_node comprehensive_type, location loc, SemanticTree.field_access_level field_access_level, SemanticTree.polymorphic_state polymorphic_state) { _name = name; _comprehensive_type = comprehensive_type; _loc = loc; _field_access_level = field_access_level; _polymorphic_state = polymorphic_state; } public common_property_node(string name,common_type_node comprehensive_type,type_node property_type, function_node get_function,function_node set_function,location loc, SemanticTree.field_access_level field_access_level, SemanticTree.polymorphic_state polymorphic_state) { _name=name; _comprehensive_type=comprehensive_type; _property_type=property_type; _get_function=get_function; _set_function=set_function; _loc = loc; _field_access_level = field_access_level; _polymorphic_state = polymorphic_state; } /// /// Расположение свойства. /// public location loc { get { return _loc; } } /// /// Расположение свойства. /// Используется при обходе дерева посетителем. /// public SemanticTree.ILocation Location { get { return _loc; } } /// /// Имя свойства. /// public override string name { get { return _name; } } /// /// Уровень доступа к свойству. /// public override SemanticTree.field_access_level field_access_level { get { return _field_access_level; } } /// /// Тип, в котором определено свойство. /// public override type_node comprehensive_type { get { return common_comprehensive_type; } } /// /// Тип, который содержит это свойство. /// public common_type_node common_comprehensive_type { get { return _comprehensive_type; } } public type_node internal_property_type { get { return _property_type; } set { _property_type = value; } } /// /// Тип свойства. /// public override type_node property_type { get { return _property_type; } } public function_node internal_get_function { get { return _get_function; } set { _get_function = value; } } /// /// Акцессор get свойства. /// public override function_node get_function { get { return _get_function; } } public function_node internal_set_function { get { return _set_function; } set { _set_function = value; } } /// /// Акцессор set свойства. /// public override function_node set_function { get { return _set_function; } } /// /// Тип узла. /// public override semantic_node_type semantic_node_type { get { return semantic_node_type.common_property_node; } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } //SemanticTree.ICommonTypeNode SemanticTree.ICommonPropertyNode.common_comprehensive_type //{ // get // { // return _comprehensive_type; // } //} SemanticTree.ICommonTypeNode SemanticTree.ICommonClassMemberNode.common_comprehensive_type { get { return _comprehensive_type; } } SemanticTree.ITypeNode SemanticTree.IClassMemberNode.comperehensive_type { get { return _comprehensive_type; } } SemanticTree.field_access_level SemanticTree.IClassMemberNode.field_access_level { get { return _field_access_level; } } public override SemanticTree.polymorphic_state polymorphic_state { get { return _polymorphic_state; } set { _polymorphic_state = value; } } public override SemanticTree.node_kind node_kind { get { return SemanticTree.node_kind.common; } } } /// /// Свойство откомпилированного класса. /// [Serializable] public class compiled_property_node : property_node, SemanticTree.ICompiledPropertyNode { /// /// Оборачиваемое свойство. /// private System.Reflection.PropertyInfo _pi; //TODO: Поговорить с Ваней на тему того, чтобы разместить храилища функций, свойств и т.д. в этих классах. Тогда конструкторы можно будет сделать закрытыми. /// /// Конструктор класса. /// /// Оборачиваемое свойство. public compiled_property_node(System.Reflection.PropertyInfo prop_info) { _pi=prop_info; System.Reflection.ParameterInfo[] pas = _pi.GetIndexParameters(); if ((pas != null) && (pas.Length > 0)) { foreach (System.Reflection.ParameterInfo parinfo in pas) { parameters.AddElement(new compiled_parameter(parinfo)); } } } //TODO: Закрыть бы его от любопытных и оставить только для интерфейсов. /// /// Оборачиваемое свойство. /// public System.Reflection.PropertyInfo prop_info { get { return _pi; } } /// /// Имя свойства. /// public override string name { get { return _pi.Name; } } /// /// Тип, который содержит это свойство. /// public override type_node comprehensive_type { get { return compiled_comprehensive_type; } } /// /// Тип, который содержит это свойство. /// public compiled_type_node compiled_comprehensive_type { get { return compiled_type_node.get_type_node(_pi.DeclaringType); } } /// /// Тип свойства. /// public override type_node property_type { get { return compiled_type_node.get_type_node(_pi.PropertyType); } } /// /// Акцессор get. /// public compiled_function_node compiled_get_accessor { get { System.Reflection.MethodInfo mi=PascalABCCompiler.NetHelper.NetHelper.GetReadAccessor(_pi); if (mi==null) { return null; } return compiled_function_node.get_compiled_method(mi); } } /// /// Акцессор get. /// public override function_node get_function { get { return compiled_get_accessor; } } public compiled_function_node compiled_set_accessor { get { System.Reflection.MethodInfo mi=PascalABCCompiler.NetHelper.NetHelper.GetWriteAccessor(_pi); if (mi==null) { return null; } return compiled_function_node.get_compiled_method(mi); } } /// /// Акцессор set. /// public override function_node set_function { get { return compiled_set_accessor; } } /// /// Тип узла. /// public override semantic_node_type semantic_node_type { get { return semantic_node_type.basic_property_node; } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } //TODO: Сделать меьлды в NetHelper-е, которые будут возвращать уровень доступа и polymorphic_state для всего. /// /// Виртуальное, статическое или обычное свойство. /// public override SemanticTree.polymorphic_state polymorphic_state { get { System.Reflection.MethodInfo _mi=PascalABCCompiler.NetHelper.NetHelper.GetAnyAccessor(_pi); if (_mi==null) { return SemanticTree.polymorphic_state.ps_common; } if (_mi.IsAbstract) { return SemanticTree.polymorphic_state.ps_virtual_abstract; } if (_mi.IsStatic) { return SemanticTree.polymorphic_state.ps_static; } if (_mi.IsVirtual) { return SemanticTree.polymorphic_state.ps_virtual; } //Как с остальными - override,new? Наверно они не нужны? return SemanticTree.polymorphic_state.ps_common; } } /// /// Уровень доступа к свойству. Мало что значит, т.к. надо проверять акцессоры /// по отдельности при обращении к ним, т.к. могут быть акцессоры с разными уровнями доступа. /// public override SemanticTree.field_access_level field_access_level { get { System.Reflection.MethodInfo _mi=PascalABCCompiler.NetHelper.NetHelper.GetAnyAccessor(_pi); if (_mi==null) { return SemanticTree.field_access_level.fal_private; } if (_mi.IsPublic) { return SemanticTree.field_access_level.fal_public; } if (_mi.IsPrivate) { return SemanticTree.field_access_level.fal_private; } //Как в System.Reflection отображается то, что метод protected? return SemanticTree.field_access_level.fal_protected; } } //TODO: Лучше эту информацию вообще никому кроме интерфейсов не выдавать. /// /// Информация о свойстве. /// public System.Reflection.PropertyInfo property_info { get { return _pi; } } SemanticTree.ICompiledMethodNode SemanticTree.ICompiledPropertyNode.compiled_get_method { get { return this.compiled_get_accessor; } } SemanticTree.ICompiledMethodNode SemanticTree.ICompiledPropertyNode.compiled_set_method { get { return this.compiled_set_accessor; } } SemanticTree.ICompiledTypeNode SemanticTree.ICompiledPropertyNode.compiled_comprehensive_type { get { return this.compiled_comprehensive_type; } } public override SemanticTree.node_kind node_kind { get { return SemanticTree.node_kind.compiled; } } SemanticTree.ICompiledTypeNode SemanticTree.ICompiledClassMemberNode.comprehensive_type { get { return compiled_comprehensive_type; } } public SemanticTree.ITypeNode comperehensive_type { get { return compiled_comprehensive_type; } } } /// /// Класс, представляющий обращение к статическому свойству. /// Реально в выходной код обращения к свойствам не идут. Они заменяются на вызовы акцессоров. /// Эти классы используются как промежуточные. /// [Serializable] public class static_property_reference : addressed_expression { /// /// Свойство. /// private property_node _prop; /// /// Список фактических параметров. /// private expressions_list _fact_parametres = new expressions_list(); public static_property_reference(property_node pn, location loc) : base(pn.property_type,loc) { _prop=pn; } /// /// Свойство, к которому мы обращаемся. /// public property_node property { get { return _prop; } } /// /// Список фактических параметров. /// public expressions_list fact_parametres { get { return _fact_parametres; } } /// /// Выражение не адресное. /// public override bool is_addressed { get { return false; } } /// /// Тип узла. /// public override semantic_node_type semantic_node_type { get { return semantic_node_type.static_property_reference; } } } //TODO: Не очень хорошая структура наследования для этих двух классов (static_property_reference и non_static_property_reference). /// /// Класс, представляющий обращение к не статическому свойству. /// Реально в выходной код обращения к свойствам не идут. Они заменяются на вызовы акцессоров. /// Эти классы используются как промежуточные. /// [Serializable] public class non_static_property_reference : static_property_reference { /// /// Выражение, к свойству которого мы обращаемся. /// private expression_node _en; public non_static_property_reference(property_node pn,expression_node obj,location loc) : base(pn,loc) { _en=obj; } /// /// Выражение, к свойству которого мы обращаемся. /// public expression_node expression { get { return _en; } } /// /// Тип узла. /// public override semantic_node_type semantic_node_type { get { return semantic_node_type.non_static_property_reference; } } } }