idlize

Форк
0
/
ExtensionStylesTransformer.ts 
211 строк · 8.9 Кб
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

16
import * as ts from 'ohos-typescript'
17
import { AbstractVisitor } from './AbstractVisitor'
18
import { Importer } from './Importer'
19
import { ExtendDecorator, StylesDecorator, typeParameterExtendsType, adaptorComponentName, AnimatableExtendDecorator, getAnnotationArgument, prependMemoComment, dropStylesLike, asString, ArkCommonMethod, T_TypeParameter, Instance, CommonInstance, extendsLikeFunctionName } from './utils'
20
import { Any, getDecorator, hasDecorator, id, parameter } from './ApiUtils'
21

22
function rewriteStyles(node: ts.FunctionDeclaration, importer: Importer): ts.FunctionDeclaration {
23
    const firstParameter = parameter(
24
        CommonInstance,
25
        //ts.factory.createTypeReferenceNode(T_TypeParameter),
26
        Any()
27
    )
28

29
    const singleExpressionStatement = node.body?.statements?.[0]
30
    if (!singleExpressionStatement) return node
31
    if (!ts.isExpressionStatement(singleExpressionStatement)) return node
32

33
    const declaration = ts.factory.createFunctionDeclaration(
34
        // @Styles dropped as "Illegal decorator" because of create instead of update
35
        // We could not make updateFunctionDecl() remove the illegal decorators
36
        node.modifiers,
37
        node.asteriskToken,
38
        node.name,
39
        [typeParameterExtendsType(
40
            T_TypeParameter,
41
            importer.withArkuiCommonImport(ArkCommonMethod),
42
            [T_TypeParameter]
43
        )],
44
        [firstParameter, ...node.parameters],
45
        ts.factory.createTypeReferenceNode(T_TypeParameter),
46
        ts.factory.createBlock([
47
            ts.factory.createReturnStatement(singleExpressionStatement.expression)
48
        ], true)
49
    )
50

51
    return importer.__isArkoalaImplementation ? prependMemoComment(declaration) : declaration
52
}
53

54
function rewriteStylesMethod(node: ts.MethodDeclaration, importer: Importer): ts.MethodDeclaration {
55
    const firstParameter = parameter(
56
        CommonInstance,
57
        //ts.factory.createTypeReferenceNode(T_TypeParameter),
58
        Any()
59
    )
60

61
    const singleExpressionStatement = node.body?.statements?.[0]
62
    if (!singleExpressionStatement) return node
63
    if (!ts.isExpressionStatement(singleExpressionStatement)) return node
64

65
    const declaration = ts.factory.createMethodDeclaration(
66
        dropStylesLike(node.modifiers),
67
        node.asteriskToken,
68
        node.name,
69
        node.questionToken,
70
        [typeParameterExtendsType(
71
            T_TypeParameter,
72
            importer.withArkuiCommonImport(ArkCommonMethod),
73
            [T_TypeParameter]
74
        )],
75
        [firstParameter, ...node.parameters],
76
        ts.factory.createTypeReferenceNode(T_TypeParameter),
77
        ts.factory.createBlock([
78
            ts.factory.createReturnStatement(singleExpressionStatement.expression)
79
        ], true)
80
    )
81

82
    return importer.__isArkoalaImplementation ? prependMemoComment(declaration) : declaration
83
}
84

85
function rewriteExtend(node: ts.FunctionDeclaration, extendType: string, importer: Importer): ts.FunctionDeclaration {
86
    const firstParameter = parameter(
87
        extendType + Instance,
88
        //ts.factory.createTypeReferenceNode(T_TypeParameter),
89
        Any()
90
    )
91

92
    const singleExpressionStatement = node.body?.statements?.[0]
93
    if (!singleExpressionStatement) return node
94
    if (!ts.isExpressionStatement(singleExpressionStatement)) return node
95

96
    const declaration = ts.factory.createFunctionDeclaration(
97
        // @Extend dropped as "Illegal decorator" because of create instead of update
98
        // We could not make updateFunctionDecl() remove the illegal decorators
99
        node.modifiers,
100
        node.asteriskToken,
101
        id(extendsLikeFunctionName(ts.idText(node.name!), extendType)),
102
        [typeParameterExtendsType(
103
            T_TypeParameter,
104
            adaptorComponentName(extendType),
105
            []
106
        )],
107
        [firstParameter, ...node.parameters],
108
        ts.factory.createTypeReferenceNode(adaptorComponentName(extendType)),
109
        ts.factory.createBlock([
110
            ts.factory.createReturnStatement(singleExpressionStatement.expression)
111
        ], true)
112
    )
113
    return importer.__isArkoalaImplementation ? prependMemoComment(declaration) : declaration
114
}
115

116
function rewriteExtendMethod(node: ts.MethodDeclaration, extendType: string, importer: Importer): ts.MethodDeclaration {
117
    const firstParameter = parameter(
118
        extendType + Instance,
119
        //ts.factory.createTypeReferenceNode(T_TypeParameter),
120
        Any()
121
    )
122

123
    const singleExpressionStatement = node.body?.statements?.[0]
124
    if (!singleExpressionStatement) return node
125
    if (!ts.isExpressionStatement(singleExpressionStatement)) return node
126

127
    const declaration = ts.factory.updateMethodDeclaration(
128
        node,
129
        dropStylesLike(node.modifiers)?.concat(ts.factory.createToken(ts.SyntaxKind.StaticKeyword)),
130
        node.asteriskToken,
131
        id(extendsLikeFunctionName(ts.idText(node.name! as ts.Identifier), extendType)),
132
        node.questionToken,
133
        [typeParameterExtendsType(T_TypeParameter, adaptorComponentName(extendType), [])],
134
        [firstParameter, ...node.parameters],
135
        ts.factory.createTypeReferenceNode(adaptorComponentName(extendType)),
136
        ts.factory.createBlock([
137
            ts.factory.createReturnStatement(singleExpressionStatement.expression)
138
        ], true)
139
    )
140
    return importer.__isArkoalaImplementation ? prependMemoComment(declaration) : declaration
141
}
142

143
export class ExtensionStylesTransformer extends AbstractVisitor {
144
    public stylesFunctions: string[] = []
145
    public extendFunctions: string[] = []
146
    public animatableExtendFunctions: string[] = []
147
    public stylesMethods: ts.Node[] = []
148
    public extendMethods: ts.Node[] = []
149
    public animatableExtendMethods: ts.Node[] = []
150

151
    constructor(
152
        sourceFile: ts.SourceFile,
153
        ctx: ts.TransformationContext,
154
        public typechecker: ts.TypeChecker,
155
        public importer: Importer
156
    ) {
157
        super(sourceFile, ctx)
158
    }
159

160
    visitor(beforeChildren: ts.Node): ts.Node {
161
        const node = this.visitEachChild(beforeChildren)
162

163
        if (ts.isFunctionDeclaration(node)) {
164
            if (hasDecorator(node, StylesDecorator)) {
165
                this.stylesFunctions.push(ts.idText(node.name!))
166
                return rewriteStyles(node, this.importer)
167
            }
168
            if (hasDecorator(node, ExtendDecorator)) {
169
                const decorator = getDecorator(node, ExtendDecorator)!
170
                const extensibleType = ts.idText(getAnnotationArgument(decorator)!)
171
                this.extendFunctions.push(extendsLikeFunctionName(ts.idText(node.name!), extensibleType))
172
                return rewriteExtend(node, extensibleType, this.importer)
173
            }
174
            if (hasDecorator(node, AnimatableExtendDecorator)) {
175
                const decorator = getDecorator(node, AnimatableExtendDecorator)!
176
                const extensibleType = ts.idText(getAnnotationArgument(decorator)!)
177
                this.animatableExtendFunctions.push(extendsLikeFunctionName(ts.idText(node.name!), extensibleType))
178
                return rewriteExtend(node, extensibleType, this.importer)
179
            }
180
        }
181
        if (ts.isMethodDeclaration(node)) {
182
            if (hasDecorator(node, StylesDecorator)) {
183
                this.stylesMethods.push(ts.getOriginalNode(node))
184
                return rewriteStylesMethod(node, this.importer)
185
            }
186
            if (hasDecorator(node, ExtendDecorator)) {
187
                const decorator = getDecorator(node, ExtendDecorator)!
188
                const extensibleType = ts.idText(getAnnotationArgument(decorator)!)
189
                this.extendMethods.push(ts.getOriginalNode(node))
190
                return rewriteExtendMethod(node, extensibleType, this.importer)
191
            }
192
            if (hasDecorator(node, AnimatableExtendDecorator)) {
193
                const decorator = getDecorator(node, AnimatableExtendDecorator)!
194
                const extensibleType = ts.idText(getAnnotationArgument(decorator)!)
195
                this.animatableExtendMethods.push(ts.getOriginalNode(node))
196
                return rewriteExtendMethod(node, extensibleType, this.importer)
197
            }
198
        }
199
        if (ts.isIdentifier(node)) {
200
            if (ts.idText(node) == CommonInstance) {
201
                return id(CommonInstance)
202
            }
203
            if (ts.idText(node).endsWith(Instance)) {
204
                const instanceName = ts.idText(node).slice(0, -8)
205
                return id(instanceName + Instance)
206
            }
207
        }
208

209
        return node
210
    }
211
}
212

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.