From bf2a95ef01d7bd63c5d8062e1973d239b8ac6f38 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Mon, 25 May 2026 23:55:19 -0600 Subject: [PATCH] update --- ast_checker/engines/__init__.py | 2 ++ ast_checker/engines/nesting.py | 33 +++++++++++++++++++++++++++++++++ problem/serializers.py | 7 ++++++- 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 ast_checker/engines/nesting.py diff --git a/ast_checker/engines/__init__.py b/ast_checker/engines/__init__.py index 9b88312..92a095e 100644 --- a/ast_checker/engines/__init__.py +++ b/ast_checker/engines/__init__.py @@ -1,5 +1,6 @@ from .function_call import CountFunctionCallEngine, MustCallFunctionEngine, MustNotCallFunctionEngine from .method_call import MustCallMethodEngine, MustNotCallMethodEngine +from .nesting import MustHaveNestingEngine from .node_count import CountNodeEngine from .node_exists import MustExistNodeEngine, MustNotExistNodeEngine from .operator import MustUseOperatorEngine @@ -14,6 +15,7 @@ ENGINES = { "must_call_method": MustCallMethodEngine(), "must_not_call_method": MustNotCallMethodEngine(), "must_use_operator": MustUseOperatorEngine(), + "must_have_nesting": MustHaveNestingEngine(), } diff --git a/ast_checker/engines/nesting.py b/ast_checker/engines/nesting.py new file mode 100644 index 0000000..cb7df25 --- /dev/null +++ b/ast_checker/engines/nesting.py @@ -0,0 +1,33 @@ +from .base import BaseEngine +from ast_checker.labels import label + + +class MustHaveNestingEngine(BaseEngine): + def _has_inner_in_subtree(self, node, inner_type): + for child in node.children: + if self.has_node(child, inner_type): + return True + return False + + def _message(self, rule): + if rule.get("message"): + return rule["message"] + outer = rule.get("outer", "") + inner = rule.get("inner", "") + outer_label = label(outer) + inner_label = label(inner) + if outer == inner: + return f"必须使用 {outer_label} 嵌套" + return f"必须在 {outer_label} 中嵌套使用 {inner_label}" + + def check(self, tree, rule, language, mapping): + outer_type = mapping.get(rule["outer"], rule["outer"]) + inner_type = mapping.get(rule["inner"], rule["inner"]) + outer_nodes = self.collect_nodes(tree.root_node, outer_type) + for outer_node in outer_nodes: + if self._has_inner_in_subtree(outer_node, inner_type): + return [] + return [self._message(rule)] + + def describe(self, rule, language, mapping): + return self._message(rule) diff --git a/problem/serializers.py b/problem/serializers.py index 63cc071..8b5f998 100644 --- a/problem/serializers.py +++ b/problem/serializers.py @@ -131,9 +131,14 @@ class ProblemAdminSerializer(BaseProblemSerializer): class ProblemAdminListSerializer(BaseProblemSerializer): + has_ast_rules = serializers.SerializerMethodField() + + def get_has_ast_rules(self, obj): + return bool(obj.ast_rules) + class Meta: model = Problem - fields = ["_id", "id", "title", "created_by", "visible", "create_time", "difficulty", "tags"] + fields = ["_id", "id", "title", "created_by", "visible", "create_time", "difficulty", "tags", "has_ast_rules", "allow_flowchart", "show_flowchart"] class ProblemSerializer(BaseProblemSerializer):