// 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;
}
}
}
}