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