Exemplo n.º 1
0
        private void ClassNodeCheck(SyntaxisNode node, int level, string className)
        {
            //вконце проверка на непонятные переменные
            //заменяем новым массивом для этого класса, чтобы потом вернуть после проверки
            List <SyntaxisNode> notFoundReserve = notFoundPerem;

            notFoundPerem = new List <SyntaxisNode>();

            if (node.GetType() != typeof(ClassNode))
            {
                throw SymException.Show(SymExType.IncorrectNode, node);
            }

            levelIdentifiers.Insert(level - 1, new List <Identify>());
            ClassBodyNode _classBody = SymMethod.SearchForType(node.children, typeof(ClassBodyNode)) as ClassBodyNode;

            foreach (SyntaxisNode item in _classBody.children)
            {
                if (item.GetType() == typeof(ConstantDeclarationNode))
                {
                    int Pos = SymMethod.SearchPos(item.children, typeof(ConstantDeclaratorNode));
                    List <SyntaxisNode> list = SymMethod.Copy(item.children, Pos);
                    ConstantDeclaratorNodeCheck(list, level, className);
                    continue;
                }

                if (item.GetType() == typeof(FieldDeclarationNode))
                {
                    int Pos = SymMethod.SearchPos(item.children, typeof(VariableDeclaratorNode));
                    List <SyntaxisNode> list = SymMethod.Copy(item.children, Pos);
                    ConstantDeclaratorNodeCheck(list, level, className);//FieldDeclarationNodeCheck(list, level, className);
                    continue;
                }

                if (item.GetType() == typeof(ConstructorDeclarationNode))
                {
                    NodeIdentificator identify = SymMethod.SearchForType(item.children, typeof(NodeIdentificator)) as NodeIdentificator;

                    if (identify.token.GetText() != className)
                    {
                        throw new System.Exception("Неправильное имя конструктора: " + identify.ToString());
                    }

                    //ProgrammBlockNode pbNode
                    var pb = SymMethod.SearchForType(item.children, typeof(ProgrammBlockNode));
                    if (pb != null)
                    {
                        ProgrammBlockNodeCheck(pb, level + 1);
                    }
                }

                if (item.GetType() == typeof(DestructorDeclarationNode))
                {
                    NodeIdentificator identify = SymMethod.SearchForType(item.children, typeof(NodeIdentificator)) as NodeIdentificator;

                    if (identify.token.GetText() != className)
                    {
                        throw new System.Exception("Неправильное имя деструктора: " + identify.ToString());
                    }

                    //ProgrammBlockNode pbNode
                    var pb = SymMethod.SearchForType(item.children, typeof(ProgrammBlockNode));
                    if (pb != null)
                    {
                        ProgrammBlockNodeCheck(pb, level + 1);
                    }
                }

                if (item.GetType() == typeof(MethodDeclarationNode))
                {
                    NodeIdentificator identify = SymMethod.SearchForType(item.children, typeof(NodeIdentificator)) as NodeIdentificator;

                    if (identify.token.GetText() == className)
                    {
                        throw new System.Exception("Имя метода не должно совпадать с именем класса: " + identify.ToString());
                    }

                    //ProgrammBlockNode pbNode
                    var pb = SymMethod.SearchForType(item.children, typeof(ProgrammBlockNode));
                    if (pb != null)
                    {
                        ProgrammBlockNodeCheck(pb, level + 1);
                    }
                }
            }

            //проверка на ненайденные identify. Обязательно в конце класса или структуры
            foreach (SyntaxisNode item in notFoundPerem)
            {
                if (SymMethod.CheckUnique(levelIdentifiers, item.token.GetText(), level))
                {
                    throw SymException.Show(SymExType.NonexistentIdentify, item);
                }
            }
            //удаление данных

            notFoundPerem = notFoundReserve;
            levelIdentifiers.RemoveAt(level - 1);
        }
Exemplo n.º 2
0
        private static void WalkClass([NotNull] Agent agent, [CanBeNull] IdentifierNode id, [CanBeNull] ExpressionNode superClass, [NotNull] ClassBodyNode body)
        {
            //https://tc39.github.io/ecma262/#sec-class-definitions-static-semantics-early-errors

            if (id != null)
            {
                Walk(agent, id, true);
            }

            if (superClass == null)
            {
                var constructor = body.Body.FirstOrDefault(x => x.Kind == PropertyKind.Constructor);
                if (constructor != null)
                {
                    if (HasParameterSuper(constructor.Value.Parameters))
                    {
                        throw agent.CreateSyntaxError();
                    }
                    if (HasDirectSuper(constructor.Value.Body))
                    {
                        throw agent.CreateSyntaxError();
                    }
                }
            }

            foreach (var element in body.Body)
            {
                if (element.Kind != PropertyKind.Constructor)
                {
                    if (HasDirectSuper(element.Value.Body))
                    {
                        throw agent.CreateSyntaxError();
                    }
                }

                Walk(agent, element, true);
            }
        }