mirror of
https://github.com/KenanZhu/AutoLibrary.git
synced 2026-06-18 07:23:03 +08:00
refactor(autoscript): 公开 splitTopLevel 并导出常量,消除冗余委托与重复变量
This commit is contained in:
@@ -33,7 +33,7 @@ from .ASTokenizer import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["execute", "addTargetVar"]
|
__all__ = ["execute", "addTargetVar", "splitTopLevel"]
|
||||||
|
|
||||||
|
|
||||||
# Engine state
|
# Engine state
|
||||||
@@ -69,7 +69,7 @@ _RE_CUR_DATE_OFFSET = re.compile(r"^CURRENT_DATE\s*\+\s*(\d+)$", re.IGNORECASE)
|
|||||||
_RE_CUR_TIME_OFFSET = re.compile(r"^CURRENT_TIME\s*\+\s*(\d+)$", re.IGNORECASE)
|
_RE_CUR_TIME_OFFSET = re.compile(r"^CURRENT_TIME\s*\+\s*(\d+)$", re.IGNORECASE)
|
||||||
|
|
||||||
|
|
||||||
def _splitTopLevel(
|
def splitTopLevel(
|
||||||
text: str,
|
text: str,
|
||||||
delimiter: str
|
delimiter: str
|
||||||
) -> list:
|
) -> list:
|
||||||
@@ -281,13 +281,13 @@ def _evaluateCondition(
|
|||||||
s = condition_str.strip()
|
s = condition_str.strip()
|
||||||
if not s:
|
if not s:
|
||||||
return False
|
return False
|
||||||
or_parts = _splitTopLevel(s, ".OR.")
|
or_parts = splitTopLevel(s, ".OR.")
|
||||||
if len(or_parts) > 1:
|
if len(or_parts) > 1:
|
||||||
return any(
|
return any(
|
||||||
_evaluateCondition(p.strip(), target_data, line)
|
_evaluateCondition(p.strip(), target_data, line)
|
||||||
for p in or_parts
|
for p in or_parts
|
||||||
)
|
)
|
||||||
and_parts = _splitTopLevel(s, ".AND.")
|
and_parts = splitTopLevel(s, ".AND.")
|
||||||
if len(and_parts) > 1:
|
if len(and_parts) > 1:
|
||||||
return all(
|
return all(
|
||||||
_evaluateCondition(p.strip(), target_data, line)
|
_evaluateCondition(p.strip(), target_data, line)
|
||||||
@@ -466,12 +466,14 @@ class _EngineExecutor(NodeVisitor):
|
|||||||
|
|
||||||
return self._cur_line
|
return self._cur_line
|
||||||
|
|
||||||
|
|
||||||
def _incLine(
|
def _incLine(
|
||||||
self
|
self
|
||||||
):
|
):
|
||||||
|
|
||||||
self._cur_line += 1
|
self._cur_line += 1
|
||||||
|
|
||||||
|
|
||||||
def visitScript(
|
def visitScript(
|
||||||
self,
|
self,
|
||||||
_node: Script
|
_node: Script
|
||||||
@@ -480,6 +482,7 @@ class _EngineExecutor(NodeVisitor):
|
|||||||
for child in _node.body:
|
for child in _node.body:
|
||||||
child.accept(self)
|
child.accept(self)
|
||||||
|
|
||||||
|
|
||||||
def visitIf(
|
def visitIf(
|
||||||
self,
|
self,
|
||||||
_node: IfNode
|
_node: IfNode
|
||||||
@@ -506,6 +509,7 @@ class _EngineExecutor(NodeVisitor):
|
|||||||
for child in _node.else_body:
|
for child in _node.else_body:
|
||||||
child.accept(self)
|
child.accept(self)
|
||||||
|
|
||||||
|
|
||||||
def visitSet(
|
def visitSet(
|
||||||
self,
|
self,
|
||||||
_node: SetNode
|
_node: SetNode
|
||||||
@@ -515,6 +519,7 @@ class _EngineExecutor(NodeVisitor):
|
|||||||
full_line = f"SET {_node.target} = {_node.value}"
|
full_line = f"SET {_node.target} = {_node.value}"
|
||||||
_executeSet(full_line, self._target_data, self._line)
|
_executeSet(full_line, self._target_data, self._line)
|
||||||
|
|
||||||
|
|
||||||
def visitOp(
|
def visitOp(
|
||||||
self,
|
self,
|
||||||
_node: OpNode
|
_node: OpNode
|
||||||
@@ -525,6 +530,7 @@ class _EngineExecutor(NodeVisitor):
|
|||||||
full_line = f"{_node.target} .{op_upper}. {_node.value}"
|
full_line = f"{_node.target} .{op_upper}. {_node.value}"
|
||||||
_executeOperation(full_line, self._target_data, self._line)
|
_executeOperation(full_line, self._target_data, self._line)
|
||||||
|
|
||||||
|
|
||||||
def visitPass(
|
def visitPass(
|
||||||
self,
|
self,
|
||||||
_node: PassNode
|
_node: PassNode
|
||||||
@@ -532,6 +538,7 @@ class _EngineExecutor(NodeVisitor):
|
|||||||
|
|
||||||
self._incLine()
|
self._incLine()
|
||||||
|
|
||||||
|
|
||||||
def visitUnrecog(
|
def visitUnrecog(
|
||||||
self,
|
self,
|
||||||
_node: UnrecogNode
|
_node: UnrecogNode
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ from datetime import (
|
|||||||
from .ASObject import ASObject
|
from .ASObject import ASObject
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["ASOperator"]
|
__all__ = ["ASOperator", "ARITH_TYPES", "COMPARISON_OPERATORS"]
|
||||||
|
|
||||||
|
|
||||||
class ASOperator:
|
class ASOperator:
|
||||||
@@ -96,12 +96,11 @@ class ASOperator:
|
|||||||
target_val = target.getValue(target_data)
|
target_val = target.getValue(target_data)
|
||||||
if target_val is None:
|
if target_val is None:
|
||||||
raise ValueError(f"'{target.name}' 的值为空,无法进行运算")
|
raise ValueError(f"'{target.name}' 的值为空,无法进行运算")
|
||||||
if op == ".ADD.":
|
op_name = "ADD" if op == ".ADD." else "SUB" if op == ".SUB." else None
|
||||||
cls._arithAdd(target, target_val, operand, target_data)
|
if op_name is None:
|
||||||
elif op == ".SUB.":
|
|
||||||
cls._arithSub(target, target_val, operand, target_data)
|
|
||||||
else:
|
|
||||||
raise ValueError(f"不支持的操作 '{op}'")
|
raise ValueError(f"不支持的操作 '{op}'")
|
||||||
|
sign = 1 if op == ".ADD." else -1
|
||||||
|
cls._arithBinary(target, target_val, operand, target_data, sign, op_name)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _arithBinary(
|
def _arithBinary(
|
||||||
@@ -110,13 +109,13 @@ class ASOperator:
|
|||||||
target_val,
|
target_val,
|
||||||
operand: ASObject,
|
operand: ASObject,
|
||||||
target_data: dict,
|
target_data: dict,
|
||||||
sign: int
|
sign: int,
|
||||||
|
op_name: str = ""
|
||||||
):
|
):
|
||||||
"""Apply ADD (sign=1) or SUB (sign=-1) per type."""
|
"""Apply arithmetic per type."""
|
||||||
|
|
||||||
tp = target.var_type
|
tp = target.var_type
|
||||||
raw_op = operand._value
|
raw_op = operand._value
|
||||||
op_name = "ADD" if sign == 1 else "SUB"
|
|
||||||
|
|
||||||
if tp == "Date":
|
if tp == "Date":
|
||||||
if not isinstance(target_val, date):
|
if not isinstance(target_val, date):
|
||||||
@@ -129,35 +128,13 @@ class ASOperator:
|
|||||||
dt = datetime.combine(datetime.today(), target_val) + delta
|
dt = datetime.combine(datetime.today(), target_val) + delta
|
||||||
new_val = dt.time()
|
new_val = dt.time()
|
||||||
elif tp == "Int":
|
elif tp == "Int":
|
||||||
new_val = int(target_val) + int(raw_op) * sign
|
new_val = int(target_val) + int(raw_op)*sign
|
||||||
elif tp == "Float":
|
elif tp == "Float":
|
||||||
new_val = float(target_val) + float(raw_op) * sign
|
new_val = float(target_val) + float(raw_op)*sign
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"'{tp}' 类型不支持 {op_name} 操作")
|
raise ValueError(f"'{tp}' 类型不支持 {op_name} 操作")
|
||||||
target.setValue(new_val, target_data)
|
target.setValue(new_val, target_data)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _arithAdd(
|
|
||||||
cls,
|
|
||||||
target: ASObject,
|
|
||||||
target_val,
|
|
||||||
operand: ASObject,
|
|
||||||
target_data: dict
|
|
||||||
):
|
|
||||||
"""Dispatch ADD per type."""
|
|
||||||
cls._arithBinary(target, target_val, operand, target_data, 1)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _arithSub(
|
|
||||||
cls,
|
|
||||||
target: ASObject,
|
|
||||||
target_val,
|
|
||||||
operand: ASObject,
|
|
||||||
target_data: dict
|
|
||||||
):
|
|
||||||
"""Dispatch SUB per type."""
|
|
||||||
cls._arithBinary(target, target_val, operand, target_data, -1)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def compare(
|
def compare(
|
||||||
cls,
|
cls,
|
||||||
@@ -206,3 +183,9 @@ class ASOperator:
|
|||||||
f"无法比较 '{left.name}' ({left.var_type}) "
|
f"无法比较 '{left.name}' ({left.var_type}) "
|
||||||
f"与 '{right.name}' ({right.var_type})"
|
f"与 '{right.name}' ({right.var_type})"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Public constants
|
||||||
|
# may be used by the GUI orchestration dialog.
|
||||||
|
ARITH_TYPES = ASOperator._ARITH_TYPES
|
||||||
|
COMPARISON_OPERATORS = set(ASOperator._COMPARE.keys())
|
||||||
|
|||||||
+12
-12
@@ -14,13 +14,16 @@ from autoscript.ASTokenizer import (
|
|||||||
from autoscript.ASEngine import (
|
from autoscript.ASEngine import (
|
||||||
execute,
|
execute,
|
||||||
addTargetVar,
|
addTargetVar,
|
||||||
|
splitTopLevel,
|
||||||
)
|
)
|
||||||
from autoscript.ASObject import _META_VARS as META_VARS
|
from autoscript.ASObject import _META_VARS as META_VARS
|
||||||
from autoscript.ASObserver import ParsingObserver
|
from autoscript.ASObserver import ParsingObserver
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"execute",
|
"execute",
|
||||||
"addTargetVar",
|
"addTargetVar",
|
||||||
|
"splitTopLevel",
|
||||||
"registerDefaultTargetVars",
|
"registerDefaultTargetVars",
|
||||||
"buildMockTargetData",
|
"buildMockTargetData",
|
||||||
"META_VARS",
|
"META_VARS",
|
||||||
@@ -35,18 +38,6 @@ __all__ = [
|
|||||||
"ParsingObserver",
|
"ParsingObserver",
|
||||||
]
|
]
|
||||||
|
|
||||||
# All variables available to scripts (display_name -> (name, type)).
|
|
||||||
# This mirrors the old AutoScriptEngine.VARIABLE_META for backward
|
|
||||||
# compatibility in the UI orchestration dialog.
|
|
||||||
ALL_VARIABLES: dict = {
|
|
||||||
"用户名": ("USERNAME", "String"),
|
|
||||||
"用户启用": ("USER_ENABLE", "Boolean"),
|
|
||||||
"预约日期": ("RESERVE_DATE", "Date"),
|
|
||||||
"预约开始时间": ("RESERVE_BEGIN_TIME", "Time"),
|
|
||||||
"预约结束时间": ("RESERVE_END_TIME", "Time"),
|
|
||||||
"当前时间": ("CURRENT_TIME", "Time"),
|
|
||||||
"当前日期": ("CURRENT_DATE", "Date"),
|
|
||||||
}
|
|
||||||
|
|
||||||
# Key paths into target_data dict for each target variable.
|
# Key paths into target_data dict for each target variable.
|
||||||
# (name, type, key_path, display_name)
|
# (name, type, key_path, display_name)
|
||||||
@@ -57,6 +48,15 @@ _TARGET_VAR_DEFS = [
|
|||||||
("RESERVE_BEGIN_TIME", "Time", ["reserve_info", "begin_time", "time"], "预约开始时间"),
|
("RESERVE_BEGIN_TIME", "Time", ["reserve_info", "begin_time", "time"], "预约开始时间"),
|
||||||
("RESERVE_END_TIME", "Time", ["reserve_info", "end_time", "time"], "预约结束时间"),
|
("RESERVE_END_TIME", "Time", ["reserve_info", "end_time", "time"], "预约结束时间"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# All variables (display_name -> (name, type)), derived from target vars + meta vars.
|
||||||
|
ALL_VARIABLES = {
|
||||||
|
display_name: (name, var_type)
|
||||||
|
for name, var_type, _, display_name in _TARGET_VAR_DEFS
|
||||||
|
} | {
|
||||||
|
obj.display_name: (obj.name, obj.var_type)
|
||||||
|
for obj in META_VARS.values()
|
||||||
|
}
|
||||||
_MOCK_TYPE_VALUES = {
|
_MOCK_TYPE_VALUES = {
|
||||||
"String": "__mock__",
|
"String": "__mock__",
|
||||||
"Boolean": True,
|
"Boolean": True,
|
||||||
|
|||||||
Reference in New Issue
Block a user