fix #2033
This commit is contained in:
Ivan Bondarev 2021-03-28 14:08:47 +02:00
parent 68e50baf9d
commit 31cf309e4e
30 changed files with 12090 additions and 8530 deletions

View file

@ -3464,6 +3464,18 @@ namespace CodeFormatters
visit(new uint64_const(bi.val, bi.source_context));
//sb.Append("bi");
}
public override void visit(property_ident _property_ident)
{
if (_property_ident.ln != null)
{
foreach (ident id in _property_ident.ln)
visit_node(id);
}
WriteAmpersandIfNeed(_property_ident);
sb.Append(prepare_ident(_property_ident.name));
}
public override void visit(foreach_stmt_formatting fe)
{
WriteKeyword("foreach");
@ -3485,4 +3497,6 @@ namespace CodeFormatters
}
#endregion
}
}

View file

@ -143,7 +143,7 @@ namespace PascalABCCompiler.SyntaxTree
CompareInternal(left.expr, right.expr);
}
}
public void CompareInternal(assign_var_tuple left, assign_var_tuple right)
{
if (left == null && right != null || left != null && right == null)
@ -154,7 +154,7 @@ namespace PascalABCCompiler.SyntaxTree
CompareInternal(left.expr, right.expr);
}
}
public void CompareInternal(loop_stmt left, loop_stmt right)
{
if (left == null && right != null || left != null && right == null)
@ -452,7 +452,7 @@ namespace PascalABCCompiler.SyntaxTree
throw_not_equal(left, right);
if (left != null && right != null)
{
}
}
@ -544,7 +544,7 @@ namespace PascalABCCompiler.SyntaxTree
throw_not_equal(left, right);
if (left != null && right != null)
{
}
}
@ -716,6 +716,10 @@ namespace PascalABCCompiler.SyntaxTree
CompareInternal(left as dot_question_node, right as dot_question_node);
else if (left is double_question_node)
CompareInternal(left as double_question_node, right as double_question_node);
else if (left is bigint_const)
CompareInternal(left as bigint_const, right as bigint_const);
else if (left is array_const_new)
CompareInternal(left as array_const_new, right as array_const_new);
else
throw new NotImplementedException(left.GetType().ToString());
@ -1022,7 +1026,7 @@ namespace PascalABCCompiler.SyntaxTree
throw_not_equal(left, right);
if (left != null && right != null)
{
}
}
@ -1435,7 +1439,7 @@ namespace PascalABCCompiler.SyntaxTree
throw_not_equal(left, right);
if (left != null && right != null)
{
}
}
@ -1711,6 +1715,8 @@ namespace PascalABCCompiler.SyntaxTree
CompareInternal(left as assign_tuple, right as assign_tuple);
else if (left is assign_var_tuple)
CompareInternal(left as assign_var_tuple, right as assign_var_tuple);
else if (left is match_with)
CompareInternal(left as match_with, right as match_with);
//else if (left is expression) // SSM 12/06/15
// CompareInternal(left as expression, right as expression);
@ -1951,7 +1957,7 @@ namespace PascalABCCompiler.SyntaxTree
throw_not_equal(left, right);
if (left != null && right != null)
{
}
}
@ -2366,7 +2372,7 @@ namespace PascalABCCompiler.SyntaxTree
CompareInternal(left.if_false, right.if_false);
}
}
public void CompareInternal(dot_question_node left, dot_question_node right)
{
if (left == null && right != null || left != null && right == null)
@ -2377,7 +2383,7 @@ namespace PascalABCCompiler.SyntaxTree
CompareInternal(left.right, right.right);
}
}
public void CompareInternal(double_question_node left, double_question_node right)
{
if (left == null && right != null || left != null && right == null)
@ -2388,5 +2394,89 @@ namespace PascalABCCompiler.SyntaxTree
CompareInternal(left.right, right.right);
}
}
public void CompareInternal(property_ident left, property_ident right)
{
if (left == null && right != null || left != null && right == null)
throw_not_equal(left, right);
if (left != null && right != null)
{
if (left.ln != null && right.ln == null)
throw_not_equal(left, right);
if (left.ln == null && right.ln != null)
throw_not_equal(left, right);
if (left.ln != null && right.ln != null)
{
if (left.ln.Count != right.ln.Count)
throw_not_equal(left, right);
for (int i = 0; i < left.ln.Count; i++)
{
CompareInternal(left.ln[i], right.ln[i]);
}
}
if (string.Compare(left.name, right.name, true) != 0)
throw_not_equal(left, right);
}
}
public void CompareInternal(bigint_const left, bigint_const right)
{
if (left == null && right != null || left != null && right == null)
throw_not_equal(left, right);
if (left != null && right != null)
{
if (left.val != right.val)
throw_not_equal(left, right);
}
}
public void CompareInternal(match_with left, match_with right)
{
if (left == null && right != null || left != null && right == null)
throw_not_equal(left, right);
if (left != null && right != null)
{
CompareInternal(left.expr, right.expr);
CompareInternal(left.defaultAction, right.defaultAction);
CompareInternal(left.case_list, right.case_list);
}
}
public void CompareInternal(pattern_cases left, pattern_cases right)
{
if (left == null && right != null || left != null && right == null)
throw_not_equal(left, right);
if (left != null && right != null)
{
if (left.Count != right.Count)
throw_not_equal(left, right);
for (int i = 0; i < left.Count; i++)
CompareInternal(left.elements[i], right.elements[i]);
}
}
public void CompareInternal(pattern_case left, pattern_case right)
{
if (left == null && right != null || left != null && right == null)
throw_not_equal(left, right);
if (left != null && right != null)
{
CompareInternal(left.case_action, right.case_action);
CompareInternal(left.condition, right.condition);
}
}
public void CompareInternal(array_const_new left, array_const_new right)
{
if (left == null && right != null || left != null && right == null)
throw_not_equal(left, right);
if (left != null && right != null)
{
if (left.elements.Count != right.elements.Count)
throw_not_equal(left, right);
for (int i = 0; i < left.elements.Count; i++)
CompareInternal(left.elements.expressions[i], right.elements.expressions[i]);
}
}
}
}

View file

@ -1,9 +1,9 @@
//
// This CSharp output file generated by Gardens Point LEX
// Version: 1.1.3.301
// Machine: DESKTOP-G8V08V4
// DateTime: 14.03.2021 20:13:22
// UserName: ?????????
// Machine: DESKTOP-2BJCJ7I
// DateTime: 28.03.2021 12:12:58
// UserName: ibond
// GPLEX input file <ABCPascal.lex>
// GPLEX frame file <embedded resource>
//

View file

@ -2040,11 +2040,11 @@ property_definition
;
simple_property_definition
: tkProperty qualified_identifier property_interface property_specifiers tkSemiColon array_defaultproperty
: tkProperty func_name property_interface property_specifiers tkSemiColon array_defaultproperty
{
$$ = NewSimplePropertyDefinition($2 as method_name, $3 as property_interface, $4 as property_accessors, proc_attribute.attr_none, $6 as property_array_default, @$);
}
| tkProperty qualified_identifier property_interface property_specifiers tkSemiColon property_modificator tkSemiColon array_defaultproperty
| tkProperty func_name property_interface property_specifiers tkSemiColon property_modificator tkSemiColon array_defaultproperty
{
proc_attribute pa = proc_attribute.attr_none;
if ($6.name.ToLower() == "virtual")
@ -2055,22 +2055,22 @@ simple_property_definition
pa = proc_attribute.attr_abstract;
$$ = NewSimplePropertyDefinition($2 as method_name, $3 as property_interface, $4 as property_accessors, pa, $8 as property_array_default, @$);
}
| class_or_static tkProperty qualified_identifier property_interface property_specifiers tkSemiColon array_defaultproperty
| class_or_static tkProperty func_name property_interface property_specifiers tkSemiColon array_defaultproperty
{
$$ = NewSimplePropertyDefinition($3 as method_name, $4 as property_interface, $5 as property_accessors, proc_attribute.attr_none, $7 as property_array_default, @$);
($$ as simple_property).attr = definition_attribute.Static;
}
| class_or_static tkProperty qualified_identifier property_interface property_specifiers tkSemiColon property_modificator tkSemiColon array_defaultproperty
| class_or_static tkProperty func_name property_interface property_specifiers tkSemiColon property_modificator tkSemiColon array_defaultproperty
{
parsertools.AddErrorFromResource("STATIC_PROPERTIES_CANNOT_HAVE_ATTRBUTE_{0}",@7,$7.name);
}
| tkAuto tkProperty qualified_identifier property_interface optional_property_initialization tkSemiColon
| tkAuto tkProperty func_name property_interface optional_property_initialization tkSemiColon
{
$$ = NewSimplePropertyDefinition($3 as method_name, $4 as property_interface, null, proc_attribute.attr_none, null, @$);
($$ as simple_property).is_auto = true;
($$ as simple_property).initial_value = $5;
}
| class_or_static tkAuto tkProperty qualified_identifier property_interface optional_property_initialization tkSemiColon
| class_or_static tkAuto tkProperty func_name property_interface optional_property_initialization tkSemiColon
{
$$ = NewSimplePropertyDefinition($4 as method_name, $5 as property_interface, null, proc_attribute.attr_none, null, @$);
($$ as simple_property).is_auto = true;

File diff suppressed because it is too large Load diff

View file

@ -174,7 +174,7 @@ namespace GPPGParserScanner
public method_name NewQualifiedIdentifier(method_name qualified_identifier, ident identifier, LexLocation loc)
{
var nqi = qualified_identifier;
nqi.class_name = nqi.meth_name;
nqi.class_name = nqi.meth_name;
nqi.meth_name = identifier;
nqi.source_context = loc;
return nqi;
@ -200,8 +200,15 @@ namespace GPPGParserScanner
{
var nnspd = new simple_property();
nnspd.virt_over_none_attr = virt_over_none_attr;
nnspd.property_name = qualified_identifier.meth_name;
List<ident> ln = null;
if (qualified_identifier.ln != null)
ln = qualified_identifier.ln;
else if (qualified_identifier.class_name != null)
{
ln = new List<ident>();
ln.Add(qualified_identifier.class_name);
}
nnspd.property_name = new property_ident(qualified_identifier.meth_name.name, ln, qualified_identifier.source_context);
if (property_interface != null)
{
nnspd.parameter_list = property_interface.parameter_list;

View file

@ -1292,6 +1292,11 @@ namespace PascalABCCompiler.SyntaxTree
{
DefaultVisit(_foreach_stmt_formatting);
}
public virtual void visit(property_ident _property_ident)
{
DefaultVisit(_property_ident);
}
}

View file

@ -2061,6 +2061,14 @@ namespace PascalABCCompiler.SyntaxTree
{
}
public virtual void pre_do_visit(property_ident _property_ident)
{
}
public virtual void post_do_visit(property_ident _property_ident)
{
}
public override void visit(expression _expression)
{
DefaultVisit(_expression);
@ -4256,6 +4264,15 @@ namespace PascalABCCompiler.SyntaxTree
visit(foreach_stmt_formatting.stmt);
post_do_visit(_foreach_stmt_formatting);
}
public override void visit(property_ident _property_ident)
{
DefaultVisit(_property_ident);
pre_do_visit(_property_ident);
for (int i = 0; i < ln.Count; i++)
visit(property_ident.ln[i]);
post_do_visit(_property_ident);
}
}

View file

@ -112,7 +112,7 @@ namespace PascalABCCompiler.SyntaxTree
public static simple_property BuildSimpleReadWriteProperty(ident name, ident field, type_definition type)
{
return new simple_property(name, type, new property_accessors(new read_accessor_name(field,null,null), new write_accessor_name(field, null, null)));
return new simple_property(new property_ident(name.name, null, name.source_context), type, new property_accessors(new read_accessor_name(field,null,null), new write_accessor_name(field, null, null)));
}
public static class_members BuildSimpleReadPropertiesSection(List<ident> names, List<ident> fields, List<type_definition> types)

View file

@ -534,6 +534,8 @@ namespace PascalABCCompiler.SyntaxTree
return new bigint_const();
case 256:
return new foreach_stmt_formatting();
case 257:
return new property_ident();
}
return null;
}
@ -1724,7 +1726,7 @@ namespace PascalABCCompiler.SyntaxTree
public void read_simple_property(simple_property _simple_property)
{
read_declaration(_simple_property);
_simple_property.property_name = _read_node() as ident;
_simple_property.property_name = _read_node() as property_ident;
_simple_property.property_type = _read_node() as type_definition;
_simple_property.index_expression = _read_node() as expression;
_simple_property.accessors = _read_node() as property_accessors;
@ -4475,6 +4477,30 @@ namespace PascalABCCompiler.SyntaxTree
_foreach_stmt_formatting.stmt = _read_node() as statement;
}
public void visit(property_ident _property_ident)
{
read_property_ident(_property_ident);
}
public void read_property_ident(property_ident _property_ident)
{
read_ident(_property_ident);
if (br.ReadByte() == 0)
{
_property_ident.ln = null;
}
else
{
_property_ident.ln = new List<ident>();
Int32 ssyy_count = br.ReadInt32();
for(Int32 ssyy_i = 0; ssyy_i < ssyy_count; ssyy_i++)
{
_property_ident.ln.Add(_read_node() as ident);
}
}
}
}

View file

@ -7011,6 +7011,39 @@ namespace PascalABCCompiler.SyntaxTree
}
}
public void visit(property_ident _property_ident)
{
bw.Write((Int16)257);
write_property_ident(_property_ident);
}
public void write_property_ident(property_ident _property_ident)
{
write_ident(_property_ident);
if (_property_ident.ln == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
bw.Write(_property_ident.ln.Count);
for(Int32 ssyy_i = 0; ssyy_i < _property_ident.ln.Count; ssyy_i++)
{
if (_property_ident.ln[ssyy_i] == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_property_ident.ln[ssyy_i].visit(this);
}
}
}
}
}

View file

@ -16294,7 +16294,7 @@ namespace PascalABCCompiler.SyntaxTree
///<summary>
///Конструктор с параметрами.
///</summary>
public simple_property(ident _property_name,type_definition _property_type,expression _index_expression,property_accessors _accessors,property_array_default _array_default,property_parameter_list _parameter_list,definition_attribute _attr,proc_attribute _virt_over_none_attr,bool _is_auto,expression _initial_value)
public simple_property(property_ident _property_name,type_definition _property_type,expression _index_expression,property_accessors _accessors,property_array_default _array_default,property_parameter_list _parameter_list,definition_attribute _attr,proc_attribute _virt_over_none_attr,bool _is_auto,expression _initial_value)
{
this._property_name=_property_name;
this._property_type=_property_type;
@ -16312,7 +16312,7 @@ namespace PascalABCCompiler.SyntaxTree
///<summary>
///Конструктор с параметрами.
///</summary>
public simple_property(ident _property_name,type_definition _property_type,expression _index_expression,property_accessors _accessors,property_array_default _array_default,property_parameter_list _parameter_list,definition_attribute _attr,proc_attribute _virt_over_none_attr,bool _is_auto,expression _initial_value,SourceContext sc)
public simple_property(property_ident _property_name,type_definition _property_type,expression _index_expression,property_accessors _accessors,property_array_default _array_default,property_parameter_list _parameter_list,definition_attribute _attr,proc_attribute _virt_over_none_attr,bool _is_auto,expression _initial_value,SourceContext sc)
{
this._property_name=_property_name;
this._property_type=_property_type;
@ -16327,7 +16327,7 @@ namespace PascalABCCompiler.SyntaxTree
source_context = sc;
FillParentsInDirectChilds();
}
protected ident _property_name;
protected property_ident _property_name;
protected type_definition _property_type;
protected expression _index_expression;
protected property_accessors _accessors;
@ -16341,7 +16341,7 @@ namespace PascalABCCompiler.SyntaxTree
///<summary>
///
///</summary>
public ident property_name
public property_ident property_name
{
get
{
@ -16517,7 +16517,7 @@ namespace PascalABCCompiler.SyntaxTree
}
if (property_name != null)
{
copy.property_name = (ident)property_name.Clone();
copy.property_name = (property_ident)property_name.Clone();
copy.property_name.Parent = copy;
}
if (property_type != null)
@ -16652,7 +16652,7 @@ namespace PascalABCCompiler.SyntaxTree
switch(ind)
{
case 0:
property_name = (ident)value;
property_name = (property_ident)value;
break;
case 1:
property_type = (type_definition)value;
@ -16727,7 +16727,7 @@ namespace PascalABCCompiler.SyntaxTree
///<summary>
///Конструктор с параметрами.
///</summary>
public index_property(ident _property_name,type_definition _property_type,expression _index_expression,property_accessors _accessors,property_array_default _array_default,property_parameter_list _parameter_list,definition_attribute _attr,proc_attribute _virt_over_none_attr,bool _is_auto,expression _initial_value,formal_parameters _property_parametres,default_indexer_property_node _is_default)
public index_property(property_ident _property_name,type_definition _property_type,expression _index_expression,property_accessors _accessors,property_array_default _array_default,property_parameter_list _parameter_list,definition_attribute _attr,proc_attribute _virt_over_none_attr,bool _is_auto,expression _initial_value,formal_parameters _property_parametres,default_indexer_property_node _is_default)
{
this._property_name=_property_name;
this._property_type=_property_type;
@ -16747,7 +16747,7 @@ namespace PascalABCCompiler.SyntaxTree
///<summary>
///Конструктор с параметрами.
///</summary>
public index_property(ident _property_name,type_definition _property_type,expression _index_expression,property_accessors _accessors,property_array_default _array_default,property_parameter_list _parameter_list,definition_attribute _attr,proc_attribute _virt_over_none_attr,bool _is_auto,expression _initial_value,formal_parameters _property_parametres,default_indexer_property_node _is_default,SourceContext sc)
public index_property(property_ident _property_name,type_definition _property_type,expression _index_expression,property_accessors _accessors,property_array_default _array_default,property_parameter_list _parameter_list,definition_attribute _attr,proc_attribute _virt_over_none_attr,bool _is_auto,expression _initial_value,formal_parameters _property_parametres,default_indexer_property_node _is_default,SourceContext sc)
{
this._property_name=_property_name;
this._property_type=_property_type;
@ -16816,7 +16816,7 @@ namespace PascalABCCompiler.SyntaxTree
}
if (property_name != null)
{
copy.property_name = (ident)property_name.Clone();
copy.property_name = (property_ident)property_name.Clone();
copy.property_name.Parent = copy;
}
if (property_type != null)
@ -16971,7 +16971,7 @@ namespace PascalABCCompiler.SyntaxTree
switch(ind)
{
case 0:
property_name = (ident)value;
property_name = (property_ident)value;
break;
case 1:
property_type = (type_definition)value;
@ -54740,6 +54740,359 @@ namespace PascalABCCompiler.SyntaxTree
}
///<summary>
///
///</summary>
[Serializable]
public partial class property_ident : ident
{
///<summary>
///Конструктор без параметров.
///</summary>
public property_ident()
{
}
///<summary>
///Конструктор с параметрами.
///</summary>
public property_ident(List<ident> _ln)
{
this._ln=_ln;
FillParentsInDirectChilds();
}
///<summary>
///Конструктор с параметрами.
///</summary>
public property_ident(List<ident> _ln,SourceContext sc)
{
this._ln=_ln;
source_context = sc;
FillParentsInDirectChilds();
}
///<summary>
///Конструктор с параметрами.
///</summary>
public property_ident(string _name,List<ident> _ln)
{
this._name=_name;
this._ln=_ln;
FillParentsInDirectChilds();
}
///<summary>
///Конструктор с параметрами.
///</summary>
public property_ident(string _name,List<ident> _ln,SourceContext sc)
{
this._name=_name;
this._ln=_ln;
source_context = sc;
FillParentsInDirectChilds();
}
public property_ident(ident elem, SourceContext sc = null)
{
Add(elem, sc);
FillParentsInDirectChilds();
}
protected List<ident> _ln;
///<summary>
///
///</summary>
public List<ident> ln
{
get
{
return _ln;
}
set
{
_ln=value;
}
}
public property_ident Add(ident elem, SourceContext sc = null)
{
ln.Add(elem);
if (elem != null)
elem.Parent = this;
if (sc != null)
source_context = sc;
return this;
}
public void AddFirst(ident el)
{
if (el == null)
throw new ArgumentNullException(nameof(el));
ln.Insert(0, el);
FillParentsInDirectChilds();
}
public void AddFirst(IEnumerable<ident> els)
{
if (els == null)
throw new ArgumentNullException(nameof(els));
ln.InsertRange(0, els);
foreach (var el in els)
if (el != null)
el.Parent = this;
}
public void AddMany(params ident[] els)
{
if (els == null)
throw new ArgumentNullException(nameof(els));
ln.AddRange(els);
foreach (var el in els)
if (el != null)
el.Parent = this;
}
private int FindIndexInList(ident el)
{
if (el == null)
throw new ArgumentNullException(nameof(el));
var ind = ln.FindIndex(x => x == el);
if (ind == -1)
throw new Exception(string.Format("У списка {0} не найден элемент {1} среди дочерних\n", this, el));
return ind;
}
public void InsertAfter(ident el, ident newel)
{
if (el == null)
throw new ArgumentNullException(nameof(el));
if (newel == null)
throw new ArgumentNullException(nameof(newel));
ln.Insert(FindIndexInList(el) + 1, newel);
newel.Parent = this;
}
public void InsertAfter(ident el, IEnumerable<ident> newels)
{
if (el == null)
throw new ArgumentNullException(nameof(el));
if (newels == null)
throw new ArgumentNullException(nameof(newels));
ln.InsertRange(FindIndexInList(el) + 1, newels);
foreach (var newel in newels)
if (newel != null)
newel.Parent = this;
}
public void InsertBefore(ident el, ident newel)
{
if (el == null)
throw new ArgumentNullException(nameof(el));
if (newel == null)
throw new ArgumentNullException(nameof(newel));
ln.Insert(FindIndexInList(el), newel);
newel.Parent = this;
}
public void InsertBefore(ident el, IEnumerable<ident> newels)
{
if (el == null)
throw new ArgumentNullException(nameof(el));
if (newels == null)
throw new ArgumentNullException(nameof(newels));
ln.InsertRange(FindIndexInList(el), newels);
foreach (var newel in newels)
if (newel != null)
newel.Parent = this;
}
public bool Remove(ident el)
{
return ln.Remove(el);
}
public void ReplaceInList(ident el, ident newel)
{
if (el == null)
throw new ArgumentNullException(nameof(el));
if (newel == null)
throw new ArgumentNullException(nameof(newel));
ln[FindIndexInList(el)] = newel;
newel.Parent = this;
}
public void ReplaceInList(ident el, IEnumerable<ident> newels)
{
if (el == null)
throw new ArgumentNullException(nameof(el));
if (newels == null)
throw new ArgumentNullException(nameof(newels));
var ind = FindIndexInList(el);
ln.RemoveAt(ind);
ln.InsertRange(ind, newels);
foreach (var newel in newels)
if (newel != null)
newel.Parent = this;
}
public int RemoveAll(Predicate<ident> match)
{
return ln.RemoveAll(match);
}
public ident Last()
{
if (ln.Count > 0)
return ln[ln.Count - 1];
throw new InvalidOperationException("Список пуст");
}
public int Count
{
get { return ln.Count; }
}
public void Insert(int pos, ident el)
{
if (el == null)
throw new ArgumentNullException(nameof(el));
ln.Insert(pos,el);
if (el != null)
el.Parent = this;
}
/// <summary> Создает копию узла </summary>
public override syntax_tree_node Clone()
{
property_ident copy = new property_ident();
copy.Parent = this.Parent;
if (source_context != null)
copy.source_context = new SourceContext(source_context);
if (attributes != null)
{
copy.attributes = (attribute_list)attributes.Clone();
copy.attributes.Parent = copy;
}
copy.name = name;
if (ln != null)
{
foreach (ident elem in ln)
{
if (elem != null)
{
copy.Add((ident)elem.Clone());
copy.Last().Parent = copy;
}
else
copy.Add(null);
}
}
return copy;
}
/// <summary> Получает копию данного узла корректного типа </summary>
public new property_ident TypedClone()
{
return Clone() as property_ident;
}
///<summary> Заполняет поля Parent в непосредственных дочерних узлах </summary>
public override void FillParentsInDirectChilds()
{
if (attributes != null)
attributes.Parent = this;
if (ln != null)
{
foreach (var child in ln)
if (child != null)
child.Parent = this;
}
}
///<summary> Заполняет поля Parent во всем поддереве </summary>
public override void FillParentsInAllChilds()
{
FillParentsInDirectChilds();
attributes?.FillParentsInAllChilds();
if (ln != null)
{
foreach (var child in ln)
child?.FillParentsInAllChilds();
}
}
///<summary>
///Свойство для получения количества всех подузлов без элементов поля типа List
///</summary>
public override Int32 subnodes_without_list_elements_count
{
get
{
return 0;
}
}
///<summary>
///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List
///</summary>
public override Int32 subnodes_count
{
get
{
return 0 + (ln == null ? 0 : ln.Count);
}
}
///<summary>
///Индексатор для получения всех подузлов
///</summary>
public override syntax_tree_node this[Int32 ind]
{
get
{
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException();
Int32 index_counter=ind - 0;
if(ln != null)
{
if(index_counter < ln.Count)
{
return ln[index_counter];
}
}
return null;
}
set
{
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException();
Int32 index_counter=ind - 0;
if(ln != null)
{
if(index_counter < ln.Count)
{
ln[index_counter]= (ident)value;
return;
}
}
}
}
///<summary>
///Метод для обхода дерева посетителем
///</summary>
///<param name="visitor">Объект-посетитель.</param>
///<returns>Return value is void</returns>
public override void visit(IVisitor visitor)
{
visitor.visit(this);
}
}
}

View file

@ -1123,7 +1123,7 @@ namespace PascalABCCompiler.SyntaxTree
public partial class simple_property
{
public simple_property(ident name, type_definition type, property_accessors accessors, SourceContext sc = null)
public simple_property(property_ident name, type_definition type, property_accessors accessors, SourceContext sc = null)
: this(name, type, null, accessors, null, null, definition_attribute.None, proc_attribute.attr_none, false, null, sc)
{ }
}

View file

@ -1546,6 +1546,12 @@ namespace PascalABCCompiler.SyntaxTree
///<param name="_foreach_stmt_formatting">Node to visit</param>
///<returns> Return value is void </returns>
void visit(foreach_stmt_formatting _foreach_stmt_formatting);
///<summary>
///Method to visit property_ident.
///</summary>
///<param name="_property_ident">Node to visit</param>
///<returns> Return value is void </returns>
void visit(property_ident _property_ident);
}

View file

@ -1013,7 +1013,7 @@
</SyntaxNode>
<SyntaxNode Name="simple_property" BaseName="declaration">
<Fields>
<SyntaxField Name="property_name" SyntaxType="ident" />
<SyntaxField Name="property_name" SyntaxType="property_ident" />
<SyntaxField Name="property_type" SyntaxType="type_definition" />
<SyntaxField Name="index_expression" SyntaxType="expression" />
<SyntaxField Name="accessors" SyntaxType="property_accessors" />
@ -3313,6 +3313,16 @@
<TagIndices />
</Tags>
</SyntaxNode>
<SyntaxNode Name="property_ident" BaseName="ident">
<Fields>
<ExtendedField Name="ln" Type="List&lt;ident&gt;" CreateVariable="false" DeleteVariable="false" />
</Fields>
<Methods />
<Tags>
<CategoryIndices />
<TagIndices />
</Tags>
</SyntaxNode>
</SyntaxNodes>
<Settings>
<FileName>Tree.cs</FileName>
@ -3391,6 +3401,7 @@
<HelpData Key=".left" Value="" />
<HelpData Key=".lists" Value="" />
<HelpData Key=".listunitsections" Value="" />
<HelpData Key=".ln" Value="" />
<HelpData Key=".mark" Value="" />
<HelpData Key=".name" Value="" />
<HelpData Key=".name_expr" Value="" />
@ -4336,11 +4347,15 @@
<HelpData Key="program_tree.program_tree Add(compilation_unit _compilation_unit)" Value="" />
<HelpData Key="program_tree.program_tree Add(compilation_unit _compilation_unit, SourceContext sc)" Value="" />
<HelpData Key="program_tree.program_tree(compilation_unit _compilation_unit, SourceContext sc)" Value="" />
<HelpData Key="properpty_ident" Value="" />
<HelpData Key="properpty_ident.ln" Value="" />
<HelpData Key="property_accessors" Value="" />
<HelpData Key="property_accessors.property_accessors(ident read_accessor, ident write_accessor): this(new read_accessor_name(read_accessor), new write_accessor_name(write_accessor))" Value="" />
<HelpData Key="property_accessors.read_accessor" Value="" />
<HelpData Key="property_accessors.write_accessor" Value="" />
<HelpData Key="property_array_default" Value="" />
<HelpData Key="property_ident" Value="" />
<HelpData Key="property_ident.ln" Value="" />
<HelpData Key="property_interface" Value="" />
<HelpData Key="property_interface." Value="" />
<HelpData Key="property_interface.index_expression" Value="" />

View file

@ -0,0 +1,20 @@
type
I1 = interface
property X: byte read;
end;
I2 = interface
property X: byte read;
end;
T = class(I1, I2)
public
property I1.X: byte read 0;
//I2.X не реализовано, но компиляция успешна
end;
begin
var x := new T();
Writeln(I1(x).X);
Writeln(I2(x).X);
end.

View file

@ -0,0 +1,14 @@
type
I1 = interface
property X: byte read;
end;
T = class(I1)
public
property T.X: byte read 0;
end;
begin
var x := new T();
Writeln(I1(x).X);
end.

View file

@ -0,0 +1,16 @@
type
I1<T> = interface
property X: integer read;
end;
T1<T> = record(I1<T>)
property X: integer read 1;
property I1<T>.X: integer read 2;
end;
begin
var r: T1<integer>;
assert(r.X = 1);
var r1: I1<integer> := r;
assert(r1.X = 2);
end.

View file

@ -0,0 +1,16 @@
type
I1 = interface
property X: integer read;
end;
T1 = record(I1)
property X: integer read 1;
property I1.X: integer read 2;
end;
begin
var r: T1;
assert(r.X = 1);
var r1: I1 := r;
assert(r1.X = 2);
end.

View file

@ -376,8 +376,12 @@ procedure MoveRel(dx,dy: real);
/// Рисует отрезок от текущей позиции до точки, смещённой на вектор (dx,dy). Текущая позиция переносится в новую точку
procedure LineRel(dx,dy: real);
/// Перемещает текущую позицию рисования на вектор (dx,dy)
procedure MoveOn(dx,dy: real);
procedure MoveBy(dx,dy: real);
/// Рисует отрезок от текущей позиции до точки, смещённой на вектор (dx,dy). Текущая позиция переносится в новую точку
procedure LineBy(dx,dy: real);
///--
procedure MoveOn(dx,dy: real);
///--
procedure LineOn(dx,dy: real);
/// Рисует ломаную, заданную массивом точек
@ -1206,6 +1210,8 @@ procedure MoveRel(dx,dy: real) := (Pen.fx,Pen.fy) := (Pen.fx + dx, Pen.fy + dy);
procedure LineRel(dx,dy: real) := LineTo(Pen.fx + dx, Pen.fy + dy);
procedure MoveOn(dx,dy: real) := MoveRel(dx,dy);
procedure LineOn(dx,dy: real) := LineRel(dx,dy);
procedure MoveBy(dx,dy: real) := MoveRel(dx,dy);
procedure LineBy(dx,dy: real) := LineRel(dx,dy);
procedure PolyLine(points: array of Point) := InvokeVisual(PolyLineP,points);
procedure PolyLine(points: array of Point; c: GColor) := InvokeVisual(PolyLinePC,points,c);
@ -1614,6 +1620,11 @@ begin
var sz := Size(host.DataContext);
if sz.Width = 0 then
sz.Width := GraphWindow.Width;
if sz.Height = 0 then
sz.Height := GraphWindow.Height;
var bmp := new RenderTargetBitmap(Round(sz.Width*scalex), Round(sz.Height*scaley), dpiX, dpiY, PixelFormats.Pbgra32);
var myvis := new DrawingVisual();

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -858,9 +858,10 @@ namespace PascalABCCompiler.TreeConverter
}
//Нахождение узла по имени либо точечному имени (напр. Unit1.type1)
public List<SymbolInfo> find_definition_node(SyntaxTree.named_type_reference names, location loc) // SSM перебросил сюда из syntax_tree_visitor 3.04.14
public List<SymbolInfo> find_definition_node(SyntaxTree.named_type_reference names, location loc, bool throw_error = false) // SSM перебросил сюда из syntax_tree_visitor 3.04.14
{
definition_node di = null;
List<SymbolInfo> si = null;
if (names.names.Count > 1)
{
di = convert_names_to_namespace(names, loc);
@ -870,18 +871,28 @@ namespace PascalABCCompiler.TreeConverter
int num = names.names.Count - 1;
if (di is namespace_node)
{
return (di as namespace_node).find(names.names[num].name);
si = (di as namespace_node).find(names.names[num].name);
if (si == null && throw_error)
AddError(new UndefinedNameReference(names.names[num].name, syntax_tree_visitor.get_location(names.names[num])));
}
else if (di is type_node)
{
return (di as type_node).find_in_type(names.names[num].name);
si = (di as type_node).find_in_type(names.names[num].name);
if (si == null && throw_error)
AddError(new UndefinedNameReference(names.names[num].name, syntax_tree_visitor.get_location(names.names[num])));
}
else
{
return (di as unit_node).find_only_in_namespace(names.names[num].name);
si = (di as unit_node).find_only_in_namespace(names.names[num].name);
if (si == null && throw_error)
AddError(new UndefinedNameReference(names.names[num].name, syntax_tree_visitor.get_location(names.names[num])));
}
return si;
}
return find(names.names[0].name);
si = find(names.names[0].name);
if (si == null && throw_error)
AddError(new UndefinedNameReference(names.names[0].name, syntax_tree_visitor.get_location(names.names[0])));
return si;
}
//\ssyy
@ -2263,7 +2274,6 @@ namespace PascalABCCompiler.TreeConverter
{
return _ctn.base_generic_instance.ConvertSymbolInfo(sil);
}
return sil;
}
@ -3524,7 +3534,7 @@ namespace PascalABCCompiler.TreeConverter
}
}
public common_property_node add_property(string property_name,location loc)
public common_property_node add_property(string property_name, location loc)
{
if (_ctn==null)
{
@ -3742,6 +3752,40 @@ namespace PascalABCCompiler.TreeConverter
return fn;
}
public property_node FindPropertyToImplement(common_property_node cpn, string pure_name, type_node interf)
{
List<SymbolInfo> sil = interf.find_in_type(pure_name, CurrentScope);
property_node pn = null;
SymbolInfo find_property = null;
if (sil != null)
{
foreach (SymbolInfo si in sil)
{
if (si.sym_info.general_node_type != general_node_type.property_node)
{
return null;
}
pn = si.sym_info as property_node;
//(ssyy) Сверяем как параметры функций, так и типы возвращаемых значений
if (cpn.get_function == null && pn.get_function == null && pn.property_type == cpn.property_type)
{
find_property = si;
break;
}
else if (cpn.get_function != null && pn.get_function != null && convertion_data_and_alghoritms.function_eq_params_and_result(cpn.get_function, pn.get_function))
{
find_property = si;
break;
}
}
}
if (find_property == null)
{
return null;
}
return pn;
}
public property_node FindPropertyToOverride(common_property_node cpn)
{
type_node base_class = cpn.common_comprehensive_type.base_type;
@ -3816,7 +3860,7 @@ namespace PascalABCCompiler.TreeConverter
{
(cpn.get_function as common_method_node).overrided_method = overrided_property.get_function;
(cpn.get_function as common_method_node).polymorphic_state = SemanticTree.polymorphic_state.ps_virtual;
}
}
if (cpn.set_function is common_method_node)
{
(cpn.set_function as common_method_node).overrided_method = overrided_property.set_function;
@ -3825,6 +3869,28 @@ namespace PascalABCCompiler.TreeConverter
}
}
public void set_implement(common_property_node cpn, string pure_name, type_node interf)
{
property_node overrided_property = FindPropertyToImplement(cpn, pure_name, interf);
if (overrided_property == null)
AddError(cpn.loc, "NO_PROPERTY_TO_OVERRIDE");
else
{
if (cpn.get_function is common_method_node)
{
(cpn.get_function as common_method_node).overrided_method = overrided_property.get_function;
(cpn.get_function as common_method_node).is_final = true;
(cpn.get_function as common_method_node).newslot_awaited = true;
}
if (cpn.set_function is common_method_node)
{
(cpn.set_function as common_method_node).overrided_method = overrided_property.set_function;
(cpn.set_function as common_method_node).is_final = true;
(cpn.set_function as common_method_node).newslot_awaited = true;
}
}
}
public void set_override(common_method_node cmn)
{
cmn.polymorphic_state = SemanticTree.polymorphic_state.ps_virtual;

View file

@ -4257,9 +4257,29 @@ namespace PascalABCCompiler.TreeConverter
AddError(get_location(_simple_property), "PROPERTYACCESSOR_{0}_OR_{1}_EXPECTED", compiler_string_consts.PascalReadAccessorName, compiler_string_consts.PascalWriteAccessorName);
if (_simple_property.property_type == null)
AddError(get_location(_simple_property.property_name), "TYPE_NAME_EXPECTED");
common_property_node pn = context.add_property(_simple_property.property_name.name,
get_location(_simple_property.property_name));
string name = _simple_property.property_name.name;
type_node expl_interface = null;
if (_simple_property.property_name.ln != null)
{
for (var i = 0; i < _simple_property.property_name.ln.Count - 1; i++)
if (_simple_property.property_name.ln[i] is SyntaxTree.template_type_name)
AddError(new NameCannotHaveGenericParameters(_simple_property.property_name.ln[i].name, get_location(_simple_property.property_name.ln[i])));
var ntr = new SyntaxTree.named_type_reference();
for (var i = 0; i < _simple_property.property_name.ln.Count; i++)
{
ntr.Add(new ident(_simple_property.property_name.ln[i].name+
(_simple_property.property_name.ln[i] is template_type_name ? "`"+(_simple_property.property_name.ln[i] as template_type_name).template_args.Count :""), _simple_property.property_name.ln[i].source_context));
}
List<SymbolInfo> sil = context.find_definition_node(ntr, get_location(_simple_property.property_name), true);
if (!(sil[0].sym_info as type_node).IsInterface)
AddError(get_location(_simple_property.property_name), "INTERFACE_AWAITED");
name = (sil[0].sym_info as type_node).BaseFullName + "." + name;
expl_interface = sil[0].sym_info as type_node;
}
common_property_node pn = context.add_property(name, get_location(_simple_property.property_name));
assign_doc_info(pn, _simple_property);
//pn.polymorphic_state=SemanticTree.polymorphic_state.ps_common;
//pn.loc=get_location(_simple_property.property_name);
@ -4605,6 +4625,11 @@ namespace PascalABCCompiler.TreeConverter
make_attributes_for_declaration(_simple_property,pn);
if (_simple_property.virt_over_none_attr == proc_attribute.attr_override)
context.set_override(pn);
else if (expl_interface != null)
{
context.set_implement(pn, _simple_property.property_name.name, expl_interface);
}
//TODO: Можно сделать множество свойств по умолчанию.
if (_simple_property.array_default != null)
{
@ -4622,8 +4647,14 @@ namespace PascalABCCompiler.TreeConverter
private function_node GenerateGetMethod(common_property_node cpn, common_method_node accessor, location loc)
{
string getter_name = "get_" + cpn.name;
if (cpn.name.IndexOf('.') != -1)
{
string[] names = cpn.name.Split('.');
getter_name = names.Take(names.Length - 1).ToArray().JoinIntoString(".") + "get_" + names[names.Length - 1];
}
common_method_node cmn = new common_method_node(
"get_"+cpn.name, loc, cpn.common_comprehensive_type,
getter_name, loc, cpn.common_comprehensive_type,
cpn.polymorphic_state, cpn.field_access_level, null);
cpn.common_comprehensive_type.methods.AddElement(cmn);
cmn.return_value_type = cpn.property_type;
@ -4651,14 +4682,20 @@ namespace PascalABCCompiler.TreeConverter
}
}
cmn.function_code = new return_node(meth_call, loc);
cpn.common_comprehensive_type.scope.AddSymbol("get_" + cpn.name, new SymbolInfo(cmn));
cpn.common_comprehensive_type.scope.AddSymbol(getter_name, new SymbolInfo(cmn));
return cmn;
}
private function_node GenerateSetMethod(common_property_node cpn, common_method_node accessor, location loc)
{
string setter_name = "set_" + cpn.name;
if (cpn.name.IndexOf('.') != -1)
{
string[] names = cpn.name.Split('.');
setter_name = names.Take(names.Length - 1).ToArray().JoinIntoString(".") + "set_" + names[names.Length - 1];
}
common_method_node cmn = new common_method_node(
"set_" + cpn.name, loc, cpn.common_comprehensive_type,
setter_name, loc, cpn.common_comprehensive_type,
cpn.polymorphic_state, cpn.field_access_level, null);
cpn.common_comprehensive_type.methods.AddElement(cmn);
//cmn.return_value_type = cpn.property_type;
@ -4686,7 +4723,7 @@ namespace PascalABCCompiler.TreeConverter
}
}
cmn.function_code = meth_call;
cpn.common_comprehensive_type.scope.AddSymbol("set_" + cpn.name, new SymbolInfo(cmn));
cpn.common_comprehensive_type.scope.AddSymbol(setter_name, new SymbolInfo(cmn));
return cmn;
}

View file

@ -204,7 +204,9 @@ namespace PascalABCCompiler.TreeRealization
/// </summary>
private location _loc;
public common_property_node(string name, common_type_node comprehensive_type, location loc,
private type_node _explicit_interface;
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;
@ -318,7 +320,19 @@ namespace PascalABCCompiler.TreeRealization
}
}
public function_node internal_get_function
public type_node explicit_interface
{
get
{
return _explicit_interface;
}
set
{
_explicit_interface = value;
}
}
public function_node internal_get_function
{
get
{

View file

@ -169,6 +169,7 @@ PARTIAL_CLASS_PARENTS_MISMATCH=Partial declarations must not specify different b
PARAMETER_{0}_HAS_TYPE_{1}_FROM_UNIT_{2}=Parameter {0} has type {1} from unit {2}. Add unit {2} to uses section.
PARTIAL_CLASS_PREDEFINITION_NOT_ALLOWED=Predefinitions of partial classes are not allowed
AMBIGUOUS_DELEGATES=Ambiguous delegates detected
INTERFACE_AWAITED=Interface expected
%PREFIX%=COMPILATIONERROR_
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Unit expected, library found
ASSEMBLY_{0}_READING_ERROR=Error by reading assembly '{0}'

View file

@ -164,6 +164,7 @@ PARTIAL_CLASS_PARENTS_MISMATCH=partial-класс не может иметь и
PARAMETER_{0}_HAS_TYPE_{1}_FROM_UNIT_{2}=Параметр {0} имеет тип {1} из неподключенного модуля {2}. Добавьте модуль {2} в секцию uses.
PARTIAL_CLASS_PREDEFINITION_NOT_ALLOWED=Предописания partial-классов недопустимы
AMBIGUOUS_DELEGATES=Невозможно выбрать конкретный делегат из перегруженных
INTERFACE_AWAITED=Ожидалось имя интерфейса
%PREFIX%=COMPILATIONERROR_
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Ожидался модуль, а встречена библиотека
ASSEMBLY_{0}_READING_ERROR=Ошибка при чтении сборки '{0}'

View file

@ -161,6 +161,7 @@ PARTIAL_CLASS_PARENTS_MISMATCH=partial-класс не может иметь и
PARAMETER_{0}_HAS_TYPE_{1}_FROM_UNIT_{2}=Параметр {0} имеет тип {1} из неподключенного модуля {2}. Добавьте модуль {2} в секцию uses.
PARTIAL_CLASS_PREDEFINITION_NOT_ALLOWED=Предописания partial-классов недопустимы#
AMBIGUOUS_DELEGATES=Невозможно выбрать конкретный делегат из перегруженных
INTERFACE_AWAITED=Ожидалось имя интерфейса
%PREFIX%=COMPILATIONERROR_
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Очікувався модуль, а зустріли бібліотеку
ASSEMBLY_{0}_READING_ERROR=Помилка при читанні збірки '{0}'