├── assembly ├── index.ts ├── data.dat ├── hello.ts ├── __tests__ │ ├── as-pect.d.ts │ ├── capitalize.spec.ts │ ├── toString.spec.ts │ └── function-call-replacement.spec.ts ├── foo.ts ├── exportAs.ts ├── tsconfig.json ├── obj.ts ├── as_types.d.ts ├── strings.ts └── includeBytesTest.ts ├── .gitignore ├── asconfig.json ├── .mocharc.json ├── .npmignore ├── src ├── portable.d.ts ├── index.ts ├── transformRange.ts ├── tsconfig.json ├── examples │ ├── functionCallTransform.ts │ ├── list.ts │ ├── capitalize.ts │ ├── exportAs.ts │ ├── toString.ts │ └── includeBytesTransform.ts ├── transformer.ts ├── path.ts ├── simpleParser.ts ├── visitor.ts ├── decorator.ts ├── utils.ts ├── base.ts ├── baseTransform.ts └── astBuilder.ts ├── tsconfig.json ├── .github └── workflows │ └── test.yml ├── __tests__ ├── setup.js └── tests.spec.js ├── package.json ├── README.md ├── as-pect.config.js ├── LICENSE └── yarn.lock /assembly/index.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assembly/data.dat: -------------------------------------------------------------------------------- 1 | ABCD -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | package-lock.json -------------------------------------------------------------------------------- /assembly/hello.ts: -------------------------------------------------------------------------------- 1 | 2 | assert("hello world" == foo()); -------------------------------------------------------------------------------- /asconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "options": { 3 | "runtime": "stub" 4 | } 5 | } -------------------------------------------------------------------------------- /.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec": [ 3 | "__tests__/*.spec.js" 4 | ] 5 | } -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | __tests__ 2 | assembly 3 | src/ 4 | as-pect.config.js 5 | jest.config.js -------------------------------------------------------------------------------- /assembly/__tests__/as-pect.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /assembly/foo.ts: -------------------------------------------------------------------------------- 1 | @list 2 | class Foo { 3 | a: u8; 4 | b: bool; 5 | i: i32; 6 | } 7 | -------------------------------------------------------------------------------- /assembly/exportAs.ts: -------------------------------------------------------------------------------- 1 | //@ts-ignore 2 | @exportAs("new") 3 | export function main(): u32 { 4 | return 42; 5 | } -------------------------------------------------------------------------------- /assembly/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "assemblyscript/std/assembly.json", 3 | "include": ["./**/*.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /src/portable.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// -------------------------------------------------------------------------------- /assembly/obj.ts: -------------------------------------------------------------------------------- 1 | export class Obj { 2 | a: i32 = 34; 3 | b: i64 = 1111111; 4 | c: string[] = ["hello", "wassup"]; 5 | } 6 | -------------------------------------------------------------------------------- /assembly/as_types.d.ts: -------------------------------------------------------------------------------- 1 | declare function list(c: any): void; 2 | declare function foo(): string; 3 | declare function includeBytes(path: string): StaticArray; 4 | 5 | interface Object { 6 | toString(): string; 7 | } -------------------------------------------------------------------------------- /assembly/__tests__/capitalize.spec.ts: -------------------------------------------------------------------------------- 1 | import { helloWorld } from "../strings"; 2 | 3 | describe("Capitalize Visitor", () => { 4 | it("hello world --> HELLO WORLD", () => { 5 | expect(helloWorld()).toBe("HELLO WORLD"); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /assembly/strings.ts: -------------------------------------------------------------------------------- 1 | //@ts-ignore 2 | @capitalize 3 | export const hello = `hello`; 4 | //@ts-ignore 5 | @capitalize 6 | export const world = "world"; 7 | 8 | export function helloWorld(): string { 9 | return hello + " " + world; 10 | } 11 | -------------------------------------------------------------------------------- /assembly/__tests__/toString.spec.ts: -------------------------------------------------------------------------------- 1 | import { Obj } from "../obj"; 2 | 3 | describe("Obj", () => { 4 | it("should print nicely", ()=> { 5 | expect((new Obj()).toString()).toStrictEqual(`Obj:\n\ta: 34\n\tb: 1111111\n\tc: hello,wassup`) 6 | }); 7 | }) -------------------------------------------------------------------------------- /assembly/includeBytesTest.ts: -------------------------------------------------------------------------------- 1 | export function usingIncludeBytes(): StaticArray { 2 | var result = includeBytes('data.dat'); 3 | return result; 4 | } 5 | 6 | export function hardCodedSAu8(): StaticArray { 7 | var result = StaticArray.fromArray([65,66,67,68]); 8 | return result; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./base.js"; 2 | export * from "./transformer.js"; 3 | export * from "./baseTransform.js"; 4 | export * from "./visitor.js"; 5 | export * from "./astBuilder.js"; 6 | export * from "./decorator.js"; 7 | export * from "./path.js"; 8 | export * from "./simpleParser.js" 9 | import * as utils from "./utils.js"; 10 | export { utils }; 11 | -------------------------------------------------------------------------------- /assembly/__tests__/function-call-replacement.spec.ts: -------------------------------------------------------------------------------- 1 | import { usingIncludeBytes, hardCodedSAu8 } from '../includeBytesTest' 2 | 3 | 4 | describe('function call replacement', () => { 5 | it("a call to foo() should return 'hello world' string", () => { 6 | expect(foo()).toBe("hello world"); 7 | }) 8 | 9 | it("includeBytes should include data.dat", () => { 10 | expect(usingIncludeBytes().toString()).toBe(hardCodedSAu8().toString()); 11 | }) 12 | 13 | 14 | }) -------------------------------------------------------------------------------- /src/transformRange.ts: -------------------------------------------------------------------------------- 1 | import { Node } from "assemblyscript/dist/assemblyscript.js" 2 | import { BaseTransformVisitor } from "./baseTransform.js"; 3 | 4 | 5 | 6 | export class RangeTransform extends BaseTransformVisitor { 7 | constructor(private node: Node){super()}; 8 | 9 | _visit(node: Node): Node { 10 | node.range = this.node.range; 11 | return super._visit(node); 12 | } 13 | 14 | static visit(node: Node, from: Node): Node { 15 | return (new RangeTransform(from))._visit(node) 16 | 17 | } 18 | } -------------------------------------------------------------------------------- /src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "../dist", 4 | "inlineSourceMap": true, 5 | "inlineSources": true, 6 | "target": "esnext", 7 | "module": "esnext", 8 | "moduleResolution": "node", 9 | "downlevelIteration": true, 10 | "preserveConstEnums": true, 11 | "allowSyntheticDefaultImports": true, 12 | "esModuleInterop":true, 13 | "alwaysStrict": true, 14 | "noImplicitAny": true, 15 | "noImplicitReturns": true, 16 | "noImplicitThis": true, 17 | "noEmitOnError": true, 18 | "allowJs": false, 19 | "strictNullChecks": true, 20 | "experimentalDecorators": true, 21 | "declaration": true, 22 | "strict": true, 23 | "lib": ["esnext","esnext.string"] 24 | }, 25 | "include": ["./**/*"] 26 | } 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "inlineSourceMap": true, 4 | "inlineSources": true, 5 | "target": "esnext", 6 | "module": "esnext", 7 | "downlevelIteration": true, 8 | "preserveConstEnums": true, 9 | "alwaysStrict": true, 10 | "noImplicitAny": true, 11 | "noImplicitReturns": true, 12 | "noImplicitThis": true, 13 | "noEmitOnError": true, 14 | "allowJs": false, 15 | "strictNullChecks": true, 16 | "experimentalDecorators": true, 17 | "allowSyntheticDefaultImports": true, 18 | "esModuleInterop":true, 19 | "declaration": true, 20 | "strict": true, 21 | "lib": ["esnext","esnext.string"], 22 | "outDir": "dist" 23 | 24 | }, 25 | "include": ["src/**/*"], 26 | "exclude": ["node_modules/**/*"] 27 | } 28 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | jobs: 8 | test: 9 | runs-on: ${{ matrix.platform }} 10 | name: "${{ matrix.platform }} ${{ matrix.nodeversion }}" 11 | strategy: 12 | matrix: 13 | platform: [ubuntu-latest, macos-latest] 14 | nodeversion: ['16.x', '18.x', '19.x'] 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: Use Node.js v${{ matrix.nodeversion }} 18 | uses: actions/setup-node@v3 19 | with: 20 | node-version: ${{ matrix.nodeversion }} 21 | - name: Install dependencies 22 | run: yarn --frozen-lockfile 23 | - name: Install dependencies 24 | run: yarn build 25 | - name: test 26 | env: 27 | YARN_GPG: no 28 | run: yarn test:mocha 29 | -------------------------------------------------------------------------------- /__tests__/setup.js: -------------------------------------------------------------------------------- 1 | import { compileString } from "assemblyscript/dist/asc.js"; 2 | 3 | import * as loader from "@assemblyscript/loader"; 4 | 5 | export async function compileExample(code, transform) { 6 | const res = await compile(code, transform); 7 | return res.stdout.toString().trim().split("\n"); 8 | } 9 | 10 | export async function compile(code, transform) { 11 | const baseDir = process.cwd(); 12 | const res = await compileString(code, { 13 | transform, 14 | baseDir, 15 | }); 16 | const errStr = res.stderr.toString(); 17 | if (errStr) { 18 | throw new Error(errStr); 19 | } 20 | return res; 21 | } 22 | 23 | export async function compileAndInit(code, transform) { 24 | const res = await compile(code, transform); 25 | const imports = { /* imports go here */ }; 26 | return loader.instantiateSync(res.binary.buffer, imports); 27 | } -------------------------------------------------------------------------------- /src/examples/functionCallTransform.ts: -------------------------------------------------------------------------------- 1 | import { TransformVisitor, SimpleParser } from "../index.js"; 2 | import { Node, Expression, Parser, CallExpression, IdentifierExpression } from "assemblyscript/dist/assemblyscript.js"; 3 | import { not, isLibrary } from '../utils.js'; 4 | 5 | class FunctionCallTransform extends TransformVisitor { 6 | visitCallExpression(node: CallExpression): Expression { 7 | if (node.expression instanceof IdentifierExpression){ 8 | if (node.expression.text == "foo") { 9 | let res = SimpleParser.parseExpression('"hello world"'); 10 | res.range = node.range; 11 | return res; 12 | } 13 | } 14 | return super.visitCallExpression(node); 15 | } 16 | 17 | afterParse(_: Parser): void { 18 | let sources = _.sources.filter(not(isLibrary)); 19 | this.visit(sources); 20 | } 21 | } 22 | 23 | export default new FunctionCallTransform(); 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "visitor-as", 3 | "version": "0.11.4", 4 | "description": "A generic visitor framework for AssemblyScript", 5 | "main": "dist/index.js", 6 | "types": "dist", 7 | "repository": "https://github.com/as-pect/visitor-as", 8 | "author": "Willem Wyndham", 9 | "license": "MIT", 10 | "private": false, 11 | "type": "module", 12 | "scripts": { 13 | "test": "mocha", 14 | "test:mocha": "npx mocha", 15 | "build": "rimraf dist/ && tsc -p src" 16 | }, 17 | "peerDependencies": { 18 | "assemblyscript": "^0.25.0" 19 | }, 20 | "devDependencies": { 21 | "@assemblyscript/loader": "^0.25.0", 22 | "@types/lodash.clonedeep": "^4.5.7", 23 | "@types/node": "^18.11.13", 24 | "assemblyscript": "^0.25.0", 25 | "chai": "^4.3.7", 26 | "mocha": "^10.2.0", 27 | "prettier": "^2.8.1", 28 | "rimraf": "^3.0.2", 29 | "ts-node": "^10.9.1", 30 | "typescript": "^4.9.4" 31 | }, 32 | "dependencies": { 33 | "lodash.clonedeep": "^4.5.0", 34 | "ts-mixer": "^6.0.2" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/examples/list.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ClassDeclaration, 3 | DecoratorNode, 4 | FieldDeclaration, 5 | MethodDeclaration, 6 | } from "assemblyscript/dist/assemblyscript.js"; 7 | import { ClassDecorator, registerDecorator } from "../decorator.js"; 8 | import { getName, toString } from "../utils.js"; 9 | 10 | class ListMembers extends ClassDecorator { 11 | visitFieldDeclaration(node: FieldDeclaration): void { 12 | if (!node.name) console.log(getName(node) + "\n"); 13 | const name = getName(node); 14 | const _type = getName(node.type!); 15 | this.stdout.write(name + ": " + _type + "\n"); 16 | } 17 | 18 | visitMethodDeclaration(node: MethodDeclaration): void { 19 | const name = getName(node); 20 | if (name == "constructor") { 21 | return; 22 | } 23 | const sig = toString(node.signature); 24 | this.stdout.write(name + ": " + sig + "\n"); 25 | } 26 | 27 | visitClassDeclaration(node: ClassDeclaration): void { 28 | this.visit(node.members); 29 | } 30 | 31 | get name(): string { return "list"; } 32 | 33 | } 34 | 35 | export default registerDecorator(new ListMembers()); 36 | -------------------------------------------------------------------------------- /src/transformer.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/ban-ts-comment */ 2 | import { BaseVisitor } from "./base.js"; 3 | import { Transform as _Transform } from "assemblyscript/dist/transform.js"; 4 | import { ASTBuilder } from "./astBuilder.js"; 5 | import { PathVisitor } from "./path.js"; 6 | import { Mixin } from "ts-mixer"; 7 | import { BaseTransformVisitor } from "./baseTransform.js"; 8 | 9 | class Transform extends _Transform {} 10 | 11 | export class ASTTransformVisitor extends Mixin(BaseVisitor, Transform) {} 12 | 13 | export class ASTBuilderVisitor extends Mixin(ASTBuilder, Transform) {} 14 | 15 | export class PathTransformVisitor extends Mixin(PathVisitor, Transform) {} 16 | 17 | export function mergeTransformer(from: Transform, to: Transform): void { 18 | // @ts-ignore 19 | to.program = from.program; 20 | // @ts-ignore 21 | to.baseDir = from.baseDir; 22 | // @ts-ignore 23 | to.stdout = from.stdout; 24 | // @ts-ignore 25 | to.stderr = from.stderr; 26 | // @ts-ignore 27 | to.log = from.log; 28 | to.writeFile = from.writeFile; 29 | to.readFile = from.readFile; 30 | to.listFiles = from.listFiles; 31 | } 32 | 33 | export class TransformVisitor extends Mixin(BaseTransformVisitor, Transform) {} -------------------------------------------------------------------------------- /src/examples/capitalize.ts: -------------------------------------------------------------------------------- 1 | import { cloneNode, decorates } from "../utils.js"; 2 | import { VariableDecorator, registerDecorator } from "../decorator.js"; 3 | import { DecoratorNode, StringLiteralExpression, TemplateLiteralExpression, VariableDeclaration, Module, Parser } from "assemblyscript/dist/assemblyscript.js"; 4 | 5 | class CapitalizeVisitor extends VariableDecorator { 6 | visitVariableDeclaration(node: VariableDeclaration): void { 7 | this.visit(node.initializer); 8 | } 9 | 10 | get decoratorMatcher(): (node: DecoratorNode) => boolean { 11 | return (node) => decorates(node, "capitalize"); 12 | } 13 | 14 | afterParse(parser: Parser) { 15 | // console.log(parser.) 16 | } 17 | 18 | visitStringLiteralExpression(node: StringLiteralExpression): void { 19 | const oldValue = node.value; 20 | node.value = node.value.toUpperCase(); 21 | this.stdout.write(oldValue + " -> " + node.value + "\n"); 22 | } 23 | 24 | visitTemplateLiteralExpression(node: TemplateLiteralExpression): void { 25 | if (node.parts.length == 1 && node.expressions.length == 0){ 26 | const oldValue = node.parts[0]; 27 | node.parts[0] = node.parts[0].toUpperCase(); 28 | this.stdout.write(oldValue + " -> " + node.parts[0] + "\n"); 29 | } 30 | } 31 | } 32 | 33 | export default registerDecorator(new CapitalizeVisitor()); 34 | -------------------------------------------------------------------------------- /src/path.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Node, 3 | } from "assemblyscript/dist/assemblyscript.js"; 4 | 5 | import { BaseVisitor } from "./base.js"; 6 | import { utils } from "./index.js"; 7 | 8 | export class PathVisitor extends BaseVisitor { 9 | currentPath: Node[] = []; 10 | 11 | _visit(node: Node): void { 12 | this.currentPath.push(node); 13 | super._visit(node); 14 | this.currentPath.pop(); 15 | } 16 | 17 | get currentNode(): Node { 18 | return this.currentPath[this.currentPath.length - 1]; 19 | } 20 | 21 | get currentParent(): Node { 22 | if (this.currentPath.length == 1) return this.currentNode; 23 | return this.currentPath[this.currentPath.length - 2]; 24 | } 25 | 26 | get currentParentPath(): Node[] { 27 | return this.currentPath.slice(0, this.currentPath.length - 1); 28 | } 29 | 30 | get currentGrandParentPath(): Node[] { 31 | return this.currentPath.length < 3 32 | ? [] 33 | : this.currentPath.slice(0, this.currentPath.length - 2); 34 | } 35 | 36 | cloneCurrentNode(): Node { 37 | return utils.cloneNode(this.currentNode); 38 | } 39 | 40 | replaceCurrentNode(node: Node): void { 41 | Object.getOwnPropertyNames(this.currentParent).forEach((name) => { 42 | //@ts-ignore 43 | const prop = this.currentParent[name]; 44 | if (prop == this.currentNode) { 45 | //@ts-ignore 46 | this.currentParent[name] = node; 47 | } 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/examples/exportAs.ts: -------------------------------------------------------------------------------- 1 | import { 2 | LiteralKind, 3 | StringLiteralExpression, 4 | Program, 5 | DeclaredElement, 6 | } from "assemblyscript/dist/assemblyscript.js"; 7 | import { Transform } from "assemblyscript/dist/transform.js"; 8 | import { getDecorator, hasDecorator, isLibrary, isUserEntry } from "../utils.js"; 9 | 10 | function getName(element: DeclaredElement): string { 11 | let decorator = getDecorator(element.declaration, "exportAs"); 12 | if (decorator.args == null) { 13 | throw Error("exportAs expects a string argument but got null."); 14 | } 15 | if (decorator.args.length != 1) { 16 | throw Error(`exportAs expects 1 argument but got ${decorator.args.length}`); 17 | } 18 | if (!decorator.args[0].isLiteralKind(LiteralKind.String)) { 19 | throw Error("exportAs expects a string argument"); 20 | } 21 | return (decorator.args[0]).value; 22 | } 23 | 24 | class Transformer extends Transform { 25 | afterInitialize(program: Program): void { 26 | let files = Array.from(program.filesByName.values()).filter( 27 | (file) => isUserEntry(file.source) && !isLibrary(file.source) 28 | ); 29 | for (let file of files) { 30 | for (let _export of file.exports?.values() || []) { 31 | if (_export != null && hasDecorator(_export, "exportAs")) { 32 | let newName = getName(_export); 33 | file.exports?.delete(_export.name); 34 | file.exports?.set(newName, _export); 35 | } 36 | } 37 | } 38 | } 39 | } 40 | 41 | export default Transformer; 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Visitor utilities for AssemblyScript Compiler transformers 2 | 3 | ## Example 4 | 5 | ### List Fields 6 | 7 | The transformer: 8 | 9 | ```ts 10 | import { 11 | ClassDeclaration, 12 | FieldDeclaration, 13 | MethodDeclaration, 14 | } from "../../as"; 15 | import { ClassDecorator, registerDecorator } from "../decorator"; 16 | import { getName } from "../utils"; 17 | 18 | class ListMembers extends ClassDecorator { 19 | visitFieldDeclaration(node: FieldDeclaration): void { 20 | if (!node.name) console.log(getName(node) + "\n"); 21 | const name = getName(node); 22 | const _type = getName(node.type!); 23 | this.stdout.write(name + ": " + _type + "\n"); 24 | } 25 | 26 | visitMethodDeclaration(node: MethodDeclaration): void { 27 | const name = getName(node); 28 | if (name == "constructor") { 29 | return; 30 | } 31 | const sig = getName(node.signature); 32 | this.stdout.write(name + ": " + sig + "\n"); 33 | } 34 | 35 | visitClassDeclaration(node: ClassDeclaration): void { 36 | this.visit(node.members); 37 | } 38 | 39 | get name(): string { 40 | return "list"; 41 | } 42 | } 43 | 44 | export = registerDecorator(new ListMembers()); 45 | ``` 46 | 47 | assembly/foo.ts: 48 | ```ts 49 | @list 50 | class Foo { 51 | a: u8; 52 | b: bool; 53 | i: i32; 54 | } 55 | ``` 56 | 57 | And then compile with `--transform` flag: 58 | 59 | ``` 60 | asc assembly/foo.ts --transform ./dist/examples/list --noEmit 61 | ``` 62 | 63 | Which prints the following to the console: 64 | 65 | ``` 66 | a: u8 67 | b: bool 68 | i: i32 69 | ``` 70 | -------------------------------------------------------------------------------- /src/examples/toString.ts: -------------------------------------------------------------------------------- 1 | import { ASTTransformVisitor } from "../index.js"; 2 | import { Parser, ClassDeclaration, FieldDeclaration } from "assemblyscript/dist/assemblyscript.js"; 3 | import { SimpleParser } from "../simpleParser.js"; 4 | import { not, isStdlib, className, toString, isMethodNamed, getName } from '../utils.js'; 5 | 6 | 7 | 8 | class ToStringCallTransform extends ASTTransformVisitor { 9 | currentClass?: ClassDeclaration; 10 | fields!: string[]; 11 | 12 | visitFieldDeclaration(node: FieldDeclaration): void { 13 | const name = getName(node); 14 | let rhs = `this.${name}.toString()`; 15 | this.fields.push(`sb.push(\`${name}: \${${rhs}}\`)`); 16 | super.visitFieldDeclaration(node); 17 | } 18 | 19 | 20 | visitClassDeclaration(node: ClassDeclaration): void { 21 | if (!node.members || node.members.some(isMethodNamed("toString"))) { 22 | super.visitClassDeclaration(node); 23 | return; 24 | } 25 | 26 | this.currentClass = node; 27 | this.fields = []; 28 | this.visit(node.members); // will visit fields and methods 29 | const method = ` 30 | toString(): string { 31 | const sb = new Array(); 32 | ${this.fields.join(";\n\t")}; 33 | return \`${getName(node)}:\\n\\t\${sb.join("\\n\\t")}\` 34 | } 35 | ` 36 | let member = SimpleParser.parseClassMember(method, node); 37 | node.members.push(member); 38 | super.visitClassDeclaration(node); 39 | } 40 | 41 | afterParse(_: Parser): void { 42 | let sources = _.sources.filter(not(isStdlib)); 43 | this.visit(sources); 44 | } 45 | 46 | } 47 | 48 | 49 | export default ToStringCallTransform; 50 | -------------------------------------------------------------------------------- /src/simpleParser.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Parser, 3 | Tokenizer, 4 | Source, 5 | SourceKind, 6 | Expression, 7 | Statement, 8 | NamespaceDeclaration, 9 | ClassDeclaration, 10 | DeclarationStatement, 11 | } from "assemblyscript/dist/assemblyscript.js"; 12 | 13 | export class SimpleParser { 14 | private static get parser(): Parser { 15 | return new Parser(); 16 | } 17 | 18 | private static getTokenizer(s: string, file: string = "index.ts"): Tokenizer { 19 | return new Tokenizer(new Source(SourceKind.User, file, s)); 20 | } 21 | 22 | static parseExpression(s: string): Expression { 23 | const res = this.parser.parseExpression(this.getTokenizer(s)); 24 | if (res == null) { 25 | throw new Error("Failed to parse the expression: '" + s + "'"); 26 | } 27 | return res; 28 | } 29 | 30 | static parseStatement(s: string, topLevel = false): Statement { 31 | const res = this.parser.parseStatement(this.getTokenizer(s), topLevel); 32 | if (res == null) { 33 | throw new Error("Failed to parse the statement: '" + s + "'"); 34 | } 35 | return res; 36 | } 37 | 38 | static parseTopLevelStatement( 39 | s: string, 40 | namespace?: NamespaceDeclaration | null 41 | ): Statement { 42 | const res = this.parser.parseTopLevelStatement(this.getTokenizer(s), namespace); 43 | if (res == null) { 44 | throw new Error("Failed to parse the top level statement: '" + s + "'"); 45 | } 46 | return res; 47 | } 48 | 49 | static parseClassMember(s: string, _class: ClassDeclaration): DeclarationStatement { 50 | let res = this.parser.parseClassMember( 51 | this.getTokenizer(s, _class.range.source.normalizedPath), 52 | _class 53 | ); 54 | if (res == null) { 55 | throw new Error("Failed to parse the class member: '" + s + "'"); 56 | } 57 | return res; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/examples/includeBytesTransform.ts: -------------------------------------------------------------------------------- 1 | import { TransformVisitor, SimpleParser } from "../index.js"; 2 | import { 3 | Expression, 4 | Parser, 5 | CallExpression, 6 | IdentifierExpression, 7 | LiteralKind, 8 | StringLiteralExpression, 9 | } from "assemblyscript/dist/assemblyscript.js"; 10 | import { not, isStdlib } from "../utils.js"; 11 | import * as path from "path"; 12 | import * as fs from "fs"; 13 | 14 | class IncludeBytesTransform extends TransformVisitor { 15 | visitCallExpression(node: CallExpression): Expression { 16 | if (node.expression instanceof IdentifierExpression) { 17 | if (node.expression.text == "includeBytes") { 18 | if (!node.args[0].isLiteralKind(LiteralKind.String)) 19 | throw "[Error] includeBytes requires a constant literal filename"; 20 | let arg0 = node.args[0] as StringLiteralExpression; 21 | let filename = path.join( 22 | path.dirname(node.range.source.normalizedPath), 23 | arg0.value 24 | ); 25 | var data; 26 | try { 27 | data = fs.readFileSync(filename); 28 | } catch (e) { 29 | throw `[Error] includeBytes '${filename}', ${e}`; 30 | } 31 | let asJSONString = JSON.stringify(data); // use stringify to convert bytes to text 32 | let arrayStart = asJSONString.indexOf("["); //find the u8 array inside the JSON string 33 | let arrayEnd = asJSONString.lastIndexOf("]"); 34 | let newCode = 35 | "StaticArray.fromArray(" + 36 | asJSONString.substring(arrayStart, arrayEnd + 1) + 37 | ")"; 38 | let res = SimpleParser.parseExpression(newCode); //parse StaticArray.fromArray expression 39 | res.range = node.range; //same range 40 | return res; //replace node 41 | } 42 | } 43 | return super.visitCallExpression(node); 44 | } 45 | 46 | afterParse(_: Parser): void { 47 | let sources = _.sources.filter(not(isStdlib)); 48 | this.visit(sources); 49 | } 50 | } 51 | 52 | export default IncludeBytesTransform; 53 | -------------------------------------------------------------------------------- /src/visitor.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/ban-ts-comment */ 2 | export type Collection = 3 | | T 4 | | T[] 5 | | Map> 6 | | Iterable; 7 | 8 | function isIterable(object: T): boolean { 9 | // @ts-ignore 10 | return object != null && typeof object[Symbol.iterator] === "function"; 11 | } 12 | /** 13 | * Top level visitor that will expect an implemented _visit function to visit 14 | * a single node and then provides a generic function for collections of nodes 15 | * and will visit each member of the collection. 16 | */ 17 | export abstract class AbstractVisitor { 18 | visit(node: Collection | null): void { 19 | if (node == null) return; 20 | if (node instanceof Array) { 21 | node.map((node) => this.visit(node)); 22 | } else if (node instanceof Map) { 23 | for (let _node of node.values()) { 24 | this.visit(_node); 25 | } 26 | } else if (isIterable(node)) { 27 | // TODO: Find better way to test if iterable 28 | // @ts-ignore is iterable 29 | for (let _node of node) { 30 | this.visit(_node); 31 | } 32 | } else { 33 | /// @ts-ignore Node is not iterable. 34 | this._visit(node); 35 | } 36 | } 37 | 38 | protected abstract _visit(node: T): void; 39 | } 40 | 41 | export abstract class AbstractTransformVisitor { 42 | visit(node: Collection | null): Collection | null { 43 | if (node == null) return null; 44 | if (node instanceof Array) { 45 | return node.map((node) => this.visit(node) as T); 46 | } else if (node instanceof Map) { 47 | let res = new Map(); 48 | for (let [key, _node] of node.entries()) { 49 | res.set(key, this.visit(_node)); 50 | } 51 | return res; 52 | } else if (isIterable(node)) { 53 | let res: T[] = []; 54 | // TODO: Find better way to test if iterable 55 | // @ts-ignore is iterable 56 | for (let _node of node) { 57 | res.push(this.visit(_node) as T); 58 | } 59 | return res; 60 | } else { 61 | /// @ts-ignore Node is not iterable. 62 | return this._visit(node); 63 | } 64 | } 65 | 66 | protected abstract _visit(node: T): T; 67 | } -------------------------------------------------------------------------------- /as-pect.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | /** 3 | * A set of globs passed to the glob package that qualify typescript files for testing. 4 | */ 5 | include: ["assembly/__tests__/**/*.spec.ts"], 6 | /** 7 | * A set of globs passed to the glob package that quality files to be added to each test. 8 | */ 9 | add: ["assembly/__tests__/**/*.include.ts"], 10 | /** 11 | * All the compiler flags needed for this test suite. Make sure that a binary file is output. 12 | */ 13 | flags: { 14 | /** To output a wat file, uncomment the following line. */ 15 | // "--textFile": ["output.wat"], 16 | /** A runtime must be provided here. */ 17 | // "--runtime": ["none"], // Acceptable values are: full, half, stub (arena), and none 18 | "--transform": [ 19 | "./src/examples/toString.ts", 20 | "./src/examples/includeBytesTransform.ts", 21 | "./src/examples/capitalize.ts", 22 | "./src/examples/functionCallTransform.ts", 23 | ], 24 | }, 25 | /** 26 | * A set of regexp that will disclude source files from testing. 27 | */ 28 | disclude: [/node_modules/], 29 | /** 30 | * Add your required AssemblyScript imports here. 31 | */ 32 | imports(memory, createImports, instantiateSync, binary) { 33 | let instance; // Imports can reference this 34 | const myImports = { 35 | // put your web assembly imports here, and return the module 36 | }; 37 | instance = instantiateSync(binary, createImports(myImports)); 38 | return instance; 39 | }, 40 | /** 41 | * Add a custom reporter here if you want one. The following example is in typescript. 42 | * 43 | * @example 44 | * import { TestReporter, TestGroup, TestResult, TestContext } from "as-pect"; 45 | * 46 | * export class CustomReporter extends TestReporter { 47 | * // implement each abstract method here 48 | * public abstract onStart(suite: TestContext): void; 49 | * public abstract onGroupStart(group: TestGroup): void; 50 | * public abstract onGroupFinish(group: TestGroup): void; 51 | * public abstract onTestStart(group: TestGroup, result: TestResult): void; 52 | * public abstract onTestFinish(group: TestGroup, result: TestResult): void; 53 | * public abstract onFinish(suite: TestContext): void; 54 | * } 55 | */ 56 | // reporter: new CustomReporter(), 57 | /** 58 | * Specify if the binary wasm file should be written to the file system. 59 | */ 60 | outputBinary: false, 61 | }; 62 | -------------------------------------------------------------------------------- /src/decorator.ts: -------------------------------------------------------------------------------- 1 | import { PathTransformVisitor, mergeTransformer } from "./transformer.js"; 2 | import { 3 | ClassDeclaration, 4 | FieldDeclaration, 5 | MethodDeclaration, 6 | Parser, 7 | VariableDeclaration, 8 | FunctionDeclaration, 9 | Source, 10 | DecoratorNode, 11 | DeclarationStatement, 12 | } from "assemblyscript/dist/assemblyscript.js"; 13 | import { decorates, not, isStdlib } from "./utils.js"; 14 | 15 | export function registerDecorator(decorator: DecoratorVisitor) { 16 | TopLevelDecorator.registerVisitor(decorator); 17 | return TopLevelDecorator; 18 | } 19 | 20 | interface DecoratorVisitor extends PathTransformVisitor { 21 | decoratorMatcher: (node: DecoratorNode) => boolean; 22 | sourceFilter: (s: Source) => bool; 23 | } 24 | 25 | export class TopLevelDecorator extends PathTransformVisitor { 26 | private static _visitor: DecoratorVisitor; 27 | 28 | static registerVisitor(visitor: DecoratorVisitor): void { 29 | TopLevelDecorator._visitor = visitor; 30 | } 31 | 32 | private get visitor(): DecoratorVisitor { 33 | return TopLevelDecorator._visitor; 34 | } 35 | 36 | visitDecoratorNode(node: DecoratorNode) { 37 | if (this.visitor.decoratorMatcher(node)) { 38 | this.visitor.currentPath = this.currentParentPath; 39 | this.visitor.visit(this.currentParent); 40 | } 41 | } 42 | 43 | afterParse(_: Parser): void { 44 | mergeTransformer(this, this.visitor); 45 | this.visit(this.program.sources.filter(this.visitor.sourceFilter)); 46 | } 47 | 48 | } 49 | 50 | export abstract class Decorator extends PathTransformVisitor { 51 | /** 52 | * Default filter that removes library files 53 | */ 54 | get sourceFilter(): (s: Source) => bool { 55 | return not(isStdlib); 56 | } 57 | 58 | get decoratorMatcher(): (node: DecoratorNode) => boolean { 59 | return (node: DecoratorNode) => decorates(node, this.name) 60 | } 61 | 62 | get name(): string { return ""; } 63 | 64 | getDecorator(node: DeclarationStatement): DecoratorNode | null { 65 | return node.decorators && node.decorators.find(this.decoratorMatcher) || null; 66 | } 67 | } 68 | 69 | export abstract class ClassDecorator extends Decorator { 70 | abstract visitFieldDeclaration(node: FieldDeclaration): void; 71 | abstract visitMethodDeclaration(node: MethodDeclaration): void; 72 | abstract visitClassDeclaration(node: ClassDeclaration): void; 73 | } 74 | 75 | export abstract class FunctionDecorator extends Decorator { 76 | abstract visitFunctionDeclaration(node: FunctionDeclaration): void; 77 | } 78 | 79 | export abstract class VariableDecorator extends Decorator { 80 | abstract visitVariableDeclaration(node: VariableDeclaration): void; 81 | } 82 | -------------------------------------------------------------------------------- /__tests__/tests.spec.js: -------------------------------------------------------------------------------- 1 | import { compileAndInit, compileExample } from "./setup.js"; 2 | import { ASTBuilder, SimpleParser } from "../dist/index.js"; 3 | import mocha from "mocha" 4 | const { describe, it } = mocha 5 | import { expect } from "chai" 6 | 7 | const FOO = ` 8 | @list 9 | class Foo { 10 | a: u8; 11 | b: bool; 12 | i: i32; 13 | c: Animal.Cat; 14 | } 15 | `; 16 | 17 | const VEC = ` 18 | @list 19 | class Vec3 { 20 | constructor(public x: f64 = 0, public y: i64 = 0, public z: u32 = 0) {} 21 | } 22 | `; 23 | 24 | const GENERIC = ` 25 | @list 26 | class GenericMethods { 27 | nonGeneric(): void {} 28 | 29 | foo(t: T): void {} 30 | 31 | faa(): string { return "hello"; } 32 | 33 | orNull(): string | null { return null; } 34 | 35 | orNullMap(): Map | null { 36 | return null; 37 | } 38 | } 39 | ` 40 | 41 | describe("List", () => { 42 | it("should handle simple struct", async () => { 43 | expect(await compileExample(FOO, "./dist/examples/list.js")).to.deep.equal([ 44 | "a: u8", 45 | "b: bool", 46 | "i: i32", 47 | "c: Animal.Cat", 48 | ]); 49 | }); 50 | it("should list fields defined in constructor", async () => { 51 | expect(await compileExample(VEC, "./dist/examples/list.js")).to.deep.equal([ 52 | "x: f64", 53 | "y: i64", 54 | "z: u32", 55 | ]); 56 | }); 57 | it("should list methods", async () => { 58 | expect(await compileExample(GENERIC, "./dist/examples/list.js")).to.deep.equal([ 59 | "nonGeneric: () => void", 60 | "foo: (t: T) => void", 61 | "faa: () => string", 62 | "orNull: () => string | null", 63 | "orNullMap: () => Map | null", 64 | ]); 65 | }); 66 | }); 67 | 68 | const HelloWorldYay = ` 69 | @capitalize 70 | const hello = \`hello\`; 71 | @capitalize 72 | const world = "world"; 73 | @capitalize 74 | const yay = 'yay'; 75 | `; 76 | 77 | describe("Capitilize", () => { 78 | it("should handle simple struct", async () => { 79 | expect( 80 | await compileExample(HelloWorldYay, "./dist/examples/capitalize.js") 81 | ).to.deep.equal(["hello -> HELLO", "world -> WORLD", "yay -> YAY"]); 82 | }); 83 | }); 84 | 85 | 86 | 87 | 88 | const EXPORT_AS = ` 89 | @exportAs("new") 90 | export function main(): u32 { 91 | return 42; 92 | } 93 | ` 94 | 95 | describe("exportAs", () => { 96 | it("should rename exported function", async () => { 97 | let res = await compileAndInit(EXPORT_AS, "./dist/examples/exportAs.js"); 98 | expect(res.exports["new"]()).to.equal(42); 99 | }) 100 | }) 101 | 102 | describe('hello world transform', () => { 103 | it("should not throw", async () => { 104 | await compileAndInit("assert(foo() == 'hello world', 'should equal')", "./dist/examples/functionCallTransform.js") 105 | }); 106 | it("should handle \`'s", async () => { 107 | await compileAndInit("assert(foo() == `hello world`, 'should equal')", "./dist/examples/functionCallTransform.js") 108 | }); 109 | }); 110 | 111 | function expr(s) { 112 | expect(ASTBuilder.build(SimpleParser.parseExpression(s))) 113 | .to.equal(s) 114 | } 115 | 116 | function stmt(s) { 117 | expect(ASTBuilder.build(SimpleParser.parseStatement(s))) 118 | .to.equal(s) 119 | } 120 | 121 | const foo = ` 122 | class Foo { 123 | f: i32 = 0; 124 | } 125 | ` 126 | 127 | 128 | describe("Parser", () => { 129 | describe("Expressions", () => { 130 | it("binary", () => { 131 | expr("1 + 1"); 132 | }); 133 | 134 | it("call", () => { 135 | expr("callFunction()"); 136 | }); 137 | }); 138 | 139 | describe("Statements", () => { 140 | it("assignment", () => { 141 | stmt("let x = 1"); 142 | }); 143 | 144 | }); 145 | 146 | describe("top level", () => { 147 | let _class; 148 | beforeEach(() => { 149 | _class = SimpleParser.parseTopLevelStatement(foo); 150 | }); 151 | 152 | it("should have a field", () => { 153 | expect(_class.members.length).to.equal(1); 154 | expect(_class.members[0].name.range.toString()).to.equal("f"); 155 | }); 156 | 157 | it("should be able to add member", () => { 158 | let method = ` 159 | getF(): i32 { return this.f; } 160 | ` 161 | let methodAST = SimpleParser.parseClassMember(method, _class); 162 | _class.members.push(methodAST); 163 | expect(_class.members[1].name.text).to.equal("getF"); 164 | }) 165 | }) 166 | 167 | }); 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DecoratorNode, 3 | IdentifierExpression, 4 | DeclarationStatement, 5 | Source, 6 | Node, 7 | SourceKind, 8 | Program, 9 | ClassDeclaration, 10 | TypeNode, 11 | NodeKind, 12 | InterfaceDeclaration, 13 | FunctionDeclaration, 14 | TypeName, 15 | DiagnosticCategory, 16 | DiagnosticEmitter, 17 | NamedTypeNode, 18 | Range, 19 | util, 20 | } from "assemblyscript/dist/assemblyscript.js"; 21 | import { ASTBuilder } from "./astBuilder.js"; 22 | import cloneDeep from "lodash.clonedeep"; 23 | 24 | // const cloneDeep: (t: T) => T = require("lodash.clonedeep") as any; 25 | 26 | export function decorates(node: DecoratorNode, name: string): boolean { 27 | return (node.name).text === name; 28 | } 29 | 30 | export function isDecorator(name: string): (node: DecoratorNode) => boolean { 31 | return (node) => decorates(node, name); 32 | } 33 | 34 | 35 | export function hasDecorator( 36 | node: DeclarationStatement | {declaration: DeclarationStatement}, 37 | name: string 38 | ): boolean { 39 | let decl; 40 | if (node instanceof DeclarationStatement) { 41 | decl = node; 42 | } else { 43 | decl = node.declaration; 44 | } 45 | // because it could be undefined 46 | return decl.decorators?.some(isDecorator(name)) == true; 47 | } 48 | 49 | export function getDecorator( 50 | node: DeclarationStatement, 51 | name: string 52 | ): DecoratorNode { 53 | return node.decorators?.find(isDecorator(name))!; 54 | } 55 | 56 | export function isLibrary(node: Source): boolean { 57 | return node.isLibrary || node.internalPath.startsWith("~lib/rt/"); 58 | } 59 | 60 | export function not(fn: (t: T) => boolean): (t: T) => boolean { 61 | return (t: T) => !fn(t); 62 | } 63 | 64 | export function toString(node: Node): string { 65 | return ASTBuilder.build(node); 66 | } 67 | 68 | interface Named { 69 | name: IdentifierExpression; 70 | } 71 | 72 | const OR_NULL = /\|.*null/; 73 | 74 | 75 | export function getName(node: Node & Named | TypeNode): string { 76 | if (node instanceof TypeNode) { 77 | if (node instanceof NamedTypeNode) { 78 | let name = getTypeName(node.name) 79 | const typeParameters = node.typeArguments; 80 | if (typeParameters && typeParameters.length > 0) { 81 | name += `<${typeParameters.map(getName).join(", ")}>`; 82 | } 83 | if (node.isNullable && !OR_NULL.test(name)) { 84 | name = `${name} | null`; 85 | } 86 | return name 87 | } else if (node instanceof TypeName) { 88 | return toString(node.identifier) 89 | } 90 | return ""; 91 | } 92 | if (node instanceof ClassDeclaration || node instanceof InterfaceDeclaration || node instanceof FunctionDeclaration) { 93 | return className(node); 94 | } 95 | return toString(node.name); 96 | } 97 | 98 | 99 | export function getTypeName(node: TypeName): string { 100 | const partNames = []; 101 | let currentNode: TypeName | null = node; 102 | while (currentNode) { 103 | partNames.push(toString(currentNode.identifier)); 104 | currentNode = currentNode.next; 105 | } 106 | return partNames.join("."); 107 | } 108 | 109 | export function cloneNode(node: T): T { 110 | return cloneDeep(node); 111 | } 112 | 113 | export function isUserEntry(node: Node): boolean { 114 | return node.range.source.sourceKind == SourceKind.UserEntry; 115 | } 116 | 117 | export function isEntry(node: Node): boolean { 118 | return isUserEntry(node) || node.range.source.sourceKind == SourceKind.LibraryEntry; 119 | } 120 | 121 | export function className(_class: ClassDeclaration | InterfaceDeclaration | FunctionDeclaration): string { 122 | let name = toString(_class.name) 123 | const typeParameters = _class.typeParameters; 124 | if (typeParameters) { 125 | name += `<${typeParameters.map(getName).join(", ")}>`; 126 | } 127 | return name; 128 | } 129 | 130 | export function isMethodNamed(name: string): (_: DeclarationStatement) => boolean { 131 | return (stmt: DeclarationStatement) => stmt.kind == NodeKind.MethodDeclaration && toString(stmt.name) === name; 132 | } 133 | 134 | export function updateSource(program: Program, newSource: Source) { 135 | const sources = program.sources; 136 | for (let i = 0, len = sources.length; i < len; i++) { 137 | if (sources[i].internalPath == newSource.internalPath) { 138 | sources[i] = newSource; 139 | break; 140 | } 141 | } 142 | } 143 | 144 | export class StringBuilder { 145 | private sb: string[] = []; 146 | 147 | push(s: string): void { 148 | this.sb.push(s); 149 | } 150 | 151 | finish(separator = "\n"): string { 152 | let res = this.sb.join(separator); 153 | this.sb = []; 154 | return res; 155 | } 156 | 157 | get last(): string { return this.sb[this.sb.length -1]} 158 | } 159 | 160 | /** 161 | * 162 | * @param emitter DiagnosticEmitter 163 | * @returns return true if emitter have ERROR message 164 | */ 165 | export function hasErrorMessage(emitter: DiagnosticEmitter): boolean { 166 | return hasMessage(emitter, DiagnosticCategory.Error); 167 | } 168 | 169 | /** 170 | * 171 | * @param emitter DiagnosticEmitter 172 | * @returns return true if emitter have WARNING message 173 | */ 174 | export function hasWarningMessage(emitter: DiagnosticEmitter): boolean { 175 | return hasMessage(emitter, DiagnosticCategory.Warning); 176 | } 177 | 178 | /** 179 | * 180 | * @param emitter DiagnosticEmitter 181 | * @returns return true if emitter have `category` message 182 | */ 183 | export function hasMessage( 184 | emitter: DiagnosticEmitter, 185 | category: DiagnosticCategory 186 | ): boolean { 187 | const diagnostics = emitter.diagnostics ? emitter.diagnostics : []; 188 | for (const msg of diagnostics) { 189 | if (msg.category === category) { 190 | return true; 191 | } 192 | } 193 | return false; 194 | } 195 | 196 | 197 | let isStdlibRegex = 198 | /\~lib\/(?:array|arraybuffer|atomics|builtins|crypto|console|compat|dataview|date|diagnostics|error|function|iterator|map|math|number|object|process|reference|regexp|set|staticarray|string|symbol|table|typedarray|vector|rt\/?|bindings\/|shared\/typeinfo)|util\/|uri|polyfills|memory/; 199 | 200 | export function isStdlib(s: Source | { range: Range }): boolean { 201 | let source = s instanceof Source ? s : s.range.source; 202 | return isStdlibRegex.test(source.internalPath); 203 | } 204 | 205 | export const indent = util.indent; 206 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {2020} {Willem Wyndham} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/base.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-function */ 2 | import { 3 | Node, 4 | NodeKind, 5 | Source, 6 | NamedTypeNode, 7 | FunctionTypeNode, 8 | TypeName, 9 | TypeParameterNode, 10 | IdentifierExpression, 11 | AssertionExpression, 12 | BinaryExpression, 13 | CallExpression, 14 | ClassExpression, 15 | CommaExpression, 16 | ElementAccessExpression, 17 | FunctionExpression, 18 | InstanceOfExpression, 19 | LiteralExpression, 20 | NewExpression, 21 | ParenthesizedExpression, 22 | PropertyAccessExpression, 23 | TernaryExpression, 24 | UnaryPostfixExpression, 25 | UnaryPrefixExpression, 26 | BlockStatement, 27 | BreakStatement, 28 | ContinueStatement, 29 | DoStatement, 30 | EmptyStatement, 31 | ExportStatement, 32 | ExportDefaultStatement, 33 | ExportImportStatement, 34 | ExpressionStatement, 35 | ForStatement, 36 | IfStatement, 37 | ImportStatement, 38 | ReturnStatement, 39 | SwitchStatement, 40 | ThrowStatement, 41 | TryStatement, 42 | VariableStatement, 43 | WhileStatement, 44 | ClassDeclaration, 45 | EnumDeclaration, 46 | EnumValueDeclaration, 47 | FieldDeclaration, 48 | FunctionDeclaration, 49 | ImportDeclaration, 50 | InterfaceDeclaration, 51 | MethodDeclaration, 52 | NamespaceDeclaration, 53 | TypeDeclaration, 54 | VariableDeclaration, 55 | DecoratorNode, 56 | IndexSignatureNode, 57 | ParameterNode, 58 | ExportMember, 59 | SwitchCase, 60 | TypeNode, 61 | ArrayLiteralExpression, 62 | Expression, 63 | ObjectLiteralExpression, 64 | FloatLiteralExpression, 65 | IntegerLiteralExpression, 66 | StringLiteralExpression, 67 | RegexpLiteralExpression, 68 | UnaryExpression, 69 | SuperExpression, 70 | FalseExpression, 71 | TrueExpression, 72 | ThisExpression, 73 | NullExpression, 74 | ConstructorExpression, 75 | Statement, 76 | VoidStatement, 77 | LiteralKind, 78 | CommentNode, 79 | TemplateLiteralExpression, 80 | } from "assemblyscript/dist/assemblyscript.js"; 81 | 82 | import { AbstractVisitor } from "./visitor.js"; 83 | 84 | export class BaseVisitor extends AbstractVisitor { 85 | depth = 0; 86 | 87 | protected _visit(node: Node): void { 88 | switch (node.kind) { 89 | case NodeKind.Source: { 90 | this.visitSource(node); 91 | break; 92 | } 93 | 94 | // types 95 | 96 | case NodeKind.NamedType: { 97 | this.visitNamedTypeNode(node); 98 | break; 99 | } 100 | case NodeKind.FunctionType: { 101 | this.visitFunctionTypeNode(node); 102 | break; 103 | } 104 | case NodeKind.TypeName: { 105 | this.visitTypeName(node); 106 | } 107 | case NodeKind.TypeParameter: { 108 | this.visitTypeParameter(node); 109 | break; 110 | } 111 | 112 | // expressions 113 | 114 | case NodeKind.False: 115 | case NodeKind.Null: 116 | case NodeKind.Super: 117 | case NodeKind.This: 118 | case NodeKind.True: 119 | case NodeKind.Constructor: 120 | case NodeKind.Identifier: { 121 | this.visitIdentifierExpression(node); 122 | break; 123 | } 124 | case NodeKind.Assertion: { 125 | this.visitAssertionExpression(node); 126 | break; 127 | } 128 | case NodeKind.Binary: { 129 | this.visitBinaryExpression(node); 130 | break; 131 | } 132 | case NodeKind.Call: { 133 | this.visitCallExpression(node); 134 | break; 135 | } 136 | case NodeKind.Class: { 137 | this.visitClassExpression(node); 138 | break; 139 | } 140 | case NodeKind.Comma: { 141 | this.visitCommaExpression(node); 142 | break; 143 | } 144 | case NodeKind.ElementAccess: { 145 | this.visitElementAccessExpression( 146 | node 147 | ); 148 | break; 149 | } 150 | case NodeKind.Function: { 151 | this.visitFunctionExpression(node); 152 | break; 153 | } 154 | case NodeKind.InstanceOf: { 155 | this.visitInstanceOfExpression(node); 156 | break; 157 | } 158 | case NodeKind.Literal: { 159 | this.visitLiteralExpression(node); 160 | break; 161 | } 162 | case NodeKind.New: { 163 | this.visitNewExpression(node); 164 | break; 165 | } 166 | case NodeKind.Parenthesized: { 167 | this.visitParenthesizedExpression( 168 | node 169 | ); 170 | break; 171 | } 172 | case NodeKind.PropertyAccess: { 173 | this.visitPropertyAccessExpression( 174 | node 175 | ); 176 | break; 177 | } 178 | case NodeKind.Ternary: { 179 | this.visitTernaryExpression(node); 180 | break; 181 | } 182 | case NodeKind.UnaryPostfix: { 183 | this.visitUnaryPostfixExpression(node); 184 | break; 185 | } 186 | case NodeKind.UnaryPrefix: { 187 | this.visitUnaryPrefixExpression(node); 188 | break; 189 | } 190 | 191 | // statements 192 | 193 | case NodeKind.Block: { 194 | this.visitBlockStatement(node); 195 | break; 196 | } 197 | case NodeKind.Break: { 198 | this.visitBreakStatement(node); 199 | break; 200 | } 201 | case NodeKind.Continue: { 202 | this.visitContinueStatement(node); 203 | break; 204 | } 205 | case NodeKind.Do: { 206 | this.visitDoStatement(node); 207 | break; 208 | } 209 | case NodeKind.Empty: { 210 | this.visitEmptyStatement(node); 211 | break; 212 | } 213 | case NodeKind.Export: { 214 | this.visitExportStatement(node); 215 | break; 216 | } 217 | case NodeKind.ExportDefault: { 218 | this.visitExportDefaultStatement(node); 219 | break; 220 | } 221 | case NodeKind.ExportImport: { 222 | this.visitExportImportStatement(node); 223 | break; 224 | } 225 | case NodeKind.Expression: { 226 | this.visitExpressionStatement(node); 227 | break; 228 | } 229 | case NodeKind.For: { 230 | this.visitForStatement(node); 231 | break; 232 | } 233 | case NodeKind.If: { 234 | this.visitIfStatement(node); 235 | break; 236 | } 237 | case NodeKind.Import: { 238 | this.visitImportStatement(node); 239 | break; 240 | } 241 | case NodeKind.Return: { 242 | this.visitReturnStatement(node); 243 | break; 244 | } 245 | case NodeKind.Switch: { 246 | this.visitSwitchStatement(node); 247 | break; 248 | } 249 | case NodeKind.Throw: { 250 | this.visitThrowStatement(node); 251 | break; 252 | } 253 | case NodeKind.Try: { 254 | this.visitTryStatement(node); 255 | break; 256 | } 257 | case NodeKind.Variable: { 258 | this.visitVariableStatement(node); 259 | break; 260 | } 261 | case NodeKind.While: { 262 | this.visitWhileStatement(node); 263 | break; 264 | } 265 | 266 | // declaration statements 267 | 268 | case NodeKind.ClassDeclaration: { 269 | this.visitClassDeclaration(node); 270 | break; 271 | } 272 | case NodeKind.EnumDeclaration: { 273 | this.visitEnumDeclaration(node); 274 | break; 275 | } 276 | case NodeKind.EnumValueDeclaration: { 277 | this.visitEnumValueDeclaration(node); 278 | break; 279 | } 280 | case NodeKind.FieldDeclaration: { 281 | this.visitFieldDeclaration(node); 282 | break; 283 | } 284 | case NodeKind.FunctionDeclaration: { 285 | this.visitFunctionDeclaration(node); 286 | break; 287 | } 288 | case NodeKind.ImportDeclaration: { 289 | this.visitImportDeclaration(node); 290 | break; 291 | } 292 | case NodeKind.InterfaceDeclaration: { 293 | this.visitInterfaceDeclaration(node); 294 | break; 295 | } 296 | case NodeKind.MethodDeclaration: { 297 | this.visitMethodDeclaration(node); 298 | break; 299 | } 300 | case NodeKind.NamespaceDeclaration: { 301 | this.visitNamespaceDeclaration(node); 302 | break; 303 | } 304 | case NodeKind.TypeDeclaration: { 305 | this.visitTypeDeclaration(node); 306 | break; 307 | } 308 | case NodeKind.VariableDeclaration: { 309 | this.visitVariableDeclaration(node); 310 | break; 311 | } 312 | 313 | // other 314 | 315 | case NodeKind.Decorator: { 316 | this.visitDecoratorNode(node); 317 | break; 318 | } 319 | case NodeKind.ExportMember: { 320 | this.visitExportMember(node); 321 | break; 322 | } 323 | case NodeKind.Parameter: { 324 | this.visitParameter(node); 325 | break; 326 | } 327 | case NodeKind.SwitchCase: { 328 | this.visitSwitchCase(node); 329 | break; 330 | } 331 | case NodeKind.IndexSignature: { 332 | this.visitIndexSignature(node); 333 | break; 334 | } 335 | default: 336 | assert(false); 337 | } 338 | } 339 | 340 | visitSource(node: Source): void { 341 | for (const stmt of node.statements) { 342 | this.depth++; 343 | this.visit(stmt); 344 | this.depth--; 345 | } 346 | } 347 | 348 | visitTypeNode(node: TypeNode): void { } 349 | 350 | visitTypeName(node: TypeName): void { 351 | this.visit(node.identifier); 352 | this.visit(node.next); 353 | } 354 | 355 | visitNamedTypeNode(node: NamedTypeNode): void { 356 | this.visit(node.name); 357 | this.visit(node.typeArguments); 358 | } 359 | 360 | visitFunctionTypeNode(node: FunctionTypeNode): void { 361 | this.visit(node.parameters); 362 | this.visit(node.returnType); 363 | this.visit(node.explicitThisType); 364 | } 365 | 366 | visitTypeParameter(node: TypeParameterNode): void { 367 | this.visit(node.name); 368 | this.visit(node.extendsType); 369 | this.visit(node.defaultType); 370 | } 371 | 372 | visitIdentifierExpression(node: IdentifierExpression): void { } 373 | 374 | visitArrayLiteralExpression(node: ArrayLiteralExpression): void { 375 | this.visit(node.elementExpressions); 376 | } 377 | 378 | visitObjectLiteralExpression(node: ObjectLiteralExpression): void { 379 | this.visit(node.names); 380 | this.visit(node.values); 381 | } 382 | 383 | visitAssertionExpression(node: AssertionExpression): void { 384 | this.visit(node.toType); 385 | this.visit(node.expression); 386 | } 387 | 388 | visitBinaryExpression(node: BinaryExpression): void { 389 | this.visit(node.left); 390 | this.visit(node.right); 391 | } 392 | 393 | visitCallExpression(node: CallExpression): void { 394 | this.visit(node.expression); 395 | this.visitArguments(node.typeArguments, node.args); 396 | } 397 | 398 | visitArguments(typeArguments: TypeNode[] | null, args: Expression[]): void { 399 | this.visit(typeArguments); 400 | this.visit(args); 401 | } 402 | 403 | visitClassExpression(node: ClassExpression): void { 404 | this.visit(node.declaration); 405 | } 406 | 407 | visitCommaExpression(node: CommaExpression): void { 408 | this.visit(node.expressions); 409 | } 410 | 411 | visitElementAccessExpression(node: ElementAccessExpression): void { 412 | this.visit(node.elementExpression); 413 | this.visit(node.expression); 414 | } 415 | 416 | visitFunctionExpression(node: FunctionExpression): void { 417 | this.visit(node.declaration); 418 | } 419 | 420 | visitLiteralExpression(node: LiteralExpression): void { 421 | switch (node.literalKind) { 422 | case LiteralKind.Float: { 423 | this.visitFloatLiteralExpression(node); 424 | break; 425 | } 426 | case LiteralKind.Integer: { 427 | this.visitIntegerLiteralExpression( 428 | node 429 | ); 430 | break; 431 | } 432 | case LiteralKind.String: { 433 | this.visitStringLiteralExpression( 434 | node 435 | ); 436 | break; 437 | } 438 | case LiteralKind.Template: { 439 | this.visitTemplateLiteralExpression( 440 | node 441 | ); 442 | break; 443 | } 444 | case LiteralKind.RegExp: { 445 | this.visitRegexpLiteralExpression( 446 | node 447 | ); 448 | break; 449 | } 450 | case LiteralKind.Array: { 451 | this.visitArrayLiteralExpression(node); 452 | break; 453 | } 454 | case LiteralKind.Object: { 455 | this.visitObjectLiteralExpression( 456 | node 457 | ); 458 | break; 459 | } 460 | default: 461 | throw new Error("Invalid LiteralKind: " + node.literalKind); 462 | } 463 | } 464 | 465 | visitFloatLiteralExpression(node: FloatLiteralExpression): void { } 466 | 467 | visitInstanceOfExpression(node: InstanceOfExpression): void { 468 | this.visit(node.expression); 469 | this.visit(node.isType); 470 | } 471 | 472 | visitIntegerLiteralExpression(node: IntegerLiteralExpression): void { } 473 | 474 | visitStringLiteral(str: string, singleQuoted: bool = false): void { } 475 | 476 | visitStringLiteralExpression(node: StringLiteralExpression): void { 477 | this.visitStringLiteral(node.value); 478 | } 479 | 480 | visitTemplateLiteralExpression(node: TemplateLiteralExpression): void { } 481 | 482 | visitRegexpLiteralExpression(node: RegexpLiteralExpression): void { } 483 | 484 | visitNewExpression(node: NewExpression): void { 485 | this.visit(node.typeArguments); 486 | this.visitArguments(node.typeArguments, node.args); 487 | this.visit(node.args); 488 | } 489 | 490 | visitParenthesizedExpression(node: ParenthesizedExpression): void { 491 | this.visit(node.expression); 492 | } 493 | 494 | visitPropertyAccessExpression(node: PropertyAccessExpression): void { 495 | this.visit(node.property); 496 | this.visit(node.expression); 497 | } 498 | 499 | visitTernaryExpression(node: TernaryExpression): void { 500 | this.visit(node.condition); 501 | this.visit(node.ifThen); 502 | this.visit(node.ifElse); 503 | } 504 | 505 | visitUnaryExpression(node: UnaryExpression): void { 506 | this.visit(node.operand); 507 | } 508 | 509 | visitUnaryPostfixExpression(node: UnaryPostfixExpression): void { 510 | this.visit(node.operand); 511 | } 512 | 513 | visitUnaryPrefixExpression(node: UnaryPrefixExpression): void { 514 | this.visit(node.operand); 515 | } 516 | 517 | visitSuperExpression(node: SuperExpression): void { } 518 | 519 | visitFalseExpression(node: FalseExpression): void { } 520 | 521 | visitTrueExpression(node: TrueExpression): void { } 522 | 523 | visitThisExpression(node: ThisExpression): void { } 524 | 525 | visitNullExperssion(node: NullExpression): void { } 526 | 527 | visitConstructorExpression(node: ConstructorExpression): void { } 528 | 529 | visitNodeAndTerminate(statement: Statement): void { } 530 | 531 | visitBlockStatement(node: BlockStatement): void { 532 | this.depth++; 533 | this.visit(node.statements); 534 | this.depth--; 535 | } 536 | 537 | visitBreakStatement(node: BreakStatement): void { 538 | this.visit(node.label); 539 | } 540 | 541 | visitContinueStatement(node: ContinueStatement): void { 542 | this.visit(node.label); 543 | } 544 | 545 | visitClassDeclaration(node: ClassDeclaration, isDefault = false): void { 546 | this.visit(node.name); 547 | this.depth++; 548 | this.visit(node.decorators); 549 | assert( 550 | node.isGeneric 551 | ? node.typeParameters != null 552 | : node.typeParameters == null 553 | ); 554 | this.visit(node.typeParameters); 555 | this.visit(node.extendsType); 556 | this.visit(node.implementsTypes); 557 | this.visit(node.members); 558 | this.depth--; 559 | } 560 | 561 | visitDoStatement(node: DoStatement): void { 562 | this.visit(node.condition); 563 | this.visit(node.body); 564 | } 565 | 566 | visitEmptyStatement(node: EmptyStatement): void { } 567 | 568 | visitEnumDeclaration(node: EnumDeclaration, isDefault = false): void { 569 | this.visit(node.name); 570 | this.visit(node.decorators); 571 | this.visit(node.values); 572 | } 573 | 574 | visitEnumValueDeclaration(node: EnumValueDeclaration): void { 575 | this.visit(node.name); 576 | this.visit(node.initializer); 577 | } 578 | 579 | visitExportImportStatement(node: ExportImportStatement): void { 580 | this.visit(node.name); 581 | this.visit(node.externalName); 582 | } 583 | 584 | visitExportMember(node: ExportMember): void { 585 | this.visit(node.localName); 586 | this.visit(node.exportedName); 587 | } 588 | 589 | visitExportStatement(node: ExportStatement): void { 590 | this.visit(node.path); 591 | this.visit(node.members); 592 | } 593 | 594 | visitExportDefaultStatement(node: ExportDefaultStatement): void { 595 | this.visit(node.declaration); 596 | } 597 | 598 | visitExpressionStatement(node: ExpressionStatement): void { 599 | this.visit(node.expression); 600 | } 601 | 602 | visitFieldDeclaration(node: FieldDeclaration): void { 603 | this.visit(node.name); 604 | this.visit(node.type); 605 | this.visit(node.initializer); 606 | this.visit(node.decorators); 607 | } 608 | 609 | visitForStatement(node: ForStatement): void { 610 | this.visit(node.initializer); 611 | this.visit(node.condition); 612 | this.visit(node.incrementor); 613 | this.visit(node.body); 614 | } 615 | 616 | visitFunctionDeclaration( 617 | node: FunctionDeclaration, 618 | isDefault = false 619 | ): void { 620 | this.visit(node.name); 621 | this.visit(node.decorators); 622 | this.visit(node.typeParameters); 623 | this.visit(node.signature); 624 | this.depth++; 625 | this.visit(node.body); 626 | this.depth--; 627 | } 628 | 629 | visitIfStatement(node: IfStatement): void { 630 | this.visit(node.condition); 631 | this.visit(node.ifTrue); 632 | this.visit(node.ifFalse); 633 | } 634 | 635 | visitImportDeclaration(node: ImportDeclaration): void { 636 | this.visit(node.foreignName); 637 | this.visit(node.name); 638 | this.visit(node.decorators); 639 | } 640 | 641 | visitImportStatement(node: ImportStatement): void { 642 | this.visit(node.namespaceName); 643 | this.visit(node.declarations); 644 | } 645 | 646 | visitIndexSignature(node: IndexSignatureNode): void { 647 | this.visit(node.keyType); 648 | this.visit(node.valueType); 649 | } 650 | 651 | visitInterfaceDeclaration( 652 | node: InterfaceDeclaration, 653 | isDefault = false 654 | ): void { 655 | this.visit(node.name); 656 | this.visit(node.typeParameters); 657 | this.visit(node.implementsTypes); 658 | this.visit(node.extendsType); 659 | this.depth++; 660 | this.visit(node.members); 661 | this.depth--; 662 | } 663 | 664 | visitMethodDeclaration(node: MethodDeclaration): void { 665 | this.visit(node.name); 666 | this.visit(node.typeParameters); 667 | this.visit(node.signature); 668 | this.visit(node.decorators); 669 | this.depth++; 670 | this.visit(node.body); 671 | this.depth--; 672 | } 673 | 674 | visitNamespaceDeclaration( 675 | node: NamespaceDeclaration, 676 | isDefault = false 677 | ): void { 678 | this.visit(node.name); 679 | this.visit(node.decorators); 680 | this.visit(node.members); 681 | } 682 | 683 | visitReturnStatement(node: ReturnStatement): void { 684 | this.visit(node.value); 685 | } 686 | 687 | visitSwitchCase(node: SwitchCase): void { 688 | this.visit(node.label); 689 | this.visit(node.statements); 690 | } 691 | 692 | visitSwitchStatement(node: SwitchStatement): void { 693 | this.visit(node.condition); 694 | this.depth++; 695 | this.visit(node.cases); 696 | this.depth--; 697 | } 698 | 699 | visitThrowStatement(node: ThrowStatement): void { 700 | this.visit(node.value); 701 | } 702 | 703 | visitTryStatement(node: TryStatement): void { 704 | this.visit(node.bodyStatements); 705 | this.visit(node.catchVariable); 706 | this.visit(node.catchStatements); 707 | this.visit(node.finallyStatements); 708 | } 709 | 710 | visitTypeDeclaration(node: TypeDeclaration): void { 711 | this.visit(node.name); 712 | this.visit(node.decorators); 713 | this.visit(node.type); 714 | this.visit(node.typeParameters); 715 | } 716 | 717 | visitVariableDeclaration(node: VariableDeclaration): void { 718 | this.visit(node.name); 719 | this.visit(node.type); 720 | this.visit(node.initializer); 721 | } 722 | 723 | visitVariableStatement(node: VariableStatement): void { 724 | this.visit(node.decorators); 725 | this.visit(node.declarations); 726 | } 727 | 728 | visitWhileStatement(node: WhileStatement): void { 729 | this.visit(node.condition); 730 | this.depth++; 731 | this.visit(node.body); 732 | this.depth--; 733 | } 734 | 735 | visitVoidStatement(node: VoidStatement): void { } 736 | 737 | visitComment(node: CommentNode): void { } 738 | 739 | visitDecoratorNode(node: DecoratorNode): void { 740 | this.visit(node.name); 741 | this.visit(node.args); 742 | } 743 | 744 | visitParameter(node: ParameterNode): void { 745 | this.visit(node.name); 746 | this.visit(node.implicitFieldDeclaration); 747 | this.visit(node.initializer); 748 | this.visit(node.type); 749 | } 750 | } 751 | -------------------------------------------------------------------------------- /src/baseTransform.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Node, 3 | NodeKind, 4 | Source, 5 | NamedTypeNode, 6 | FunctionTypeNode, 7 | TypeName, 8 | TypeParameterNode, 9 | IdentifierExpression, 10 | AssertionExpression, 11 | BinaryExpression, 12 | CallExpression, 13 | ClassExpression, 14 | CommaExpression, 15 | ElementAccessExpression, 16 | FunctionExpression, 17 | InstanceOfExpression, 18 | LiteralExpression, 19 | NewExpression, 20 | ParenthesizedExpression, 21 | PropertyAccessExpression, 22 | TernaryExpression, 23 | UnaryPostfixExpression, 24 | UnaryPrefixExpression, 25 | BlockStatement, 26 | BreakStatement, 27 | ContinueStatement, 28 | DoStatement, 29 | EmptyStatement, 30 | ExportStatement, 31 | ExportDefaultStatement, 32 | ExportImportStatement, 33 | ExpressionStatement, 34 | ForStatement, 35 | IfStatement, 36 | ImportStatement, 37 | ReturnStatement, 38 | SwitchStatement, 39 | ThrowStatement, 40 | TryStatement, 41 | VariableStatement, 42 | WhileStatement, 43 | ClassDeclaration, 44 | EnumDeclaration, 45 | EnumValueDeclaration, 46 | FieldDeclaration, 47 | FunctionDeclaration, 48 | ImportDeclaration, 49 | InterfaceDeclaration, 50 | MethodDeclaration, 51 | NamespaceDeclaration, 52 | TypeDeclaration, 53 | VariableDeclaration, 54 | DecoratorNode, 55 | IndexSignatureNode, 56 | ParameterNode, 57 | ExportMember, 58 | SwitchCase, 59 | TypeNode, 60 | ArrayLiteralExpression, 61 | Expression, 62 | ObjectLiteralExpression, 63 | FloatLiteralExpression, 64 | IntegerLiteralExpression, 65 | StringLiteralExpression, 66 | RegexpLiteralExpression, 67 | UnaryExpression, 68 | SuperExpression, 69 | FalseExpression, 70 | TrueExpression, 71 | ThisExpression, 72 | NullExpression, 73 | ConstructorExpression, 74 | Statement, 75 | VoidStatement, 76 | LiteralKind, 77 | CommentNode, 78 | DeclarationStatement, 79 | TemplateLiteralExpression, 80 | } from "assemblyscript/dist/assemblyscript.js"; 81 | 82 | import { AbstractTransformVisitor } from "./visitor.js"; 83 | 84 | export class BaseTransformVisitor extends AbstractTransformVisitor { 85 | depth = 0; 86 | 87 | protected _visit(node: Node): Node { 88 | switch (node.kind) { 89 | case NodeKind.Source: { 90 | return this.visitSource(node); 91 | } 92 | 93 | // types 94 | 95 | case NodeKind.NamedType: { 96 | return this.visitNamedTypeNode(node); 97 | } 98 | case NodeKind.FunctionType: { 99 | return this.visitFunctionTypeNode(node); 100 | } 101 | case NodeKind.TypeName: { 102 | return this.visitTypeName(node); 103 | } 104 | case NodeKind.TypeParameter: { 105 | return this.visitTypeParameter(node); 106 | } 107 | 108 | // expressions 109 | 110 | case NodeKind.False: 111 | case NodeKind.Null: 112 | case NodeKind.Super: 113 | case NodeKind.This: 114 | case NodeKind.True: 115 | case NodeKind.Constructor: 116 | case NodeKind.Identifier: { 117 | return this.visitIdentifierExpression( 118 | node 119 | ); 120 | } 121 | case NodeKind.Assertion: { 122 | return this.visitAssertionExpression(node); 123 | } 124 | case NodeKind.Binary: { 125 | return this.visitBinaryExpression(node); 126 | } 127 | case NodeKind.Call: { 128 | return this.visitCallExpression(node); 129 | } 130 | case NodeKind.Class: { 131 | return this.visitClassExpression(node); 132 | } 133 | case NodeKind.Comma: { 134 | return this.visitCommaExpression(node); 135 | } 136 | case NodeKind.ElementAccess: { 137 | return this.visitElementAccessExpression( 138 | node 139 | ); 140 | } 141 | case NodeKind.Function: { 142 | return this.visitFunctionExpression(node); 143 | } 144 | case NodeKind.InstanceOf: { 145 | return this.visitInstanceOfExpression( 146 | node 147 | ); 148 | } 149 | case NodeKind.Literal: { 150 | return this.visitLiteralExpression(node); 151 | } 152 | case NodeKind.New: { 153 | return this.visitNewExpression(node); 154 | } 155 | case NodeKind.Parenthesized: { 156 | return this.visitParenthesizedExpression( 157 | node 158 | ); 159 | } 160 | case NodeKind.PropertyAccess: { 161 | return this.visitPropertyAccessExpression( 162 | node 163 | ); 164 | } 165 | case NodeKind.Ternary: { 166 | return this.visitTernaryExpression(node); 167 | } 168 | case NodeKind.UnaryPostfix: { 169 | return this.visitUnaryPostfixExpression( 170 | node 171 | ); 172 | } 173 | case NodeKind.UnaryPrefix: { 174 | return this.visitUnaryPrefixExpression( 175 | node 176 | ); 177 | } 178 | 179 | // statements 180 | 181 | case NodeKind.Block: { 182 | return this.visitBlockStatement(node); 183 | } 184 | case NodeKind.Break: { 185 | return this.visitBreakStatement(node); 186 | } 187 | case NodeKind.Continue: { 188 | return this.visitContinueStatement(node); 189 | } 190 | case NodeKind.Do: { 191 | return this.visitDoStatement(node); 192 | } 193 | case NodeKind.Empty: { 194 | return this.visitEmptyStatement(node); 195 | } 196 | case NodeKind.Export: { 197 | return this.visitExportStatement(node); 198 | } 199 | case NodeKind.ExportDefault: { 200 | return this.visitExportDefaultStatement( 201 | node 202 | ); 203 | } 204 | case NodeKind.ExportImport: { 205 | return this.visitExportImportStatement( 206 | node 207 | ); 208 | } 209 | case NodeKind.Expression: { 210 | return this.visitExpressionStatement(node); 211 | } 212 | case NodeKind.For: { 213 | return this.visitForStatement(node); 214 | } 215 | case NodeKind.If: { 216 | return this.visitIfStatement(node); 217 | } 218 | case NodeKind.Import: { 219 | return this.visitImportStatement(node); 220 | } 221 | case NodeKind.Return: { 222 | return this.visitReturnStatement(node); 223 | } 224 | case NodeKind.Switch: { 225 | return this.visitSwitchStatement(node); 226 | } 227 | case NodeKind.Throw: { 228 | return this.visitThrowStatement(node); 229 | } 230 | case NodeKind.Try: { 231 | return this.visitTryStatement(node); 232 | } 233 | case NodeKind.Variable: { 234 | return this.visitVariableStatement(node); 235 | } 236 | case NodeKind.While: { 237 | return this.visitWhileStatement(node); 238 | } 239 | 240 | // declaration statements 241 | 242 | case NodeKind.ClassDeclaration: { 243 | return this.visitClassDeclaration(node); 244 | } 245 | case NodeKind.EnumDeclaration: { 246 | return this.visitEnumDeclaration(node); 247 | } 248 | case NodeKind.EnumValueDeclaration: { 249 | return this.visitEnumValueDeclaration( 250 | node 251 | ); 252 | } 253 | case NodeKind.FieldDeclaration: { 254 | return this.visitFieldDeclaration(node); 255 | } 256 | case NodeKind.FunctionDeclaration: { 257 | return this.visitFunctionDeclaration(node); 258 | } 259 | case NodeKind.ImportDeclaration: { 260 | return this.visitImportDeclaration(node); 261 | } 262 | case NodeKind.InterfaceDeclaration: { 263 | return this.visitInterfaceDeclaration( 264 | node 265 | ); 266 | } 267 | case NodeKind.MethodDeclaration: { 268 | return this.visitMethodDeclaration(node); 269 | } 270 | case NodeKind.NamespaceDeclaration: { 271 | return this.visitNamespaceDeclaration( 272 | node 273 | ); 274 | } 275 | case NodeKind.TypeDeclaration: { 276 | return this.visitTypeDeclaration(node); 277 | } 278 | case NodeKind.VariableDeclaration: { 279 | return this.visitVariableDeclaration(node); 280 | } 281 | 282 | // other 283 | 284 | case NodeKind.Decorator: { 285 | return this.visitDecoratorNode(node); 286 | } 287 | case NodeKind.ExportMember: { 288 | return this.visitExportMember(node); 289 | } 290 | case NodeKind.Parameter: { 291 | return this.visitParameter(node); 292 | } 293 | case NodeKind.SwitchCase: { 294 | return this.visitSwitchCase(node); 295 | } 296 | case NodeKind.IndexSignature: { 297 | return this.visitIndexSignature(node); 298 | } 299 | default: 300 | assert(false, "visit panic"); 301 | } 302 | return node; 303 | } 304 | 305 | visitSource(node: Source): Source { 306 | let statements: Statement[] = []; 307 | for (let i = 0; i < node.statements.length; i++) { 308 | const stmt = node.statements[i]; 309 | this.depth++; 310 | statements.push(this._visit(stmt) as Statement); 311 | this.depth--; 312 | 313 | } 314 | node.statements = statements; 315 | return node; 316 | } 317 | 318 | visitTypeNode(node: TypeNode): TypeNode { 319 | return node; 320 | } 321 | 322 | visitTypeName(node: TypeName): TypeName { 323 | node.identifier = this.visitIdentifierExpression(node.identifier); 324 | node.next = this.visit(node.next) as TypeName; 325 | return node; 326 | } 327 | 328 | visitNamedTypeNode(node: NamedTypeNode): NamedTypeNode { 329 | node.name = this.visit(node.name) as TypeName; 330 | node.typeArguments = this.visit(node.typeArguments) as TypeNode[] | null; 331 | return node; 332 | } 333 | 334 | visitFunctionTypeNode(node: FunctionTypeNode): FunctionTypeNode { 335 | node.parameters = this.visit(node.parameters) as ParameterNode[]; 336 | node.returnType = this.visit(node.returnType) as TypeNode; 337 | node.explicitThisType = this.visit(node.explicitThisType) as NamedTypeNode | null; 338 | return node; 339 | } 340 | 341 | visitTypeParameter(node: TypeParameterNode): TypeParameterNode { 342 | node.name = this.visit(node.name) as IdentifierExpression; 343 | node.extendsType = this.visit(node.extendsType) as NamedTypeNode; 344 | node.defaultType = this.visit(node.defaultType) as NamedTypeNode; 345 | return node; 346 | } 347 | 348 | visitIdentifierExpression( 349 | node: IdentifierExpression 350 | ): IdentifierExpression { 351 | return node; 352 | } 353 | 354 | visitArrayLiteralExpression( 355 | node: ArrayLiteralExpression 356 | ): ArrayLiteralExpression { 357 | node.elementExpressions = this.visit( 358 | node.elementExpressions 359 | ) as Expression[]; 360 | return node; 361 | } 362 | 363 | visitObjectLiteralExpression( 364 | node: ObjectLiteralExpression 365 | ): ObjectLiteralExpression { 366 | node.names = this.visit(node.names) as IdentifierExpression[]; 367 | node.values = this.visit(node.values) as Expression[]; 368 | return node; 369 | } 370 | 371 | visitAssertionExpression(node: AssertionExpression): AssertionExpression { 372 | node.expression = this.visit(node.expression) as Expression; 373 | node.toType = this.visit(node.toType) as TypeNode; 374 | return node; 375 | } 376 | 377 | visitBinaryExpression(node: BinaryExpression): BinaryExpression { 378 | node.left = this.visit(node.left) as Expression; 379 | node.right = this.visit(node.right) as Expression; 380 | return node; 381 | } 382 | 383 | visitCallExpression(node: CallExpression): Expression { 384 | node.expression = this.visit(node.expression) as Expression; 385 | node.typeArguments = this.visit(node.typeArguments) as TypeNode[] | null; 386 | node.args = this.visit(node.args) as Expression[]; 387 | return node; 388 | } 389 | 390 | visitClassExpression(node: ClassExpression): ClassExpression { 391 | node.declaration = this.visit(node.declaration) as ClassDeclaration; 392 | return node; 393 | } 394 | 395 | visitCommaExpression(node: CommaExpression): CommaExpression { 396 | node.expressions = this.visit(node.expressions) as Expression[]; 397 | return node; 398 | } 399 | 400 | visitElementAccessExpression( 401 | node: ElementAccessExpression 402 | ): ElementAccessExpression { 403 | node.elementExpression = this.visit( 404 | node.elementExpression 405 | ) as Expression; 406 | node.expression = this.visit(node.expression) as Expression; 407 | return node; 408 | } 409 | 410 | visitFunctionExpression(node: FunctionExpression): Node { 411 | node.declaration = this.visit(node.declaration) as FunctionDeclaration; 412 | return node; 413 | } 414 | 415 | visitLiteralExpression(node: LiteralExpression): LiteralExpression { 416 | switch (node.literalKind) { 417 | case LiteralKind.Array: { 418 | return this.visitArrayLiteralExpression( 419 | node 420 | ); 421 | } 422 | case LiteralKind.Float: { 423 | return this.visitFloatLiteralExpression( 424 | node 425 | ); 426 | } 427 | case LiteralKind.Integer: { 428 | return this.visitIntegerLiteralExpression( 429 | node 430 | ); 431 | } 432 | case LiteralKind.Object: { 433 | return this.visitObjectLiteralExpression( 434 | node 435 | ); 436 | } 437 | case LiteralKind.RegExp: { 438 | return this.visitRegexpLiteralExpression( 439 | node 440 | ); 441 | } 442 | case LiteralKind.String: { 443 | return this.visitStringLiteralExpression( 444 | node 445 | ); 446 | } 447 | case LiteralKind.Template: { 448 | return this.visitTemplateLiteralExpression( 449 | node 450 | ); 451 | } 452 | default: 453 | throw new Error( 454 | "Invalid LiteralKind: " + node.literalKind 455 | ); 456 | } 457 | } 458 | 459 | visitFloatLiteralExpression( 460 | node: FloatLiteralExpression 461 | ): FloatLiteralExpression { 462 | return node; 463 | } 464 | 465 | visitInstanceOfExpression( 466 | node: InstanceOfExpression 467 | ): InstanceOfExpression { 468 | node.expression = this.visit(node.expression) as Expression; 469 | node.isType = this.visit(node.isType) as TypeNode; 470 | return node; 471 | } 472 | 473 | visitIntegerLiteralExpression( 474 | node: IntegerLiteralExpression 475 | ): IntegerLiteralExpression { 476 | return node; 477 | } 478 | 479 | visitStringLiteral(str: string, singleQuoted = false): string { 480 | return str; 481 | } 482 | 483 | visitStringLiteralExpression( 484 | node: StringLiteralExpression 485 | ): StringLiteralExpression { 486 | node.value = this.visitStringLiteral(node.value); 487 | return node; 488 | } 489 | 490 | visitTemplateLiteralExpression( 491 | node: TemplateLiteralExpression 492 | ): TemplateLiteralExpression { 493 | return node; 494 | } 495 | 496 | visitRegexpLiteralExpression( 497 | node: RegexpLiteralExpression 498 | ): RegexpLiteralExpression { 499 | return node; 500 | } 501 | 502 | visitNewExpression(node: NewExpression): NewExpression { 503 | node.typeArguments = this.visit(node.typeArguments) as TypeNode[] | null; 504 | node.typeArguments = this.visit(node.typeArguments) as TypeNode[] | null; 505 | node.args = this.visit(node.args) as Expression[]; 506 | return node; 507 | } 508 | 509 | visitParenthesizedExpression( 510 | node: ParenthesizedExpression 511 | ): ParenthesizedExpression { 512 | node.expression = this.visit(node.expression) as Expression; 513 | return node; 514 | } 515 | 516 | visitPropertyAccessExpression( 517 | node: PropertyAccessExpression 518 | ): PropertyAccessExpression { 519 | node.property = this.visit(node.property) as IdentifierExpression; 520 | node.expression = this.visit(node.expression) as Expression; 521 | return node; 522 | } 523 | 524 | visitTernaryExpression(node: TernaryExpression): TernaryExpression { 525 | node.condition = this.visit(node.condition) as Expression; 526 | node.ifThen = this.visit(node.ifThen) as Expression; 527 | node.ifElse = this.visit(node.ifElse) as Expression; 528 | return node; 529 | } 530 | 531 | visitUnaryExpression(node: UnaryExpression): UnaryExpression { 532 | node.operand = this.visit(node.operand) as Expression; 533 | return node; 534 | } 535 | 536 | visitUnaryPostfixExpression( 537 | node: UnaryPostfixExpression 538 | ): UnaryPostfixExpression { 539 | node.operand = this.visit(node.operand) as Expression; 540 | return node; 541 | } 542 | 543 | visitUnaryPrefixExpression( 544 | node: UnaryPrefixExpression 545 | ): UnaryPrefixExpression { 546 | node.operand = this.visit(node.operand) as Expression; 547 | return node; 548 | } 549 | 550 | visitSuperExpression(node: SuperExpression): SuperExpression { 551 | return node; 552 | } 553 | 554 | visitFalseExpression(node: FalseExpression): FalseExpression { 555 | return node; 556 | } 557 | 558 | visitTrueExpression(node: TrueExpression): TrueExpression { 559 | return node; 560 | } 561 | 562 | visitThisExpression(node: ThisExpression): ThisExpression { 563 | return node; 564 | } 565 | 566 | visitNullExperssion(node: NullExpression): NullExpression { 567 | return node; 568 | } 569 | 570 | visitConstructorExpression( 571 | node: ConstructorExpression 572 | ): ConstructorExpression { 573 | return node; 574 | } 575 | 576 | visitNodeAndTerminate(node: Statement): Statement { 577 | return node; 578 | } 579 | 580 | visitBlockStatement(node: BlockStatement): BlockStatement { 581 | this.depth++; 582 | node.statements = this.visit(node.statements) as Statement[]; 583 | this.depth--; 584 | return node; 585 | } 586 | 587 | visitBreakStatement(node: BreakStatement): BreakStatement { 588 | node.label = this.visit(node.label) as IdentifierExpression | null; 589 | return node; 590 | } 591 | 592 | visitContinueStatement(node: ContinueStatement): ContinueStatement { 593 | node.label = this.visit(node.label) as IdentifierExpression | null; 594 | return node; 595 | } 596 | 597 | visitClassDeclaration( 598 | node: ClassDeclaration, 599 | isDefault = false 600 | ): ClassDeclaration { 601 | node.name = this.visit(node.name) as IdentifierExpression; 602 | node.decorators = this.visit(node.decorators) as DecoratorNode[] | null; 603 | node.typeParameters = this.visit( 604 | node.typeParameters 605 | ) as TypeParameterNode[]; 606 | node.extendsType = this.visit(node.extendsType) as NamedTypeNode; 607 | node.implementsTypes = this.visit(node.implementsTypes) as NamedTypeNode[] | null; 608 | this.depth++; 609 | node.members = this.visit(node.members) as DeclarationStatement[]; 610 | this.depth--; 611 | return node; 612 | } 613 | 614 | visitDoStatement(node: DoStatement): DoStatement { 615 | node.condition = this.visit(node.condition) as Expression; 616 | node.body = this.visit(node.body) as Statement; 617 | return node; 618 | } 619 | 620 | visitEmptyStatement(node: EmptyStatement): EmptyStatement { 621 | return node; 622 | } 623 | 624 | visitEnumDeclaration( 625 | node: EnumDeclaration, 626 | isDefault = false 627 | ): EnumDeclaration { 628 | node.name = this.visit(node.name) as IdentifierExpression; 629 | node.decorators = this.visit(node.decorators) as DecoratorNode[] | null; 630 | node.values = this.visit(node.values) as EnumValueDeclaration[]; 631 | return node; 632 | } 633 | 634 | visitEnumValueDeclaration( 635 | node: EnumValueDeclaration 636 | ): EnumValueDeclaration { 637 | node.name = this.visit(node.name) as IdentifierExpression; 638 | node.initializer = this.visit(node.initializer) as Expression; 639 | return node; 640 | } 641 | 642 | visitExportImportStatement( 643 | node: ExportImportStatement 644 | ): ExportImportStatement { 645 | node.name = this.visit(node.name) as IdentifierExpression; 646 | node.externalName = this.visit( 647 | node.externalName 648 | ) as IdentifierExpression; 649 | return node; 650 | } 651 | 652 | visitExportMember(node: ExportMember): ExportMember { 653 | node.localName = this.visit(node.localName) as IdentifierExpression; 654 | node.exportedName = this.visit( 655 | node.exportedName 656 | ) as IdentifierExpression; 657 | return node; 658 | } 659 | 660 | visitExportStatement(node: ExportStatement): ExportStatement { 661 | node.path = this.visit(node.path) as StringLiteralExpression; 662 | node.members = this.visit(node.members) as ExportMember[]; 663 | return node; 664 | } 665 | 666 | visitExportDefaultStatement( 667 | node: ExportDefaultStatement 668 | ): ExportDefaultStatement { 669 | node.declaration = this.visit(node.declaration) as DeclarationStatement; 670 | return node; 671 | } 672 | 673 | visitExpressionStatement(node: ExpressionStatement): ExpressionStatement { 674 | node.expression = this.visit(node.expression) as Expression; 675 | return node; 676 | } 677 | 678 | visitFieldDeclaration(node: FieldDeclaration): FieldDeclaration { 679 | node.name = this.visit(node.name) as IdentifierExpression; 680 | node.type = this.visit(node.type) as TypeNode; 681 | node.initializer = this.visit(node.initializer) as Expression; 682 | node.decorators = this.visit(node.decorators) as DecoratorNode[] | null; 683 | return node; 684 | } 685 | 686 | visitForStatement(node: ForStatement): ForStatement { 687 | node.initializer = this.visit(node.initializer) as Statement; 688 | node.condition = this.visit(node.condition) as Expression; 689 | node.incrementor = this.visit(node.incrementor) as Expression; 690 | node.body = this.visit(node.body) as Statement; 691 | return node; 692 | } 693 | 694 | visitFunctionDeclaration( 695 | node: FunctionDeclaration, 696 | isDefault = false 697 | ): FunctionDeclaration { 698 | node.name = this.visit(node.name) as IdentifierExpression; 699 | node.decorators = this.visit(node.decorators) as DecoratorNode[] | null; 700 | node.typeParameters = this.visit( 701 | node.typeParameters 702 | ) as TypeParameterNode[]; 703 | node.signature = this.visit(node.signature) as FunctionTypeNode; 704 | this.depth++; 705 | node.body = this.visit(node.body) as Statement; 706 | this.depth--; 707 | return node; 708 | } 709 | 710 | visitIfStatement(node: IfStatement): IfStatement { 711 | node.condition = this.visit(node.condition) as Expression; 712 | node.ifTrue = this.visit(node.ifTrue) as Statement; 713 | node.ifFalse = this.visit(node.ifFalse) as Statement | null; 714 | return node; 715 | } 716 | 717 | visitImportDeclaration(node: ImportDeclaration): ImportDeclaration { 718 | node.foreignName = this.visit(node.foreignName) as IdentifierExpression; 719 | node.name = this.visit(node.name) as IdentifierExpression; 720 | node.decorators = this.visit(node.decorators) as DecoratorNode[] | null; 721 | return node; 722 | } 723 | 724 | visitImportStatement(node: ImportStatement): ImportStatement { 725 | node.namespaceName = this.visit(node.namespaceName) as IdentifierExpression | null; 726 | node.declarations = this.visit(node.declarations) as ImportDeclaration[] | null; 727 | return node; 728 | } 729 | 730 | visitIndexSignature(node: IndexSignatureNode): IndexSignatureNode { 731 | node.keyType = this.visit(node.keyType) as NamedTypeNode; 732 | node.valueType = this.visit(node.valueType) as TypeNode; 733 | return node; 734 | } 735 | 736 | visitInterfaceDeclaration( 737 | node: InterfaceDeclaration, 738 | isDefault = false 739 | ): InterfaceDeclaration { 740 | node.name = this.visit(node.name) as IdentifierExpression; 741 | node.decorators = this.visit(node.decorators) as DecoratorNode[] | null; 742 | node.typeParameters = this.visit(node.typeParameters) as TypeParameterNode[] | null; 743 | node.implementsTypes = this.visit(node.implementsTypes) as NamedTypeNode[] | null; 744 | node.extendsType = this.visit(node.extendsType) as NamedTypeNode | null; 745 | this.depth++; 746 | node.members = this.visit(node.members) as DeclarationStatement[]; 747 | this.depth--; 748 | return node; 749 | } 750 | 751 | visitMethodDeclaration(node: MethodDeclaration): MethodDeclaration { 752 | node.name = this.visit(node.name) as IdentifierExpression; 753 | node.typeParameters = this.visit(node.typeParameters)as TypeParameterNode[] | null; 754 | node.signature = this.visit(node.signature) as FunctionTypeNode; 755 | node.decorators = this.visit(node.decorators) as DecoratorNode[] | null; 756 | this.depth++; 757 | node.body = this.visit(node.body) as Statement| null; 758 | this.depth--; 759 | return node; 760 | } 761 | 762 | visitNamespaceDeclaration( 763 | node: NamespaceDeclaration, 764 | isDefault = false 765 | ): NamespaceDeclaration { 766 | node.name = this.visit(node.name) as IdentifierExpression; 767 | node.decorators = this.visit(node.decorators) as DecoratorNode[] | null; 768 | node.members = this.visit(node.members) as Statement[]; 769 | return node; 770 | } 771 | 772 | visitReturnStatement(node: ReturnStatement): ReturnStatement { 773 | node.value = this.visit(node.value) as Expression |null; 774 | return node; 775 | } 776 | 777 | visitSwitchCase(node: SwitchCase): SwitchCase { 778 | node.label = this.visit(node.label) as Expression |null; 779 | node.statements = this.visit(node.statements) as Statement[]; 780 | return node; 781 | } 782 | 783 | visitSwitchStatement(node: SwitchStatement): SwitchStatement { 784 | node.condition = this.visit(node.condition) as Expression; 785 | this.depth++; 786 | node.cases = this.visit(node.cases) as SwitchCase[]; 787 | this.depth--; 788 | return node; 789 | } 790 | 791 | visitThrowStatement(node: ThrowStatement): ThrowStatement { 792 | node.value = this.visit(node.value) as Expression; 793 | return node; 794 | } 795 | 796 | visitTryStatement(node: TryStatement): TryStatement { 797 | node.bodyStatements = this.visit(node.bodyStatements) as Statement[]; 798 | node.catchVariable = this.visit(node.catchVariable) as IdentifierExpression | null; 799 | node.catchStatements = this.visit(node.catchStatements) as Statement[]; 800 | node.finallyStatements = this.visit( 801 | node.finallyStatements 802 | ) as Statement[]; 803 | return node; 804 | } 805 | 806 | visitTypeDeclaration(node: TypeDeclaration): TypeDeclaration { 807 | node.name = this.visit(node.name) as IdentifierExpression; 808 | node.decorators = this.visit(node.decorators) as DecoratorNode[] | null; 809 | node.type = this.visit(node.type) as TypeNode; 810 | node.typeParameters = this.visit( 811 | node.typeParameters 812 | ) as TypeParameterNode[]; 813 | return node; 814 | } 815 | 816 | visitVariableDeclaration(node: VariableDeclaration): VariableDeclaration { 817 | node.name = this.visit(node.name) as IdentifierExpression; 818 | node.decorators = this.visit(node.decorators) as DecoratorNode[] | null; 819 | node.type = this.visit(node.type) as TypeNode | null; 820 | node.initializer = this.visit(node.initializer) as Expression | null; 821 | return node; 822 | } 823 | 824 | visitVariableStatement(node: VariableStatement): VariableStatement { 825 | node.decorators = this.visit(node.decorators) as DecoratorNode[] | null; 826 | node.declarations = this.visit( 827 | node.declarations 828 | ) as VariableDeclaration[]; 829 | return node; 830 | } 831 | 832 | visitWhileStatement(node: WhileStatement): WhileStatement { 833 | node.condition = this.visit(node.condition) as Expression; 834 | this.depth++; 835 | node.body = this.visit(node.body) as Statement; 836 | this.depth--; 837 | return node; 838 | } 839 | 840 | visitVoidStatement(node: VoidStatement): VoidStatement { 841 | return node; 842 | } 843 | 844 | visitComment(node: CommentNode): CommentNode { 845 | return node; 846 | } 847 | 848 | visitDecoratorNode(node: DecoratorNode): DecoratorNode { 849 | node.name = this.visit(node.name) as IdentifierExpression; 850 | node.args = this.visit(node.args) as Expression[]; 851 | return node; 852 | } 853 | 854 | visitParameter(node: ParameterNode): ParameterNode { 855 | node.name = this.visit(node.name) as IdentifierExpression; 856 | node.implicitFieldDeclaration = this.visit( 857 | node.implicitFieldDeclaration 858 | ) as FieldDeclaration | null; 859 | node.initializer = this.visit(node.initializer) as Expression | null; 860 | node.type = this.visit(node.type) as TypeNode; 861 | return node; 862 | } 863 | } 864 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@assemblyscript/loader@^0.25.0": 6 | "integrity" "sha512-y73avi0tPwy/fkmHgcDDBtsvtKInFZE9hEFkgUNcohjH/us8nbQk+aDt/73U9jjRdMQcex9Oaa+Ra0kLJ329Gg==" 7 | "resolved" "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.25.0.tgz" 8 | "version" "0.25.0" 9 | 10 | "@cspotcode/source-map-support@^0.8.0": 11 | "integrity" "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==" 12 | "resolved" "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz" 13 | "version" "0.8.1" 14 | dependencies: 15 | "@jridgewell/trace-mapping" "0.3.9" 16 | 17 | "@jridgewell/resolve-uri@^3.0.3": 18 | "integrity" "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" 19 | "resolved" "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" 20 | "version" "3.1.0" 21 | 22 | "@jridgewell/sourcemap-codec@^1.4.10": 23 | "integrity" "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" 24 | "resolved" "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" 25 | "version" "1.4.14" 26 | 27 | "@jridgewell/trace-mapping@0.3.9": 28 | "integrity" "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==" 29 | "resolved" "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" 30 | "version" "0.3.9" 31 | dependencies: 32 | "@jridgewell/resolve-uri" "^3.0.3" 33 | "@jridgewell/sourcemap-codec" "^1.4.10" 34 | 35 | "@tsconfig/node10@^1.0.7": 36 | "integrity" "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" 37 | "resolved" "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz" 38 | "version" "1.0.8" 39 | 40 | "@tsconfig/node12@^1.0.7": 41 | "integrity" "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" 42 | "resolved" "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz" 43 | "version" "1.0.9" 44 | 45 | "@tsconfig/node14@^1.0.0": 46 | "integrity" "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" 47 | "resolved" "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz" 48 | "version" "1.0.1" 49 | 50 | "@tsconfig/node16@^1.0.2": 51 | "integrity" "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" 52 | "resolved" "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz" 53 | "version" "1.0.3" 54 | 55 | "@types/lodash.clonedeep@^4.5.7": 56 | "integrity" "sha512-ccNqkPptFIXrpVqUECi60/DFxjNKsfoQxSQsgcBJCX/fuX1wgyQieojkcWH/KpE3xzLoWN/2k+ZeGqIN3paSvw==" 57 | "resolved" "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.7.tgz" 58 | "version" "4.5.7" 59 | dependencies: 60 | "@types/lodash" "*" 61 | 62 | "@types/lodash@*": 63 | "integrity" "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==" 64 | "resolved" "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz" 65 | "version" "4.14.182" 66 | 67 | "@types/node@*", "@types/node@^18.11.13": 68 | "integrity" "sha512-IASpMGVcWpUsx5xBOrxMj7Bl8lqfuTY7FKAnPmu5cHkfQVWF8GulWS1jbRqA934qZL35xh5xN/+Xe/i26Bod4w==" 69 | "resolved" "https://registry.npmjs.org/@types/node/-/node-18.11.13.tgz" 70 | "version" "18.11.13" 71 | 72 | "acorn-walk@^8.1.1": 73 | "integrity" "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" 74 | "resolved" "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" 75 | "version" "8.2.0" 76 | 77 | "acorn@^8.4.1": 78 | "integrity" "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" 79 | "resolved" "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz" 80 | "version" "8.8.0" 81 | 82 | "ansi-colors@4.1.1": 83 | "integrity" "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" 84 | "resolved" "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" 85 | "version" "4.1.1" 86 | 87 | "ansi-regex@^5.0.0": 88 | "integrity" "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" 89 | "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz" 90 | "version" "5.0.0" 91 | 92 | "ansi-styles@^4.0.0", "ansi-styles@^4.1.0": 93 | "integrity" "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==" 94 | "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" 95 | "version" "4.3.0" 96 | dependencies: 97 | "color-convert" "^2.0.1" 98 | 99 | "anymatch@~3.1.2": 100 | "integrity" "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==" 101 | "resolved" "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" 102 | "version" "3.1.2" 103 | dependencies: 104 | "normalize-path" "^3.0.0" 105 | "picomatch" "^2.0.4" 106 | 107 | "arg@^4.1.0": 108 | "integrity" "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 109 | "resolved" "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" 110 | "version" "4.1.3" 111 | 112 | "argparse@^2.0.1": 113 | "integrity" "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" 114 | "resolved" "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" 115 | "version" "2.0.1" 116 | 117 | "assemblyscript@^0.25.0": 118 | "integrity" "sha512-amIamciuS/sk8a9Ou2PLKyHExIZZIU31mVPEoEISNGJS4ptxbNx27TaQHXrngaW2/AGkpNljWkkzlXUO5K+RHg==" 119 | "resolved" "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.25.0.tgz" 120 | "version" "0.25.0" 121 | dependencies: 122 | "binaryen" "110.0.0-nightly.20221105" 123 | "long" "^5.2.0" 124 | 125 | "assertion-error@^1.1.0": 126 | "integrity" "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" 127 | "resolved" "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" 128 | "version" "1.1.0" 129 | 130 | "balanced-match@^1.0.0": 131 | "integrity" "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 132 | "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" 133 | "version" "1.0.2" 134 | 135 | "binary-extensions@^2.0.0": 136 | "integrity" "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" 137 | "resolved" "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" 138 | "version" "2.2.0" 139 | 140 | "binaryen@110.0.0-nightly.20221105": 141 | "integrity" "sha512-OBESOc51q3SwgG8Uv8nMzGnSq7LJpSB/Fu8B3AjlZg6YtCEwRnlDWlnwNB6mdql+VdexfKmNcsrs4K7MYidmdQ==" 142 | "resolved" "https://registry.npmjs.org/binaryen/-/binaryen-110.0.0-nightly.20221105.tgz" 143 | "version" "110.0.0-nightly.20221105" 144 | 145 | "brace-expansion@^1.1.7": 146 | "integrity" "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==" 147 | "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" 148 | "version" "1.1.11" 149 | dependencies: 150 | "balanced-match" "^1.0.0" 151 | "concat-map" "0.0.1" 152 | 153 | "brace-expansion@^2.0.1": 154 | "integrity" "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==" 155 | "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" 156 | "version" "2.0.1" 157 | dependencies: 158 | "balanced-match" "^1.0.0" 159 | 160 | "braces@~3.0.2": 161 | "integrity" "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==" 162 | "resolved" "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" 163 | "version" "3.0.2" 164 | dependencies: 165 | "fill-range" "^7.0.1" 166 | 167 | "browser-stdout@1.3.1": 168 | "integrity" "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" 169 | "resolved" "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" 170 | "version" "1.3.1" 171 | 172 | "camelcase@^6.0.0": 173 | "integrity" "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" 174 | "resolved" "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" 175 | "version" "6.3.0" 176 | 177 | "chai@^4.3.7": 178 | "integrity" "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==" 179 | "resolved" "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz" 180 | "version" "4.3.7" 181 | dependencies: 182 | "assertion-error" "^1.1.0" 183 | "check-error" "^1.0.2" 184 | "deep-eql" "^4.1.2" 185 | "get-func-name" "^2.0.0" 186 | "loupe" "^2.3.1" 187 | "pathval" "^1.1.1" 188 | "type-detect" "^4.0.5" 189 | 190 | "chalk@^4.1.0": 191 | "integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==" 192 | "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" 193 | "version" "4.1.2" 194 | dependencies: 195 | "ansi-styles" "^4.1.0" 196 | "supports-color" "^7.1.0" 197 | 198 | "check-error@^1.0.2": 199 | "integrity" "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==" 200 | "resolved" "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz" 201 | "version" "1.0.2" 202 | 203 | "chokidar@3.5.3": 204 | "integrity" "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==" 205 | "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" 206 | "version" "3.5.3" 207 | dependencies: 208 | "anymatch" "~3.1.2" 209 | "braces" "~3.0.2" 210 | "glob-parent" "~5.1.2" 211 | "is-binary-path" "~2.1.0" 212 | "is-glob" "~4.0.1" 213 | "normalize-path" "~3.0.0" 214 | "readdirp" "~3.6.0" 215 | optionalDependencies: 216 | "fsevents" "~2.3.2" 217 | 218 | "cliui@^7.0.2": 219 | "integrity" "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==" 220 | "resolved" "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" 221 | "version" "7.0.4" 222 | dependencies: 223 | "string-width" "^4.2.0" 224 | "strip-ansi" "^6.0.0" 225 | "wrap-ansi" "^7.0.0" 226 | 227 | "color-convert@^2.0.1": 228 | "integrity" "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==" 229 | "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" 230 | "version" "2.0.1" 231 | dependencies: 232 | "color-name" "~1.1.4" 233 | 234 | "color-name@~1.1.4": 235 | "integrity" "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 236 | "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" 237 | "version" "1.1.4" 238 | 239 | "concat-map@0.0.1": 240 | "integrity" "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" 241 | "resolved" "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" 242 | "version" "0.0.1" 243 | 244 | "create-require@^1.1.0": 245 | "integrity" "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" 246 | "resolved" "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" 247 | "version" "1.1.1" 248 | 249 | "debug@4.3.4": 250 | "integrity" "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==" 251 | "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" 252 | "version" "4.3.4" 253 | dependencies: 254 | "ms" "2.1.2" 255 | 256 | "decamelize@^4.0.0": 257 | "integrity" "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==" 258 | "resolved" "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" 259 | "version" "4.0.0" 260 | 261 | "deep-eql@^4.1.2": 262 | "integrity" "sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w==" 263 | "resolved" "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.2.tgz" 264 | "version" "4.1.2" 265 | dependencies: 266 | "type-detect" "^4.0.0" 267 | 268 | "diff@^4.0.1": 269 | "integrity" "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 270 | "resolved" "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" 271 | "version" "4.0.2" 272 | 273 | "diff@5.0.0": 274 | "integrity" "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==" 275 | "resolved" "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" 276 | "version" "5.0.0" 277 | 278 | "emoji-regex@^8.0.0": 279 | "integrity" "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 280 | "resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" 281 | "version" "8.0.0" 282 | 283 | "escalade@^3.1.1": 284 | "integrity" "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" 285 | "resolved" "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" 286 | "version" "3.1.1" 287 | 288 | "escape-string-regexp@4.0.0": 289 | "integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" 290 | "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" 291 | "version" "4.0.0" 292 | 293 | "fill-range@^7.0.1": 294 | "integrity" "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==" 295 | "resolved" "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" 296 | "version" "7.0.1" 297 | dependencies: 298 | "to-regex-range" "^5.0.1" 299 | 300 | "find-up@5.0.0": 301 | "integrity" "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==" 302 | "resolved" "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" 303 | "version" "5.0.0" 304 | dependencies: 305 | "locate-path" "^6.0.0" 306 | "path-exists" "^4.0.0" 307 | 308 | "flat@^5.0.2": 309 | "integrity" "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" 310 | "resolved" "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" 311 | "version" "5.0.2" 312 | 313 | "fs.realpath@^1.0.0": 314 | "integrity" "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" 315 | "resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" 316 | "version" "1.0.0" 317 | 318 | "get-caller-file@^2.0.5": 319 | "integrity" "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" 320 | "resolved" "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" 321 | "version" "2.0.5" 322 | 323 | "get-func-name@^2.0.0": 324 | "integrity" "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==" 325 | "resolved" "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz" 326 | "version" "2.0.0" 327 | 328 | "glob-parent@~5.1.2": 329 | "integrity" "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==" 330 | "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" 331 | "version" "5.1.2" 332 | dependencies: 333 | "is-glob" "^4.0.1" 334 | 335 | "glob@^7.1.3", "glob@7.2.0": 336 | "integrity" "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==" 337 | "resolved" "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" 338 | "version" "7.2.0" 339 | dependencies: 340 | "fs.realpath" "^1.0.0" 341 | "inflight" "^1.0.4" 342 | "inherits" "2" 343 | "minimatch" "^3.0.4" 344 | "once" "^1.3.0" 345 | "path-is-absolute" "^1.0.0" 346 | 347 | "has-flag@^4.0.0": 348 | "integrity" "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" 349 | "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" 350 | "version" "4.0.0" 351 | 352 | "he@1.2.0": 353 | "integrity" "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" 354 | "resolved" "https://registry.npmjs.org/he/-/he-1.2.0.tgz" 355 | "version" "1.2.0" 356 | 357 | "inflight@^1.0.4": 358 | "integrity" "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==" 359 | "resolved" "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" 360 | "version" "1.0.6" 361 | dependencies: 362 | "once" "^1.3.0" 363 | "wrappy" "1" 364 | 365 | "inherits@2": 366 | "integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 367 | "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" 368 | "version" "2.0.4" 369 | 370 | "is-binary-path@~2.1.0": 371 | "integrity" "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==" 372 | "resolved" "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" 373 | "version" "2.1.0" 374 | dependencies: 375 | "binary-extensions" "^2.0.0" 376 | 377 | "is-extglob@^2.1.1": 378 | "integrity" "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" 379 | "resolved" "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" 380 | "version" "2.1.1" 381 | 382 | "is-fullwidth-code-point@^3.0.0": 383 | "integrity" "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" 384 | "resolved" "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" 385 | "version" "3.0.0" 386 | 387 | "is-glob@^4.0.1", "is-glob@~4.0.1": 388 | "integrity" "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==" 389 | "resolved" "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" 390 | "version" "4.0.3" 391 | dependencies: 392 | "is-extglob" "^2.1.1" 393 | 394 | "is-number@^7.0.0": 395 | "integrity" "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" 396 | "resolved" "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" 397 | "version" "7.0.0" 398 | 399 | "is-plain-obj@^2.1.0": 400 | "integrity" "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" 401 | "resolved" "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" 402 | "version" "2.1.0" 403 | 404 | "is-unicode-supported@^0.1.0": 405 | "integrity" "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" 406 | "resolved" "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" 407 | "version" "0.1.0" 408 | 409 | "js-yaml@4.1.0": 410 | "integrity" "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==" 411 | "resolved" "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" 412 | "version" "4.1.0" 413 | dependencies: 414 | "argparse" "^2.0.1" 415 | 416 | "locate-path@^6.0.0": 417 | "integrity" "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==" 418 | "resolved" "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" 419 | "version" "6.0.0" 420 | dependencies: 421 | "p-locate" "^5.0.0" 422 | 423 | "lodash.clonedeep@^4.5.0": 424 | "integrity" "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" 425 | "resolved" "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz" 426 | "version" "4.5.0" 427 | 428 | "log-symbols@4.1.0": 429 | "integrity" "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==" 430 | "resolved" "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" 431 | "version" "4.1.0" 432 | dependencies: 433 | "chalk" "^4.1.0" 434 | "is-unicode-supported" "^0.1.0" 435 | 436 | "long@^5.2.0": 437 | "integrity" "sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w==" 438 | "resolved" "https://registry.npmjs.org/long/-/long-5.2.0.tgz" 439 | "version" "5.2.0" 440 | 441 | "loupe@^2.3.1": 442 | "integrity" "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==" 443 | "resolved" "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz" 444 | "version" "2.3.4" 445 | dependencies: 446 | "get-func-name" "^2.0.0" 447 | 448 | "make-error@^1.1.1": 449 | "integrity" "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 450 | "resolved" "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" 451 | "version" "1.3.6" 452 | 453 | "minimatch@^3.0.4": 454 | "integrity" "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==" 455 | "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" 456 | "version" "3.0.4" 457 | dependencies: 458 | "brace-expansion" "^1.1.7" 459 | 460 | "minimatch@5.0.1": 461 | "integrity" "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==" 462 | "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz" 463 | "version" "5.0.1" 464 | dependencies: 465 | "brace-expansion" "^2.0.1" 466 | 467 | "mocha@^10.2.0": 468 | "integrity" "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==" 469 | "resolved" "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz" 470 | "version" "10.2.0" 471 | dependencies: 472 | "ansi-colors" "4.1.1" 473 | "browser-stdout" "1.3.1" 474 | "chokidar" "3.5.3" 475 | "debug" "4.3.4" 476 | "diff" "5.0.0" 477 | "escape-string-regexp" "4.0.0" 478 | "find-up" "5.0.0" 479 | "glob" "7.2.0" 480 | "he" "1.2.0" 481 | "js-yaml" "4.1.0" 482 | "log-symbols" "4.1.0" 483 | "minimatch" "5.0.1" 484 | "ms" "2.1.3" 485 | "nanoid" "3.3.3" 486 | "serialize-javascript" "6.0.0" 487 | "strip-json-comments" "3.1.1" 488 | "supports-color" "8.1.1" 489 | "workerpool" "6.2.1" 490 | "yargs" "16.2.0" 491 | "yargs-parser" "20.2.4" 492 | "yargs-unparser" "2.0.0" 493 | 494 | "ms@2.1.2": 495 | "integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 496 | "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" 497 | "version" "2.1.2" 498 | 499 | "ms@2.1.3": 500 | "integrity" "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 501 | "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" 502 | "version" "2.1.3" 503 | 504 | "nanoid@3.3.3": 505 | "integrity" "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==" 506 | "resolved" "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz" 507 | "version" "3.3.3" 508 | 509 | "normalize-path@^3.0.0", "normalize-path@~3.0.0": 510 | "integrity" "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" 511 | "resolved" "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" 512 | "version" "3.0.0" 513 | 514 | "once@^1.3.0": 515 | "integrity" "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==" 516 | "resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz" 517 | "version" "1.4.0" 518 | dependencies: 519 | "wrappy" "1" 520 | 521 | "p-limit@^3.0.2": 522 | "integrity" "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==" 523 | "resolved" "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" 524 | "version" "3.1.0" 525 | dependencies: 526 | "yocto-queue" "^0.1.0" 527 | 528 | "p-locate@^5.0.0": 529 | "integrity" "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==" 530 | "resolved" "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" 531 | "version" "5.0.0" 532 | dependencies: 533 | "p-limit" "^3.0.2" 534 | 535 | "path-exists@^4.0.0": 536 | "integrity" "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" 537 | "resolved" "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" 538 | "version" "4.0.0" 539 | 540 | "path-is-absolute@^1.0.0": 541 | "integrity" "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" 542 | "resolved" "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" 543 | "version" "1.0.1" 544 | 545 | "pathval@^1.1.1": 546 | "integrity" "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==" 547 | "resolved" "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" 548 | "version" "1.1.1" 549 | 550 | "picomatch@^2.0.4", "picomatch@^2.2.1": 551 | "integrity" "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" 552 | "resolved" "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz" 553 | "version" "2.3.0" 554 | 555 | "prettier@^2.8.1": 556 | "integrity" "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==" 557 | "resolved" "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz" 558 | "version" "2.8.1" 559 | 560 | "randombytes@^2.1.0": 561 | "integrity" "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==" 562 | "resolved" "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" 563 | "version" "2.1.0" 564 | dependencies: 565 | "safe-buffer" "^5.1.0" 566 | 567 | "readdirp@~3.6.0": 568 | "integrity" "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==" 569 | "resolved" "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" 570 | "version" "3.6.0" 571 | dependencies: 572 | "picomatch" "^2.2.1" 573 | 574 | "require-directory@^2.1.1": 575 | "integrity" "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" 576 | "resolved" "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" 577 | "version" "2.1.1" 578 | 579 | "rimraf@^3.0.2": 580 | "integrity" "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==" 581 | "resolved" "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" 582 | "version" "3.0.2" 583 | dependencies: 584 | "glob" "^7.1.3" 585 | 586 | "safe-buffer@^5.1.0": 587 | "integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 588 | "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" 589 | "version" "5.2.1" 590 | 591 | "serialize-javascript@6.0.0": 592 | "integrity" "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==" 593 | "resolved" "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" 594 | "version" "6.0.0" 595 | dependencies: 596 | "randombytes" "^2.1.0" 597 | 598 | "string-width@^4.1.0", "string-width@^4.2.0": 599 | "integrity" "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==" 600 | "resolved" "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz" 601 | "version" "4.2.2" 602 | dependencies: 603 | "emoji-regex" "^8.0.0" 604 | "is-fullwidth-code-point" "^3.0.0" 605 | "strip-ansi" "^6.0.0" 606 | 607 | "strip-ansi@^6.0.0": 608 | "integrity" "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==" 609 | "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz" 610 | "version" "6.0.0" 611 | dependencies: 612 | "ansi-regex" "^5.0.0" 613 | 614 | "strip-json-comments@3.1.1": 615 | "integrity" "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" 616 | "resolved" "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" 617 | "version" "3.1.1" 618 | 619 | "supports-color@^7.1.0": 620 | "integrity" "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==" 621 | "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" 622 | "version" "7.2.0" 623 | dependencies: 624 | "has-flag" "^4.0.0" 625 | 626 | "supports-color@8.1.1": 627 | "integrity" "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==" 628 | "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" 629 | "version" "8.1.1" 630 | dependencies: 631 | "has-flag" "^4.0.0" 632 | 633 | "to-regex-range@^5.0.1": 634 | "integrity" "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==" 635 | "resolved" "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" 636 | "version" "5.0.1" 637 | dependencies: 638 | "is-number" "^7.0.0" 639 | 640 | "ts-mixer@^6.0.2": 641 | "integrity" "sha512-zvHx3VM83m2WYCE8XL99uaM7mFwYSkjR2OZti98fabHrwkjsCvgwChda5xctein3xGOyaQhtTeDq/1H/GNvF3A==" 642 | "resolved" "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.2.tgz" 643 | "version" "6.0.2" 644 | 645 | "ts-node@^10.9.1": 646 | "integrity" "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==" 647 | "resolved" "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" 648 | "version" "10.9.1" 649 | dependencies: 650 | "@cspotcode/source-map-support" "^0.8.0" 651 | "@tsconfig/node10" "^1.0.7" 652 | "@tsconfig/node12" "^1.0.7" 653 | "@tsconfig/node14" "^1.0.0" 654 | "@tsconfig/node16" "^1.0.2" 655 | "acorn" "^8.4.1" 656 | "acorn-walk" "^8.1.1" 657 | "arg" "^4.1.0" 658 | "create-require" "^1.1.0" 659 | "diff" "^4.0.1" 660 | "make-error" "^1.1.1" 661 | "v8-compile-cache-lib" "^3.0.1" 662 | "yn" "3.1.1" 663 | 664 | "type-detect@^4.0.0", "type-detect@^4.0.5": 665 | "integrity" "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" 666 | "resolved" "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" 667 | "version" "4.0.8" 668 | 669 | "typescript@^4.9.4", "typescript@>=2.7": 670 | "integrity" "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==" 671 | "resolved" "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz" 672 | "version" "4.9.4" 673 | 674 | "v8-compile-cache-lib@^3.0.1": 675 | "integrity" "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" 676 | "resolved" "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" 677 | "version" "3.0.1" 678 | 679 | "workerpool@6.2.1": 680 | "integrity" "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==" 681 | "resolved" "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz" 682 | "version" "6.2.1" 683 | 684 | "wrap-ansi@^7.0.0": 685 | "integrity" "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==" 686 | "resolved" "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" 687 | "version" "7.0.0" 688 | dependencies: 689 | "ansi-styles" "^4.0.0" 690 | "string-width" "^4.1.0" 691 | "strip-ansi" "^6.0.0" 692 | 693 | "wrappy@1": 694 | "integrity" "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 695 | "resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" 696 | "version" "1.0.2" 697 | 698 | "y18n@^5.0.5": 699 | "integrity" "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" 700 | "resolved" "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" 701 | "version" "5.0.8" 702 | 703 | "yargs-parser@^20.2.2", "yargs-parser@20.2.4": 704 | "integrity" "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" 705 | "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" 706 | "version" "20.2.4" 707 | 708 | "yargs-unparser@2.0.0": 709 | "integrity" "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==" 710 | "resolved" "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" 711 | "version" "2.0.0" 712 | dependencies: 713 | "camelcase" "^6.0.0" 714 | "decamelize" "^4.0.0" 715 | "flat" "^5.0.2" 716 | "is-plain-obj" "^2.1.0" 717 | 718 | "yargs@16.2.0": 719 | "integrity" "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==" 720 | "resolved" "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" 721 | "version" "16.2.0" 722 | dependencies: 723 | "cliui" "^7.0.2" 724 | "escalade" "^3.1.1" 725 | "get-caller-file" "^2.0.5" 726 | "require-directory" "^2.1.1" 727 | "string-width" "^4.2.0" 728 | "y18n" "^5.0.5" 729 | "yargs-parser" "^20.2.2" 730 | 731 | "yn@3.1.1": 732 | "integrity" "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" 733 | "resolved" "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" 734 | "version" "3.1.1" 735 | 736 | "yocto-queue@^0.1.0": 737 | "integrity" "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" 738 | "resolved" "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" 739 | "version" "0.1.0" 740 | -------------------------------------------------------------------------------- /src/astBuilder.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable: as-internal-case 2 | 3 | import { 4 | CommonFlags, 5 | TypeNode, 6 | Node, 7 | NodeKind, 8 | Source, 9 | NamedTypeNode, 10 | FunctionTypeNode, 11 | TypeParameterNode, 12 | IdentifierExpression, 13 | CallExpression, 14 | ClassExpression, 15 | ElementAccessExpression, 16 | FunctionExpression, 17 | InstanceOfExpression, 18 | LiteralExpression, 19 | NewExpression, 20 | ParenthesizedExpression, 21 | PropertyAccessExpression, 22 | TernaryExpression, 23 | UnaryPostfixExpression, 24 | UnaryPrefixExpression, 25 | BlockStatement, 26 | BreakStatement, 27 | ContinueStatement, 28 | DoStatement, 29 | EmptyStatement, 30 | ExportStatement, 31 | ExportDefaultStatement, 32 | ExportImportStatement, 33 | ExpressionStatement, 34 | ForStatement, 35 | IfStatement, 36 | ImportStatement, 37 | ReturnStatement, 38 | SwitchStatement, 39 | ThrowStatement, 40 | TryStatement, 41 | VariableStatement, 42 | WhileStatement, 43 | ClassDeclaration, 44 | EnumDeclaration, 45 | EnumValueDeclaration, 46 | FieldDeclaration, 47 | FunctionDeclaration, 48 | ImportDeclaration, 49 | InterfaceDeclaration, 50 | MethodDeclaration, 51 | NamespaceDeclaration, 52 | TypeDeclaration, 53 | VariableDeclaration, 54 | DecoratorNode, 55 | ExportMember, 56 | ParameterNode, 57 | SwitchCase, 58 | TypeName, 59 | ArrayLiteralExpression, 60 | Expression, 61 | ObjectLiteralExpression, 62 | AssertionKind, 63 | LiteralKind, 64 | FloatLiteralExpression, 65 | StringLiteralExpression, 66 | RegexpLiteralExpression, 67 | UnaryExpression, 68 | ArrowKind, 69 | ParameterKind, 70 | DeclarationStatement, 71 | AssertionExpression, 72 | BinaryExpression, 73 | CommaExpression, 74 | IntegerLiteralExpression, 75 | isTypeOmitted, 76 | operatorTokenToString, 77 | ForOfStatement, 78 | IndexSignatureNode, 79 | TemplateLiteralExpression, 80 | util, 81 | } from "assemblyscript/dist/assemblyscript.js"; 82 | import { BaseVisitor } from "./base.js"; 83 | import { indent } from "./utils.js"; 84 | 85 | // declare function i64_to_string(i: I64): string; 86 | // import { i64_to_string } from "../../../src/glue/i64" 87 | 88 | /** An AST builder. */ 89 | export class ASTBuilder extends BaseVisitor { 90 | _visit(node: Node): void { 91 | this.visitNode(node); 92 | } 93 | /** Rebuilds the textual source from the specified AST, as far as possible. */ 94 | static build(node: Node): string { 95 | var builder = new ASTBuilder(); 96 | builder.visitNode(node); 97 | return builder.finish(); 98 | } 99 | 100 | private sb: string[] = []; 101 | private indentLevel: i32 = 0; 102 | 103 | visitNode(node: Node): void { 104 | switch (node.kind) { 105 | case NodeKind.Source: { 106 | this.visitSource(node); 107 | break; 108 | } 109 | 110 | // types 111 | 112 | case NodeKind.NamedType: { 113 | this.visitNamedTypeNode(node); 114 | break; 115 | } 116 | case NodeKind.FunctionType: { 117 | this.visitFunctionTypeNode(node); 118 | break; 119 | } 120 | case NodeKind.TypeParameter: { 121 | this.visitTypeParameter(node); 122 | break; 123 | } 124 | 125 | // expressions 126 | 127 | case NodeKind.False: 128 | case NodeKind.Null: 129 | case NodeKind.Super: 130 | case NodeKind.This: 131 | case NodeKind.True: 132 | case NodeKind.Constructor: 133 | case NodeKind.Identifier: { 134 | this.visitIdentifierExpression(node); 135 | break; 136 | } 137 | case NodeKind.Assertion: { 138 | this.visitAssertionExpression(node); 139 | break; 140 | } 141 | case NodeKind.Binary: { 142 | this.visitBinaryExpression(node); 143 | break; 144 | } 145 | case NodeKind.Call: { 146 | this.visitCallExpression(node); 147 | break; 148 | } 149 | case NodeKind.Class: { 150 | this.visitClassExpression(node); 151 | break; 152 | } 153 | case NodeKind.Comma: { 154 | this.visitCommaExpression(node); 155 | break; 156 | } 157 | case NodeKind.ElementAccess: { 158 | this.visitElementAccessExpression(node); 159 | break; 160 | } 161 | case NodeKind.Function: { 162 | this.visitFunctionExpression(node); 163 | break; 164 | } 165 | case NodeKind.InstanceOf: { 166 | this.visitInstanceOfExpression(node); 167 | break; 168 | } 169 | case NodeKind.Literal: { 170 | this.visitLiteralExpression(node); 171 | break; 172 | } 173 | case NodeKind.New: { 174 | this.visitNewExpression(node); 175 | break; 176 | } 177 | case NodeKind.Parenthesized: { 178 | this.visitParenthesizedExpression(node); 179 | break; 180 | } 181 | case NodeKind.PropertyAccess: { 182 | this.visitPropertyAccessExpression(node); 183 | break; 184 | } 185 | case NodeKind.Ternary: { 186 | this.visitTernaryExpression(node); 187 | break; 188 | } 189 | case NodeKind.UnaryPostfix: { 190 | this.visitUnaryPostfixExpression(node); 191 | break; 192 | } 193 | case NodeKind.UnaryPrefix: { 194 | this.visitUnaryPrefixExpression(node); 195 | break; 196 | } 197 | 198 | // statements 199 | 200 | case NodeKind.Block: { 201 | this.visitBlockStatement(node); 202 | break; 203 | } 204 | case NodeKind.Break: { 205 | this.visitBreakStatement(node); 206 | break; 207 | } 208 | case NodeKind.Continue: { 209 | this.visitContinueStatement(node); 210 | break; 211 | } 212 | case NodeKind.Do: { 213 | this.visitDoStatement(node); 214 | break; 215 | } 216 | case NodeKind.Empty: { 217 | this.visitEmptyStatement(node); 218 | break; 219 | } 220 | case NodeKind.Export: { 221 | this.visitExportStatement(node); 222 | break; 223 | } 224 | case NodeKind.ExportDefault: { 225 | this.visitExportDefaultStatement(node); 226 | break; 227 | } 228 | case NodeKind.ExportImport: { 229 | this.visitExportImportStatement(node); 230 | break; 231 | } 232 | case NodeKind.Expression: { 233 | this.visitExpressionStatement(node); 234 | break; 235 | } 236 | case NodeKind.For: { 237 | this.visitForStatement(node); 238 | break; 239 | } 240 | case NodeKind.ForOf: { 241 | this.visitForOfStatement(node); 242 | break; 243 | } 244 | case NodeKind.If: { 245 | this.visitIfStatement(node); 246 | break; 247 | } 248 | case NodeKind.Import: { 249 | this.visitImportStatement(node); 250 | break; 251 | } 252 | case NodeKind.Return: { 253 | this.visitReturnStatement(node); 254 | break; 255 | } 256 | case NodeKind.Switch: { 257 | this.visitSwitchStatement(node); 258 | break; 259 | } 260 | case NodeKind.Throw: { 261 | this.visitThrowStatement(node); 262 | break; 263 | } 264 | case NodeKind.Try: { 265 | this.visitTryStatement(node); 266 | break; 267 | } 268 | case NodeKind.Variable: { 269 | this.visitVariableStatement(node); 270 | break; 271 | } 272 | case NodeKind.While: { 273 | this.visitWhileStatement(node); 274 | break; 275 | } 276 | 277 | // declaration statements 278 | 279 | case NodeKind.ClassDeclaration: { 280 | this.visitClassDeclaration(node); 281 | break; 282 | } 283 | case NodeKind.EnumDeclaration: { 284 | this.visitEnumDeclaration(node); 285 | break; 286 | } 287 | case NodeKind.EnumValueDeclaration: { 288 | this.visitEnumValueDeclaration(node); 289 | break; 290 | } 291 | case NodeKind.FieldDeclaration: { 292 | this.visitFieldDeclaration(node); 293 | break; 294 | } 295 | case NodeKind.FunctionDeclaration: { 296 | this.visitFunctionDeclaration(node); 297 | break; 298 | } 299 | case NodeKind.ImportDeclaration: { 300 | this.visitImportDeclaration(node); 301 | break; 302 | } 303 | case NodeKind.InterfaceDeclaration: { 304 | this.visitInterfaceDeclaration(node); 305 | break; 306 | } 307 | case NodeKind.MethodDeclaration: { 308 | this.visitMethodDeclaration(node); 309 | break; 310 | } 311 | case NodeKind.NamespaceDeclaration: { 312 | this.visitNamespaceDeclaration(node); 313 | break; 314 | } 315 | case NodeKind.TypeDeclaration: { 316 | this.visitTypeDeclaration(node); 317 | break; 318 | } 319 | case NodeKind.VariableDeclaration: { 320 | this.visitVariableDeclaration(node); 321 | break; 322 | } 323 | 324 | // other 325 | 326 | case NodeKind.Decorator: { 327 | this.serializeDecorator(node); 328 | break; 329 | } 330 | case NodeKind.ExportMember: { 331 | this.visitExportMember(node); 332 | break; 333 | } 334 | case NodeKind.Parameter: { 335 | this.serializeParameter(node); 336 | break; 337 | } 338 | case NodeKind.SwitchCase: { 339 | this.visitSwitchCase(node); 340 | break; 341 | } 342 | case NodeKind.IndexSignature: { 343 | this.visitIndexSignature(node); 344 | break; 345 | } 346 | default: 347 | assert(false, node.kind.toString()); 348 | } 349 | } 350 | 351 | visitSource(source: Source): void { 352 | var statements = source.statements; 353 | for (let i = 0, k = statements.length; i < k; ++i) { 354 | this.visitNodeAndTerminate(statements[i]); 355 | } 356 | } 357 | 358 | // types 359 | 360 | visitTypeNode(node: TypeNode): void { 361 | switch (node.kind) { 362 | case NodeKind.NamedType: { 363 | this.visitNamedTypeNode(node); 364 | break; 365 | } 366 | case NodeKind.FunctionType: { 367 | this.visitFunctionTypeNode(node); 368 | break; 369 | } 370 | default: 371 | assert(false); 372 | } 373 | } 374 | 375 | visitTypeName(node: TypeName): void { 376 | this.visitIdentifierExpression(node.identifier); 377 | var sb = this.sb; 378 | var current = node.next; 379 | while (current) { 380 | sb.push("."); 381 | this.visitIdentifierExpression(current.identifier); 382 | current = current.next; 383 | } 384 | } 385 | 386 | visitNamedTypeNode(node: NamedTypeNode): void { 387 | this.visitTypeName(node.name); 388 | var typeArguments = node.typeArguments; 389 | if (typeArguments) { 390 | let numTypeArguments = typeArguments.length; 391 | let sb = this.sb; 392 | if (numTypeArguments) { 393 | sb.push("<"); 394 | this.visitTypeNode(typeArguments[0]); 395 | for (let i = 1; i < numTypeArguments; ++i) { 396 | sb.push(", "); 397 | this.visitTypeNode(typeArguments[i]); 398 | } 399 | sb.push(">"); 400 | } 401 | if (node.isNullable) sb.push(" | null"); 402 | } 403 | } 404 | 405 | visitFunctionTypeNode(node: FunctionTypeNode): void { 406 | var isNullable = node.isNullable; 407 | var sb = this.sb; 408 | sb.push(isNullable ? "((" : "("); 409 | var explicitThisType = node.explicitThisType; 410 | if (explicitThisType) { 411 | sb.push("this: "); 412 | this.visitTypeNode(explicitThisType); 413 | } 414 | var parameters = node.parameters; 415 | var numParameters = parameters.length; 416 | if (numParameters) { 417 | if (explicitThisType) sb.push(", "); 418 | this.serializeParameter(parameters[0]); 419 | for (let i = 1; i < numParameters; ++i) { 420 | sb.push(", "); 421 | this.serializeParameter(parameters[i]); 422 | } 423 | } 424 | var returnType = node.returnType; 425 | if (returnType) { 426 | sb.push(") => "); 427 | this.visitTypeNode(returnType); 428 | } else { 429 | sb.push(") => void"); 430 | } 431 | if (isNullable) sb.push(") | null"); 432 | } 433 | 434 | visitTypeParameter(node: TypeParameterNode): void { 435 | this.visitIdentifierExpression(node.name); 436 | var extendsType = node.extendsType; 437 | if (extendsType) { 438 | this.sb.push(" extends "); 439 | this.visitTypeNode(extendsType); 440 | } 441 | var defaultType = node.defaultType; 442 | if (defaultType) { 443 | this.sb.push("="); 444 | this.visitTypeNode(defaultType); 445 | } 446 | } 447 | 448 | // expressions 449 | 450 | visitIdentifierExpression(node: IdentifierExpression): void { 451 | if (node.isQuoted) this.visitStringLiteral(node.text); 452 | else this.sb.push(node.text); 453 | } 454 | 455 | visitArrayLiteralExpression(node: ArrayLiteralExpression): void { 456 | var sb = this.sb; 457 | sb.push("["); 458 | var elements = node.elementExpressions; 459 | var numElements = elements.length; 460 | if (numElements) { 461 | let element = elements[0]; 462 | if (element) this.visitNode(element); 463 | for (let i = 1; i < numElements; ++i) { 464 | element = elements[i]; 465 | sb.push(", "); 466 | if (element) this.visitNode(element); 467 | } 468 | } 469 | sb.push("]"); 470 | } 471 | 472 | visitObjectLiteralExpression(node: ObjectLiteralExpression): void { 473 | var sb = this.sb; 474 | var names = node.names; 475 | var values = node.values; 476 | var numElements = names.length; 477 | assert(numElements == values.length); 478 | if (numElements) { 479 | sb.push("{\n"); 480 | indent(sb, ++this.indentLevel); 481 | this.visitNode(names[0]); 482 | sb.push(": "); 483 | this.visitNode(values[0]); 484 | for (let i = 1; i < numElements; ++i) { 485 | sb.push(",\n"); 486 | indent(sb, this.indentLevel); 487 | let name = names[i]; 488 | let value = values[i]; 489 | if (name === value) { 490 | this.visitNode(name); 491 | } else { 492 | this.visitNode(name); 493 | sb.push(": "); 494 | this.visitNode(value); 495 | } 496 | } 497 | sb.push("\n"); 498 | indent(sb, --this.indentLevel); 499 | sb.push("}"); 500 | } else { 501 | sb.push("{}"); 502 | } 503 | } 504 | 505 | visitAssertionExpression(node: AssertionExpression): void { 506 | var sb = this.sb; 507 | switch (node.assertionKind) { 508 | case AssertionKind.Prefix: { 509 | sb.push("<"); 510 | this.visitTypeNode(assert(node.toType)); 511 | sb.push(">"); 512 | this.visitNode(node.expression); 513 | break; 514 | } 515 | case AssertionKind.As: { 516 | this.visitNode(node.expression); 517 | sb.push(" as "); 518 | this.visitTypeNode(assert(node.toType)); 519 | break; 520 | } 521 | case AssertionKind.NonNull: { 522 | this.visitNode(node.expression); 523 | sb.push("!"); 524 | break; 525 | } 526 | case AssertionKind.Const: { 527 | this.visitNode(node.expression); 528 | sb.push(" as const"); 529 | break; 530 | } 531 | default: 532 | assert(false); 533 | } 534 | } 535 | 536 | visitBinaryExpression(node: BinaryExpression): void { 537 | var sb = this.sb; 538 | this.visitNode(node.left); 539 | sb.push(" "); 540 | sb.push(operatorTokenToString(node.operator)); 541 | sb.push(" "); 542 | this.visitNode(node.right); 543 | } 544 | 545 | visitCallExpression(node: CallExpression): void { 546 | this.visitNode(node.expression); 547 | this.visitArguments(node.typeArguments, node.args); 548 | } 549 | 550 | visitArguments( 551 | typeArguments: TypeNode[] | null, 552 | args: Expression[] 553 | ): void { 554 | var sb = this.sb; 555 | if (typeArguments) { 556 | let numTypeArguments = typeArguments.length; 557 | if (numTypeArguments) { 558 | sb.push("<"); 559 | this.visitTypeNode(typeArguments[0]); 560 | for (let i = 1; i < numTypeArguments; ++i) { 561 | sb.push(", "); 562 | this.visitTypeNode(typeArguments[i]); 563 | } 564 | sb.push(">("); 565 | } 566 | } else { 567 | sb.push("("); 568 | } 569 | var numArgs = args.length; 570 | if (numArgs) { 571 | this.visitNode(args[0]); 572 | for (let i = 1; i < numArgs; ++i) { 573 | sb.push(", "); 574 | this.visitNode(args[i]); 575 | } 576 | } 577 | sb.push(")"); 578 | } 579 | 580 | visitClassExpression(node: ClassExpression): void { 581 | var declaration = node.declaration; 582 | this.visitClassDeclaration(declaration); 583 | } 584 | 585 | visitCommaExpression(node: CommaExpression): void { 586 | var expressions = node.expressions; 587 | var numExpressions = assert(expressions.length); 588 | this.visitNode(expressions[0]); 589 | var sb = this.sb; 590 | for (let i = 1; i < numExpressions; ++i) { 591 | sb.push(","); 592 | this.visitNode(expressions[i]); 593 | } 594 | } 595 | 596 | visitElementAccessExpression(node: ElementAccessExpression): void { 597 | var sb = this.sb; 598 | this.visitNode(node.expression); 599 | sb.push("["); 600 | this.visitNode(node.elementExpression); 601 | sb.push("]"); 602 | } 603 | 604 | visitFunctionExpression(node: FunctionExpression): void { 605 | var declaration = node.declaration; 606 | if (!declaration.arrowKind) { 607 | if (declaration.name.text.length) { 608 | this.sb.push("function "); 609 | } else { 610 | this.sb.push("function"); 611 | } 612 | } else { 613 | assert(declaration.name.text.length == 0); 614 | } 615 | this.visitFunctionCommon(declaration); 616 | } 617 | 618 | visitLiteralExpression(node: LiteralExpression): void { 619 | switch (node.literalKind) { 620 | case LiteralKind.Float: { 621 | this.visitFloatLiteralExpression(node); 622 | break; 623 | } 624 | case LiteralKind.Integer: { 625 | this.visitIntegerLiteralExpression(node); 626 | break; 627 | } 628 | case LiteralKind.String: { 629 | this.visitStringLiteralExpression(node); 630 | break; 631 | } 632 | case LiteralKind.Template: { 633 | this.visitTemplateLiteralExpression(node); 634 | break; 635 | } 636 | case LiteralKind.RegExp: { 637 | this.visitRegexpLiteralExpression(node); 638 | break; 639 | } 640 | case LiteralKind.Array: { 641 | this.visitArrayLiteralExpression(node); 642 | break; 643 | } 644 | case LiteralKind.Object: { 645 | this.visitObjectLiteralExpression(node); 646 | break; 647 | } 648 | default: { 649 | assert(false); 650 | break; 651 | } 652 | } 653 | } 654 | 655 | visitFloatLiteralExpression(node: FloatLiteralExpression): void { 656 | this.sb.push(node.value.toString()); 657 | } 658 | 659 | visitInstanceOfExpression(node: InstanceOfExpression): void { 660 | this.visitNode(node.expression); 661 | this.sb.push(" instanceof "); 662 | this.visitTypeNode(node.isType); 663 | } 664 | 665 | visitIntegerLiteralExpression(node: IntegerLiteralExpression): void { 666 | this.sb.push(i64_to_string(node.value)); 667 | } 668 | 669 | visitStringLiteral(str: string): void { 670 | var sb = this.sb; 671 | sb.push('"'); 672 | this.visitRawString(str, util.CharCode.DoubleQuote); 673 | sb.push('"'); 674 | } 675 | 676 | private visitRawString(str: string, quote: util.CharCode): void { 677 | var sb = this.sb; 678 | var off = 0; 679 | var i = 0; 680 | for (let k = str.length; i < k; ) { 681 | switch (str.charCodeAt(i)) { 682 | case util.CharCode.Null: { 683 | if (i > off) sb.push(str.substring(off, (off = i + 1))); 684 | sb.push("\\0"); 685 | off = ++i; 686 | break; 687 | } 688 | case util.CharCode.Backslash: { 689 | if (i > off) sb.push(str.substring(off, i)); 690 | off = ++i; 691 | sb.push("\\b"); 692 | break; 693 | } 694 | case util.CharCode.Tab: { 695 | if (i > off) sb.push(str.substring(off, i)); 696 | off = ++i; 697 | sb.push("\\t"); 698 | break; 699 | } 700 | case util.CharCode.LineFeed: { 701 | if (i > off) sb.push(str.substring(off, i)); 702 | off = ++i; 703 | sb.push("\\n"); 704 | break; 705 | } 706 | case util.CharCode.VerticalTab: { 707 | if (i > off) sb.push(str.substring(off, i)); 708 | off = ++i; 709 | sb.push("\\v"); 710 | break; 711 | } 712 | case util.CharCode.FormFeed: { 713 | if (i > off) sb.push(str.substring(off, i)); 714 | off = ++i; 715 | sb.push("\\f"); 716 | break; 717 | } 718 | case util.CharCode.CarriageReturn: { 719 | if (i > off) sb.push(str.substring(off, i)); 720 | sb.push("\\r"); 721 | off = ++i; 722 | break; 723 | } 724 | case util.CharCode.DoubleQuote: { 725 | if (quote == util.CharCode.DoubleQuote) { 726 | if (i > off) sb.push(str.substring(off, i)); 727 | sb.push('\\"'); 728 | off = ++i; 729 | } else { 730 | ++i; 731 | } 732 | break; 733 | } 734 | case util.CharCode.SingleQuote: { 735 | if (quote == util.CharCode.SingleQuote) { 736 | if (i > off) sb.push(str.substring(off, i)); 737 | sb.push("\\'"); 738 | off = ++i; 739 | } else { 740 | ++i; 741 | } 742 | break; 743 | } 744 | case util.CharCode.Backslash: { 745 | if (i > off) sb.push(str.substring(off, i)); 746 | sb.push("\\\\"); 747 | off = ++i; 748 | break; 749 | } 750 | case util.CharCode.Backtick: { 751 | if (quote == util.CharCode.Backtick) { 752 | if (i > off) sb.push(str.substring(off, i)); 753 | sb.push("\\`"); 754 | off = ++i; 755 | } else { 756 | ++i; 757 | } 758 | break; 759 | } 760 | default: { 761 | ++i; 762 | break; 763 | } 764 | } 765 | } 766 | if (i > off) sb.push(str.substring(off, i)); 767 | } 768 | 769 | visitStringLiteralExpression(node: StringLiteralExpression): void { 770 | this.visitStringLiteral(node.value); 771 | } 772 | 773 | visitTemplateLiteralExpression(node: TemplateLiteralExpression): void { 774 | var sb = this.sb; 775 | var tag = node.tag; 776 | var parts = node.parts; 777 | var expressions = node.expressions; 778 | if (tag) this.visitNode(tag); 779 | sb.push("`"); 780 | this.visitRawString(parts[0], util.CharCode.Backtick); 781 | assert(parts.length == expressions.length + 1); 782 | for (let i = 0, k = expressions.length; i < k; ++i) { 783 | sb.push("${"); 784 | this.visitNode(expressions[i]); 785 | sb.push("}"); 786 | this.visitRawString(parts[i + 1], util.CharCode.Backtick); 787 | } 788 | sb.push("`"); 789 | } 790 | 791 | visitRegexpLiteralExpression(node: RegexpLiteralExpression): void { 792 | var sb = this.sb; 793 | sb.push("/"); 794 | sb.push(node.pattern); 795 | sb.push("/"); 796 | sb.push(node.patternFlags); 797 | } 798 | 799 | visitNewExpression(node: NewExpression): void { 800 | this.sb.push("new "); 801 | this.visitTypeName(node.typeName); 802 | this.visitArguments(node.typeArguments, node.args); 803 | } 804 | 805 | visitParenthesizedExpression(node: ParenthesizedExpression): void { 806 | var sb = this.sb; 807 | sb.push("("); 808 | this.visitNode(node.expression); 809 | sb.push(")"); 810 | } 811 | 812 | visitPropertyAccessExpression(node: PropertyAccessExpression): void { 813 | this.visitNode(node.expression); 814 | this.sb.push("."); 815 | this.visitIdentifierExpression(node.property); 816 | } 817 | 818 | visitTernaryExpression(node: TernaryExpression): void { 819 | var sb = this.sb; 820 | this.visitNode(node.condition); 821 | sb.push(" ? "); 822 | this.visitNode(node.ifThen); 823 | sb.push(" : "); 824 | this.visitNode(node.ifElse); 825 | } 826 | 827 | visitUnaryExpression(node: UnaryExpression): void { 828 | switch (node.kind) { 829 | case NodeKind.UnaryPostfix: { 830 | this.visitUnaryPostfixExpression(node); 831 | break; 832 | } 833 | case NodeKind.UnaryPrefix: { 834 | this.visitUnaryPrefixExpression(node); 835 | break; 836 | } 837 | default: 838 | assert(false); 839 | } 840 | } 841 | 842 | visitUnaryPostfixExpression(node: UnaryPostfixExpression): void { 843 | this.visitNode(node.operand); 844 | this.sb.push(operatorTokenToString(node.operator)); 845 | } 846 | 847 | visitUnaryPrefixExpression(node: UnaryPrefixExpression): void { 848 | this.sb.push(operatorTokenToString(node.operator)); 849 | this.visitNode(node.operand); 850 | } 851 | 852 | // statements 853 | 854 | visitNodeAndTerminate(node: Node): void { 855 | this.visitNode(node); 856 | var sb = this.sb; 857 | if ( 858 | !sb.length || // leading EmptyStatement 859 | node.kind == NodeKind.Variable || // potentially assigns a FunctionExpression 860 | node.kind == NodeKind.Expression // potentially assigns a FunctionExpression 861 | ) { 862 | sb.push(";\n"); 863 | } else { 864 | let last = sb[sb.length - 1]; 865 | let lastCharPos = last.length - 1; 866 | if ( 867 | lastCharPos >= 0 && 868 | (last.charCodeAt(lastCharPos) == util.CharCode.CloseBrace || 869 | last.charCodeAt(lastCharPos) == util.CharCode.Semicolon) 870 | ) { 871 | sb.push("\n"); 872 | } else { 873 | sb.push(";\n"); 874 | } 875 | } 876 | } 877 | 878 | visitBlockStatement(node: BlockStatement): void { 879 | var sb = this.sb; 880 | var statements = node.statements; 881 | var numStatements = statements.length; 882 | if (numStatements) { 883 | sb.push("{\n"); 884 | let indentLevel = ++this.indentLevel; 885 | for (let i = 0; i < numStatements; ++i) { 886 | indent(sb, indentLevel); 887 | this.visitNodeAndTerminate(statements[i]); 888 | } 889 | indent(sb, --this.indentLevel); 890 | sb.push("}"); 891 | } else { 892 | sb.push("{}"); 893 | } 894 | } 895 | 896 | visitBreakStatement(node: BreakStatement): void { 897 | var label = node.label; 898 | if (label) { 899 | this.sb.push("break "); 900 | this.visitIdentifierExpression(label); 901 | } else { 902 | this.sb.push("break"); 903 | } 904 | } 905 | 906 | visitContinueStatement(node: ContinueStatement): void { 907 | var label = node.label; 908 | if (label) { 909 | this.sb.push("continue "); 910 | this.visitIdentifierExpression(label); 911 | } else { 912 | this.sb.push("continue"); 913 | } 914 | } 915 | 916 | visitClassDeclaration(node: ClassDeclaration, isDefault = false): void { 917 | var decorators = node.decorators; 918 | if (decorators) { 919 | for (let i = 0, k = decorators.length; i < k; ++i) { 920 | this.serializeDecorator(decorators[i]); 921 | } 922 | } 923 | var sb = this.sb; 924 | if (isDefault) { 925 | sb.push("export default "); 926 | } else { 927 | this.serializeExternalModifiers(node); 928 | } 929 | if (node.is(CommonFlags.Abstract)) sb.push("abstract "); 930 | if (node.name.text.length) { 931 | sb.push("class "); 932 | this.visitIdentifierExpression(node.name); 933 | } else { 934 | sb.push("class"); 935 | } 936 | var typeParameters = node.typeParameters; 937 | if (typeParameters != null && typeParameters.length > 0) { 938 | sb.push("<"); 939 | this.visitTypeParameter(typeParameters[0]); 940 | for (let i = 1, k = typeParameters.length; i < k; ++i) { 941 | sb.push(", "); 942 | this.visitTypeParameter(typeParameters[i]); 943 | } 944 | sb.push(">"); 945 | } 946 | var extendsType = node.extendsType; 947 | if (extendsType) { 948 | sb.push(" extends "); 949 | this.visitTypeNode(extendsType); 950 | } 951 | var implementsTypes = node.implementsTypes; 952 | if (implementsTypes) { 953 | let numImplementsTypes = implementsTypes.length; 954 | if (numImplementsTypes) { 955 | sb.push(" implements "); 956 | this.visitTypeNode(implementsTypes[0]); 957 | for (let i = 1; i < numImplementsTypes; ++i) { 958 | sb.push(", "); 959 | this.visitTypeNode(implementsTypes[i]); 960 | } 961 | } 962 | } 963 | var indexSignature = node.indexSignature; 964 | var members = node.members; 965 | var numMembers = members.length; 966 | if (indexSignature !== null || numMembers) { 967 | sb.push(" {\n"); 968 | let indentLevel = ++this.indentLevel; 969 | if (indexSignature) { 970 | indent(sb, indentLevel); 971 | this.visitNodeAndTerminate(indexSignature); 972 | } 973 | for (let i = 0, k = members.length; i < k; ++i) { 974 | let member = members[i]; 975 | if ( 976 | member.kind != NodeKind.FieldDeclaration || 977 | (member).parameterIndex < 0 978 | ) { 979 | indent(sb, indentLevel); 980 | this.visitNodeAndTerminate(member); 981 | } 982 | } 983 | indent(sb, --this.indentLevel); 984 | sb.push("}"); 985 | } else { 986 | sb.push(" {}"); 987 | } 988 | } 989 | 990 | visitDoStatement(node: DoStatement): void { 991 | var sb = this.sb; 992 | sb.push("do "); 993 | this.visitNode(node.body); 994 | if (node.body.kind == NodeKind.Block) { 995 | sb.push(" while ("); 996 | } else { 997 | indent(sb, this.indentLevel); 998 | sb.push("while ("); 999 | } 1000 | this.visitNode(node.condition); 1001 | sb.push(")"); 1002 | } 1003 | 1004 | visitEmptyStatement(node: EmptyStatement): void { 1005 | /* nop */ 1006 | } 1007 | 1008 | visitEnumDeclaration(node: EnumDeclaration, isDefault = false): void { 1009 | var sb = this.sb; 1010 | if (isDefault) { 1011 | sb.push("export default "); 1012 | } else { 1013 | this.serializeExternalModifiers(node); 1014 | } 1015 | if (node.is(CommonFlags.Const)) sb.push("const "); 1016 | sb.push("enum "); 1017 | this.visitIdentifierExpression(node.name); 1018 | var values = node.values; 1019 | var numValues = values.length; 1020 | if (numValues) { 1021 | sb.push(" {\n"); 1022 | let indentLevel = ++this.indentLevel; 1023 | indent(sb, indentLevel); 1024 | this.visitEnumValueDeclaration(node.values[0]); 1025 | for (let i = 1; i < numValues; ++i) { 1026 | sb.push(",\n"); 1027 | indent(sb, indentLevel); 1028 | this.visitEnumValueDeclaration(node.values[i]); 1029 | } 1030 | sb.push("\n"); 1031 | indent(sb, --this.indentLevel); 1032 | sb.push("}"); 1033 | } else { 1034 | sb.push(" {}"); 1035 | } 1036 | } 1037 | 1038 | visitEnumValueDeclaration(node: EnumValueDeclaration): void { 1039 | this.visitIdentifierExpression(node.name); 1040 | var initializer = node.initializer; 1041 | if (initializer) { 1042 | this.sb.push(" = "); 1043 | this.visitNode(initializer); 1044 | } 1045 | } 1046 | 1047 | visitExportImportStatement(node: ExportImportStatement): void { 1048 | var sb = this.sb; 1049 | sb.push("export import "); 1050 | this.visitIdentifierExpression(node.externalName); 1051 | sb.push(" = "); 1052 | this.visitIdentifierExpression(node.name); 1053 | } 1054 | 1055 | visitExportMember(node: ExportMember): void { 1056 | this.visitIdentifierExpression(node.localName); 1057 | if (node.exportedName.text != node.localName.text) { 1058 | this.sb.push(" as "); 1059 | this.visitIdentifierExpression(node.exportedName); 1060 | } 1061 | } 1062 | 1063 | visitExportStatement(node: ExportStatement): void { 1064 | var sb = this.sb; 1065 | if (node.isDeclare) { 1066 | sb.push("declare "); 1067 | } 1068 | var members = node.members; 1069 | if (members == null) { 1070 | sb.push("export *"); 1071 | } else if (members.length > 0) { 1072 | let numMembers = members.length; 1073 | sb.push("export {\n"); 1074 | let indentLevel = ++this.indentLevel; 1075 | indent(sb, indentLevel); 1076 | this.visitExportMember(members[0]); 1077 | for (let i = 1; i < numMembers; ++i) { 1078 | sb.push(",\n"); 1079 | indent(sb, indentLevel); 1080 | this.visitExportMember(members[i]); 1081 | } 1082 | --this.indentLevel; 1083 | sb.push("\n}"); 1084 | } else { 1085 | sb.push("export {}"); 1086 | } 1087 | var path = node.path; 1088 | if (path) { 1089 | sb.push(" from "); 1090 | this.visitStringLiteralExpression(path); 1091 | } 1092 | sb.push(";"); 1093 | } 1094 | 1095 | visitExportDefaultStatement(node: ExportDefaultStatement): void { 1096 | var declaration = node.declaration; 1097 | switch (declaration.kind) { 1098 | case NodeKind.EnumDeclaration: { 1099 | this.visitEnumDeclaration(declaration, true); 1100 | break; 1101 | } 1102 | case NodeKind.FunctionDeclaration: { 1103 | this.visitFunctionDeclaration(declaration, true); 1104 | break; 1105 | } 1106 | case NodeKind.ClassDeclaration: { 1107 | this.visitClassDeclaration(declaration, true); 1108 | break; 1109 | } 1110 | case NodeKind.InterfaceDeclaration: { 1111 | this.visitInterfaceDeclaration(declaration, true); 1112 | break; 1113 | } 1114 | case NodeKind.NamespaceDeclaration: { 1115 | this.visitNamespaceDeclaration(declaration, true); 1116 | break; 1117 | } 1118 | default: 1119 | assert(false); 1120 | } 1121 | } 1122 | 1123 | visitExpressionStatement(node: ExpressionStatement): void { 1124 | this.visitNode(node.expression); 1125 | } 1126 | 1127 | visitFieldDeclaration(node: FieldDeclaration): void { 1128 | var decorators = node.decorators; 1129 | if (decorators) { 1130 | for (let i = 0, k = decorators.length; i < k; ++i) { 1131 | this.serializeDecorator(decorators[i]); 1132 | } 1133 | } 1134 | this.serializeAccessModifiers(node); 1135 | this.visitIdentifierExpression(node.name); 1136 | var sb = this.sb; 1137 | if (node.flags & CommonFlags.DefinitelyAssigned) { 1138 | sb.push("!"); 1139 | } 1140 | var type = node.type; 1141 | if (type) { 1142 | sb.push(": "); 1143 | this.visitTypeNode(type); 1144 | } 1145 | var initializer = node.initializer; 1146 | if (initializer) { 1147 | sb.push(" = "); 1148 | this.visitNode(initializer); 1149 | } 1150 | } 1151 | 1152 | visitForStatement(node: ForStatement): void { 1153 | var sb = this.sb; 1154 | sb.push("for ("); 1155 | var initializer = node.initializer; 1156 | if (initializer) { 1157 | this.visitNode(initializer); 1158 | } 1159 | var condition = node.condition; 1160 | if (condition) { 1161 | sb.push("; "); 1162 | this.visitNode(condition); 1163 | } else { 1164 | sb.push(";"); 1165 | } 1166 | var incrementor = node.incrementor; 1167 | if (incrementor) { 1168 | sb.push("; "); 1169 | this.visitNode(incrementor); 1170 | } else { 1171 | sb.push(";"); 1172 | } 1173 | sb.push(") "); 1174 | this.visitNode(node.body); 1175 | } 1176 | 1177 | visitForOfStatement(node: ForOfStatement): void { 1178 | var sb = this.sb; 1179 | sb.push("for ("); 1180 | this.visitNode(node.variable); 1181 | sb.push(" of "); 1182 | this.visitNode(node.iterable); 1183 | sb.push(") "); 1184 | this.visitNode(node.body); 1185 | } 1186 | 1187 | visitFunctionDeclaration( 1188 | node: FunctionDeclaration, 1189 | isDefault = false 1190 | ): void { 1191 | var sb = this.sb; 1192 | var decorators = node.decorators; 1193 | if (decorators) { 1194 | for (let i = 0, k = decorators.length; i < k; ++i) { 1195 | this.serializeDecorator(decorators[i]); 1196 | } 1197 | } 1198 | if (isDefault) { 1199 | sb.push("export default "); 1200 | } else { 1201 | this.serializeExternalModifiers(node); 1202 | this.serializeAccessModifiers(node); 1203 | } 1204 | if (node.name.text.length) { 1205 | sb.push("function "); 1206 | } else { 1207 | sb.push("function"); 1208 | } 1209 | this.visitFunctionCommon(node); 1210 | } 1211 | 1212 | visitFunctionCommon(node: FunctionDeclaration): void { 1213 | var sb = this.sb; 1214 | this.visitIdentifierExpression(node.name); 1215 | var signature = node.signature; 1216 | var typeParameters = node.typeParameters; 1217 | if (typeParameters) { 1218 | let numTypeParameters = typeParameters.length; 1219 | if (numTypeParameters) { 1220 | sb.push("<"); 1221 | this.visitTypeParameter(typeParameters[0]); 1222 | for (let i = 1; i < numTypeParameters; ++i) { 1223 | sb.push(", "); 1224 | this.visitTypeParameter(typeParameters[i]); 1225 | } 1226 | sb.push(">"); 1227 | } 1228 | } 1229 | if (node.arrowKind == ArrowKind.Single) { 1230 | let parameters = signature.parameters; 1231 | assert(parameters.length == 1); 1232 | assert(!signature.explicitThisType); 1233 | this.serializeParameter(parameters[0]); 1234 | } else { 1235 | sb.push("("); 1236 | let parameters = signature.parameters; 1237 | let numParameters = parameters.length; 1238 | let explicitThisType = signature.explicitThisType; 1239 | if (explicitThisType) { 1240 | sb.push("this: "); 1241 | this.visitTypeNode(explicitThisType); 1242 | } 1243 | if (numParameters) { 1244 | if (explicitThisType) sb.push(", "); 1245 | this.serializeParameter(parameters[0]); 1246 | for (let i = 1; i < numParameters; ++i) { 1247 | sb.push(", "); 1248 | this.serializeParameter(parameters[i]); 1249 | } 1250 | } 1251 | } 1252 | var body = node.body; 1253 | var returnType = signature.returnType; 1254 | if (node.arrowKind) { 1255 | if (body) { 1256 | if (node.arrowKind == ArrowKind.Single) { 1257 | assert(isTypeOmitted(returnType)); 1258 | } else { 1259 | if (isTypeOmitted(returnType)) { 1260 | sb.push(")"); 1261 | } else { 1262 | sb.push("): "); 1263 | this.visitTypeNode(returnType); 1264 | } 1265 | } 1266 | sb.push(" => "); 1267 | this.visitNode(body); 1268 | } else { 1269 | assert(!isTypeOmitted(returnType)); 1270 | sb.push(" => "); 1271 | this.visitTypeNode(returnType); 1272 | } 1273 | } else { 1274 | if ( 1275 | !isTypeOmitted(returnType) && 1276 | !node.isAny(CommonFlags.Constructor | CommonFlags.Set) 1277 | ) { 1278 | sb.push("): "); 1279 | this.visitTypeNode(returnType); 1280 | } else { 1281 | sb.push(")"); 1282 | } 1283 | if (body) { 1284 | sb.push(" "); 1285 | this.visitNode(body); 1286 | } 1287 | } 1288 | } 1289 | 1290 | visitIfStatement(node: IfStatement): void { 1291 | var sb = this.sb; 1292 | sb.push("if ("); 1293 | this.visitNode(node.condition); 1294 | sb.push(") "); 1295 | var ifTrue = node.ifTrue; 1296 | this.visitNode(ifTrue); 1297 | if (ifTrue.kind != NodeKind.Block) { 1298 | sb.push(";\n"); 1299 | } 1300 | var ifFalse = node.ifFalse; 1301 | if (ifFalse) { 1302 | if (ifTrue.kind == NodeKind.Block) { 1303 | sb.push(" else "); 1304 | } else { 1305 | sb.push("else "); 1306 | } 1307 | this.visitNode(ifFalse); 1308 | } 1309 | } 1310 | 1311 | visitImportDeclaration(node: ImportDeclaration): void { 1312 | var externalName = node.foreignName; 1313 | var name = node.name; 1314 | this.visitIdentifierExpression(externalName); 1315 | if (externalName.text != name.text) { 1316 | this.sb.push(" as "); 1317 | this.visitIdentifierExpression(name); 1318 | } 1319 | } 1320 | 1321 | visitImportStatement(node: ImportStatement): void { 1322 | var sb = this.sb; 1323 | sb.push("import "); 1324 | var declarations = node.declarations; 1325 | var namespaceName = node.namespaceName; 1326 | if (declarations) { 1327 | let numDeclarations = declarations.length; 1328 | if (numDeclarations) { 1329 | sb.push("{\n"); 1330 | let indentLevel = ++this.indentLevel; 1331 | indent(sb, indentLevel); 1332 | this.visitImportDeclaration(declarations[0]); 1333 | for (let i = 1; i < numDeclarations; ++i) { 1334 | sb.push(",\n"); 1335 | indent(sb, indentLevel); 1336 | this.visitImportDeclaration(declarations[i]); 1337 | } 1338 | --this.indentLevel; 1339 | sb.push("\n} from "); 1340 | } else { 1341 | sb.push("{} from "); 1342 | } 1343 | } else if (namespaceName) { 1344 | sb.push("* as "); 1345 | this.visitIdentifierExpression(namespaceName); 1346 | sb.push(" from "); 1347 | } 1348 | this.visitStringLiteralExpression(node.path); 1349 | } 1350 | 1351 | visitIndexSignature(node: IndexSignatureNode): void { 1352 | var sb = this.sb; 1353 | sb.push("[key: "); 1354 | this.visitTypeNode(node.keyType); 1355 | sb.push("]: "); 1356 | this.visitTypeNode(node.valueType); 1357 | } 1358 | 1359 | visitInterfaceDeclaration( 1360 | node: InterfaceDeclaration, 1361 | isDefault = false 1362 | ): void { 1363 | var decorators = node.decorators; 1364 | if (decorators) { 1365 | for (let i = 0, k = decorators.length; i < k; ++i) { 1366 | this.serializeDecorator(decorators[i]); 1367 | } 1368 | } 1369 | var sb = this.sb; 1370 | if (isDefault) { 1371 | sb.push("export default "); 1372 | } else { 1373 | this.serializeExternalModifiers(node); 1374 | } 1375 | sb.push("interface "); 1376 | this.visitIdentifierExpression(node.name); 1377 | var typeParameters = node.typeParameters; 1378 | if (typeParameters != null && typeParameters.length > 0) { 1379 | sb.push("<"); 1380 | this.visitTypeParameter(typeParameters[0]); 1381 | for (let i = 1, k = typeParameters.length; i < k; ++i) { 1382 | sb.push(", "); 1383 | this.visitTypeParameter(typeParameters[i]); 1384 | } 1385 | sb.push(">"); 1386 | } 1387 | var extendsType = node.extendsType; 1388 | if (extendsType) { 1389 | sb.push(" extends "); 1390 | this.visitTypeNode(extendsType); 1391 | } 1392 | // must not have implementsTypes 1393 | sb.push(" {\n"); 1394 | var indentLevel = ++this.indentLevel; 1395 | var members = node.members; 1396 | for (let i = 0, k = members.length; i < k; ++i) { 1397 | indent(sb, indentLevel); 1398 | this.visitNodeAndTerminate(members[i]); 1399 | } 1400 | --this.indentLevel; 1401 | sb.push("}"); 1402 | } 1403 | 1404 | visitMethodDeclaration(node: MethodDeclaration): void { 1405 | var decorators = node.decorators; 1406 | if (decorators) { 1407 | for (let i = 0, k = decorators.length; i < k; ++i) { 1408 | this.serializeDecorator(decorators[i]); 1409 | } 1410 | } 1411 | this.serializeAccessModifiers(node); 1412 | if (node.is(CommonFlags.Get)) { 1413 | this.sb.push("get "); 1414 | } else if (node.is(CommonFlags.Set)) { 1415 | this.sb.push("set "); 1416 | } 1417 | this.visitFunctionCommon(node); 1418 | } 1419 | 1420 | visitNamespaceDeclaration( 1421 | node: NamespaceDeclaration, 1422 | isDefault = false 1423 | ): void { 1424 | var decorators = node.decorators; 1425 | if (decorators) { 1426 | for (let i = 0, k = decorators.length; i < k; ++i) { 1427 | this.serializeDecorator(decorators[i]); 1428 | } 1429 | } 1430 | var sb = this.sb; 1431 | if (isDefault) { 1432 | sb.push("export default "); 1433 | } else { 1434 | this.serializeExternalModifiers(node); 1435 | } 1436 | sb.push("namespace "); 1437 | this.visitIdentifierExpression(node.name); 1438 | var members = node.members; 1439 | var numMembers = members.length; 1440 | if (numMembers) { 1441 | sb.push(" {\n"); 1442 | let indentLevel = ++this.indentLevel; 1443 | for (let i = 0, k = members.length; i < k; ++i) { 1444 | indent(sb, indentLevel); 1445 | this.visitNodeAndTerminate(members[i]); 1446 | } 1447 | indent(sb, --this.indentLevel); 1448 | sb.push("}"); 1449 | } else { 1450 | sb.push(" {}"); 1451 | } 1452 | } 1453 | 1454 | visitReturnStatement(node: ReturnStatement): void { 1455 | var value = node.value; 1456 | if (value) { 1457 | this.sb.push("return "); 1458 | this.visitNode(value); 1459 | } else { 1460 | this.sb.push("return"); 1461 | } 1462 | } 1463 | 1464 | visitSwitchCase(node: SwitchCase): void { 1465 | var sb = this.sb; 1466 | var label = node.label; 1467 | if (label) { 1468 | sb.push("case "); 1469 | this.visitNode(label); 1470 | sb.push(":\n"); 1471 | } else { 1472 | sb.push("default:\n"); 1473 | } 1474 | var statements = node.statements; 1475 | var numStatements = statements.length; 1476 | if (numStatements) { 1477 | let indentLevel = ++this.indentLevel; 1478 | indent(sb, indentLevel); 1479 | this.visitNodeAndTerminate(statements[0]); 1480 | for (let i = 1; i < numStatements; ++i) { 1481 | indent(sb, indentLevel); 1482 | this.visitNodeAndTerminate(statements[i]); 1483 | } 1484 | --this.indentLevel; 1485 | } 1486 | } 1487 | 1488 | visitSwitchStatement(node: SwitchStatement): void { 1489 | var sb = this.sb; 1490 | sb.push("switch ("); 1491 | this.visitNode(node.condition); 1492 | sb.push(") {\n"); 1493 | var indentLevel = ++this.indentLevel; 1494 | var cases = node.cases; 1495 | for (let i = 0, k = cases.length; i < k; ++i) { 1496 | indent(sb, indentLevel); 1497 | this.visitSwitchCase(cases[i]); 1498 | sb.push("\n"); 1499 | } 1500 | --this.indentLevel; 1501 | sb.push("}"); 1502 | } 1503 | 1504 | visitThrowStatement(node: ThrowStatement): void { 1505 | this.sb.push("throw "); 1506 | this.visitNode(node.value); 1507 | } 1508 | 1509 | visitTryStatement(node: TryStatement): void { 1510 | var sb = this.sb; 1511 | sb.push("try {\n"); 1512 | var indentLevel = ++this.indentLevel; 1513 | var statements = node.bodyStatements; 1514 | for (let i = 0, k = statements.length; i < k; ++i) { 1515 | indent(sb, indentLevel); 1516 | this.visitNodeAndTerminate(statements[i]); 1517 | } 1518 | var catchVariable = node.catchVariable; 1519 | if (catchVariable) { 1520 | indent(sb, indentLevel - 1); 1521 | sb.push("} catch ("); 1522 | this.visitIdentifierExpression(catchVariable); 1523 | sb.push(") {\n"); 1524 | let catchStatements = node.catchStatements; 1525 | if (catchStatements) { 1526 | for (let i = 0, k = catchStatements.length; i < k; ++i) { 1527 | indent(sb, indentLevel); 1528 | this.visitNodeAndTerminate(catchStatements[i]); 1529 | } 1530 | } 1531 | } 1532 | var finallyStatements = node.finallyStatements; 1533 | if (finallyStatements) { 1534 | indent(sb, indentLevel - 1); 1535 | sb.push("} finally {\n"); 1536 | for (let i = 0, k = finallyStatements.length; i < k; ++i) { 1537 | indent(sb, indentLevel); 1538 | this.visitNodeAndTerminate(finallyStatements[i]); 1539 | } 1540 | } 1541 | indent(sb, indentLevel - 1); 1542 | sb.push("}"); 1543 | } 1544 | 1545 | visitTypeDeclaration(node: TypeDeclaration): void { 1546 | var decorators = node.decorators; 1547 | if (decorators) { 1548 | for (let i = 0, k = decorators.length; i < k; ++i) { 1549 | this.serializeDecorator(decorators[i]); 1550 | } 1551 | } 1552 | var sb = this.sb; 1553 | this.serializeExternalModifiers(node); 1554 | sb.push("type "); 1555 | this.visitIdentifierExpression(node.name); 1556 | var typeParameters = node.typeParameters; 1557 | if (typeParameters) { 1558 | let numTypeParameters = typeParameters.length; 1559 | if (numTypeParameters) { 1560 | sb.push("<"); 1561 | for (let i = 0; i < numTypeParameters; ++i) { 1562 | this.visitTypeParameter(typeParameters[i]); 1563 | } 1564 | sb.push(">"); 1565 | } 1566 | } 1567 | sb.push(" = "); 1568 | this.visitTypeNode(node.type); 1569 | } 1570 | 1571 | visitVariableDeclaration(node: VariableDeclaration): void { 1572 | this.visitIdentifierExpression(node.name); 1573 | var type = node.type; 1574 | var sb = this.sb; 1575 | if (node.flags & CommonFlags.DefinitelyAssigned) { 1576 | sb.push("!"); 1577 | } 1578 | if (type) { 1579 | sb.push(": "); 1580 | this.visitTypeNode(type); 1581 | } 1582 | var initializer = node.initializer; 1583 | if (initializer) { 1584 | sb.push(" = "); 1585 | this.visitNode(initializer); 1586 | } 1587 | } 1588 | 1589 | visitVariableStatement(node: VariableStatement): void { 1590 | var decorators = node.decorators; 1591 | if (decorators) { 1592 | for (let i = 0, k = decorators.length; i < k; ++i) { 1593 | this.serializeDecorator(decorators[i]); 1594 | } 1595 | } 1596 | var sb = this.sb; 1597 | var declarations = node.declarations; 1598 | var numDeclarations = assert(declarations.length); 1599 | var firstDeclaration = declarations[0]; 1600 | this.serializeExternalModifiers(firstDeclaration); 1601 | sb.push( 1602 | firstDeclaration.is(CommonFlags.Const) 1603 | ? "const " 1604 | : firstDeclaration.is(CommonFlags.Let) 1605 | ? "let " 1606 | : "var " 1607 | ); 1608 | this.visitVariableDeclaration(node.declarations[0]); 1609 | for (let i = 1; i < numDeclarations; ++i) { 1610 | sb.push(", "); 1611 | this.visitVariableDeclaration(node.declarations[i]); 1612 | } 1613 | } 1614 | 1615 | visitWhileStatement(node: WhileStatement): void { 1616 | var sb = this.sb; 1617 | sb.push("while ("); 1618 | this.visitNode(node.condition); 1619 | var statement = node.body; 1620 | if (statement.kind == NodeKind.Empty) { 1621 | sb.push(")"); 1622 | } else { 1623 | sb.push(") "); 1624 | this.visitNode(node.body); 1625 | } 1626 | } 1627 | 1628 | // other 1629 | 1630 | serializeDecorator(node: DecoratorNode): void { 1631 | var sb = this.sb; 1632 | sb.push("@"); 1633 | this.visitNode(node.name); 1634 | var args = node.args; 1635 | if (args) { 1636 | sb.push("("); 1637 | let numArgs = args.length; 1638 | if (numArgs) { 1639 | this.visitNode(args[0]); 1640 | for (let i = 1; i < numArgs; ++i) { 1641 | sb.push(", "); 1642 | this.visitNode(args[i]); 1643 | } 1644 | } 1645 | sb.push(")\n"); 1646 | } else { 1647 | sb.push("\n"); 1648 | } 1649 | indent(sb, this.indentLevel); 1650 | } 1651 | 1652 | serializeParameter(node: ParameterNode): void { 1653 | var sb = this.sb; 1654 | var kind = node.parameterKind; 1655 | var implicitFieldDeclaration = node.implicitFieldDeclaration; 1656 | if (implicitFieldDeclaration) { 1657 | this.serializeAccessModifiers(implicitFieldDeclaration); 1658 | } 1659 | if (kind == ParameterKind.Rest) { 1660 | sb.push("..."); 1661 | } 1662 | this.visitIdentifierExpression(node.name); 1663 | var type = node.type; 1664 | var initializer = node.initializer; 1665 | if (type) { 1666 | if (kind == ParameterKind.Optional && !initializer) sb.push("?"); 1667 | if (!isTypeOmitted(type)) { 1668 | sb.push(": "); 1669 | this.visitTypeNode(type); 1670 | } 1671 | } 1672 | if (initializer) { 1673 | sb.push(" = "); 1674 | this.visitNode(initializer); 1675 | } 1676 | } 1677 | 1678 | serializeExternalModifiers(node: DeclarationStatement): void { 1679 | var sb = this.sb; 1680 | if (node.is(CommonFlags.Export)) { 1681 | sb.push("export "); 1682 | } else if (node.is(CommonFlags.Import)) { 1683 | sb.push("import "); 1684 | } else if (node.is(CommonFlags.Declare)) { 1685 | sb.push("declare "); 1686 | } 1687 | } 1688 | 1689 | serializeAccessModifiers(node: DeclarationStatement): void { 1690 | var sb = this.sb; 1691 | if (node.is(CommonFlags.Public)) { 1692 | sb.push("public "); 1693 | } else if (node.is(CommonFlags.Private)) { 1694 | sb.push("private "); 1695 | } else if (node.is(CommonFlags.Protected)) { 1696 | sb.push("protected "); 1697 | } 1698 | if (node.is(CommonFlags.Static)) { 1699 | sb.push("static "); 1700 | } else if (node.is(CommonFlags.Abstract)) { 1701 | sb.push("abstract "); 1702 | } 1703 | if (node.is(CommonFlags.Readonly)) { 1704 | sb.push("readonly "); 1705 | } 1706 | } 1707 | 1708 | finish(): string { 1709 | var ret = this.sb.join(""); 1710 | this.sb = []; 1711 | return ret; 1712 | } 1713 | } 1714 | --------------------------------------------------------------------------------