idlize
93 строки · 3.1 Кб
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 { ScopedVisitor } from './ScopedVisitor';
18import {
19FunctionKind,
20Tracer,
21isTrackableParameter,
22parameterStateName as localStateName,
23PositionalIdTracker,
24runtimeIdentifier,
25RuntimeNames,
26isFunctionOrMethod,
27getDeclarationsByNode,
28isMemoKind,
29asString,
30} from "./util"
31
32export class ParameterTransformer extends ScopedVisitor<void> {
33constructor(
34public tracer: Tracer,
35public typechecker: ts.TypeChecker,
36public sourceFile: ts.SourceFile,
37public positionalIdTracker: PositionalIdTracker,
38public functionTable: Map<ts.SignatureDeclarationBase, FunctionKind>,
39ctx: ts.TransformationContext
40) {
41super(functionTable, ctx)
42}
43
44transformParameterUse(node: ts.Identifier): ts.PropertyAccessExpression {
45const originalName = ts.idText(node)
46const newName = localStateName(originalName)
47
48return ts.factory.createPropertyAccessExpression(
49ts.factory.createIdentifier(newName),
50runtimeIdentifier(RuntimeNames.VALUE)
51)
52}
53
54isTrackedParameter(node: ts.Identifier): boolean {
55const declarations = getDeclarationsByNode(this.typechecker, node)
56const declaration = declarations[0]
57if (!declaration) return false
58if (!ts.isParameter(declaration)) return false
59if (!isTrackableParameter(this.sourceFile, declaration)) return false
60
61const func = declaration.parent
62if (!isFunctionOrMethod(func)) return false
63
64const originalFunc = ts.getOriginalNode(func) as ts.FunctionLikeDeclarationBase
65const kind = this.functionTable.get(originalFunc)
66
67return isMemoKind(kind)
68}
69
70visitor(node: ts.Node): ts.Node {
71if (ts.isParameter(node)) {
72return ts.factory.updateParameterDeclaration(
73node,
74node.modifiers,
75node.dotDotDotToken,
76node.name,
77node.questionToken,
78node.type,
79node.initializer ?
80this.visitEachChild(node.initializer) as ts.Expression :
81undefined
82)
83}
84if (isFunctionOrMethod(node)) {
85const kind = this.declarationKind(node)
86return this.withFunctionScope(kind, undefined, ()=>this.visitEachChild(node))
87}
88if (ts.isIdentifier(node) && this.isTrackedParameter(node)) {
89return this.transformParameterUse(node)
90}
91return this.visitEachChild(node)
92}
93}
94