idlize
238 строк · 7.0 Кб
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 { filterDecorators } from "./utils"18
19export function parameter(20name: string|ts.Identifier,21type: ts.TypeNode | undefined,22initializer?: ts.Expression23) {24return ts.factory.createParameterDeclaration(25undefined,26undefined,27undefined,28name,29undefined,30type,31initializer
32)33}
34
35export function optionalParameter(36name: string|ts.Identifier,37type: ts.TypeNode | undefined,38initializer?: ts.Expression39) {40return ts.factory.createParameterDeclaration(41undefined,42undefined,43undefined,44name,45ts.factory.createToken(ts.SyntaxKind.QuestionToken),46type,47initializer
48)49}
50
51export function assignment(left: ts.Expression, right: ts.Expression): ts.ExpressionStatement {52return ts.factory.createExpressionStatement(53ts.factory.createBinaryExpression(54left,55ts.factory.createToken(ts.SyntaxKind.EqualsToken),56right
57)58)59}
60
61export function tripleNotEqualsUndefined(left: ts.Expression): ts.Expression {62return ts.factory.createBinaryExpression(63left,64ts.factory.createToken(ts.SyntaxKind.ExclamationEqualsEqualsToken),65undefinedValue()66)67}
68
69export function id(name: string): ts.Identifier {70return ts.factory.createIdentifier(name)71}
72
73export function Any(): ts.TypeNode {74return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)75}
76
77export function Undefined() {78return ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword)79}
80
81export function Void() {82return ts.factory.createToken(ts.SyntaxKind.VoidKeyword)83}
84
85export function Export() {86return ts.factory.createToken(ts.SyntaxKind.ExportKeyword)87}
88
89export function Private() {90return ts.factory.createToken(ts.SyntaxKind.PrivateKeyword)91}
92
93export function Exclamation() {94return ts.factory.createToken(ts.SyntaxKind.ExclamationToken)95}
96
97export function undefinedValue(): ts.Expression {98return ts.factory.createIdentifier("undefined")99}
100
101export function partialForName(className: string) {102return ts.factory.createTypeReferenceNode(103"Partial",104[105ts.factory.createTypeReferenceNode(className)106]107)108}
109
110export function partial(className: ts.Identifier) {111return ts.factory.createTypeReferenceNode(112"Partial",113[114ts.factory.createTypeReferenceNode(ts.idText(className))115]116)117}
118
119export function anyIfNoType(type: ts.TypeNode | undefined): ts.TypeNode {120if (!type) return Any()121return type122}
123
124
125export function provideAnyTypeIfNone(parameter: ts.ParameterDeclaration): ts.ParameterDeclaration {126return ts.factory.updateParameterDeclaration(127parameter,128parameter.modifiers,129parameter.dotDotDotToken,130parameter.name,131parameter.questionToken,132anyIfNoType(parameter.type),133parameter.initializer134)135}
136
137export function orUndefined(type: ts.TypeNode): ts.TypeNode {138return ts.factory.createUnionTypeNode([139type,140Undefined()141])142}
143
144export function isKnownIdentifier(name: ts.Node | undefined, value: string): boolean {145return (name != undefined) &&146(ts.isIdentifier(name) || ts.isPrivateIdentifier(name)) &&147ts.idText(name) == value148}
149
150export function isUndefined(node: ts.Expression): boolean {151return node.kind == ts.SyntaxKind.UndefinedKeyword ||152ts.isIdentifier(node) && ts.idText(node) == "undefined"153}
154
155export function prependComment<T extends ts.Node>(node: T, comment: string): T {156return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, comment, true);157}
158
159export function isDecorator(modifierLike: ts.ModifierLike, name: string): boolean {160if (!ts.isDecorator(modifierLike)) {161return false162}163return isKnownIdentifier(modifierLike.expression, name) || isCallDecorator(modifierLike, name)164}
165
166export function isCallDecorator(decorator: ts.Decorator, name: string): boolean {167return ts.isCallExpression(decorator.expression) && isKnownIdentifier(decorator.expression.expression, name)168}
169
170export function hasDecorator(node: ts.Node, name: string): boolean {171return getDecorator(node, name) != undefined172}
173
174export function getDecorator(node: ts.Node, name: string): ts.Decorator | undefined {175return filterDecorators(node)?.find(it => isDecorator(it, name))176}
177
178export function findDecoratorArguments(179decorators: ReadonlyArray<ts.Decorator> | undefined,180name: string,181nth: number182): ReadonlyArray<ts.Expression> | undefined {183return decorators184?.filter(it => isCallDecorator(it, name))185?.map(it => (it.expression as ts.CallExpression).arguments[nth])186}
187
188export function findDecoratorLiterals(189decorators: ReadonlyArray<ts.Decorator> | undefined,190name: string,191nth: number,192): ReadonlyArray<string> | undefined {193return findDecoratorArguments(decorators, name, nth)?.map(it => (it as ts.StringLiteral).text)194}
195
196export function findDecoratorArgument(197decorators: ReadonlyArray<ts.Decorator> | undefined,198name: string,199nth: number,200): ts.Expression {201const args = findDecoratorArguments(decorators, name, nth)202if (args?.length === 1) return args[0]203throw new Error(name + " must have only one argument, but got " + args?.length)204}
205
206export function createThisFieldAccess(name: string | ts.Identifier | ts.PrivateIdentifier): ts.Expression {207return ts.factory.createPropertyAccessExpression(208ts.factory.createThis(),209name
210)211}
212
213export function bindThis(expression: ts.Expression): ts.Expression {214return ts.factory.createCallExpression(215ts.factory.createPropertyAccessExpression(216expression,217"bind"218),219undefined,220[ts.factory.createThis()]221)222
223}
224
225
226export function getLineNumber(sourceFile: ts.SourceFile, position: number): number {227return ts.getLineAndCharacterOfPosition(sourceFile, position).line + 1 // First line is 1.228}
229
230export function getDeclarationsByNode(typechecker: ts.TypeChecker, node: ts.Node): ts.Declaration[] {231const symbol = typechecker.getSymbolAtLocation(node)232const declarations = symbol?.getDeclarations() ?? []233return declarations234}
235
236export function dropReadonly(modifierLikes: ts.ModifierLike[] | undefined): ts.ModifierLike[] | undefined {237return modifierLikes?.filter(it => it.kind != ts.SyntaxKind.ReadonlyKeyword)238}
239