Website Structure
This commit is contained in:
parent
62812f2090
commit
71f0676a62
22365 changed files with 4265753 additions and 791 deletions
21
Frontend-Learner/node_modules/ast-walker-scope/LICENSE
generated
vendored
Normal file
21
Frontend-Learner/node_modules/ast-walker-scope/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2022-PRESENT Kevin Deng (https://github.com/sxzz)
|
||||
|
||||
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.
|
||||
119
Frontend-Learner/node_modules/ast-walker-scope/README.md
generated
vendored
Normal file
119
Frontend-Learner/node_modules/ast-walker-scope/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
# ast-walker-scope
|
||||
|
||||
[![npm version][npm-version-src]][npm-version-href]
|
||||
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
||||
[![Unit Test][unit-test-src]][unit-test-href]
|
||||
|
||||
Traverse Babel AST with scope information.
|
||||
|
||||
Inherited from [estree-walker](https://github.com/Rich-Harris/estree-walker).
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm i ast-walker-scope
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Example
|
||||
|
||||
For a real example, you can refer to [example.ts](./example.ts)
|
||||
|
||||
```ts
|
||||
import { walk } from 'ast-walker-scope'
|
||||
|
||||
const code = `
|
||||
const a = 'root level'
|
||||
|
||||
{
|
||||
const a = 'second level'
|
||||
let secondLevel = true
|
||||
console.log(a, secondLevel)
|
||||
}
|
||||
|
||||
var err = undefined
|
||||
try {
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
|
||||
console.log(a)
|
||||
`.trim()
|
||||
|
||||
walk(code, {
|
||||
leave(this, node) {
|
||||
if (node.type === 'CallExpression') {
|
||||
console.log(`\nLevel: ${this.level}`)
|
||||
for (const [name, node] of Object.entries(this.scope)) {
|
||||
console.log(
|
||||
`variable ${name} is located at line ${node.loc?.start.line}, column ${node.loc?.start.column}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
Level: 2
|
||||
variable a is located at line 4, column 8
|
||||
variable secondLevel is located at line 5, column 6
|
||||
|
||||
Level: 2
|
||||
variable a is located at line 1, column 6
|
||||
variable err is located at line 12, column 9
|
||||
|
||||
Level: 1
|
||||
variable a is located at line 1, column 6
|
||||
variable err is located at line 9, column 4
|
||||
```
|
||||
|
||||
## Typings
|
||||
|
||||
```ts
|
||||
export type Scope = Record<string, Node>
|
||||
export interface HookContext extends WalkerContext {
|
||||
// inherited from estree-walker
|
||||
skip: () => void
|
||||
remove: () => void
|
||||
replace: (node: Node) => void
|
||||
|
||||
// arguments of estree-walker hook
|
||||
parent: Node
|
||||
key: string
|
||||
index: number
|
||||
|
||||
// scope info
|
||||
scope: Scope
|
||||
scopes: Scope[]
|
||||
level: number
|
||||
}
|
||||
```
|
||||
|
||||
## Sponsors
|
||||
|
||||
<p align="center">
|
||||
<a href="https://cdn.jsdelivr.net/gh/sxzz/sponsors/sponsors.svg">
|
||||
<img src='https://cdn.jsdelivr.net/gh/sxzz/sponsors/sponsors.svg'/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Credits
|
||||
|
||||
- [@vue/reactivity-transform](https://github.com/vuejs/core/blob/v3.2.37/packages/reactivity-transform/src/reactivityTransform.ts) - almost copy-like referenced
|
||||
|
||||
## License
|
||||
|
||||
[MIT](./LICENSE) License © 2022-PRESENT [三咲智子](https://github.com/sxzz)
|
||||
|
||||
<!-- Badges -->
|
||||
|
||||
[npm-version-src]: https://img.shields.io/npm/v/ast-walker-scope.svg
|
||||
[npm-version-href]: https://npmjs.com/package/ast-walker-scope
|
||||
[npm-downloads-src]: https://img.shields.io/npm/dm/ast-walker-scope
|
||||
[npm-downloads-href]: https://www.npmcharts.com/compare/ast-walker-scope?interval=30
|
||||
[unit-test-src]: https://github.com/sxzz/ast-walker-scope/actions/workflows/unit-test.yml/badge.svg
|
||||
[unit-test-href]: https://github.com/sxzz/ast-walker-scope/actions/workflows/unit-test.yml
|
||||
51
Frontend-Learner/node_modules/ast-walker-scope/dist/index.d.ts
generated
vendored
Normal file
51
Frontend-Learner/node_modules/ast-walker-scope/dist/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import { ParseResult, ParserPlugin } from "@babel/parser";
|
||||
import { File, Function, Identifier, Node, VariableDeclaration } from "@babel/types";
|
||||
|
||||
//#region src/types.d.ts
|
||||
interface ParseOptions {
|
||||
filename?: string;
|
||||
parserPlugins?: ParserPlugin[];
|
||||
}
|
||||
type Scope = Record<string, Node>;
|
||||
interface WalkerContext {
|
||||
skip: () => void;
|
||||
remove: () => void;
|
||||
replace: (node: Node) => void;
|
||||
}
|
||||
interface ScopeContext {
|
||||
parent: Node | undefined | null;
|
||||
key: string | undefined | null;
|
||||
index: number | undefined | null;
|
||||
scope: Scope;
|
||||
scopes: Scope[];
|
||||
level: number;
|
||||
}
|
||||
interface WalkerHooks {
|
||||
enter?: (this: WalkerContext & ScopeContext, node: Node) => void;
|
||||
enterAfter?: (this: ScopeContext, node: Node) => void;
|
||||
leave?: (this: WalkerContext & ScopeContext, node: Node) => void;
|
||||
leaveAfter?: (this: ScopeContext, node: Node) => void;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/utils/babel.d.ts
|
||||
declare const isNewScope: (node: Node | undefined | null) => boolean;
|
||||
declare function walkFunctionParams(node: Function, onIdent: (id: Identifier) => void): void;
|
||||
declare function extractIdentifiers(param: Node, nodes?: Identifier[]): Identifier[];
|
||||
declare function babelParse(code: string, filename?: string, parserPlugins?: ParserPlugin[]): ParseResult<File>;
|
||||
declare function walkVariableDeclaration(stmt: VariableDeclaration, register: (id: Identifier) => void): void;
|
||||
declare function walkNewIdentifier(node: Node, register: (id: Identifier) => void): void;
|
||||
//#endregion
|
||||
//#region src/index.d.ts
|
||||
declare function walk(code: string, walkHooks: WalkerHooks, {
|
||||
filename,
|
||||
parserPlugins
|
||||
}?: ParseOptions): ParseResult<File>;
|
||||
declare function walkAST(node: Node | Node[], {
|
||||
enter,
|
||||
leave,
|
||||
enterAfter,
|
||||
leaveAfter
|
||||
}: WalkerHooks): void;
|
||||
declare function getRootScope(nodes: Node[]): Scope;
|
||||
//#endregion
|
||||
export { ParseOptions, Scope, ScopeContext, WalkerContext, WalkerHooks, babelParse, extractIdentifiers, getRootScope, isNewScope, walk, walkAST, walkFunctionParams, walkNewIdentifier, walkVariableDeclaration };
|
||||
175
Frontend-Learner/node_modules/ast-walker-scope/dist/index.js
generated
vendored
Normal file
175
Frontend-Learner/node_modules/ast-walker-scope/dist/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
import { isFunctionType, walkAST as walkAST$1 } from "ast-kit";
|
||||
import { parse } from "@babel/parser";
|
||||
|
||||
//#region src/utils/babel.ts
|
||||
const NEW_SCOPE = new Set([
|
||||
"CatchClause",
|
||||
"ForInStatement",
|
||||
"ForOfStatement"
|
||||
]);
|
||||
const isNewScope = (node) => node && NEW_SCOPE.has(node.type) || isFunctionType(node);
|
||||
function walkFunctionParams(node, onIdent) {
|
||||
for (const p of node.params) for (const id of extractIdentifiers(p)) onIdent(id);
|
||||
}
|
||||
function extractIdentifiers(param, nodes = []) {
|
||||
switch (param.type) {
|
||||
case "Identifier":
|
||||
nodes.push(param);
|
||||
break;
|
||||
case "MemberExpression": {
|
||||
let object = param;
|
||||
while (object.type === "MemberExpression") object = object.object;
|
||||
nodes.push(object);
|
||||
break;
|
||||
}
|
||||
case "ObjectPattern":
|
||||
for (const prop of param.properties) if (prop.type === "RestElement") extractIdentifiers(prop.argument, nodes);
|
||||
else extractIdentifiers(prop.value, nodes);
|
||||
break;
|
||||
case "ArrayPattern":
|
||||
param.elements.forEach((element) => {
|
||||
if (element) extractIdentifiers(element, nodes);
|
||||
});
|
||||
break;
|
||||
case "RestElement":
|
||||
extractIdentifiers(param.argument, nodes);
|
||||
break;
|
||||
case "AssignmentPattern":
|
||||
extractIdentifiers(param.left, nodes);
|
||||
break;
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
function babelParse(code, filename, parserPlugins = []) {
|
||||
const plugins = parserPlugins || [];
|
||||
if (filename) {
|
||||
if (/\.tsx?$/.test(filename)) plugins.push("typescript");
|
||||
if (filename.endsWith("x")) plugins.push("jsx");
|
||||
}
|
||||
return parse(code, {
|
||||
sourceType: "module",
|
||||
plugins
|
||||
});
|
||||
}
|
||||
function walkVariableDeclaration(stmt, register) {
|
||||
if (stmt.declare) return;
|
||||
for (const decl of stmt.declarations) for (const id of extractIdentifiers(decl.id)) register(id);
|
||||
}
|
||||
function walkNewIdentifier(node, register) {
|
||||
if (node.type === "ExportNamedDeclaration" && node.declaration) node = node.declaration;
|
||||
if (node.type === "VariableDeclaration") walkVariableDeclaration(node, register);
|
||||
else if (node.type === "FunctionDeclaration" || node.type === "ClassDeclaration") {
|
||||
if (node.declare || !node.id) return;
|
||||
register(node.id);
|
||||
} else if (node.type === "ExportNamedDeclaration" && node.declaration && node.declaration.type === "VariableDeclaration") walkVariableDeclaration(node.declaration, register);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region src/index.ts
|
||||
function walk(code, walkHooks, { filename, parserPlugins } = {}) {
|
||||
const ast = babelParse(code, filename, parserPlugins);
|
||||
walkAST(ast.program, walkHooks);
|
||||
return ast;
|
||||
}
|
||||
function walkAST(node, { enter, leave, enterAfter, leaveAfter }) {
|
||||
let currentScope = {};
|
||||
const scopeStack = [currentScope];
|
||||
walkAST$1(Array.isArray(node) ? {
|
||||
type: "Program",
|
||||
body: node
|
||||
} : node, {
|
||||
enter(node$1, parent, ...args) {
|
||||
const { scopeCtx, walkerCtx, isSkip, isRemoved, getNode } = getHookContext(this, node$1, [parent, ...args]);
|
||||
enter?.call({
|
||||
...scopeCtx(),
|
||||
...walkerCtx
|
||||
}, node$1);
|
||||
node$1 = getNode();
|
||||
if (!isSkip() && !isRemoved()) {
|
||||
enterNode(node$1, parent);
|
||||
enterAfter?.call(scopeCtx(), node$1);
|
||||
}
|
||||
},
|
||||
leave(node$1, parent, ...args) {
|
||||
const { scopeCtx, walkerCtx, isSkip, isRemoved, getNode } = getHookContext(this, node$1, [parent, ...args]);
|
||||
leave?.call({
|
||||
...scopeCtx(),
|
||||
...walkerCtx
|
||||
}, node$1);
|
||||
node$1 = getNode();
|
||||
if (!isSkip() && !isRemoved()) {
|
||||
leaveNode(node$1, parent);
|
||||
leaveAfter?.call(scopeCtx(), node$1);
|
||||
}
|
||||
}
|
||||
});
|
||||
function getHookContext(ctx, node$1, [parent, key, index]) {
|
||||
const scopeCtx = () => ({
|
||||
parent,
|
||||
key,
|
||||
index,
|
||||
scope: scopeStack.reduce((prev, curr) => ({
|
||||
...prev,
|
||||
...curr
|
||||
}), {}),
|
||||
scopes: scopeStack,
|
||||
level: scopeStack.length
|
||||
});
|
||||
let isSkip = false;
|
||||
let isRemoved = false;
|
||||
let newNode = node$1;
|
||||
return {
|
||||
scopeCtx,
|
||||
walkerCtx: {
|
||||
skip() {
|
||||
isSkip = true;
|
||||
ctx.skip();
|
||||
},
|
||||
replace(node$2) {
|
||||
newNode = node$2;
|
||||
},
|
||||
remove() {
|
||||
isRemoved = true;
|
||||
}
|
||||
},
|
||||
isSkip: () => isSkip,
|
||||
isRemoved: () => isRemoved,
|
||||
getNode: () => newNode
|
||||
};
|
||||
}
|
||||
function enterNode(node$1, parent) {
|
||||
if (isNewScope(node$1) || node$1.type === "BlockStatement" && !isNewScope(parent)) scopeStack.push(currentScope = {});
|
||||
if (isFunctionType(node$1)) walkFunctionParams(node$1, registerBinding);
|
||||
else if (node$1.type === "CatchClause" && node$1.param && node$1.param.type === "Identifier") registerBinding(node$1.param);
|
||||
if (node$1.type === "BlockStatement" || node$1.type === "Program") {
|
||||
for (const stmt of node$1.body) if (stmt.type === "VariableDeclaration" && stmt.kind === "var") walkVariableDeclaration(stmt, registerBinding);
|
||||
else if (stmt.type === "FunctionDeclaration" && stmt.id) registerBinding(stmt.id);
|
||||
}
|
||||
}
|
||||
function leaveNode(node$1, parent) {
|
||||
if (isNewScope(node$1) || node$1.type === "BlockStatement" && !isNewScope(parent)) {
|
||||
scopeStack.pop();
|
||||
currentScope = scopeStack.at(-1);
|
||||
}
|
||||
walkNewIdentifier(node$1, registerBinding);
|
||||
}
|
||||
function registerBinding(id) {
|
||||
if (currentScope) currentScope[id.name] = id;
|
||||
else error("registerBinding called without active scope, something is wrong.", id);
|
||||
}
|
||||
function error(msg, node$1) {
|
||||
const e = new Error(msg);
|
||||
e.node = node$1;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
function getRootScope(nodes) {
|
||||
const scope = {};
|
||||
for (const node of nodes) walkNewIdentifier(node, (id) => {
|
||||
scope[id.name] = id;
|
||||
});
|
||||
return scope;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
export { babelParse, extractIdentifiers, getRootScope, isNewScope, walk, walkAST, walkFunctionParams, walkNewIdentifier, walkVariableDeclaration };
|
||||
64
Frontend-Learner/node_modules/ast-walker-scope/package.json
generated
vendored
Normal file
64
Frontend-Learner/node_modules/ast-walker-scope/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"name": "ast-walker-scope",
|
||||
"version": "0.8.3",
|
||||
"description": "Traverse Babel AST with scope information.",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/sxzz/ast-walker-scope#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/sxzz/ast-walker-scope/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/sxzz/ast-walker-scope.git"
|
||||
},
|
||||
"author": "Kevin Deng <sxzz@sxzz.moe>",
|
||||
"funding": "https://github.com/sponsors/sxzz",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.4",
|
||||
"ast-kit": "^2.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/types": "^7.28.4",
|
||||
"@sxzz/eslint-config": "^7.2.7",
|
||||
"@sxzz/prettier-config": "^2.2.4",
|
||||
"@types/node": "^24.7.0",
|
||||
"bumpp": "^10.3.1",
|
||||
"eslint": "^9.37.0",
|
||||
"magic-string": "^0.30.19",
|
||||
"prettier": "^3.6.2",
|
||||
"tsdown": "^0.15.6",
|
||||
"tsx": "^4.20.6",
|
||||
"typescript": "^5.9.3",
|
||||
"vite": "^7.1.9",
|
||||
"vitest": "^3.2.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19.0"
|
||||
},
|
||||
"prettier": "@sxzz/prettier-config",
|
||||
"tsdown": {
|
||||
"exports": true
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "pnpm run lint --fix",
|
||||
"build": "tsdown",
|
||||
"test": "vitest",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"release": "bumpp"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue