idlize
127 строк · 4.3 Кб
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 { asString, CallTable } from './utils'
19import { Importer } from './Importer'
20
21export class LegacyCallTransformer extends AbstractVisitor {
22static parameterName = "elementId"
23static page = "page"
24static line = "line"
25static LegacyNode = "LegacyNode"
26
27constructor(
28sourceFile: ts.SourceFile,
29ctx: ts.TransformationContext,
30private importer: Importer,
31private callTable: CallTable
32) {
33super(sourceFile, ctx)
34}
35
36isLegacyStructCall(call: ts.CallExpression): boolean {
37const originalCall = ts.getOriginalNode(call) as ts.CallExpression
38return this.callTable.legacyCalls.has(originalCall)
39}
40
41createLambda(name: ts.Identifier): ts.Expression {
42const locationObject = ts.factory.createObjectLiteralExpression(
43[
44ts.factory.createPropertyAssignment(
45ts.factory.createIdentifier(LegacyCallTransformer.page),
46// TODO: entry/src/main/ets/pages/LocalPage.ets
47ts.factory.createStringLiteral("")
48),
49ts.factory.createPropertyAssignment(
50ts.factory.createIdentifier(LegacyCallTransformer.line),
51// TODO: provide line number
52ts.factory.createNumericLiteral("0")
53)
54],
55false
56)
57const emptyLambda = ts.factory.createArrowFunction(
58undefined,
59undefined,
60[],
61undefined,
62ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
63ts.factory.createBlock(
64[],
65false
66)
67)
68const emptyObject = ts.factory.createObjectLiteralExpression(
69[],
70false
71)
72const elementIdParameter = ts.factory.createParameterDeclaration(
73undefined,
74undefined,
75ts.factory.createIdentifier(LegacyCallTransformer.parameterName),
76undefined,
77ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword),
78undefined
79)
80const newExpression = ts.factory.createNewExpression(
81name,
82undefined,
83[
84ts.factory.createIdentifier("undefined"),
85emptyObject,
86ts.factory.createIdentifier("undefined"),
87ts.factory.createIdentifier(LegacyCallTransformer.parameterName),
88emptyLambda,
89locationObject
90]
91)
92return ts.factory.createArrowFunction(
93undefined,
94undefined,
95[ elementIdParameter ],
96undefined,
97ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
98newExpression
99)
100}
101
102transformLegacyCall(node: ts.CallExpression): ts.CallExpression {
103const name = node.expression as ts.Identifier
104const instanceLambda = this.createLambda(name)
105return ts.factory.createCallExpression(
106ts.factory.createIdentifier(
107this.importer.withAdaptorImport(LegacyCallTransformer.LegacyNode)
108),
109undefined,
110[ instanceLambda ],
111)
112}
113
114visitor(beforeChildren: ts.Node): ts.Node {
115const node = this.visitEachChild(beforeChildren)
116
117if (ts.isExpressionStatement(node) &&
118ts.isCallExpression(node.expression) &&
119ts.isIdentifier(node.expression.expression) &&
120this.isLegacyStructCall(node.expression)
121) {
122return this.transformLegacyCall(node.expression)
123}
124
125return node
126}
127}
128