Skip to content

Commit

Permalink
refactor: remove acorn (#16238)
Browse files Browse the repository at this point in the history
  • Loading branch information
sapphi-red committed May 29, 2024
1 parent f599ab4 commit 454e2d1
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 247 deletions.
17 changes: 3 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,22 +104,11 @@
"overrides": {
"vite": "workspace:*"
},
"packageExtensions": {
"acorn-walk": {
"peerDependencies": {
"acorn": "*"
},
"peerDependenciesMeta": {
"acorn": {
"optional": true
}
}
}
},
"patchedDependencies": {
"[email protected]": "patches/[email protected]",
"[email protected]": "patches/[email protected]",
"[email protected]": "patches/[email protected].patch",
"[email protected]": "patches/[email protected].patch"
"[email protected]": "patches/[email protected].patch",
"[email protected]": "patches/[email protected].patch"
},
"peerDependencyRules": {
"allowedVersions": {
Expand Down
58 changes: 0 additions & 58 deletions packages/vite/LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -587,64 +587,6 @@ Repository: rollup/plugins
---------------------------------------

## acorn
License: MIT
By: Marijn Haverbeke, Ingvar Stepanyan, Adrian Heine
Repository: https://github.com/acornjs/acorn.git

> MIT License
>
> Copyright (C) 2012-2022 by various contributors (see AUTHORS)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
---------------------------------------

## acorn-walk
License: MIT
By: Marijn Haverbeke, Ingvar Stepanyan, Adrian Heine
Repository: https://github.com/acornjs/acorn.git

> MIT License
>
> Copyright (C) 2012-2020 by various contributors (see AUTHORS)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
---------------------------------------

## ansi-regex
License: MIT
By: Sindre Sorhus
Expand Down
2 changes: 0 additions & 2 deletions packages/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@
"@rollup/pluginutils": "^5.1.0",
"@types/escape-html": "^1.0.4",
"@types/pnpapi": "^0.0.5",
"acorn": "^8.11.3",
"acorn-walk": "^8.3.2",
"artichokie": "^0.2.1",
"cac": "^6.7.14",
"chokidar": "^3.6.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ describe('parse positives', async () => {
describe('parse negatives', async () => {
it('syntax error', async () => {
expect(await runError('import.meta.glob(')).toMatchInlineSnapshot(
'[SyntaxError: Unexpected token (1:17)]',
'[Error: Invalid glob import syntax: Close parenthesis not found]',
)
})

Expand Down
9 changes: 2 additions & 7 deletions packages/vite/src/node/plugins/dynamicImportVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { posix } from 'node:path'
import MagicString from 'magic-string'
import { init, parse as parseImports } from 'es-module-lexer'
import type { ImportSpecifier } from 'es-module-lexer'
import { parse as parseJS } from 'acorn'
import { parseAst } from 'rollup/parseAst'
import { dynamicImportToGlob } from '@rollup/plugin-dynamic-import-vars'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
Expand Down Expand Up @@ -68,12 +68,7 @@ function parseDynamicImportPattern(
strings: string,
): DynamicImportPattern | null {
const filename = strings.slice(1, -1)
const ast = (
parseJS(strings, {
ecmaVersion: 'latest',
sourceType: 'module',
}) as any
).body[0].expression
const ast = (parseAst(strings).body[0] as any).expression

const userPatternQuery = dynamicImportToGlob(ast, filename)
if (!userPatternQuery) {
Expand Down
29 changes: 17 additions & 12 deletions packages/vite/src/node/plugins/importAnalysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import type {
ImportSpecifier,
} from 'es-module-lexer'
import { init, parse as parseImports } from 'es-module-lexer'
import { parse as parseJS } from 'acorn'
import type { Node } from 'estree'
import { findStaticImports, parseStaticImport } from 'mlly'
import { parseAst } from 'rollup/parseAst'
import type { StaticImport } from 'mlly'
import { ESM_STATIC_IMPORT_RE, parseStaticImport } from 'mlly'
import { makeLegalIdentifier } from '@rollup/pluginutils'
import type { ViteDevServer } from '..'
import {
Expand Down Expand Up @@ -119,11 +119,21 @@ function extractImportedBindings(
}

const exp = source.slice(importSpec.ss, importSpec.se)
const [match0] = findStaticImports(exp)
if (!match0) {
ESM_STATIC_IMPORT_RE.lastIndex = 0
const match = ESM_STATIC_IMPORT_RE.exec(exp)
if (!match) {
return
}
const parsed = parseStaticImport(match0)

const staticImport: StaticImport = {
type: 'static',
code: match[0],
start: match.index,
end: match.index + match[0].length,
imports: match.groups!.imports,
specifier: match.groups!.specifier,
}
const parsed = parseStaticImport(staticImport)
if (!parsed) {
return
}
Expand Down Expand Up @@ -934,12 +944,7 @@ export function transformCjsImport(
importer: string,
config: ResolvedConfig,
): string | undefined {
const node = (
parseJS(importExp, {
ecmaVersion: 'latest',
sourceType: 'module',
}) as any
).body[0] as Node
const node = parseAst(importExp).body[0]

// `export * from '...'` may cause unexpected problem, so give it a warning
if (
Expand Down
99 changes: 50 additions & 49 deletions packages/vite/src/node/plugins/importMetaGlob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,18 @@ import { stripLiteral } from 'strip-literal'
import colors from 'picocolors'
import type {
ArrayExpression,
CallExpression,
Expression,
Literal,
MemberExpression,
Node,
SequenceExpression,
SpreadElement,
TemplateLiteral,
} from 'estree'
import { parseExpressionAt } from 'acorn'
import type { CustomPluginOptions, RollupError } from 'rollup'
import { findNodeAt } from 'acorn-walk'
import type { CustomPluginOptions, RollupAstNode, RollupError } from 'rollup'
import MagicString from 'magic-string'
import fg from 'fast-glob'
import { stringifyQuery } from 'ufo'
import type { GeneralImportGlobOptions } from 'types/importGlob'
import { parseAstAsync } from 'rollup/parseAst'
import type { Plugin } from '../plugin'
import type { ViteDevServer } from '../server'
import type { ModuleNode } from '../server/moduleGraph'
Expand Down Expand Up @@ -218,7 +214,7 @@ export async function parseImportGlob(
resolveId: IdResolver,
logger?: Logger,
): Promise<ParsedImportGlob[]> {
let cleanCode
let cleanCode: string
try {
cleanCode = stripLiteral(code)
} catch (e) {
Expand All @@ -236,51 +232,30 @@ export async function parseImportGlob(
return e
}

let ast: CallExpression | SequenceExpression | MemberExpression
let lastTokenPos: number | undefined

try {
ast = parseExpressionAt(code, start, {
ecmaVersion: 'latest',
sourceType: 'module',
ranges: true,
onToken: (token) => {
lastTokenPos = token.end
},
}) as any
} catch (e) {
const _e = e as any
if (_e.message && _e.message.startsWith('Unterminated string constant'))
return undefined!
if (lastTokenPos == null || lastTokenPos <= start) throw _e

// tailing comma in object or array will make the parser think it's a comma operation
// we try to parse again removing the comma
try {
const statement = code.slice(start, lastTokenPos).replace(/[,\s]*$/, '')
ast = parseExpressionAt(
' '.repeat(start) + statement, // to keep the ast position
start,
{
ecmaVersion: 'latest',
sourceType: 'module',
ranges: true,
},
) as any
} catch {
throw _e
}
const end =
findCorrespondingCloseParenthesisPosition(
cleanCode,
start + match[0].length,
) + 1
if (end <= 0) {
throw err('Close parenthesis not found')
}

const found = findNodeAt(ast as any, start, undefined, 'CallExpression')
if (!found) throw err(`Expect CallExpression, got ${ast.type}`)
ast = found.node as unknown as CallExpression
const statementCode = code.slice(start, end)

const rootAst = (await parseAstAsync(statementCode)).body[0]
if (rootAst.type !== 'ExpressionStatement') {
throw err(`Expect CallExpression, got ${rootAst.type}`)
}
const ast = rootAst.expression
if (ast.type !== 'CallExpression') {
throw err(`Expect CallExpression, got ${ast.type}`)
}
if (ast.arguments.length < 1 || ast.arguments.length > 2)
throw err(`Expected 1-2 arguments, but got ${ast.arguments.length}`)

const arg1 = ast.arguments[0] as ArrayExpression | Literal | TemplateLiteral
const arg2 = ast.arguments[1] as Node | undefined
const arg2 = ast.arguments[1] as RollupAstNode<Node> | undefined

const globs: string[] = []

Expand Down Expand Up @@ -321,14 +296,12 @@ export async function parseImportGlob(
)

options = parseGlobOptions(
code.slice(arg2.range![0], arg2.range![1]),
arg2.range![0],
code.slice(start + arg2.start, start + arg2.end),
start + arg2.start,
logger,
)
}

const end = ast.range![1]

const globsResolved = await Promise.all(
globs.map((glob) => toAbsoluteGlob(glob, root, importer, resolveId)),
)
Expand All @@ -348,6 +321,34 @@ export async function parseImportGlob(
return (await Promise.all(tasks)).filter(Boolean)
}

function findCorrespondingCloseParenthesisPosition(
cleanCode: string,
openPos: number,
) {
const closePos = cleanCode.indexOf(')', openPos)
if (closePos < 0) return -1

if (!cleanCode.slice(openPos, closePos).includes('(')) return closePos

let remainingParenthesisCount = 0
const cleanCodeLen = cleanCode.length
for (let pos = openPos; pos < cleanCodeLen; pos++) {
switch (cleanCode[pos]) {
case '(': {
remainingParenthesisCount++
break
}
case ')': {
remainingParenthesisCount--
if (remainingParenthesisCount <= 0) {
return pos
}
}
}
}
return -1
}

const importPrefix = '__vite_glob_'

const { basename, dirname, relative, join } = posix
Expand Down
12 changes: 12 additions & 0 deletions patches/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
diff --git a/package.json b/package.json
index 1b8dc76afc3cf5890cc3693c2975577fd3117dd6..9ac3a4d813fda1be476bd896a8f6168b3a459e41 100644
--- a/package.json
+++ b/package.json
@@ -46,5 +46,6 @@
},
"bin": {
"acorn": "./bin/acorn"
- }
+ },
+ "sideEffects": false
}
Loading

0 comments on commit 454e2d1

Please sign in to comment.