parent
							
								
									9527887426
								
							
						
					
					
						commit
						1045590d4b
					
				@ -1,5 +1,6 @@
 | 
			
		||||
import {
 | 
			
		||||
  isReferenced,
 | 
			
		||||
// should only use types from @babel/types
 | 
			
		||||
// do not import runtime methods
 | 
			
		||||
import type {
 | 
			
		||||
  Identifier,
 | 
			
		||||
  Node,
 | 
			
		||||
  Function,
 | 
			
		||||
@ -243,3 +244,181 @@ export const isStaticProperty = (node: Node): node is ObjectProperty =>
 | 
			
		||||
 | 
			
		||||
export const isStaticPropertyKey = (node: Node, parent: Node) =>
 | 
			
		||||
  isStaticProperty(parent) && parent.key === node
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Copied from https://github.com/babel/babel/blob/main/packages/babel-types/src/validators/isReferenced.ts
 | 
			
		||||
 * To avoid runtime dependency on @babel/types (which includes process references)
 | 
			
		||||
 * This file should not change very often in babel but we may need to keep it
 | 
			
		||||
 * up-to-date from time to time.
 | 
			
		||||
 *
 | 
			
		||||
 * https://github.com/babel/babel/blob/main/LICENSE
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
function isReferenced(node: Node, parent: Node, grandparent?: Node): boolean {
 | 
			
		||||
  switch (parent.type) {
 | 
			
		||||
    // yes: PARENT[NODE]
 | 
			
		||||
    // yes: NODE.child
 | 
			
		||||
    // no: parent.NODE
 | 
			
		||||
    case 'MemberExpression':
 | 
			
		||||
    case 'OptionalMemberExpression':
 | 
			
		||||
      if (parent.property === node) {
 | 
			
		||||
        return !!parent.computed
 | 
			
		||||
      }
 | 
			
		||||
      return parent.object === node
 | 
			
		||||
 | 
			
		||||
    case 'JSXMemberExpression':
 | 
			
		||||
      return parent.object === node
 | 
			
		||||
    // no: let NODE = init;
 | 
			
		||||
    // yes: let id = NODE;
 | 
			
		||||
    case 'VariableDeclarator':
 | 
			
		||||
      return parent.init === node
 | 
			
		||||
 | 
			
		||||
    // yes: () => NODE
 | 
			
		||||
    // no: (NODE) => {}
 | 
			
		||||
    case 'ArrowFunctionExpression':
 | 
			
		||||
      return parent.body === node
 | 
			
		||||
 | 
			
		||||
    // no: class { #NODE; }
 | 
			
		||||
    // no: class { get #NODE() {} }
 | 
			
		||||
    // no: class { #NODE() {} }
 | 
			
		||||
    // no: class { fn() { return this.#NODE; } }
 | 
			
		||||
    case 'PrivateName':
 | 
			
		||||
      return false
 | 
			
		||||
 | 
			
		||||
    // no: class { NODE() {} }
 | 
			
		||||
    // yes: class { [NODE]() {} }
 | 
			
		||||
    // no: class { foo(NODE) {} }
 | 
			
		||||
    case 'ClassMethod':
 | 
			
		||||
    case 'ClassPrivateMethod':
 | 
			
		||||
    case 'ObjectMethod':
 | 
			
		||||
      if (parent.key === node) {
 | 
			
		||||
        return !!parent.computed
 | 
			
		||||
      }
 | 
			
		||||
      return false
 | 
			
		||||
 | 
			
		||||
    // yes: { [NODE]: "" }
 | 
			
		||||
    // no: { NODE: "" }
 | 
			
		||||
    // depends: { NODE }
 | 
			
		||||
    // depends: { key: NODE }
 | 
			
		||||
    case 'ObjectProperty':
 | 
			
		||||
      if (parent.key === node) {
 | 
			
		||||
        return !!parent.computed
 | 
			
		||||
      }
 | 
			
		||||
      // parent.value === node
 | 
			
		||||
      return !grandparent || grandparent.type !== 'ObjectPattern'
 | 
			
		||||
    // no: class { NODE = value; }
 | 
			
		||||
    // yes: class { [NODE] = value; }
 | 
			
		||||
    // yes: class { key = NODE; }
 | 
			
		||||
    case 'ClassProperty':
 | 
			
		||||
      if (parent.key === node) {
 | 
			
		||||
        return !!parent.computed
 | 
			
		||||
      }
 | 
			
		||||
      return true
 | 
			
		||||
    case 'ClassPrivateProperty':
 | 
			
		||||
      return parent.key !== node
 | 
			
		||||
 | 
			
		||||
    // no: class NODE {}
 | 
			
		||||
    // yes: class Foo extends NODE {}
 | 
			
		||||
    case 'ClassDeclaration':
 | 
			
		||||
    case 'ClassExpression':
 | 
			
		||||
      return parent.superClass === node
 | 
			
		||||
 | 
			
		||||
    // yes: left = NODE;
 | 
			
		||||
    // no: NODE = right;
 | 
			
		||||
    case 'AssignmentExpression':
 | 
			
		||||
      return parent.right === node
 | 
			
		||||
 | 
			
		||||
    // no: [NODE = foo] = [];
 | 
			
		||||
    // yes: [foo = NODE] = [];
 | 
			
		||||
    case 'AssignmentPattern':
 | 
			
		||||
      return parent.right === node
 | 
			
		||||
 | 
			
		||||
    // no: NODE: for (;;) {}
 | 
			
		||||
    case 'LabeledStatement':
 | 
			
		||||
      return false
 | 
			
		||||
 | 
			
		||||
    // no: try {} catch (NODE) {}
 | 
			
		||||
    case 'CatchClause':
 | 
			
		||||
      return false
 | 
			
		||||
 | 
			
		||||
    // no: function foo(...NODE) {}
 | 
			
		||||
    case 'RestElement':
 | 
			
		||||
      return false
 | 
			
		||||
 | 
			
		||||
    case 'BreakStatement':
 | 
			
		||||
    case 'ContinueStatement':
 | 
			
		||||
      return false
 | 
			
		||||
 | 
			
		||||
    // no: function NODE() {}
 | 
			
		||||
    // no: function foo(NODE) {}
 | 
			
		||||
    case 'FunctionDeclaration':
 | 
			
		||||
    case 'FunctionExpression':
 | 
			
		||||
      return false
 | 
			
		||||
 | 
			
		||||
    // no: export NODE from "foo";
 | 
			
		||||
    // no: export * as NODE from "foo";
 | 
			
		||||
    case 'ExportNamespaceSpecifier':
 | 
			
		||||
    case 'ExportDefaultSpecifier':
 | 
			
		||||
      return false
 | 
			
		||||
 | 
			
		||||
    // no: export { foo as NODE };
 | 
			
		||||
    // yes: export { NODE as foo };
 | 
			
		||||
    // no: export { NODE as foo } from "foo";
 | 
			
		||||
    case 'ExportSpecifier':
 | 
			
		||||
      // @ts-expect-error
 | 
			
		||||
      if (grandparent?.source) {
 | 
			
		||||
        return false
 | 
			
		||||
      }
 | 
			
		||||
      return parent.local === node
 | 
			
		||||
 | 
			
		||||
    // no: import NODE from "foo";
 | 
			
		||||
    // no: import * as NODE from "foo";
 | 
			
		||||
    // no: import { NODE as foo } from "foo";
 | 
			
		||||
    // no: import { foo as NODE } from "foo";
 | 
			
		||||
    // no: import NODE from "bar";
 | 
			
		||||
    case 'ImportDefaultSpecifier':
 | 
			
		||||
    case 'ImportNamespaceSpecifier':
 | 
			
		||||
    case 'ImportSpecifier':
 | 
			
		||||
      return false
 | 
			
		||||
 | 
			
		||||
    // no: import "foo" assert { NODE: "json" }
 | 
			
		||||
    case 'ImportAttribute':
 | 
			
		||||
      return false
 | 
			
		||||
 | 
			
		||||
    // no: <div NODE="foo" />
 | 
			
		||||
    case 'JSXAttribute':
 | 
			
		||||
      return false
 | 
			
		||||
 | 
			
		||||
    // no: [NODE] = [];
 | 
			
		||||
    // no: ({ NODE }) = [];
 | 
			
		||||
    case 'ObjectPattern':
 | 
			
		||||
    case 'ArrayPattern':
 | 
			
		||||
      return false
 | 
			
		||||
 | 
			
		||||
    // no: new.NODE
 | 
			
		||||
    // no: NODE.target
 | 
			
		||||
    case 'MetaProperty':
 | 
			
		||||
      return false
 | 
			
		||||
 | 
			
		||||
    // yes: type X = { somePropert: NODE }
 | 
			
		||||
    // no: type X = { NODE: OtherType }
 | 
			
		||||
    case 'ObjectTypeProperty':
 | 
			
		||||
      return parent.key !== node
 | 
			
		||||
 | 
			
		||||
    // yes: enum X { Foo = NODE }
 | 
			
		||||
    // no: enum X { NODE }
 | 
			
		||||
    case 'TSEnumMember':
 | 
			
		||||
      return parent.id !== node
 | 
			
		||||
 | 
			
		||||
    // yes: { [NODE]: value }
 | 
			
		||||
    // no: { NODE: value }
 | 
			
		||||
    case 'TSPropertySignature':
 | 
			
		||||
      if (parent.key === node) {
 | 
			
		||||
        return !!parent.computed
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return true
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user