-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
tedjmzhang
committed
May 31, 2024
1 parent
479353c
commit ba8c831
Showing
7 changed files
with
492 additions
and
7 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
const $ = require('gogocode'); | ||
let path = require('path'); | ||
let fs = require('fs') | ||
|
||
let filePath = path.resolve(__dirname, './test.js'); | ||
let str = fs.readFileSync(filePath, { encoding: 'utf-8' }); | ||
const ast = $(str); | ||
const test1 = ast.find('const $_$variable = $_$value'); | ||
let test1Match = test1.match | ||
|
||
// const code = test1.generate(); | ||
// ast.replace('function log(){}', `let log = 12;`); | ||
// let code2 = ast.generate(); | ||
// console.log(code2) | ||
|
||
let test2 = ast.find('function log($$$param){$$$statement}') | ||
let test2match = test2.match; | ||
|
||
let ddd = ast.replace('function log($$$param){$$$statement}', 'function testLog($$$params){$$$statement}') | ||
let replacedValue = ast.generate(); | ||
fs.writeFileSync('output.js', replacedValue) | ||
|
||
|
||
test1.each(item => { | ||
let variable = item.match.variable[0].value; | ||
let value = item.match.value[0].value; | ||
console.log('variable value', variable, value) | ||
}) | ||
|
||
const res = ast.find('const dict = { $$$0 }'); | ||
const kvs = res.match['$$$0']; | ||
kvs.map((kv) => `${kv.key.name}:${kv.value.value}`); | ||
// a:1,b:2,c:f | ||
|
||
|
||
|
||
const console1 = ast.find('function testLog($_$0) {}') | ||
let console2 = console1.find('console.log($_$0)'); | ||
|
||
// 找到 reactClass 定义的语句 | ||
const reactClass = ast.find('class $_$0 extends React.Component {}'); | ||
|
||
// 找到 jsx 里面带有 onClick 属性的标签 | ||
const onClick = reactClass.find('<$_$0 onClick={$_$1}></$_$0>'); | ||
|
||
// 创建一个数组用来收集 onClick 对应的 hanlder 的名称 | ||
const clickFnNames = []; | ||
|
||
// 有可能找到很多个带有 onClick 的标签,我们这里用 each 去处理每一条 | ||
onClick.each((e) => { | ||
// 用 match[1][0] 来找到 $_$1 匹配到的第一个 onClick 属性对应的 handler 节点 | ||
// 取 value 即为节点名 | ||
// handlerName = 'this.handleClick' | ||
const handlerName = e.match[1][0].value; | ||
clickFnNames.push(handlerName); | ||
}); | ||
|
||
// 替换原有的 constructor,但利用 $$$ 保留原有的参数和语句,只是在最后补上 bind 语句即可 | ||
reactClass.replace( | ||
'constructor($$$0) { $$$1 }', | ||
`constructor($$$0) { | ||
$$$1; | ||
${clickFnNames.map((name) => `${name} = ${name}.bind(this)`).join(';')} | ||
}`, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# gogocode | ||
|
||
> 解析源码字符串为ast,然后对其操作 | ||
let ast = gogocode(string) // 生成gogoCode的ast实例 | ||
|
||
## 实例方法: 全部返回的都是gogocode实例,只不过他们的match不一样而已,返回值是一个对象,但是有each方法,返回匹配的多个值,直接调用match只会返回匹配的第一个值(改值是一个对象,对象的key是$_$name里面的name) | ||
- find: 匹配某格式文本,并且将其命名,ast.find('const $_$key = $_$value'), 可以使用.match或者(.each(item,index => item.match)index为1是表示第一个)获取第一个匹配的,如果有多个匹配,只能.each(item => item.match) | ||
|
||
- replaceBy: find之后直接替换 | ||
|
||
-- replace: 找到并替换 ast.replace('const a = $_$value', 'const b = $_$value') | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
function testLog(a,b,cs){console.log(a, b, c);} | ||
|
||
function alert(a) { | ||
alert(a); | ||
} | ||
|
||
|
||
// 以下每一种都能被匹配到 | ||
const a1 = 123; | ||
const a2 = "b"; | ||
const a3 = () => 1; | ||
|
||
const dict = { | ||
a: 1, | ||
b: 2, | ||
c: 'f', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
function log(a, b, c) { | ||
console.log(a, b, c); | ||
} | ||
|
||
function alert(a) { | ||
alert(a); | ||
} | ||
|
||
|
||
// 以下每一种都能被匹配到 | ||
const a1 = 123; | ||
const a2 = "b"; | ||
const a3 = () => 1; | ||
|
||
const dict = { | ||
a: 1, | ||
b: 2, | ||
c: 'f', | ||
}; | ||
|
||
class Toggle extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
this.state = { isToggleOn: true }; | ||
|
||
// This binding is necessary to make `this` work in the callback | ||
this.handleClick = this.handleClick.bind(this); | ||
} | ||
|
||
handleClick() { | ||
this.setState((prevState) => ({ | ||
isToggleOn: !prevState.isToggleOn, | ||
})); | ||
} | ||
|
||
render() { | ||
return ( | ||
<button onClick={this.handleClick}> | ||
{this.state.isToggleOn ? 'ON' : 'OFF'} | ||
</button> | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters