首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

借助AST ,手写一个解决运行环境差异loader

SDK中开发调试,但是项目的实际运行环境不只是游戏SDK中,还有浏览器环境中,就会导致非常多代码不兼容。...return content } 解决思路 一开始想比较简单,觉得可以loader中直接拿到代码内容,然后通过正则匹配进行替换即可,但是这样并不通用,每发现一个不同点就需要增加一个匹配判断,而且这里差异不只是属性差异...,可能还需要条件判断,才能替换。...声明变量,比如 let const var FunctionDeclaration 函数声明 声明函数,比如 function ExpressionStatement 表达式语句 通常为调用一个函数,比如...break ContinueStatement 持续语句 通常指 continue ReturnStatement 返回语句 通常指 return SwitchStatement Switch 语句

40830

JS代码之混淆

个人推荐这种写法,因为能有 js 代码提示,如果是 TypeScript 效果也一样。...()]) path.stop() }, }) 要注意是,替换节点要非常谨慎,就比如上述代码,如果我遍历 return 语句,同时我又替换成了 return 语句替换节点同样是可以进入到遍历里...path.getStatementParent 遍历语法树,直到找到语句节点(带有 Statement),如 return 语句ReturnStatement),if 语句(IfStatement),...只要程序能运行,那么我就能调试,能调试还能有什么解决不了(毕竟 bug 都是调试出来)。如果真想保全你代码,那我建议是编译成二进制文件,或采用远程调用形式将执行后结果返回。...代码执行效率​ 通常来说,混淆会使你代码数量增大至 2,3 倍,与加密壳同理,但程序执行速度也稍慢下,当然只要不是特别 ex 混淆,如将函数调用封装至,3,4 层调用导致调用堆栈过大,那么这种执行效率基本可以忽略不计

21.8K10
您找到你想要的搜索结果了吗?
是的
没有找到

经过一个月探索,我如何将 AST 操作得跟呼吸一样自然

我们声明对哪一部分语句做哪些处理,比如我要把所有符合条件 If 语句判断都加上一个新条件,然后 Babel 遍历 AST 时(@babel/traverse),发现 If 语句被注册了这么一个操作...我们从 identifier 开始创建,组装参数、if 语句条件与代码块、函数返回语句,最后通过 createFunctionDeclaration 完成组装。...TypeScript AST,如 interface、类型别名、装饰器等(你可以 ts-ast-viewer[7] 实时查看 TypeScript AST 结构)。...很明显,这样操作是有利有弊,我们能够创建 Function、Class、Import 这一类声明时,直接传入其结构即可,但对于函数(类方法)内部语句,ts-morph 目前的确只提供了这种最简单能力...将其替换为浏览器能够解析相对导入(如 importAnalysisBuild.ts[10])。

1.4K11

如何将Node.js库转换到Deno

它是由Node.js作者Ryan Dahl创建,为了解决Node一些基本设计、安全漏洞问题并集成了当前一些开发实践如ES Module和TypeScript EdgeDb中,我们建立和维护了一个官方...它也有一个复杂解析算法,从node_modules加载像react这样普通模块名,并在无额外扩展名导入时尝试添加.js或.json。...我们将使用TypeScriptCompiler API来将源文件解析为抽象语法树并找到导入语句 为了实现这个功能我们需要用到typescript NPM包compile API。...首先检查路径是否对应于实际文件;如果失败尝试添加.ts;如果再失败则尝试添加/index.ts;如果再失败则抛出一个错误。 注入Node.js全局变量 最后一步是处理Node.js全局变量。...将使用它在任何引用这些全局变量文件中注入import语句 const sourceDir = "./src"; const destDir = ".

2.4K30

基于 Roslyn 同时为 Visual Studio 插件和 NuGet 包开发 .NETC# 源代码分析器 Analyzer 和修改器 CodeFixProvider

(按下 F5 启动这个项目调试),调试时会启动一个 Visual Studio 实验实例 Walterlv.Demo.Analyzers.Test 单元测试项目 模板为我们生成了比较多辅助代码帮助我们快速编写用于测试我们分析器可用性单元测试...为了简化理解,我将多语言全部替换成了实际字符串值。 重写 SupportedDiagnostics 部分,创建并返回了一个 DiagnosticDescriptor 类型只读集合。...按下 F5 调试调试 Visual Studio 实验实例中,我们将鼠标光标放在 public string Foo { get; set; } 行上。...如下图所示: 你可能觉得有些不满,看起来似乎只有我们写那些标题和描述工作。...但实际上你还应该注意到这些: DiagnosticId、_messageFormat、_description 已经工作起来了; 只有光标属性声明语句块时,这个提示才会出现,因此说明我们已经找到了正确代码块了

36020

使用普拉特解析法解析复杂算术表达式

上一节我们实现了编译原理中语法解析入门,能够解析简单由let关键字开头变量定义语句,现在我们再接再厉,实现解析由return 开头返回语句。...因此对应于return 语句语法解析表达式是: ReturnStatement := return Expression 为了简单起见,我们代码实现时,任然假设return 后面跟着一个数字字符串,后面我们深入探讨如何解析异常复杂算术表达式...return语句语法规定,于是就构建一个ReturnStatement对象返回,该对象与我们上一节实现LetStatement类几乎一致,代码如下: class ReturnStatement extends...可以看到,点击按钮后,控制台上显示了“return with 1234”语句,这表明我们语法解析器能够识别return语句。...从上图所示结果来看,我们解析器已经能轻松处理算术表达式两种简单情况,也就是变量和数字,当然算术表达式最复杂还是带有运算符和函数调用情况,接下来我们就这些复杂情况处理做深入探讨。

1.3K20

自制Monkey语言编译器:解释执行return语句和错误处理控制

从运行结果看,编译器解释执行了一系列if条件判断语句后,将内层if语句块包含return语句执行了,并没有执行外层if语句块包含return语句,所以控制台输出上显示出编译器将数值10返回给最外层...return语句后面很可能是一个复杂运算表达式,所以代码先递归调用eval解释执行return后面的语句以便获得要返回数据对象,接着把该数据对象封装在前面设计ReturnValues符号对象里。...或者中序表达式中,编译器遇到了识别不了运算符,那么它也构造一个错误对象返回。...return语句时,检测return后面跟着表达式被编译器解释执行后是否出错,如果出错则把错误对象返回。...解释执行前置表达式时,编译器检测运算符后面的表达式解释执行时是否正常,如果出错则直接将错误返回

68850

你不容错过babel-plugin-import史上最全源码详解!

state 是一个引用类型,对其进行操作影响到后续节点 state 初始值,因此用 Program 节点, enter 时候就初始化这个收集依赖对象,方便后续操作。...因为 import 被转换后,之前我们人工引入组件名称和转换后名称不一样,因此 importMethod 需要把转换后新名字(一个 AST 结构)返回到我们对应 AST 节点对应位置上,替换掉老组件名...import 节点,最后**函数返回值就是新 import 节点 default Identifier,替换掉调用 importMethod 函数节点,从而把所有引用旧 import 绑定节点替换成最新生成...三、了如指掌 step3 中会进行按需加载转换最后两个步骤: 引入 import 绑定引用肯定不止 JSX 语法,还有其他诸如,三元表达式,类继承,运算,判断语句返回语法等等类型,我们都得对他们进行处理...,确保所有的引用都绑定到最新 import,这也导致importMethod 函数被重新调用,但我们肯定不希望 import 函数被引用了 n 次,生成 n 个新 import 语句,因此才会有先前判断语句

1.5K20

阿里面试官:如何给所有的async函数添加trycatch?

async函数,获取该函数body(函数中包含代码) 3)创建try/catch语句,将原来asyncbody放入其中 4)最后将asyncbody替换成创建try/catch语句 babel...ReturnStatement 返回语句 通常指 return SwitchStatement Switch 语句 通常指 Switch Case 语句 Switch IfStatement If...AssignmentExpression 赋值表达式 通常指将函数返回值赋值给变量 UpdateExpression 更新表达式 通常指更新成员值,例如 i++ Literal 字面量 字面量 BooleanLiteral...(...info.body); // 将父节点body替换成新创建try语句 info.body = [tryNode]; } }...; // 将父节点原来函数体放到try语句中 tryNode.block.body.push(...info.body); // 将父节点内容替换成新创建try

96350

号外!!!MySQL 8.0.24 发布

(缺陷#31496943,缺陷#99892) InnoDB: 虚拟列上创建索引引发无效调试断言失败。...这是因为服务器表达式替换为等效索引生成列时,并未尝试将对引用引用替换为对等效生成列引用;对于多值索引,将列引用替换为对生成引用来替换,该引用支持将该列转换为类型数组表达式多值索引...此修复程序通过允许字段引用可以出现在可以使用多值索引上下文中(即,当它们出现在上下文中)时替换列引用,从而解除了服务器尝试用索引生成列仅替换函数表达式和条件表达式限制。...(缺陷#32416811) TRUE源 代码中使用该符号导致某些平台上构建失败替换为 true。...(缺陷#32122078,错误#32393265) 创建包含具有非恒定默认表达式导致后续ALTER TABLE语句失败

3.6K20

深入浅出 Babel 上篇:架构和原理 + 实战

方法,支持导入需要Babel处理JavaScript模块 @babel/cli:CLI工具 访问者模式 转换器遍历 AST 树,找出自己感兴趣节点类型, 再进行转换操作....这样子不仅低效,它们逻辑分散各处,让整个系统变得难以理解和调试, 最后插件之间关系就纠缠不清,乱成一锅粥 所以转换器操作 AST 一般都是使用访问器模式,由这个访问者(Visitor)来 ① 进行统一遍历操作...,详见官方文档 节点上下文 访问者访问一个节点时, 无差别地调用 enter 方法,我们怎么知道这个节点在什么位置以及和其他节点关联关系呢?...` 替换为 `return ‘hello’ + v` const rtn = t.returnStatement(t.binaryExpression('+', t.stringLiteral(...这就是转换器需要考虑作用域问题,AST 转换前提是保证程序正确性。我们添加和修改引用时,需要确保与现有的所有引用不冲突。Babel本身不能检测这类异常,只能依靠插件开发者谨慎处理。

76821

深入浅出 Babel 上篇:架构和原理 + 实战

方法,支持导入需要Babel处理JavaScript模块 @babel/cli:CLI工具 访问者模式 转换器遍历 AST 树,找出自己感兴趣节点类型, 再进行转换操作....这样子不仅低效,它们逻辑分散各处,让整个系统变得难以理解和调试, 最后插件之间关系就纠缠不清,乱成一锅粥 所以转换器操作 AST 一般都是使用访问器模式,由这个访问者(Visitor)来 ① 进行统一遍历操作...` 替换为 `return ‘hello’ + v` const rtn = t.returnStatement(t.binaryExpression('+', t.stringLiteral(...语句替换为return "hello" + v;, 下图是遍历过程: ? 我们可以对 AST 进行任意操作,比如删除父节点兄弟节点、删除第一个子节点、新增兄弟节点......这就是转换器需要考虑作用域问题,AST 转换前提是保证程序正确性。我们添加和修改引用时,需要确保与现有的所有引用不冲突。Babel本身不能检测这类异常,只能依靠插件开发者谨慎处理。

77130

async如果不加 trycatch 会发生什么事?

.');}fn()复制代码导致浏览器报错:一个未捕获错误开发过程中,为了保证系统健壮性,或者是为了捕获异步错误,需要频繁 async 函数中添加 try/catch,避免出现上述示例情况可是我很懒...async函数,获取该函数body(函数中包含代码)3)创建try/catch语句,将原来asyncbody放入其中4)最后将asyncbody替换成创建try/catch语句babel核心...可以把tokens看作是一个扁平语法片段数组,描述了代码片段整个代码中位置和记录当前值一些信息比如let a = 1,对应AST是这样语法分析语法分析阶段会把token转换成 AST 形式...,而 a = 1 作为 let 声明描述,它 type 为 VariableDeclaratorAST在线查看工具:AST explorer再举个,加深对AST理解function demo(n.../ return 类型 "argument": { "type": "BinaryExpression",// BinaryExpression 二进制表达式类型

33820

听GPT 讲Rust源代码--compiler(10)

第二步是将MIR中操作数中零尺寸类型替换为一个唯一表达式,并更新函数调用、返回以及其他相关操作引用。...当检测到断言失败时,产生此错误。P是一个参数。...这个结构体常量传播过程中用于表示空值类型。 ConstProp:它是整个常量传播转换主要实现。它会遍历MIR中每个基本块(basic block),并尝试对其中每个语句进行常量传播优化。...当编译器尝试内联这些函数时,可能导致无限代码膨胀和循环调用依赖问题。 为了解决这个问题,cycle.rs文件中实现了一种叫做"循环路径分析"算法。...其中,分析阶段检查函数内部是否存在多个返回终止器,并记录下每个返回终止器位置及对应基本块。变换阶段将会添加一个新基本块,并将多个返回终止器替换为跳转到这个新基本块指令。

7410

python协程1:yield使用

python3.3后,pep380对生成器函数做了两处改动: 生成器可以返回一个值;以前,如果生成器中给return语句提供值,抛出SyntaxError异常。...语句处暂停,所以开始无法发送数据 # 发送 None 可以达到相同效果 my_coro.send(None) next(my_coro)# 此时协程处于 GEN_SUSPENDED (yield...,传递给next函数或send方法调用方,未处理异常会导致协程终止。...如果生成器处理了抛出异常,代码向前执行到下一个yield表达式,而产出值会成为调用throw方法得到返回值。如果没有处理,则向上冒泡,直接抛出。...永远不会执行,因为只有未处理异常才会终止循环,而一旦出现未处理异常,协程立即终止。

71330

《CLR via C#》笔记:第4部分 核心机制(1)

类 FCL定义异常类 抛出异常 定义自己异常类 用可靠性换取开发效率 设计规范和最佳实践 未处理异常 对异常进行调试 异常处理性能问题 约束执行区域(CER) 代码协定 第二十章 异常和状态管理...(P403 4) finally:一个try最多只能关联一个finally块,处理异常语句应当放在finally块中,否则可能因为异常抛出而没有捕捉到,就无法执行后续语句。...2、使用using 语句时,finally 块中调用对象 Dispose方法。 3、使用foreach 语句时,. finally块中调用IEnumerator对象 Dispose方法。...(P427 3) 未处理异常 异常抛出时,CLR调用栈中向上查找与抛出异常对象类型匹配catch 块。没有任何catch 块匹配抛出异常类型,就发生一个未处理异常。...CLR检测到进程中任何线程有未处理异常都会终止进程。(P429 last2) 示例(P430) 对异常进行调试 调试菜单栏中打开异常显示界面。

70310

《CLR via C#》笔记:第5部分 线程处理(2)

现在,硬件设备将执行请求1/O操作(⑤)。 最终,硬件设备完成IO操作。然后,Windows 唤醒你线程,把它调度给一个CPU,使它从内核模式返回用户模式,再返回至托管代码(⑦,⑧和⑨)。...4、查询表达式中,await操作符只能在初始from子句第一个集合表达式中使用,或者join子句集合表达式中使用。...生成Web服务代理类型工具(比如SvcUtil.exe)也生成XxxAsync方法。 异步函数和异常处理 如果状态机出现未处理异常,那么代表异步函数Task对象因为未处理异常而完成。...(P658 3) 异步函数其他功能 对异步函数使用逐过程调试,如果调试await操作符上停止,逐过程会在异步操作完成后,抵达下一个语句时重新由调试器接管。...(P665 last2) FileStream异步通信方面会有一些特有问题。(P665 last) I/O请求优先级 低优先级线程可能挂起高优先级线程,导致后者不能快速完成工作。

1.1K40

TypeScript语言特性(下)

最后,变量message显示屏幕上。 多选结构(switch) switch语句接受一个表达式,将表达式值与 case 语句进行匹配,然后执行关联到这种情况下语句。...// prop没有被继承 } } 计数器控制循环(for) for语句创建一个包含三个可选表达式循环,表达式圆括号中用分号分隔,紧跟一个或者一些循环中执行语句: for (var i: number...; } } 正如上述代码所示, TypeScript 中,不仅可以为函数参数加上类型,也可以给函数返回值指定类型。...TypeScript 会通过查看函数里return语句,来检查返回类型正确与否,并且它们都不是必需。...TypeScript编译器负责将 TypeScript 代码编译为兼容主流浏览器和平台 JavaScript 代码。

97510

深入浅出 Babel 下篇:既生 Plugin 何生 Macros

宏大致可以分为两种: 文本替换和语法扩展 文本替换式 大家或多或少有接触过宏,很多程序员第一门语言是C/C++(包括C衍生语言Objective-C), C中就有宏概念。...没用宏机制,现代语言可以通过提供强大反射机制或者动态编程特性(如JavascriptProxy、Python装饰器)来弥补缺失宏导致元编程短板。...所以大部分宏实现参考 Lisp S-表达式,取折中方案,将传入程序转换为Tokens,再组装成类似quoted数据结构。...除了数据结构设计,现代编程语言宏机制还包含以下特性: 1️⃣ 卫生宏(Hygiene) 卫生宏指的是宏内生成变量不会污染外部作用域,也就是说,宏展开时,Sweet.js 避免宏内定义变量和外部冲突...即使没有死,Sweet.js 这种非标准语法, 和现有的Javascript工具链生态格格不入,开发和调试都会比较麻烦(比如Typescript).

1.5K31
领券