全链路源码依赖分析工程
面是指 JS 层与 Native/C++ 层的分界线,这里会实现一些切面 API,也就是 JS 层与 Native/C++ 层交互的一系列接口,如蓝牙接口、系统信息接口等,由 Native/C++ 层来实现接口,然后往 JS 层暴露,由 JS 层调用。 三、基础实现原理 整个项目最基本也是最重要的数据就是依赖关系。所谓依赖关系,最简单的例子就是文件 A 依赖文件 B 的某个方法。 要将这个关系查出来,一般来说需要经过两个步骤。 第一步:编译源码,获得 AST 遍历所有源码,通过语法分析,生成抽象语法树(Abstract Syntax Tree, AST)。以 JS 扫描器为例,我采用了 typeScript 模块作为编译器,它同时支持 JS(X)、TS(X),通过 ts.createSourceFile 来生成 AST。除 JS 外,iOS 采用的是 CLang,Android 采用的是字节码分析,C++ 采用的是符号表分析。 第二步:路径提取,依赖寻路 从 AST 上我们可以找到所有的引用和暴露表达式,以 JS 为例就是 import/ require 和 export/ module.exports。寻找表达式的方法就是递归地遍历所有语法节点,在 JS 中我采用了 TypeScript 编译器提供的 ts.forEachChild 来进行遍历,通过 ts.SyntaxKind 进行语法节点类型的识别。 找到表达式后,通过依赖路径找到具体的依赖文件。以 JS 为例,我们可以通过 const { identifierName } = require('@bundleName/fileName') 的方式引用其它模块(bundleName)的某个文件(fileName)的某些标识符(identifierName),我们就需要根据这表达式来定位到具体的标识符。 跨切面的依赖会需要多做一步,需要将切面 API 分为调用侧和声明侧,在 JS 层通过 AST 分析出调用侧数据,在 Native/C++ 层分析出声明侧数据(对应到具体实现切面 API 的标识符),将调用侧和声明侧数据通过版本号关联到一起,即可实现全依赖链路贯通。 我们把这个关系以及一些元数据保存下来,就可以作为源数据来作数据分析了。 四、项目架构
整体项目架构如下: (编辑:鹤壁站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |