Code Monkey home page Code Monkey logo

acorn-typescript's Introduction

acorn-typescript

npm versionCoverage Status

This is plugin for Acorn - a tiny, fast JavaScript parser, written completely in JavaScript.

It was created as an experimental alternative, faster TypeScript parser. It will help you to parse typescript script into typeScript AST.

Usage

Requiring this module provides you with an Acorn plugin that you can use like this:

import * as acorn from 'acorn'
import tsPlugin from 'acorn-typescript'

/*
*
* */
const node = acorn.Parser.extend(tsPlugin()).parse(`
const a = 1
type A = number
export {
  a,
  type A as B
}
`, {
  sourceType: 'module',
  ecmaVersion: 'latest',
  locations: true
})

If you want to enable parsing within a TypeScript ambient context, where certain syntax have different rules (like .d.ts files and inside declare module blocks).

import * as acorn from 'acorn'
import tsPlugin from 'acorn-typescript'

/*
*
* */
const node = acorn.Parser.extend(tsPlugin({ dts: true })).parse(`
const a = 1
type A = number
export {
  a,
  type A as B
}
`, {
  sourceType: 'module',
  ecmaVersion: 'latest',
  locations: true
})

Notice

  • You have to enable options.locations while using acorn-typescript
acorn.parse(input, {
    sourceType: 'module',
    ecmaVersion: 'latest',
    // here
    locations: true
  })

SUPPORTED

  • Typescript normal syntax
  • Support to parse TypeScript Decorators
  • Support to parse JSX & TSX

CHANGELOG

click

RoadMap

  • support import-assertions

License

MIT

acorn-typescript's People

Contributors

ota-meshi avatar tyrealhu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

acorn-typescript's Issues

Parsing error in `1 < 2 > 3;`

The following code seems to give a parsing error when using acorn-typescript. I found this from test262 results.

1 < 2 > 3;

This is because < 2 > is judged as TypeArguments, and after that it cannot process subsequent code.
However, TypeScript parses this just fine.

By the way, the code below can be successfully parsed as an expression with TypeArguments.

1 < 2 >;

Error calling parseExpressionAt

I have tried the code below but it seems to result in an error.

import * as acorn from "acorn";
import { tsPlugin } from "acorn-typescript";

const acornTs = acorn.Parser.extend(tsPlugin());

// OK
let node = acorn.Parser.parseExpressionAt("<tag prop={foo}/>", 11, {
  sourceType: "module",
  ecmaVersion: "latest",
  locations: true,
});
console.log(node);

// Error
node = acornTs.parseExpressionAt("<tag prop={foo as number}/>", 11, {
  sourceType: "module",
  ecmaVersion: "latest",
  locations: true,
});

console.log(node);

console:

TypeError: i.parseExpressionAt is not a function
    at e.parseExpressionAt (/xxxxxxxxx/node_modules/.pnpm/[email protected][email protected]/node_modules/acorn-typescript/lib/index.js:1:100013)

I think we probably need to call parser.parseExpression() instead of parser.parseExpressionAt().

return (parser as any).parseExpressionAt()

"assert" being treated as reserved word in importdeclarations

Been scratching my head over it for a bit, but then realized it probably originates from the import assertion support (or was that targetting import attributes already? i keep confusing what stands where in that transition).
parsed file: https://github.com/TooTallNate/proxy-agents/blob/main/packages/https-proxy-agent/src/index.ts#L4
thrown error:

 SyntaxError: Unexpected token (4:7)
    at pp.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/location.js:15:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5169:44)
    at TypeScriptParser.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5175:29)
    at pp.unexpected (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:111:8)
    at pp.expect (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:105:26)
    at pp.parseImportSpecifiers (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/statement.js:1063:8)
    at TypeScriptParser.parseImport (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3381:44)
    at pp.parseStatement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/statement.js:137:44)
    at TypeScriptParser.parseStatement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3739:30)
    at pp.parseTopLevel (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/statement.js:22:21) {
  pos: 93,
  loc: Position { line: 4, column: 7 },
  raisedAt: 99
}

from what i logged, this.type at the "assert" token is tt.name in TypescriptParser.parseImport, but that somehow doesn't equal tt.name in pp.parseImportSpecifiers, with the difference being:

console.log(this.type);
// TokenType { label: 'name', updateContext: null}
console.log(tt.name);
// TokenType { label: 'name', updateContext: [Function (anonymous)]}

Unexpected token at directly exported interface declaration

back with another case study:

parsed file:
https://github.com/socketio/socket.io/blob/main/lib/socket.ts#L98

/* The handshake details */
export interface Handshake {
  /* The headers sent as part of the handshake  */
  headers: IncomingHttpHeaders;
         ^
  /* The date of creation (as string)*/
  time: string;

error:

SyntaxError: Unexpected token (98:9)
    at pp$4.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn.js:2472:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5208:44)
    at TypeScriptParser.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5214:29)
    at pp$9.unexpected (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn.js:509:8)
    at pp$9.expect (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn.js:506:26)
    at TypeScriptParser.jsx_parseExpressionContainer (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:823:18)
    at TypeScriptParser.jsx_parseElementAt (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:885:48)
    at TypeScriptParser.jsx_parseElement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:914:25)
    at TypeScriptParser.parseExprAtom (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3641:33)
    at pp$5.parseExprSubscripts (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn.js:1841:19)

should be a regular TSInterfaceDeclaration, but seems to be mistaken for some reason, only possible one seeming to be the several comments lying around... edit: that might be stupid, the direct export seems more suspect.. although weird if only now was its first occurrence.

SyntaxError: Unexpected token for optional class property

Another error coming from parsing Rollup's src/Graph.ts:

export default class Graph {
        readonly acornParser: typeof acorn.Parser;
        readonly cachedModules = new Map<string, ModuleJSON>();
        readonly deoptimizationTracker = new PathTracker();
        entryModules: Module[] = [];
        readonly fileOperationQueue: Queue;
        readonly moduleLoader: ModuleLoader;
        readonly modulesById = new Map<string, Module | ExternalModule>();
        needsTreeshakingPass = false;
        phase: BuildPhase = BuildPhase.LOAD_AND_PARSE;
        readonly pluginDriver: PluginDriver;
        readonly pureFunctions: PureFunctions;
        readonly scope = new GlobalScope();
        readonly watchFiles: Record<string, true> = Object.create(null);
        watchMode = false;

        private readonly externalModules: ExternalModule[] = [];
        private implicitEntryModules: Module[] = [];
        private modules: Module[] = [];
        private declare pluginCache?: Record<string, SerializablePluginCache>;
}
                                   ^

throwing:

SyntaxError: Unexpected token (72:28)
    at pp.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/location.js:15:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4975:44)
    at TypeScriptParser.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4981:29)
    at pp.unexpected (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:111:8)
    at pp.semicolon (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:88:59)
    at pp.parseClassField (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/statement.js:747:8)
    at TypeScriptParser.parseClassField (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3730:30)
    at callParseClassMemberWithIsStatic (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3904:34)
    at TypeScriptParser.tsInAmbientContext (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:2995:28)
    at TypeScriptParser.parseClassElement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3910:26) {
  pos: 2348,
  loc: Position { line: 72, column: 28 },
  raisedAt: 2349
}

Syntax errors in .d.ts file (unassigned const export, overloaded function type)

rollup/src/rollup/types.d.ts:

export const VERSION: string;
                            ^
SyntaxError: Unexpected token (1:28)
    at pp.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/location.js:15:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4975:44)
    at TypeScriptParser.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4981:29)
    at pp.unexpected (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:111:8)
    at pp.parseVar (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/statement.js:507:12)
    at TypeScriptParser.parseVarStatement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3519:23)
    at pp.parseStatement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/statement.js:116:17)
    at TypeScriptParser.parseStatement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3568:30)
    at TypeScriptParser.parseExport (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/xtuc_2020_acorn_importassertions/0/src/index.js:101:33)
    at TypeScriptParser.parseExport (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3392:34) {
  pos: 28,
  loc: Position { line: 1, column: 28 },
  raisedAt: 29
}

last in a batch of 4 issues.

Ranges: node.start > node.end, but loc still valid

Test input:

export default class ParamList extends Vue { // Newline here to trigger
@Watch('deepStuff') private onDeepChange() {} } 

Expected result: all nodes have .start < .end
Actual result: some nodes have a very low number as end, < start

Is this the culprit? Was expecting something along the lines of node.end = endLoc.index?

node.end = endLoc.column

error: Unexpected token

hey, team. i had some questions for this plugin

parsefile's code

const testApp = async(app: string, index: number) => {
};

parseFunction

export class ScanAnalyzer{
  private parser: any;

  constructor() {
    this.parser = Parser.extend(
      tsPlugin({
        jsx: {
          allowNamespaces: true,
        },
      })
    );
  }
  scanFileForChinese(filePath: string) : boolean {
    const sourceCode = fs.readFileSync(filePath[0], "utf8");

    const ast = this.parser.parse(sourceCode, {
      ecmaVersion: "latest",
      sourceType: "module",
      locations: true,
      onComment: (isBlock, text, start, end, startLoc, endLoc) => {
        if (isBlock) {
          console.warn(
          
          );
        } else {
          console.warn(
           
          );
        }
      }, // 保留注释信息
    });

    let hasChinese = false;
  
    
    walk.simple(
      ast,
      {
        Literal(node) {
          if (typeof node.value === "string" && chineseRegExp.test(node.value)) {
            console.warn(
             
            );
            hasChinese = true;
          }
        },
        VariableDeclarator(node) {
          if (node.init === null) {
            console.warn(
              `Variable ${node.id.name} at line ${node.loc.start.line} has a missing initializer.`
            );
          }
        },
      },
      {
        ...walk.base,
        JSXElement: (node) => {
          console.log(node)
        }
      }
    );
    return hasChinese
  }

  scanFilesForChinese(files: string[]) {
    let hasChinese = false;

    files.forEach((file) => {
      if (this.scanFileForChinese(file)) {
        hasChinese = true;
      }
    });
  
    return hasChinese;
  }
}

why show this error: SyntaxError: Unexpected token (1:23)

Type assertion error

This is the parser code that I used

const node = acorn.Parser.extend(tsPlugin.tsPlugin({dts:false})).parse(file, { sourceType: 'module', ecmaVersion: 'latest', locations: true   })

The source code file contains the Secret type assertion which cause the parser to fail:

desensitizedAdmin.token = jwt.sign({
            authenticated: true,
            admin_id: admin.id,
            username: admin.username,
            role: admin.role
        }, <Secret>process.env.TOKEN_SECRET, {
            expiresIn: 10
        })

Error:

SyntaxError: Unexpected token (175:21)
    at e.pp$4.raise (C:\Users\orang\Documents\Work\Project\misc\swagger\node_modules\acorn\dist\acorn.js:3560:15)
    at e.p.raiseCommonCheck (C:\Users\orang\Documents\Work\Project\misc\swagger\node_modules\acorn-typescript\lib\index.js:1:101327)
    at e.p.raise (C:\Users\orang\Documents\Work\Project\misc\swagger\node_modules\acorn-typescript\lib\index.js:1:101481)
    at e.pp$9.unexpected (C:\Users\orang\Documents\Work\Project\misc\swagger\node_modules\acorn\dist\acorn.js:768:10)
    at e.pp$9.expect (C:\Users\orang\Documents\Work\Project\misc\swagger\node_modules\acorn\dist\acorn.js:762:28)
    at e.s.jsx_parseExpressionContainer (C:\Users\orang\Documents\Work\Project\misc\swagger\node_modules\acorn-typescript\lib\index.js:1:20515)
    at e.s.jsx_parseElementAt (C:\Users\orang\Documents\Work\Project\misc\swagger\node_modules\acorn-typescript\lib\index.js:1:21886)
    at e.s.jsx_parseElement (C:\Users\orang\Documents\Work\Project\misc\swagger\node_modules\acorn-typescript\lib\index.js:1:22474)
    at e.p.parseExprAtom (C:\Users\orang\Documents\Work\Project\misc\swagger\node_modules\acorn-typescript\lib\index.js:1:72076)
    at e.pp$5.parseExprSubscripts (C:\Users\orang\Documents\Work\Project\misc\swagger\node_modules\acorn\dist\acorn.js:2708:21) {
  pos: 5110,
  loc: Position { line: 175, column: 21 },
  raisedAt: 5111
}

Are there some additional options that I need to enable to make this work ?

compatible with @typescript-eslint/scope-manager?

I want to do some scope analysis for acorn-typescript, the best library I can find is @typescript-eslint/scope-manager, but I'm not sure whether compatible with @typescript-eslint/scope-manager is the goal of this project or any alternative solution for it

SyntaxError: override modifier refused despite containing class extending another

Shouldn't this condition be a negation?

if (constructorAllowsSuper) {

detected in parsing file:
https://github.com/socketio/socket.io-adapter/blob/28f60b880ad04ff4b48ade0cd529f1970643604f/lib/index.ts#L438

error:

Failed to patriate typescript "file:///mnt/chromeos/GoogleDrive/MyDrive/blik/rauch_2014_socketio_adapter/0/lib/index.ts" due to SyntaxError: This member cannot have an 'override' modifier because its containing class does not extend another class. (438:2)
    at pp$4.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn.js:2473:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5207:44)
    at TypeScriptParser.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5213:29)
    at callParseClassMemberWithIsStatic (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4067:38)
    at TypeScriptParser.parseClassElement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4132:21)

SyntaxError: Unexpected token at non-null assertion in body expression of an object literal's arrow function value

Parsed file: rollup/rollup/src/ast/nodes/BinaryExpression.ts

const binaryOperators: {
        [operator in Operator]?: (left: LiteralValue, right: LiteralValue) => LiteralValueOrUnknown;
} = {
        '!=': (left, right) => left != right,
        '!==': (left, right) => left !== right,
        '%': (left: any, right: any) => left % right,
        '&': (left: any, right: any) => left & right,
        '*': (left: any, right: any) => left * right,
        // At the moment, "**" will be transpiled to Math.pow
        '**': (left: any, right: any) => left ** right,
        '+': (left: any, right: any) => left + right,
        '-': (left: any, right: any) => left - right,
        '/': (left: any, right: any) => left / right,
        '<': (left, right) => left! < right!,
//                                ^
        // ...further methods
};

Error:

SyntaxError: Unexpected token (57:29)
    at pp.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/location.js:15:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5008:44)
    at TypeScriptParser.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5014:29)
    at pp.unexpected (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:111:8)
    at pp.expect (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:105:26)
    at pp.parseObj (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/expression.js:749:12)
    at pp.parseExprAtom (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/expression.js:484:17)
    at TypeScriptParser.parseExprAtom (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3473:34)
    at pp.parseExprSubscripts (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/expression.js:292:19)
    at pp.parseMaybeUnary (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/expression.js:258:17) {
  pos: 1644,
  loc: Position { line: 57, column: 29 },
  raisedAt: 1645
}

Issue with for of loops

Hi,

It seems that it has issue with for of loops

function findLongestWord(sentence: string): number {
    const words = sentence.split(' ');
    let maxLength = 0;

    for (const word of words) {
        const length = word.length;

        if (length > maxLength) {
            maxLength = length;
        }
    }

    return maxLength;
}

image

works if I replace for of with for loop.
works if I remove Typescript and used default acorn.

fails on v1.0.13 and v1.1.0

"Unexpected token" with optional parameters at arrow functions

Consider this test code:

import * as acorn from 'acorn'
import tsPlugin from 'acorn-typescript'

const node = acorn.Parser.extend(tsPlugin()).parse(`

const someArrowFunc = (bla: any, hey?: any) => 42;

`, {
  sourceType: 'module',
  ecmaVersion: 'latest',
  locations: true
});
console.log(JSON.stringify(node, null, 2));

It will raise an "Unexpected token" exception because the hey parameter is optional. Removing the ? character immediately makes the exception disappear.

SyntaxError: Unexpected token at destructured and typed argument list of arrow function declaration

parsed file: rollup/src/utils/pureFunctions.ts

export const getPureFunctions = ({ treeshake }: NormalizedInputOptions): PureFunctions => {};
                                                                      ^
SyntaxError: Unexpected token (10:71)
    at pp.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/location.js:15:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4990:44)
    at TypeScriptParser.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4996:29)
    at pp.unexpected (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:111:8)
    at pp.semicolon (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:88:59)
    at TypeScriptParser.parseVarStatement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3520:22)
    at pp.parseStatement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/statement.js:116:17)
    at TypeScriptParser.parseStatement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3568:30)
    at TypeScriptParser.parseExport (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/xtuc_2020_acorn_importassertions/0/src/index.js:101:33)
    at TypeScriptParser.parseExport (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3392:34) {
  pos: 296,
  loc: Position { line: 10, column: 71 },
  raisedAt: 297
}

`this` variable declarations should cause an error.

It seems that an error should be raised in the following cases, but the error is not raised. I found this from test262 results.

// See: https://github.com/tc39/test262/blob/main/test/language/identifiers/val-this.js
var this = 42;

// See: https://github.com/tc39/test262/blob/main/test/language/statements/class/syntax/escaped-static.js
class C {
  st\u0061tic m() {
  } 
}

SyntaxError: Binding rvalue at second (or default-assigned) private constructor parameter

parsing Rollup's src/ast/nodes/shared/ObjectEntity.ts:

export class ObjectEntity extends ExpressionEntity {
        constructor(
                properties: ObjectProperty[] | PropertyMap,
                private prototypeExpression: ExpressionEntity | null,
                private immutable = false
                ^
        ) {}
}

SyntaxError: Binding rvalue (60:2)
    at pp.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/location.js:15:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5008:44)
    at TypeScriptParser.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5014:29)
    at pp.checkLValSimple (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/lval.js:284:10)
    at pp.checkLValPattern (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/lval.js:303:10)
    at TypeScriptParser.checkLValInnerPattern (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4223:30)
    at pp.checkParams (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/expression.js:978:10)
    at pp.parseFunctionBody (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/expression.js:955:10)
    at TypeScriptParser.parseFunctionBody (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3222:23)
    at TypeScriptParser.parseMethod (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4839:22) {
  pos: 2297,
  loc: Position { line: 60, column: 2 },
  raisedAt: 2327
}

not really sure what's the mistake in this one.

Unexpected token when using Generic tagged template function

Context & Exemple

For some libraries, it is quite usefull to be able to provide the type of a tagged template function

For exemple, styled-components:

import styled from 'styled-components';

type ExtendedProps = {
    $anyprop: string;
};

const StyledDiv = styled.div<ExtendedProps>`
    color: red;
`;

But when using acorn-typescript it fails with the error:

SyntaxError: Unexpected token (8:43)
    at pp$4.raise (/REDACTED/repro/node_modules/.pnpm/[email protected]/node_modules/acorn/dist/acorn.js:3571:15)
    at p.raiseCommonCheck (/REDACTED/repro/node_modules/.pnpm/[email protected][email protected]/node_modules/acorn-typescript/lib/index.js:1:101327)
    at p.raise (/REDACTED/repro/node_modules/.pnpm/[email protected][email protected]/node_modules/acorn-typescript/lib/index.js:1:101481)
    at pp$9.unexpected (/REDACTED/repro/node_modules/.pnpm/[email protected]/node_modules/acorn/dist/acorn.js:772:10)
    at pp$9.semicolon (/REDACTED/repro/node_modules/.pnpm/[email protected]/node_modules/acorn/dist/acorn.js:749:68)
    at p.parseVarStatement (/REDACTED/repro/node_modules/.pnpm/[email protected][email protected]/node_modules/acorn-typescript/lib/index.js:1:73894)
    at pp$8.parseStatement (/REDACTED/repro/node_modules/.pnpm/[email protected]/node_modules/acorn/dist/acorn.js:927:19)
    at p.parseStatement (/REDACTED/repro/node_modules/.pnpm/[email protected][email protected]/node_modules/acorn-typescript/lib/index.js:1:74861)
    at pp$8.parseTopLevel (/REDACTED/repro/node_modules/.pnpm/[email protected]/node_modules/acorn/dist/acorn.js:829:23)
    at e.parse (/REDACTED/repro/node_modules/.pnpm/[email protected]/node_modules/acorn/dist/acorn.js:601:17) {
  pos: 134,
  loc: Position { line: 8, column: 43 },
  raisedAt: 135
}

How to reproduce

Note
Here is a link for reproduction: https://github.com/maastrich/repro/tree/TyrealHu/acorn-typescript-48

git clone https://github.com/maastrich/repro.git
cd repro
git switch TyrealHu/acorn-typescript-48
pnpm install
node repro.js

Parser fails when used in a ESM context

It fails to parse something like 1 as number because the plugin does reference equality checks on token types.

But if using it from an ESM file, the users will load acorn/index.mjs, whereas this plugin will load the tokenTypes from acorn/index.js, which means the token types will be different objects even if they are the same token type and the reference equality will return false.

Possible solutions:

  1. Replace tokType reference equality checks with comparing tokType.label
  2. Rename the index.esm.js file to index.mjs and let users import from it manually
  3. Use exports map instead of module since node doesn't care about module and will always load the CJS version of this package (https://publint.dev/[email protected])

SyntaxError when parsing React.ComponentProps<typeof RRLink>

To reproduce:

const acorn = require('acorn');
const { tsPlugin } = require('acorn-typescript');

const parser = acorn.Parser.extend(tsPlugin());

const source = `
import * as React from 'react'
import { Link as RRLink } from 'react-router-dom';

const Link = (props: React.ComponentProps<typeof RRLink>) => null
`;

const ast = parser.parse(source, {
    sourceType: 'module',
    locations: true,
    ecmaVersion: 'latest',
}); // ERROR

This throw this error:

/Users/yadomi/workspace/node_modules/acorn/dist/acorn.js:3562
    throw err
    ^

SyntaxError: Unexpected token (5:56)
    at pp$4.raise (/Users/yadomi/workspace/node_modules/acorn/dist/acorn.js:3560:15)
    at p.raiseCommonCheck (/Users/yadomi/workspace/node_modules/acorn-typescript/lib/index.js:1:101091)
    at p.raise (/Users/yadomi/workspace/node_modules/acorn-typescript/lib/index.js:1:101245)
    at pp$9.unexpected (/Users/yadomi/workspace/node_modules/acorn/dist/acorn.js:768:10)
    at p.tsParseNonArrayType (/Users/yadomi/workspace/node_modules/acorn-typescript/lib/index.js:1:48305)
    at p.tsParseArrayTypeOrHigher (/Users/yadomi/workspace/node_modules/acorn-typescript/lib/index.js:1:48372)
    at /Users/yadomi/workspace/node_modules/acorn-typescript/lib/index.js:1:48964
    at p.tsInAllowConditionalTypesContext (/Users/yadomi/workspace/node_modules/acorn-typescript/lib/index.js:1:38740)
    at p.tsParseTypeOperatorOrHigher (/Users/yadomi/workspace/node_modules/acorn-typescript/lib/index.js:1:48911)
    at p.tsParseUnionOrIntersectionType (/Users/yadomi/workspace/node_modules/acorn-typescript/lib/index.js:1:41989) {
  pos: 140,
  loc: Position { line: 5, column: 56 },
  raisedAt: 141
}

Update:

However, this works:

type RRLinkType = typeof RRLink
const Link = (props: React.ComponentProps<RRLinkType>) => null

SyntaxError: Assigning to rvalue

Got an interesting one:

export const getHashPlaceholderGenerator = (): HashPlaceholderGenerator => {
        let nextIndex = 0;
        return (optionName: string, hashSize: number = defaultHashSize) => {}
                                            ^
}
SyntaxError: Assigning to rvalue (17:37)
    at pp.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/location.js:15:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4990:44)
    at TypeScriptParser.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4996:29)
    at pp.toAssignable (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/lval.js:82:12)
    at TypeScriptParser.toAssignable (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4288:38)
    at TypeScriptParser.parseMaybeAssignOrigin (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4023:37)
    at TypeScriptParser.parseMaybeAssign (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4078:33)
    at TypeScriptParser.parseParenAndDistinguishExpression (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4396:48)
    at pp.parseExprAtom (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/expression.js:467:41)
    at TypeScriptParser.parseExprAtom (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3459:34) {
  pos: 660,
  loc: Position { line: 17, column: 37 },
  raisedAt: 670
}

looks like the argument subscript of the arrow function being returned is prematurely mistaken for comma-operator expression due to the default assignment happening.

The parser confuses TS constrained mixins with JSX

Here's a minimal reproduction code:

export const Triggerable = <C extends HTMLElement = HTMLElement>(superClass: C) => {
  return class extends superClass {
    initTriggerable(options) {
      this.#options = options;
	}
    };
};

This is just a standard ts mixin

Trying to parse a file containing this code yields an error

> const options = { sourceType: 'module', ecmaVersion: 'latest', locations: true };
> const code = 'export const Triggerable = <C extends HTMLElement = HTMLElement>(superClass: C) => {\n' +
  '\treturn class extends superClass {\n' +
  '\t\tinitTriggerable(options) {\n' +
  '\t\t\tthis.#options = options;\n' +
  '\t\t}\n' +
  '\t};\n' +
  '};\n'
> parser.parse(code, options)
Uncaught:
[SyntaxError: JSX value should be either an expression or a quoted JSX text (1:52)
] {
  pos: 52,
  loc: Position { line: 1, column: 52 },
  raisedAt: 63
}

This prevents me from using acorn-typescript for parsing some ts files

What do you think about introducing regression tests with test262-parser-runner?

First of all thank you for working on this acorn plugin for typescript.

I personally ran test262-parser-runner, which is also used by Acorn, on acorn-typescript fork repository and found some errors.

https://github.com/adrianheine/test262-parser-runner
master...ota-meshi:acorn-typescript:add-test262

Some tests still seem to fail, but I think it makes sense to introduce test262 so that we can share with you what is failing.

Fails to parse generics without a trailing comma

const a: Foo<T,> = 1 will succeed however const a: Foo<T> = 1 will raise an unexpected token error.

Stack trace

SyntaxError: Unexpected token (1:18)
    at pp$4.raise (node_modules/.pnpm/[email protected]/node_modules/acorn/dist/acorn.mjs:3459:13)
    at A.raiseCommonCheck (node_modules/.pnpm/[email protected][email protected]/node_modules/acorn-typescript/lib/index.mjs:4216:38)
    at A.raise (node_modules/.pnpm/[email protected][email protected]/node_modules/acorn-typescript/lib/index.mjs:4223:18)
    at pp$9.unexpected (node_modules/.pnpm/[email protected]/node_modules/acorn/dist/acorn.mjs:760:8)
    at A.tsParseNonArrayType (node_modules/.pnpm/[email protected][email protected]/node_modules/acorn-typescript/lib/index.mjs:2073:11)
    at A.tsParseArrayTypeOrHigher (node_modules/.pnpm/[email protected][email protected]/node_modules/acorn-typescript/lib/index.mjs:2077:20)
    at node_modules/.pnpm/[email protected][email protected]/node_modules/acorn-typescript/lib/index.mjs:2100:18
    at A.tsInAllowConditionalTypesContext (node_modules/.pnpm/[email protected][email protected]/node_modules/acorn-typescript/lib/index.mjs:1663:14)
    at A.tsParseTypeOperatorOrHigher (node_modules/.pnpm/[email protected][email protected]/node_modules/acorn-typescript/lib/index.mjs:2099:14)
    at A.tsParseUnionOrIntersectionType (node_modules/.pnpm/[email protected][email protected]/node_modules/acorn-typescript/lib/index.mjs:1798:14) {
  pos: 16,
  loc: Position { line: 1, column: 16 },
  raisedAt: 17

SyntaxError: Unexpected token in arrow function's (nested) generic type

Thrown in Rollup's src/utils/options/normalizeInputOptions.ts:

const getIdMatcher = <T extends Array<any>>(
                                     ^
        option:
                | undefined
                | boolean
                | string
                | RegExp
                | (string | RegExp)[]
                | ((id: string, ...parameters: T) => boolean | null | void)
): ((id: string, ...parameters: T) => boolean) => {
        if (option === true) {
                return () => true;
        }
        if (typeof option === 'function') {
                return (id, ...parameters) => (!id.startsWith('\0') && option(id, ...parameters)) || false;
        }
        if (option) {
                const ids = new Set<string>();
                const matchers: RegExp[] = [];
                for (const value of ensureArray(option)) {
                        if (value instanceof RegExp) {
                                matchers.push(value);
                        } else {
                                ids.add(value);
                        }
                }
                return (id: string, ..._arguments) => ids.has(id) || matchers.some(matcher => matcher.test(id));
        }
        return () => false;
};
SyntaxError: Unexpected token (116:37)
    at pp.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/location.js:15:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4975:44)
    at TypeScriptParser.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4981:29)
    at pp.unexpected (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:111:8)
    at TypeScriptParser.jsx_parseIdentifier (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:773:22)
    at TypeScriptParser.jsx_parseNamespacedName (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:780:29)
    at TypeScriptParser.jsx_parseAttribute (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:847:30)
    at TypeScriptParser.jsx_parseOpeningElementAt (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5017:47)
    at TypeScriptParser.jsx_parseElementAt (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:878:39)
    at TypeScriptParser.jsx_parseElement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:926:25) {
  pos: 3725,
  loc: Position { line: 116, column: 37 },
  raisedAt: 3726
}

looks like jsx is getting involved, this might be a tough one...
I was surprised actually that the acorn Parser's class name became "JSXParser" by the way after extending with this plugin, is there an option to not enable JSX parsing along with typescript?

Missing internal deps

Hi again! :)

The plugin works perfectly but is throwing some errors with internal dependencies.

node_modules\acorn-typescript\lib\index.d.ts

image

Is it normal ? maybe is missing some dependencies in package.json of plugin ?

My versions of dependencies:
image

Thanks!

TypeError: Class constructors cannot be invoked without 'new'

Hi, im getting the error: TypeError: Class constructors cannot be invoked without 'new'

Stack trace...

MyExtension error: TypeError: Class constructors cannot be invoked without 'new'
    at e [as constructor] (c:\Users\myuser\Desktop\Workspace\my-extension\node_modules\acorn-typescript\lib\index.js:1:15137)
    at e [as constructor] (c:\Users\myuser\Desktop\Workspace\my-extension\node_modules\acorn-typescript\lib\index.js:1:16812)
    at new e (c:\Users\myuser\Desktop\Workspace\my-extension\node_modules\acorn-typescript\lib\index.js:1:22553)
    at Function.e.parse (c:\Users\myuser\Desktop\Workspace\my-extension\node_modules\acorn-typescript\lib\index.js:1:98376)
    at ClassAnalyzer.astParse (c:\Users\myuser\Desktop\Workspace\my-extension\src\ClassAnalyzer.ts:20:4)
    at c:\Users\myuser\Desktop\Workspace\my-extension\src\ClassAnalyzer.ts:47:22
    at Array.forEach (<anonymous>)
    at ClassAnalyzer.getComponents (c:\Users\myuser\Desktop\Workspace\my-extension\src\ClassAnalyzer.ts:44:7)
    at MyExtension.provideCompletionItems (c:\Users\myuser\Desktop\Workspace\my-extension\src\MyExtension.ts:69:44)
    at oe.provideCompletionItems (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:100:52903)
    at c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:100:73510
    at le.s (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:100:65165)
    at le.$provideCompletionItems (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:100:73496)
    at a.N (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:110:11620)
    at a.M (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:110:11338)
    at a.H (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:110:10393)
    at a.G (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:110:9412)
    at c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:110:8200
    at v.invoke (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:63:145)
    at h.deliver (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:63:2121)
    at i.fire (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:63:1729)
    at g.fire (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:72:14852)
    at c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:126:32403
    at v.invoke (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:63:145)
    at h.deliver (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:63:2121)
    at i.fire (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:63:1729)
    at g.fire (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:72:14852)
    at MessagePortMain.<anonymous> (c:\Users\myuser\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\api\node\extensionHostProcess.js:126:30529)
    at MessagePortMain.emit (C:\Users\myuser\Desktop\Workspace\my-extension\lib\events.js:513:28)
    at MessagePortMain.emit (C:\Users\myuser\Desktop\Workspace\my-extension\lib\domain.js:489:12)
    at Object.MessagePortMain._internalPort.emit (C:\Users\myuser\Desktop\Workspace\my-extension\lib\electron\js2c\utility_init.js:2:367)
    at Object.topLevelDomainCallback (C:\Users\myuser\Desktop\Workspace\my-extension\lib\domain.js:161:15)
    at Object.callbackTrampoline (node:internal/async_hooks:128:24) {vslsStack: Array(33), stack: 'TypeError: Class constructors cannot be invok…Trampoline (node:internal/async_hooks:128:24)', message: 'Class constructors cannot be invoked without 'new''}

Part of my code...

import { Node, Parser } from "acorn";
import { tsPlugin } from "acorn-typescript";
import { lstatSync, readFileSync, readdirSync } from "fs";
import path = require("path");

export class ClassAnalyzer{
  private parser: any;

  constructor() {
    this.parser = Parser.extend(
      require("acorn-jsx")(),
      tsPlugin({
        dts: true,
      })
    );
  }
...

Weird errors in index.d.ts from the library...
image

Thanks.

SyntaxError: Unexpected type cast in parameter position at left side of an assignment

Parsed file: https://github.com/rollup/rollup/blob/master/src/ast/nodes/CatchClause.ts#L26

export default class CatchClause extends NodeBase {
        declare body: BlockStatement;
        declare param: PatternNode | null;
        declare preventChildBlockScope: true;
        declare scope: CatchScope;
        declare type: NodeType.tCatchClause;
        createScope(parentScope: Scope): void {
                this.scope = new CatchScope(parentScope, this.context);
        }
        parseNode(esTreeNode: GenericEsTreeNode): void {
                const { param } = esTreeNode;
                if (param) {
                        (this.param as GenericEsTreeNode) = new (this.context.getNodeConstructor(param.type))(
//                      ^
                                param, this,this.scope
                        );
                        this.param!.declare('parameter', UNKNOWN_EXPRESSION);
                }
                super.parseNode(esTreeNode);
        }
}

Result:

SyntaxError: Unexpected type cast in parameter position. (26:4)
    at pp.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/location.js:15:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5008:44)
    at TypeScriptParser.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5014:29)
    at TypeScriptParser.toAssignable (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4294:34)
    at TypeScriptParser.parseMaybeAssignOrigin (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4037:37)
    at TypeScriptParser.parseMaybeAssign (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4092:33)
    at pp.parseExpression (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/expression.js:98:19)
    at pp.parseStatement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/statement.js:151:45)
    at TypeScriptParser.parseStatement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3582:30)
    at pp.parseBlock (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/statement.js:436:21) {
  pos: 977,
  loc: Position { line: 26, column: 4 },
  raisedAt: 1011
}

Feature-Request: support import-assertions

While parsing Rollup's src/ast/nodes/shared/FunctionBase.ts:

export default abstract class FunctionBase extends NodeBase {
                        ^
        declare async: boolean;
        // ...
}

SyntaxError: Unexpected token (36:24)
    at pp.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/location.js:15:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5008:44)
    at TypeScriptParser.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:5014:29)
    at pp.unexpected (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:111:8)
    at pp.semicolon (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:88:59)
    at TypeScriptParser.parseExport (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/xtuc_2020_acorn_importassertions/0/src/index.js:96:16)
    at TypeScriptParser.parseExport (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3392:34)
    at pp.parseStatement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/statement.js:137:69)
    at TypeScriptParser.parseStatement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3582:30)
    at pp.parseTopLevel (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/statement.js:22:21) {
  pos: 1277,
  loc: Position { line: 36, column: 24 },
  raisedAt: 1282
}

acorn expects a semicolon after the "abstract" keyword.

用ts写的代码,按照示例执行报错

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";



import  jsx from "acorn-jsx";

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);
    }
}

D:\MF\git\node_ts_test\build\model\run-acorn\service\impl\acorn-ts-service-impl.js:38
const ast = acorn_1.default.Parser.extend((0, acorn_typescript_1.default)()).parse(fs_1.default.readFileSync(path, 'utf8'), {
^

TypeError: (0 , acorn_typescript_1.default) is not a function
at Object.run (D:\MF\git\node_ts_test\build\model\run-acorn\service\impl\acorn-ts-service-impl.js:38:82)
at D:\MF\git\node_ts_test\build\model\run-acorn\service\acorn-service.js:28:59
at Array.map ()
at acorn_run (D:\MF\git\node_ts_test\build\model\run-acorn\service\acorn-service.js:15:18)
at Object. (D:\MF\git\node_ts_test\build\server.js:44:46)
at Module._compile (node:internal/modules/cjs/loader:1254:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
at Module.load (node:internal/modules/cjs/loader:1117:32)
at Module._load (node:internal/modules/cjs/loader:958:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)

The keyword 'private' is reserved

parsing Rollup, in its src/Bundle.ts file the plugin collides with this syntax:

export default class Bundle {
        private readonly facadeChunkByModule = new Map<Module, Chunk>();
        private readonly includedNamespaces = new Set<Module>();

        constructor(
                private readonly outputOptions: NormalizedOutputOptions,
                private readonly unsetOptions: ReadonlySet<string>,
                private readonly inputOptions: NormalizedInputOptions,
                private readonly pluginDriver: PluginDriver,
                private readonly graph: Graph
        ) {}

throwing:

SyntaxError: The keyword 'private' is reserved (37:2)
    at pp.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/location.js:15:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4947:44)
    at TypeScriptParser.raiseRecoverable (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4950:29)
    at pp.checkUnreserved (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/expression.js:1027:10)
    at pp.parseIdent (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/expression.js:1040:10)
    at pp.parseBindingAtom (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/lval.js:141:15)
    at TypeScriptParser.parseBindingAtom (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4288:38)
    at pp.parseMaybeDefault (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/lval.js:180:23)
    at TypeScriptParser.parseMaybeDefault (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3386:36)
    at TypeScriptParser.parseAssignableListItem (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4159:35) {
  pos: 1334,
  loc: Position { line: 37, column: 2 },
  raisedAt: 1350
}```

SyntaxError: Unexpected token on class method generic types

Another error thrown parsing Rollup's src/utils/PluginDriver.ts:

export class PluginDriver {
        public readonly emitFile: EmitFile;
        public finaliseAssets: () => void;
        public getFileName: (fileReferenceId: string) => string;
        public readonly setChunkInformation: (facadeChunkByModule: ReadonlyMap<Module, Chunk>) => void;
        public readonly setOutputBundle: (
                bundle: OutputBundleWithPlaceholders,
                outputOptions: NormalizedOutputOptions
        ) => void;

        private readonly fileEmitter: FileEmitter;
        private readonly pluginContexts: ReadonlyMap<Plugin, PluginContext>;
        private readonly plugins: readonly Plugin[];
        private readonly sortedPlugins = new Map<AsyncPluginHooks, Plugin[]>();
        private readonly unfulfilledActions = new Set<HookAction>();

        // chains, first non-null result stops and returns
        hookFirst<H extends AsyncPluginHooks & FirstPluginHooks>(
-----------------^
                hookName: H,
                parameters: Parameters<FunctionPluginHooks[H]>,
                replaceContext?: ReplaceContext | null,
                skipped?: ReadonlySet<Plugin> | null
        ): Promise<ReturnType<FunctionPluginHooks[H]> | null> {
                let promise: Promise<ReturnType<FunctionPluginHooks[H]> | null> = Promise.resolve(null);
                for (const plugin of this.getSortedPlugins(hookName)) {
                        if (skipped && skipped.has(plugin)) continue;
                        promise = promise.then(result => {
                                if (result != null) return result;
                                return this.runHook(hookName, parameters, plugin, replaceContext);
                        });
                }
                return promise;
        }
SyntaxError: Unexpected token (130:10)
    at pp.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/location.js:15:13)
    at TypeScriptParser.raiseCommonCheck (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4975:44)
    at TypeScriptParser.raise (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4981:29)
    at pp.unexpected (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:111:8)
    at pp.semicolon (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/parseutil.js:88:59)
    at pp.parseClassField (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/haverbeke_2012_acorn/0/acorn/src/statement.js:747:8)
    at TypeScriptParser.parseClassField (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3730:30)
    at callParseClassMemberWithIsStatic (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3904:34)
    at TypeScriptParser.parseClassElement (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:3913:21)
    at TypeScriptParser.parseClass (file:///mnt/chromeos/GoogleDrive/MyDrive/blik/tyrealhu_2023_acorn_typescript.js:4747:46) {
  pos: 4032,
  loc: Position { line: 130, column: 10 },
  raisedAt: 4033
}

compatibility with `acorn.walk` (visitor types)

With the following bit of code, I ran into this issue when trying to walk this with acorn.walk

interface User {
  name: string;
}

export default class Greeting extends HTMLElement {
  connectedCallback() {
    const user: User = {
      name: this.getAttribute('name') || 'World'
    };

    this.innerHTML = `
      <h3>Hello ${user.name}!</h3>
    `;
  }
}
file:///Users/owenbuckley/Workspace/github/acorn-ts-example/node_modules/acorn-walk/dist/walk.mjs:23
    baseVisitor[type](node, st, c);
                     ^

TypeError: baseVisitor[type] is not a function
    at c (file:///Users/owenbuckley/Workspace/github/acorn-ts-example/node_modules/acorn-walk/dist/walk.mjs:23:22)
    at Module.simple (file:///Users/owenbuckley/Workspace/github/acorn-ts-example/node_modules/acorn-walk/dist/walk.mjs:25:5)
    at file:///Users/owenbuckley/Workspace/github/acorn-ts-example/acorn-ts.js:18:6
    at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:530:24)
    at async loadESM (node:internal/process/esm_loader:91:5)
    at async handleMainPromise (node:internal/modules/run_main:65:12)

Unless acorn.walk is initialized with this option to explicitly support the usage of interface, which is similar to an observation I saw when using acorn-jsx plugin

walk.simple(node, {}, {
  ...walk.base,
  TSInterfaceDeclaration: () => { }
});

Is this expected? Is there some list of these visitor types available somewhere I should be using?

Here's a basic repro repo you can check out
https://github.com/thescientist13/acorn-ts-example

Thanks!

Syntax error when arrow function parameter is assignment pattern

The following code seems to give a syntax error when using acorn-typescript.

a = (x = 42) => {}

The following code is to reproduce.

import * as acorn from "acorn";
import { tsPlugin } from "acorn-typescript";

const acornTs = acorn.Parser.extend(tsPlugin());

const code = "a = (x = 42) => {}";

const options = {
  sourceType: "module",
  ecmaVersion: "latest",
  locations: true,
} as const;

// OK
let node = acorn.Parser.parse(code, options);
console.log(node);

// Error
node = acornTs.parse(code, options);
console.log(node);

Use Versions:

    "acorn": "^8.8.2",
    "acorn-typescript": "^1.2.7",

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

你好,我试了下不能支持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);
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.