Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

示例代码输出结果,对分号的处理不解 #9

Closed
kiinlam opened this issue Mar 18, 2021 · 4 comments
Closed

示例代码输出结果,对分号的处理不解 #9

kiinlam opened this issue Mar 18, 2021 · 4 comments

Comments

@kiinlam
Copy link

kiinlam commented Mar 18, 2021

对于文件/gogocode/packages/gogocode-starter/src/start.js

输入内容为:

import a from 'a';
console.log('get A');
var b = console.log();
console.log.bind();
var c = console.log;
console.log = func;

执行后实际输出结果:

import a from 'a';
;
var b = void 0
console.log.bind();
var c = function(){}
console.log = func;

而start.js文件中描述的期望结果是:

import a from 'a';
var b = void 0;
console.log.bind()
var c = function(){};
console.log = func

以上两个结果,可以明显看出,
第二行剩下分号,期望结果是没有输出,
倒数第二行结尾没有分号,期望结果是有分号,
那么,假如把输入压缩成一行,结果会出问题:

改为输入:

import a from 'a';console.log('get A');var b = console.log();console.log.bind();var c = console.log;console.log = func;

输出结果:

import a from 'a';;var b = void 0 console.log.bind();var c = function(){}console.log = func;

可以看到,由于丢失分号,输出结果是执行不了的。

@zzh3319
Copy link

zzh3319 commented Apr 21, 2021

疑惑+1
const from = console.log('get A');;

const output = $(from)
  .replace(`console.log($_$);`, ``)
  .generate();
console.log(output);

log输出了;分号 和预期不一样。

@shuerguo999
Copy link
Contributor

分号问题 正在寻求解决方案,由于ast中没有分号相关的属性设置,所以不太好解决,请耐心等待~

@xinglie
Copy link
Member

xinglie commented May 14, 2021

代码中多余的分号分被解析成EmptyStatement,但并不是所有EmptyStatement都是多余的,比如if(cond);这个空语句就是有用的,再比如for(;;);,我想来想去这种有作用的空语句其实也就这几种情况,排除这些情况,删除其余的空语句可解分号多余的问题。

从ast转文本代码理论上generator可决定要不要添加分号,或者在什么情况下必须添加分号。不过recast没有提供这个选项,即使有这个功能,估计也不能应用,我猜是为了尽可能的保持原有格式,使用了recast.print来生成文本代码。

为了保持原格式,会引入新的问题,比如对start.js中的测试代码稍做调整

const from = `
import a from 'a';
console.log('get A');
var b = console.log();
console.log.bind();
var c = console.log;console.log = func;
`;

我把倒数第1行和倒数第2行人工合并到一行上,有分号,代码正常。经过gogocode处理后的结果是

import a from 'a';
;
var b = void 0
console.log.bind();
var c = function(){}console.log = func;

按前面人的测试,这就不对了。

如果改成recast.prettyPrint,可得结果如下

import a from "a";
;
var b = void 0;
console.log.bind();
var c = function() {};
console.log = func;

recast就会格式化并插入分号。但用recast.prettyPrint又好像不符合作者的意图。

如果按最大格式的保持原有格式输出,那就需要对用户传入的replacement语句做识别,因为限制了用户传入的是合法的、能被解析的代码,因此根据情况来插入一个分号语句,或对替换前的语句识别最后有没有分号,如果有则保留也可以。

先插入替换,最后删除多余分号。

@shuerguo999
Copy link
Contributor

感谢 @kiinlam @zzh3319 提出问题,也感谢 @xinglie 行老师的点拨~

  • 多余分号问题已经修复了,我在remove节点的时候增加了一个判断:如果待删除的语句父节点是ExpressionStatement并且只有一个子语句,就删除父节点,同时generate增加了isPretty入参,为true时可以格式化输出
  • 压缩代码无分号问题只要将replace语句改为:.replace(var $_$ = console.log(), var $_$ = void 0;)即可

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants