Files
ykxmz/_build/find_orphans.py
T
xmz7891 2061f9525f 2.3.0:手表界面精简 + 播放器 + 鼠标重做
手表端
- 功能页从 10 个杂项精简到 7 个(屏幕/鼠标/媒体/文件/电脑/语音/电源)
- 删掉:游戏封锁、待办、掷骰子、抽奖、壁纸、显示器开关、定时关机、
  剪贴板历史、性能/磁盘/电量、文件夹浏览、教室限制等
- 改成显式列按钮,不再把电脑端所有功能组无脑铺到表盘
- 远程鼠标控制重做:滑动区 + 左键/滚轮/右键三按钮
  滚轮点按=中键、上下滑=滚动
- 新增视频/音乐播放器(手表本地播放):进度拖动、左右滑快进退10秒、
  点画面播放暂停、上一/下一、播完自动下一首

电脑端
- 新增 kill_all(结束所有进程),白名单保护系统关键进程和自身
- 新增 media_list / media_pull(播放器数据源)
  安全边界:只允许媒体目录,用 relative_to 判断,防同前缀兄弟目录绕过

中转站
- known_devices 从 ID 集合改成「设备ID -> 配对码」映射
- 修复:管理员改码后关机超过 6 小时,改码会被超时清理冲掉
- 老格式 state 文件平滑升级
2026-10-18 11:39:14 +08:00

109 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""找出 MainActivity 里**定义了但没人调用**的私有方法。
为什么需要这个:2.3.0 把一半的分页删了,原来那些按钮背后的方法
就全变成孤儿了。一个个跑测试太慢,先用这个脚本一次性列出来。
排除规则(这些"没人调用"是正常的):
* @Override 的回调(框架会调)
* 生命周期方法(onCreate/onPause/...)
* 构造器
* 只有 setVisibility / setText 之类直接操作的不算
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
JAVA = (Path(__file__).resolve().parent.parent
/ "android" / "src" / "com" / "lanremote" / "watch" / "MainActivity.java")
# 框架调用的,不算孤儿
LIFECYCLE = {
"onCreate", "onStart", "onResume", "onPause", "onStop", "onDestroy",
"onActivityResult", "onRequestPermissionsResult", "onBackPressed",
"onNewIntent", "onSaveInstanceState", "onRestoreInstanceState",
"onTouchEvent", "onKeyDown", "onConfigurationChanged",
"onWindowFocusChanged", "onCreateOptionsMenu", "onOptionsItemSelected",
"onClick", "run", "onPrepared", "onCompletion", "onError",
"onProgressChanged", "onStartTrackingTouch", "onStopTrackingTouch",
"onSingleTapConfirmed", "onDoubleTap", "onScroll", "onFling",
"onDown", "onLongPress", "onShowPress", "onSingleTapUp",
"onInput", "onPick", "onResponse", "onFailure", "doInBackground",
"onPostExecute", "beforeTextChanged", "onTextChanged",
"afterTextChanged", "onItemClick", "onItemSelected",
"onNothingSelected", "onFocusChange", "onEditorAction",
}
# 定义方法的各种写法
DEF_RE = re.compile(
r"^[ \t]*(?:@\w+(?:\([^)]*\))?\s*)*"
r"(?:private|protected|public|static|final|synchronized|\s)*"
r"(?:[\w<>\[\],.?\s]+?)\s+(\w+)\s*\([^)]*\)\s*(?:throws [\w,.\s]+)?\s*\{",
re.M)
def main() -> int:
text = JAVA.read_text(encoding="utf-8")
lines = text.split("\n")
# 收集定义(带行号)
defs = []
for i, ln in enumerate(lines):
m = DEF_RE.match(ln)
if not m:
continue
name = m.group(1)
# 排除构造器(名字等于类名)和 exclude 集合
if name in ("MainActivity", "if", "for", "while", "switch", "catch"):
continue
# 排除紧跟在 @Override 后面的
prev = [x.strip() for x in lines[max(0, i - 3):i]]
if any("_override_" == p or "@Override" in p for p in prev):
continue
defs.append((name, i + 1))
# 统计每个名字被调用多少次(排除定义行自己)
def_line = {}
for name, ln in defs:
def_line.setdefault(name, set()).add(ln)
orphans = []
for name, ln in defs:
# 统计调用次数:名字 + "(" 出现次数
occurrences = [(i + 1, l) for i, l in enumerate(lines)
if re.search(r"\b" + re.escape(name) + r"\s*\(", l)]
# 减去定义本身那一行
calls = [o for o in occurrences if o[0] != ln]
# 定义行可能是多行签名的第一行,精确匹配名字出现的所有行
if not calls:
if name not in LIFECYCLE:
orphans.append((name, ln))
print(" 定义的方法 %d 个" % len(defs))
print(" 孤儿方法 %d 个:" % len(orphans))
for name, ln in orphans:
print(" 第 %-5d %s()" % (ln, name))
# 也检查被调用但只出现在注释里的(可能是残留引用)
print()
print(" 被删除后仍被引用的符号(编译错误来源):")
deleted = sys.argv[1:] if len(sys.argv) > 1 else []
for sym in deleted:
hits = [(i + 1, l.strip()) for i, l in enumerate(lines)
if re.search(r"\b" + re.escape(sym) + r"\s*\(", l)]
if hits:
# 判断是不是定义行
deflines = {d[1] for d in defs if d[0] == sym}
real = [h for h in hits if h[0] not in deflines]
if real:
print(" %s: %d 处调用" % (sym, len(real)))
for ln, l in real[:5]:
print(" 第 %d: %s" % (ln, l[:100]))
return 0
if __name__ == "__main__":
sys.exit(main())