TyrealHu / acorn-typescript

Alternative, TypeScript parser
https://www.npmjs.com/package/acorn-typescript?activeTab=readme
MIT License
145 stars 18 forks source link

你好,我试了下不能支持tsx的Parser,不知道是不是我本地的问题。对于ts文件Parser而且根据你的实例写出来的也不行,我微调后可以了,下边是我的代码,期待你的回复 #2

Closed xuxiaolong1994 closed 1 year ago

xuxiaolong1994 commented 1 year ago

你好,我试了下不能支持tsx的Parser,不知道是不是我本地的问题。对于ts文件Parser而且根据你的实例写出来的也不行,我微调后可以了,但是tsPlugin.default({ })里配置参数的话也会报错,下边是我的代码,期待你的回复

import acorn from "acorn"
import tsPlugin = require("acorn-typescript");
import { Call, Module, Result } from "../../entity/result";
import { acorn_service } from "../acorn-service";
import fs from "fs";
import * as walk from "acorn-walk";

export const acorn_ts: acorn_service = {
    run: (path: string) => {

        // 解析代码并获取AST
        const ast = acorn.Parser.extend(tsPlugin.default({ })).parse(fs.readFileSync(path, 'utf8'), {
            ecmaVersion: 'latest',
            sourceType: 'module',
            allowReturnOutsideFunction: true,
            allowSuperOutsideMethod: true,
            allowHashBang: true,
            locations: true
        });
        console.log("acorn.Parser.extend")
        // 遍历AST并查找方法调用点
        const calls: Call[] = [];
        const modules: Module[] = [];

        walk.simple(ast, {
            CallExpression: (node: any) => {

                if (node.type === 'CallExpression' &&
                    node.callee.type === 'Identifier' &&
                    node.callee.name === 'require') {
                    // console.log(JSON.stringify(node));
                    const moduleName = node.arguments[0].value;
                    modules.push(new Module(moduleName, node.loc.start.line, node.loc.start.column));
                } else {
                    // console.log(JSON.stringify(node));
                    const functionName = node.callee.name || node.callee.property.name

                    // const args = node.arguments.map((arg: { value: any; }) => typeof arg.value).filter((type: any) => !!type) as string[];

                    // 判断方法调用是否属于第三方包
                    let packageName;
                    if (node.callee.type === 'MemberExpression' && node.callee.object.name !== 'console') {
                        packageName = node.callee.object.name;
                    }

                    calls.push(new Call(packageName, functionName, node.loc.start.line, node.loc.start.column));
                }
            },

            ImportDeclaration(node: any) {
                // console.log(JSON.stringify(node));
                modules.push(new Module(node.source.value, node.loc.start.line, node.loc.start.column));
            },
        });

        const result = new Result(calls, modules);
        console.log('result:', result);
        return new Result(calls, modules);
    }
}
TyrealHu commented 1 year ago

现在给的内容有点少,可以看看你要解析的代码吗,把需要解析的文件内容发我一份 @xuxiaolong1994

xuxiaolong1994 commented 1 year ago

https://github.com/kamranahmedse/developer-roadmap/blob/4b76d0b7aae62ccb956fa8e1d8c15e9ffcbfe4d3/src/components/PageSponsor.tsx 这是我随便找了个文件做测试

xuxiaolong1994 commented 1 year ago

@TyrealHu

TyrealHu commented 1 year ago

好的,我看下

TyrealHu commented 1 year ago

@xuxiaolong1994 你把.default删掉,在试试

xuxiaolong1994 commented 1 year ago
import acorn from "acorn"
import tsPlugin from "acorn-typescript";
import { Call, Module, Result } from "../../entity/result";
import { acorn_service } from "../acorn-service";
import fs from "fs";
import * as walk from "acorn-walk";

export const acorn_ts: acorn_service = {
    run: (path: string) => {

        // 解析代码并获取AST
        const ast = acorn.Parser.extend(tsPlugin()).parse(fs.readFileSync(path, 'utf8'), {
            ecmaVersion: 'latest',
            sourceType: 'module',
            allowReturnOutsideFunction: true,
            allowSuperOutsideMethod: true,
            allowHashBang: true,
            locations: true
        });
        console.log("acorn.Parser.extend")
        // 遍历AST并查找方法调用点
        const calls: Call[] = [];
        const modules: Module[] = [];

        walk.simple(ast, {
            CallExpression: (node: any) => {

                if (node.type === 'CallExpression' &&
                    node.callee.type === 'Identifier' &&
                    node.callee.name === 'require') {
                    // console.log(JSON.stringify(node));
                    const moduleName = node.arguments[0].value;
                    modules.push(new Module(moduleName, node.loc.start.line, node.loc.start.column));
                } else {
                    // console.log(JSON.stringify(node));
                    const functionName = node.callee.name || node.callee.property.name

                    // const args = node.arguments.map((arg: { value: any; }) => typeof arg.value).filter((type: any) => !!type) as string[];

                    // 判断方法调用是否属于第三方包
                    let packageName;
                    if (node.callee.type === 'MemberExpression' && node.callee.object.name !== 'console') {
                        packageName = node.callee.object.name;
                    }

                    calls.push(new Call(packageName, functionName, node.loc.start.line, node.loc.start.column));
                }
            },

            ImportDeclaration(node: any) {
                // console.log(JSON.stringify(node));
                modules.push(new Module(node.source.value, node.loc.start.line, node.loc.start.column));
            },
        });

        const result = new Result(calls, modules);
        console.log('result:', result);
        return new Result(calls, modules);
    }
}

删除掉会报错 image

TyrealHu commented 1 year ago

@xuxiaolong1994 你的项目代码发我一下?按理来说导出是没有问题的

TyrealHu commented 1 year ago

或者你用1.2.2这个版本试试

xuxiaolong1994 commented 1 year ago

这是我的代码https://github.com/xuxiaolong1994/node_ts_test 1.2.2还没有发版吧

TyrealHu commented 1 year ago

已经发布了

TyrealHu commented 1 year ago

@xuxiaolong1994 看了下是你的tsconfig配置错了,你写的代码是esm但是配置的commonjs,还有moduleResolution,不是库的问题

xuxiaolong1994 commented 1 year ago

不好意思我之前是写java的,第一次写了node,你说的这个问题 我已经改了,https://github.com/xuxiaolong1994/node_ts_test 但是还是有问题

import * as acorn from "acorn"
import tsPlugin from "acorn-typescript";
import { Call, Module, Result } from "../../entity/result.js";
import { acorn_service } from "../acorn-service.js";
import fs from "fs";
import * as walk from "acorn-walk";

export const acorn_ts: acorn_service = {
    run: (path: string) => {

        // 解析代码并获取AST
        const ast = acorn.Parser.extend(tsPlugin({dts:true})).parse(fs.readFileSync(path, 'utf8'), {
            ecmaVersion: 'latest',
            sourceType: 'module',
            allowReturnOutsideFunction: true,
            allowSuperOutsideMethod: true,
            allowHashBang: true,
            locations: true
        });
        console.log("acorn.Parser.extend")
        // 遍历AST并查找方法调用点
        const calls: Call[] = [];
        const modules: Module[] = [];

        walk.simple(ast, {
            CallExpression: (node: any) => {

                if (node.type === 'CallExpression' &&
                    node.callee.type === 'Identifier' &&
                    node.callee.name === 'require') {
                    // console.log(JSON.stringify(node));
                    const moduleName = node.arguments[0].value;
                    modules.push(new Module(moduleName, node.loc.start.line, node.loc.start.column));
                } else {
                    // console.log(JSON.stringify(node));
                    const functionName = node.callee.name || node.callee.property.name

                    // const args = node.arguments.map((arg: { value: any; }) => typeof arg.value).filter((type: any) => !!type) as string[];

                    // 判断方法调用是否属于第三方包
                    let packageName;
                    if (node.callee.type === 'MemberExpression' && node.callee.object.name !== 'console') {
                        packageName = node.callee.object.name;
                    }

                    calls.push(new Call(packageName, functionName, node.loc.start.line, node.loc.start.column));
                }
            },

            ImportDeclaration(node: any) {
                // console.log(JSON.stringify(node));
                modules.push(new Module(node.source.value, node.loc.start.line, node.loc.start.column));
            },
        });

        const result = new Result(calls, modules);
        console.log('result:', result);
        return new Result(calls, modules);
    }
}

image @TyrealHu 已经改了配置 还是有问题🍦

ota-meshi commented 1 year ago

(Sorry if I misread your comment.) I think your program will work fine if you import the following:

import { tsPlugin } from "acorn-typescript";
TyrealHu commented 1 year ago

(Sorry if I misread your comment.) I think your program will work fine if you import the following:

import { tsPlugin } from "acorn-typescript";

This was a typescript config issue, But this can be fixed like this