idlize

Форк
0
/
CustomBuilderTransformer.ts 
105 строк · 3.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

16
import * as ts from 'ohos-typescript'
17
import { AbstractVisitor } from "./AbstractVisitor"
18
import { asString, CallTable, isBuilder, isGlobalBuilder, prependMemoComment } from './utils'
19
import { Void, getDeclarationsByNode, prependComment } from './ApiUtils'
20

21

22
export class CustomBuilderTransformer extends AbstractVisitor {
23

24
    public globalFunctions: string[] = []
25

26
	constructor(
27
		sourceFile: ts.SourceFile,
28
        ctx: ts.TransformationContext,
29
        private typechecker: ts.TypeChecker,
30
        private callTable: CallTable
31
	) {
32
        super(sourceFile, ctx)
33
    }
34

35
    refersToGlobalBuilder(call: ts.CallExpression): boolean {
36
        const originalCall = ts.getOriginalNode(call) as ts.CallExpression
37
        return this.callTable.globalBuilderCalls.has(originalCall)
38
    }
39

40
    refersToBuilderMethod(callee: ts.Expression): boolean {
41
        if (ts.isPropertyAccessExpression(callee)) {
42
            const declarations = getDeclarationsByNode(this.typechecker, callee.name)
43
            if (declarations.length == 0) return false
44
            const firstDeclaration = declarations[0]
45
            if (ts.isMethodDeclaration(firstDeclaration) &&
46
                isBuilder(firstDeclaration)
47
            ) return true
48
        }
49
        return false
50
    }
51

52
    isBuilderCall(node: ts.CallExpression): boolean {
53
        const callee = node.expression
54
        return this.refersToBuilderMethod(callee) ||
55
               this.refersToGlobalBuilder(node)
56
    }
57

58
    parentIsStatement(node: ts.CallExpression) {
59
        const original = ts.getOriginalNode(node)
60
        return (ts.isExpressionStatement(original.parent) || !original.parent)
61
    }
62

63
    private wrapInMemoLambda(node: ts.CallExpression): ts.Expression {
64
        const lambda = ts.factory.createArrowFunction(
65
            undefined,
66
            undefined,
67
            [],
68
            Void(),
69
            ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
70
            node
71
        )
72
        return prependMemoComment(
73
            // This is an expression so make sure memo is a separate line
74
            prependComment(lambda, " ")
75
        )
76
    }
77

78
    private wrapPropertyInMemoLambdaCall(node: ts.PropertyAccessExpression): ts.Expression {
79
        const lambda = ts.factory.createArrowFunction(
80
            undefined,
81
            undefined,
82
            [],
83
            undefined,
84
            ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
85
            ts.factory.createCallExpression(node, undefined, undefined)
86
        )
87
        return prependMemoComment(
88
            // This is an expression so make sure memo is a separate line
89
            prependComment(lambda, " ")
90
        )
91
    }
92

93
    visitor(beforeChildren: ts.Node): ts.Node {
94
        const node = this.visitEachChild(beforeChildren)
95

96
        if (ts.isCallExpression(node) &&
97
            this.isBuilderCall(node) &&
98
            !this.parentIsStatement(node)
99
        ) {
100
            return this.wrapInMemoLambda(node)
101
        }
102

103
        return node
104
    }
105
}
106

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

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

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

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