2018-05-23 22:16:25 +03:00
|
|
|
|
using PascalABCCompiler.SyntaxTree;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
|
|
namespace SyntaxVisitors
|
|
|
|
|
|
{
|
|
|
|
|
|
public class SingleDeconstructChecker : BaseEnterExitVisitor
|
|
|
|
|
|
{
|
2023-05-31 14:04:04 +03:00
|
|
|
|
private const string DeconstructMethodName = "deconstruct"; // в трех местах эту константу - если менять
|
|
|
|
|
|
|
2018-05-23 22:16:25 +03:00
|
|
|
|
private int deconstructCount = 0;
|
|
|
|
|
|
private bool isInClass = false;
|
|
|
|
|
|
|
|
|
|
|
|
public static SingleDeconstructChecker New => new SingleDeconstructChecker();
|
|
|
|
|
|
|
|
|
|
|
|
public override void Enter(syntax_tree_node st)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (st is class_definition)
|
2018-05-25 16:28:24 +03:00
|
|
|
|
{
|
2018-05-23 22:16:25 +03:00
|
|
|
|
isInClass = true;
|
2018-05-25 16:28:24 +03:00
|
|
|
|
deconstructCount = 0;
|
|
|
|
|
|
}
|
2018-05-23 22:16:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void Exit(syntax_tree_node st)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (st is class_definition)
|
|
|
|
|
|
isInClass = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void visit(method_name _method_name)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!isInClass)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2023-05-31 14:04:04 +03:00
|
|
|
|
if (_method_name?.meth_name?.name?.ToLower() == DeconstructMethodName)
|
2018-05-23 22:16:25 +03:00
|
|
|
|
deconstructCount++;
|
|
|
|
|
|
|
|
|
|
|
|
if (deconstructCount > 1)
|
|
|
|
|
|
throw new SyntaxVisitorError("ONLY_ONE_DECONSTRUCT_ALLOWED", _method_name.Parent.source_context);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|