idlize
78 строк · 2.4 Кб
1/*
2* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14*/
15
16import * as ts from 'typescript';
17import { AbstractVisitor } from "./AbstractVisitor"
18import { FunctionKind, isAnyMemoKind, isMemoKind } from "./util"
19
20class FunctionScope<T> {
21constructor(
22public kind: FunctionKind,
23public data: T,
24){}
25}
26
27class FunctionScopes<T> {
28constructor() {}
29
30private stack: FunctionScope<T>[] = []
31
32push(kind: FunctionKind, data: T) {
33this.stack.push(new FunctionScope(kind, data))
34}
35pop() {
36this.stack.pop()
37}
38peek(): FunctionScope<T>|undefined {
39if (this.stack.length == 0) return undefined
40return this.stack[this.stack.length-1]
41}
42}
43
44export abstract class ScopedVisitor<T> extends AbstractVisitor {
45readonly functionScopes: FunctionScopes<T>
46constructor(
47public functionTable: Map<ts.SignatureDeclarationBase, FunctionKind>,
48ctx: ts.TransformationContext
49) {
50super(ctx)
51this.functionScopes = new FunctionScopes()
52}
53
54declarationKind(node: ts.FunctionLikeDeclarationBase): FunctionKind {
55const originalNode = ts.getOriginalNode(node) as ts.FunctionLikeDeclarationBase
56return this.functionTable.get(originalNode) ?? FunctionKind.REGULAR
57}
58
59currentKind(): FunctionKind {
60return this.functionScopes.peek()?.kind ?? FunctionKind.REGULAR
61}
62
63isAnyMemo(node: ts.FunctionLikeDeclarationBase): boolean {
64return isAnyMemoKind(this.declarationKind(node))
65}
66
67isMemoOrComponent(node: ts.FunctionLikeDeclarationBase): boolean {
68return isMemoKind(this.declarationKind(node))
69}
70
71withFunctionScope<R>(kind: FunctionKind, data: T, body: ()=>R): R {
72let result: R
73this.functionScopes.push(kind, data)
74result = body()
75this.functionScopes.pop()
76return result
77}
78}
79