idlize
74 строки · 2.5 Кб
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 "ohos-typescript"
17import { AbstractVisitor } from "./AbstractVisitor";
18import { NameTable } from "./utils";
19
20
21export class DollarTransformer extends AbstractVisitor {
22constructor(
23sourceFile: ts.SourceFile,
24ctx: ts.TransformationContext,
25private nameTable: NameTable
26) {
27super(sourceFile, ctx)
28}
29
30currentStruct: ts.StructDeclaration | undefined = undefined
31
32whiteList = ["$$", "$r", "$rawfile"]
33
34isDollarVariableAccess(node: ts.Identifier): boolean {
35const name = ts.idText(node)
36if (!name.startsWith("$")) return false
37const fieldName = name.substring(1)
38// TODO: is it correct?
39// The white list has a preference over the fields.
40if (this.whiteList.includes(name)) return false
41if (!this.currentStruct) return false
42if (this.currentStruct.members.find(it => (
43it.name &&
44ts.isIdentifier(it.name) &&
45ts.idText(it.name) == fieldName
46)) == undefined) return false
47// Already has a receiver.
48if (ts.isPropertyAccessExpression(node.parent)) return false
49
50return true
51}
52
53transformDollarVariableAccess(node: ts.Identifier): ts.Expression {
54this.nameTable.dollars.push(ts.idText(node))
55return ts.factory.createPropertyAccessExpression(
56ts.factory.createThis(),
57node
58)
59}
60
61visitor(node: ts.Node): ts.Node {
62if (ts.isStruct(node)) {
63this.currentStruct = node
64const transformed = this.visitEachChild(node)
65this.currentStruct = undefined
66return transformed
67} else if (ts.isIdentifier(node)) {
68if (this.currentStruct && this.isDollarVariableAccess(node)) {
69return this.transformDollarVariableAccess(node)
70}
71}
72return this.visitEachChild(node)
73}
74}