Skip to content

Commit 1045590

Browse files
committed
fix(compiler-core): avoid runtime dependency on @babel/types
fix #4531
1 parent 9527887 commit 1045590

File tree

1 file changed

+181
-2
lines changed

1 file changed

+181
-2
lines changed

packages/compiler-core/src/babelUtils.ts

+181-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import {
2-
isReferenced,
1+
// should only use types from @babel/types
2+
// do not import runtime methods
3+
import type {
34
Identifier,
45
Node,
56
Function,
@@ -243,3 +244,181 @@ export const isStaticProperty = (node: Node): node is ObjectProperty =>
243244

244245
export const isStaticPropertyKey = (node: Node, parent: Node) =>
245246
isStaticProperty(parent) && parent.key === node
247+
248+
/**
249+
* Copied from https://github.com/babel/babel/blob/main/packages/babel-types/src/validators/isReferenced.ts
250+
* To avoid runtime dependency on @babel/types (which includes process references)
251+
* This file should not change very often in babel but we may need to keep it
252+
* up-to-date from time to time.
253+
*
254+
* https://github.com/babel/babel/blob/main/LICENSE
255+
*
256+
*/
257+
function isReferenced(node: Node, parent: Node, grandparent?: Node): boolean {
258+
switch (parent.type) {
259+
// yes: PARENT[NODE]
260+
// yes: NODE.child
261+
// no: parent.NODE
262+
case 'MemberExpression':
263+
case 'OptionalMemberExpression':
264+
if (parent.property === node) {
265+
return !!parent.computed
266+
}
267+
return parent.object === node
268+
269+
case 'JSXMemberExpression':
270+
return parent.object === node
271+
// no: let NODE = init;
272+
// yes: let id = NODE;
273+
case 'VariableDeclarator':
274+
return parent.init === node
275+
276+
// yes: () => NODE
277+
// no: (NODE) => {}
278+
case 'ArrowFunctionExpression':
279+
return parent.body === node
280+
281+
// no: class { #NODE; }
282+
// no: class { get #NODE() {} }
283+
// no: class { #NODE() {} }
284+
// no: class { fn() { return this.#NODE; } }
285+
case 'PrivateName':
286+
return false
287+
288+
// no: class { NODE() {} }
289+
// yes: class { [NODE]() {} }
290+
// no: class { foo(NODE) {} }
291+
case 'ClassMethod':
292+
case 'ClassPrivateMethod':
293+
case 'ObjectMethod':
294+
if (parent.key === node) {
295+
return !!parent.computed
296+
}
297+
return false
298+
299+
// yes: { [NODE]: "" }
300+
// no: { NODE: "" }
301+
// depends: { NODE }
302+
// depends: { key: NODE }
303+
case 'ObjectProperty':
304+
if (parent.key === node) {
305+
return !!parent.computed
306+
}
307+
// parent.value === node
308+
return !grandparent || grandparent.type !== 'ObjectPattern'
309+
// no: class { NODE = value; }
310+
// yes: class { [NODE] = value; }
311+
// yes: class { key = NODE; }
312+
case 'ClassProperty':
313+
if (parent.key === node) {
314+
return !!parent.computed
315+
}
316+
return true
317+
case 'ClassPrivateProperty':
318+
return parent.key !== node
319+
320+
// no: class NODE {}
321+
// yes: class Foo extends NODE {}
322+
case 'ClassDeclaration':
323+
case 'ClassExpression':
324+
return parent.superClass === node
325+
326+
// yes: left = NODE;
327+
// no: NODE = right;
328+
case 'AssignmentExpression':
329+
return parent.right === node
330+
331+
// no: [NODE = foo] = [];
332+
// yes: [foo = NODE] = [];
333+
case 'AssignmentPattern':
334+
return parent.right === node
335+
336+
// no: NODE: for (;;) {}
337+
case 'LabeledStatement':
338+
return false
339+
340+
// no: try {} catch (NODE) {}
341+
case 'CatchClause':
342+
return false
343+
344+
// no: function foo(...NODE) {}
345+
case 'RestElement':
346+
return false
347+
348+
case 'BreakStatement':
349+
case 'ContinueStatement':
350+
return false
351+
352+
// no: function NODE() {}
353+
// no: function foo(NODE) {}
354+
case 'FunctionDeclaration':
355+
case 'FunctionExpression':
356+
return false
357+
358+
// no: export NODE from "foo";
359+
// no: export * as NODE from "foo";
360+
case 'ExportNamespaceSpecifier':
361+
case 'ExportDefaultSpecifier':
362+
return false
363+
364+
// no: export { foo as NODE };
365+
// yes: export { NODE as foo };
366+
// no: export { NODE as foo } from "foo";
367+
case 'ExportSpecifier':
368+
// @ts-expect-error
369+
if (grandparent?.source) {
370+
return false
371+
}
372+
return parent.local === node
373+
374+
// no: import NODE from "foo";
375+
// no: import * as NODE from "foo";
376+
// no: import { NODE as foo } from "foo";
377+
// no: import { foo as NODE } from "foo";
378+
// no: import NODE from "bar";
379+
case 'ImportDefaultSpecifier':
380+
case 'ImportNamespaceSpecifier':
381+
case 'ImportSpecifier':
382+
return false
383+
384+
// no: import "foo" assert { NODE: "json" }
385+
case 'ImportAttribute':
386+
return false
387+
388+
// no: <div NODE="foo" />
389+
case 'JSXAttribute':
390+
return false
391+
392+
// no: [NODE] = [];
393+
// no: ({ NODE }) = [];
394+
case 'ObjectPattern':
395+
case 'ArrayPattern':
396+
return false
397+
398+
// no: new.NODE
399+
// no: NODE.target
400+
case 'MetaProperty':
401+
return false
402+
403+
// yes: type X = { somePropert: NODE }
404+
// no: type X = { NODE: OtherType }
405+
case 'ObjectTypeProperty':
406+
return parent.key !== node
407+
408+
// yes: enum X { Foo = NODE }
409+
// no: enum X { NODE }
410+
case 'TSEnumMember':
411+
return parent.id !== node
412+
413+
// yes: { [NODE]: value }
414+
// no: { NODE: value }
415+
case 'TSPropertySignature':
416+
if (parent.key === node) {
417+
return !!parent.computed
418+
}
419+
420+
return true
421+
}
422+
423+
return true
424+
}

0 commit comments

Comments
 (0)