13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ciimport * as path from 'node:path';
173af6ab5fSopenharmony_ciimport * as ts from 'typescript';
183af6ab5fSopenharmony_ciimport type { IsEtsFileCallback } from '../IsEtsFileCallback';
193af6ab5fSopenharmony_ciimport { FaultID } from '../Problems';
203af6ab5fSopenharmony_ciimport { ARKTS_IGNORE_DIRS, ARKTS_IGNORE_FILES } from './consts/ArktsIgnorePaths';
213af6ab5fSopenharmony_ciimport { ES_OBJECT } from './consts/ESObject';
223af6ab5fSopenharmony_ciimport { EXTENDED_BASE_TYPES } from './consts/ExtendedBaseTypes';
233af6ab5fSopenharmony_ciimport { SENDABLE_DECORATOR } from './consts/SendableAPI';
243af6ab5fSopenharmony_ciimport { USE_SHARED } from './consts/SharedModuleAPI';
253af6ab5fSopenharmony_ciimport { STANDARD_LIBRARIES } from './consts/StandardLibraries';
263af6ab5fSopenharmony_ciimport {
273af6ab5fSopenharmony_ci  ARKTS_COLLECTIONS_D_ETS,
283af6ab5fSopenharmony_ci  ARKTS_LANG_D_ETS,
293af6ab5fSopenharmony_ci  COLLECTIONS_NAMESPACE,
303af6ab5fSopenharmony_ci  ISENDABLE_TYPE,
313af6ab5fSopenharmony_ci  LANG_NAMESPACE
323af6ab5fSopenharmony_ci} from './consts/SupportedDetsIndexableTypes';
333af6ab5fSopenharmony_ciimport { TYPED_ARRAYS } from './consts/TypedArrays';
343af6ab5fSopenharmony_ciimport { forEachNodeInSubtree } from './functions/ForEachNodeInSubtree';
353af6ab5fSopenharmony_ciimport { getScriptKind } from './functions/GetScriptKind';
363af6ab5fSopenharmony_ciimport { isStdLibrarySymbol, isStdLibraryType } from './functions/IsStdLibrary';
373af6ab5fSopenharmony_ciimport { isStructDeclaration, isStructDeclarationKind } from './functions/IsStruct';
383af6ab5fSopenharmony_ciimport type { NameGenerator } from './functions/NameGenerator';
393af6ab5fSopenharmony_ciimport { srcFilePathContainsDirectory } from './functions/PathHelper';
403af6ab5fSopenharmony_ciimport { isAssignmentOperator } from './functions/isAssignmentOperator';
413af6ab5fSopenharmony_ciimport { isIntrinsicObjectType } from './functions/isIntrinsicObjectType';
423af6ab5fSopenharmony_ci
433af6ab5fSopenharmony_ciexport const SYMBOL = 'Symbol';
443af6ab5fSopenharmony_ciexport const SYMBOL_CONSTRUCTOR = 'SymbolConstructor';
453af6ab5fSopenharmony_ciconst ITERATOR = 'iterator';
463af6ab5fSopenharmony_ci
473af6ab5fSopenharmony_ciexport type CheckType = (this: TsUtils, t: ts.Type) => boolean;
483af6ab5fSopenharmony_ciexport class TsUtils {
493af6ab5fSopenharmony_ci  constructor(
503af6ab5fSopenharmony_ci    private readonly tsTypeChecker: ts.TypeChecker,
513af6ab5fSopenharmony_ci    private readonly testMode: boolean,
523af6ab5fSopenharmony_ci    private readonly advancedClassChecks: boolean,
533af6ab5fSopenharmony_ci    private readonly useSdkLogic: boolean,
543af6ab5fSopenharmony_ci    private readonly arkts2: boolean
553af6ab5fSopenharmony_ci  ) {}
563af6ab5fSopenharmony_ci
573af6ab5fSopenharmony_ci  entityNameToString(name: ts.EntityName): string {
583af6ab5fSopenharmony_ci    if (ts.isIdentifier(name)) {
593af6ab5fSopenharmony_ci      return name.escapedText.toString();
603af6ab5fSopenharmony_ci    }
613af6ab5fSopenharmony_ci    return this.entityNameToString(name.left) + this.entityNameToString(name.right);
623af6ab5fSopenharmony_ci  }
633af6ab5fSopenharmony_ci
643af6ab5fSopenharmony_ci  isNumberLikeType(tsType: ts.Type): boolean {
653af6ab5fSopenharmony_ci    if (!this.useSdkLogic && tsType.isUnion()) {
663af6ab5fSopenharmony_ci      for (const tsCompType of tsType.types) {
673af6ab5fSopenharmony_ci        if ((tsCompType.flags & ts.TypeFlags.NumberLike) === 0) {
683af6ab5fSopenharmony_ci          return false;
693af6ab5fSopenharmony_ci        }
703af6ab5fSopenharmony_ci      }
713af6ab5fSopenharmony_ci      return true;
723af6ab5fSopenharmony_ci    }
733af6ab5fSopenharmony_ci    return (tsType.getFlags() & ts.TypeFlags.NumberLike) !== 0;
743af6ab5fSopenharmony_ci  }
753af6ab5fSopenharmony_ci
763af6ab5fSopenharmony_ci  static isBooleanLikeType(tsType: ts.Type): boolean {
773af6ab5fSopenharmony_ci    return (tsType.getFlags() & ts.TypeFlags.BooleanLike) !== 0;
783af6ab5fSopenharmony_ci  }
793af6ab5fSopenharmony_ci
803af6ab5fSopenharmony_ci  static isDestructuringAssignmentLHS(tsExpr: ts.ArrayLiteralExpression | ts.ObjectLiteralExpression): boolean {
813af6ab5fSopenharmony_ci
823af6ab5fSopenharmony_ci    /*
833af6ab5fSopenharmony_ci     * Check whether given expression is the LHS part of the destructuring
843af6ab5fSopenharmony_ci     * assignment (or is a nested element of destructuring pattern).
853af6ab5fSopenharmony_ci     */
863af6ab5fSopenharmony_ci    let tsParent = tsExpr.parent;
873af6ab5fSopenharmony_ci    let tsCurrentExpr: ts.Node = tsExpr;
883af6ab5fSopenharmony_ci    while (tsParent) {
893af6ab5fSopenharmony_ci      if (
903af6ab5fSopenharmony_ci        ts.isBinaryExpression(tsParent) &&
913af6ab5fSopenharmony_ci        isAssignmentOperator(tsParent.operatorToken) &&
923af6ab5fSopenharmony_ci        tsParent.left === tsCurrentExpr
933af6ab5fSopenharmony_ci      ) {
943af6ab5fSopenharmony_ci        return true;
953af6ab5fSopenharmony_ci      }
963af6ab5fSopenharmony_ci
973af6ab5fSopenharmony_ci      if (
983af6ab5fSopenharmony_ci        (ts.isForStatement(tsParent) || ts.isForInStatement(tsParent) || ts.isForOfStatement(tsParent)) &&
993af6ab5fSopenharmony_ci        tsParent.initializer &&
1003af6ab5fSopenharmony_ci        tsParent.initializer === tsCurrentExpr
1013af6ab5fSopenharmony_ci      ) {
1023af6ab5fSopenharmony_ci        return true;
1033af6ab5fSopenharmony_ci      }
1043af6ab5fSopenharmony_ci
1053af6ab5fSopenharmony_ci      tsCurrentExpr = tsParent;
1063af6ab5fSopenharmony_ci      tsParent = tsParent.parent;
1073af6ab5fSopenharmony_ci    }
1083af6ab5fSopenharmony_ci
1093af6ab5fSopenharmony_ci    return false;
1103af6ab5fSopenharmony_ci  }
1113af6ab5fSopenharmony_ci
1123af6ab5fSopenharmony_ci  static isEnumType(tsType: ts.Type): boolean {
1133af6ab5fSopenharmony_ci    // when type equals `typeof <Enum>`, only symbol contains information about it's type.
1143af6ab5fSopenharmony_ci    const isEnumSymbol = tsType.symbol && this.isEnum(tsType.symbol);
1153af6ab5fSopenharmony_ci    // otherwise, we should analyze flags of the type itself
1163af6ab5fSopenharmony_ci    const isEnumType = !!(tsType.flags & ts.TypeFlags.Enum) || !!(tsType.flags & ts.TypeFlags.EnumLiteral);
1173af6ab5fSopenharmony_ci    return isEnumSymbol || isEnumType;
1183af6ab5fSopenharmony_ci  }
1193af6ab5fSopenharmony_ci
1203af6ab5fSopenharmony_ci  static isEnum(tsSymbol: ts.Symbol): boolean {
1213af6ab5fSopenharmony_ci    return !!(tsSymbol.flags & ts.SymbolFlags.Enum);
1223af6ab5fSopenharmony_ci  }
1233af6ab5fSopenharmony_ci
1243af6ab5fSopenharmony_ci  static hasModifier(tsModifiers: readonly ts.Modifier[] | undefined, tsModifierKind: number): boolean {
1253af6ab5fSopenharmony_ci    if (!tsModifiers) {
1263af6ab5fSopenharmony_ci      return false;
1273af6ab5fSopenharmony_ci    }
1283af6ab5fSopenharmony_ci
1293af6ab5fSopenharmony_ci    for (const tsModifier of tsModifiers) {
1303af6ab5fSopenharmony_ci      if (tsModifier.kind === tsModifierKind) {
1313af6ab5fSopenharmony_ci        return true;
1323af6ab5fSopenharmony_ci      }
1333af6ab5fSopenharmony_ci    }
1343af6ab5fSopenharmony_ci
1353af6ab5fSopenharmony_ci    return false;
1363af6ab5fSopenharmony_ci  }
1373af6ab5fSopenharmony_ci
1383af6ab5fSopenharmony_ci  static unwrapParenthesized(tsExpr: ts.Expression): ts.Expression {
1393af6ab5fSopenharmony_ci    let unwrappedExpr = tsExpr;
1403af6ab5fSopenharmony_ci    while (ts.isParenthesizedExpression(unwrappedExpr)) {
1413af6ab5fSopenharmony_ci      unwrappedExpr = unwrappedExpr.expression;
1423af6ab5fSopenharmony_ci    }
1433af6ab5fSopenharmony_ci
1443af6ab5fSopenharmony_ci    return unwrappedExpr;
1453af6ab5fSopenharmony_ci  }
1463af6ab5fSopenharmony_ci
1473af6ab5fSopenharmony_ci  followIfAliased(sym: ts.Symbol): ts.Symbol {
1483af6ab5fSopenharmony_ci    if ((sym.getFlags() & ts.SymbolFlags.Alias) !== 0) {
1493af6ab5fSopenharmony_ci      return this.tsTypeChecker.getAliasedSymbol(sym);
1503af6ab5fSopenharmony_ci    }
1513af6ab5fSopenharmony_ci    return sym;
1523af6ab5fSopenharmony_ci  }
1533af6ab5fSopenharmony_ci
1543af6ab5fSopenharmony_ci  private readonly trueSymbolAtLocationCache = new Map<ts.Node, ts.Symbol | null>();
1553af6ab5fSopenharmony_ci
1563af6ab5fSopenharmony_ci  trueSymbolAtLocation(node: ts.Node): ts.Symbol | undefined {
1573af6ab5fSopenharmony_ci    const cache = this.trueSymbolAtLocationCache;
1583af6ab5fSopenharmony_ci    const val = cache.get(node);
1593af6ab5fSopenharmony_ci    if (val !== undefined) {
1603af6ab5fSopenharmony_ci      return val !== null ? val : undefined;
1613af6ab5fSopenharmony_ci    }
1623af6ab5fSopenharmony_ci    let sym = this.tsTypeChecker.getSymbolAtLocation(node);
1633af6ab5fSopenharmony_ci    if (sym === undefined) {
1643af6ab5fSopenharmony_ci      cache.set(node, null);
1653af6ab5fSopenharmony_ci      return undefined;
1663af6ab5fSopenharmony_ci    }
1673af6ab5fSopenharmony_ci    sym = this.followIfAliased(sym);
1683af6ab5fSopenharmony_ci    cache.set(node, sym);
1693af6ab5fSopenharmony_ci    return sym;
1703af6ab5fSopenharmony_ci  }
1713af6ab5fSopenharmony_ci
1723af6ab5fSopenharmony_ci  private static isTypeDeclSyntaxKind(kind: ts.SyntaxKind): boolean {
1733af6ab5fSopenharmony_ci    return (
1743af6ab5fSopenharmony_ci      isStructDeclarationKind(kind) ||
1753af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.EnumDeclaration ||
1763af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.ClassDeclaration ||
1773af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.InterfaceDeclaration ||
1783af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.TypeAliasDeclaration
1793af6ab5fSopenharmony_ci    );
1803af6ab5fSopenharmony_ci  }
1813af6ab5fSopenharmony_ci
1823af6ab5fSopenharmony_ci  static symbolHasDuplicateName(symbol: ts.Symbol, tsDeclKind: ts.SyntaxKind): boolean {
1833af6ab5fSopenharmony_ci
1843af6ab5fSopenharmony_ci    /*
1853af6ab5fSopenharmony_ci     * Type Checker merges all declarations with the same name in one scope into one symbol.
1863af6ab5fSopenharmony_ci     * Thus, check whether the symbol of certain declaration has any declaration with
1873af6ab5fSopenharmony_ci     * different syntax kind.
1883af6ab5fSopenharmony_ci     */
1893af6ab5fSopenharmony_ci    const symbolDecls = symbol?.getDeclarations();
1903af6ab5fSopenharmony_ci    if (symbolDecls) {
1913af6ab5fSopenharmony_ci      for (const symDecl of symbolDecls) {
1923af6ab5fSopenharmony_ci        const declKind = symDecl.kind;
1933af6ab5fSopenharmony_ci        // we relax arkts-unique-names for namespace collision with class/interface/enum/type/struct
1943af6ab5fSopenharmony_ci        const isNamespaceTypeCollision =
1953af6ab5fSopenharmony_ci          TsUtils.isTypeDeclSyntaxKind(declKind) && tsDeclKind === ts.SyntaxKind.ModuleDeclaration ||
1963af6ab5fSopenharmony_ci          TsUtils.isTypeDeclSyntaxKind(tsDeclKind) && declKind === ts.SyntaxKind.ModuleDeclaration;
1973af6ab5fSopenharmony_ci
1983af6ab5fSopenharmony_ci        /*
1993af6ab5fSopenharmony_ci         * Don't count declarations with 'Identifier' syntax kind as those
2003af6ab5fSopenharmony_ci         * usually depict declaring an object's property through assignment.
2013af6ab5fSopenharmony_ci         */
2023af6ab5fSopenharmony_ci        if (declKind !== ts.SyntaxKind.Identifier && declKind !== tsDeclKind && !isNamespaceTypeCollision) {
2033af6ab5fSopenharmony_ci          return true;
2043af6ab5fSopenharmony_ci        }
2053af6ab5fSopenharmony_ci      }
2063af6ab5fSopenharmony_ci    }
2073af6ab5fSopenharmony_ci
2083af6ab5fSopenharmony_ci    return false;
2093af6ab5fSopenharmony_ci  }
2103af6ab5fSopenharmony_ci
2113af6ab5fSopenharmony_ci  static isPrimitiveType(type: ts.Type): boolean {
2123af6ab5fSopenharmony_ci    const f = type.getFlags();
2133af6ab5fSopenharmony_ci    return (
2143af6ab5fSopenharmony_ci      (f & ts.TypeFlags.Boolean) !== 0 ||
2153af6ab5fSopenharmony_ci      (f & ts.TypeFlags.BooleanLiteral) !== 0 ||
2163af6ab5fSopenharmony_ci      (f & ts.TypeFlags.Number) !== 0 ||
2173af6ab5fSopenharmony_ci      (f & ts.TypeFlags.NumberLiteral) !== 0
2183af6ab5fSopenharmony_ci
2193af6ab5fSopenharmony_ci    /*
2203af6ab5fSopenharmony_ci     *  In ArkTS 'string' is not a primitive type. So for the common subset 'string'
2213af6ab5fSopenharmony_ci     *  should be considered as a reference type. That is why next line is commented out.
2223af6ab5fSopenharmony_ci     * (f & ts.TypeFlags.String) != 0 || (f & ts.TypeFlags.StringLiteral) != 0
2233af6ab5fSopenharmony_ci     */
2243af6ab5fSopenharmony_ci    );
2253af6ab5fSopenharmony_ci  }
2263af6ab5fSopenharmony_ci
2273af6ab5fSopenharmony_ci  static isPrimitiveLiteralType(type: ts.Type): boolean {
2283af6ab5fSopenharmony_ci    return !!(
2293af6ab5fSopenharmony_ci      type.flags &
2303af6ab5fSopenharmony_ci      (ts.TypeFlags.BooleanLiteral |
2313af6ab5fSopenharmony_ci        ts.TypeFlags.NumberLiteral |
2323af6ab5fSopenharmony_ci        ts.TypeFlags.StringLiteral |
2333af6ab5fSopenharmony_ci        ts.TypeFlags.BigIntLiteral)
2343af6ab5fSopenharmony_ci    );
2353af6ab5fSopenharmony_ci  }
2363af6ab5fSopenharmony_ci
2373af6ab5fSopenharmony_ci  static isPurePrimitiveLiteralType(type: ts.Type): boolean {
2383af6ab5fSopenharmony_ci    return TsUtils.isPrimitiveLiteralType(type) && !(type.flags & ts.TypeFlags.EnumLiteral);
2393af6ab5fSopenharmony_ci  }
2403af6ab5fSopenharmony_ci
2413af6ab5fSopenharmony_ci  static isTypeSymbol(symbol: ts.Symbol | undefined): boolean {
2423af6ab5fSopenharmony_ci    return (
2433af6ab5fSopenharmony_ci      !!symbol &&
2443af6ab5fSopenharmony_ci      !!symbol.flags &&
2453af6ab5fSopenharmony_ci      ((symbol.flags & ts.SymbolFlags.Class) !== 0 || (symbol.flags & ts.SymbolFlags.Interface) !== 0)
2463af6ab5fSopenharmony_ci    );
2473af6ab5fSopenharmony_ci  }
2483af6ab5fSopenharmony_ci
2493af6ab5fSopenharmony_ci  // Check whether type is generic 'Array<T>' type defined in TypeScript standard library.
2503af6ab5fSopenharmony_ci  isGenericArrayType(tsType: ts.Type): tsType is ts.TypeReference {
2513af6ab5fSopenharmony_ci    return (
2523af6ab5fSopenharmony_ci      !(this.arkts2 && !isStdLibraryType(tsType)) &&
2533af6ab5fSopenharmony_ci      TsUtils.isTypeReference(tsType) &&
2543af6ab5fSopenharmony_ci      tsType.typeArguments?.length === 1 &&
2553af6ab5fSopenharmony_ci      tsType.target.typeParameters?.length === 1 &&
2563af6ab5fSopenharmony_ci      tsType.getSymbol()?.getName() === 'Array'
2573af6ab5fSopenharmony_ci    );
2583af6ab5fSopenharmony_ci  }
2593af6ab5fSopenharmony_ci
2603af6ab5fSopenharmony_ci  isReadonlyArrayType(tsType: ts.Type): boolean {
2613af6ab5fSopenharmony_ci    return (
2623af6ab5fSopenharmony_ci      !(this.arkts2 && !isStdLibraryType(tsType)) &&
2633af6ab5fSopenharmony_ci      TsUtils.isTypeReference(tsType) &&
2643af6ab5fSopenharmony_ci      tsType.typeArguments?.length === 1 &&
2653af6ab5fSopenharmony_ci      tsType.target.typeParameters?.length === 1 &&
2663af6ab5fSopenharmony_ci      tsType.getSymbol()?.getName() === 'ReadonlyArray'
2673af6ab5fSopenharmony_ci    );
2683af6ab5fSopenharmony_ci  }
2693af6ab5fSopenharmony_ci
2703af6ab5fSopenharmony_ci  static isConcatArrayType(tsType: ts.Type): boolean {
2713af6ab5fSopenharmony_ci    return (
2723af6ab5fSopenharmony_ci      isStdLibraryType(tsType) &&
2733af6ab5fSopenharmony_ci      TsUtils.isTypeReference(tsType) &&
2743af6ab5fSopenharmony_ci      tsType.typeArguments?.length === 1 &&
2753af6ab5fSopenharmony_ci      tsType.target.typeParameters?.length === 1 &&
2763af6ab5fSopenharmony_ci      tsType.getSymbol()?.getName() === 'ConcatArray'
2773af6ab5fSopenharmony_ci    );
2783af6ab5fSopenharmony_ci  }
2793af6ab5fSopenharmony_ci
2803af6ab5fSopenharmony_ci  static isArrayLikeType(tsType: ts.Type): boolean {
2813af6ab5fSopenharmony_ci    return (
2823af6ab5fSopenharmony_ci      isStdLibraryType(tsType) &&
2833af6ab5fSopenharmony_ci      TsUtils.isTypeReference(tsType) &&
2843af6ab5fSopenharmony_ci      tsType.typeArguments?.length === 1 &&
2853af6ab5fSopenharmony_ci      tsType.target.typeParameters?.length === 1 &&
2863af6ab5fSopenharmony_ci      tsType.getSymbol()?.getName() === 'ArrayLike'
2873af6ab5fSopenharmony_ci    );
2883af6ab5fSopenharmony_ci  }
2893af6ab5fSopenharmony_ci
2903af6ab5fSopenharmony_ci  isTypedArray(tsType: ts.Type): boolean {
2913af6ab5fSopenharmony_ci    const symbol = tsType.symbol;
2923af6ab5fSopenharmony_ci    if (!symbol) {
2933af6ab5fSopenharmony_ci      return false;
2943af6ab5fSopenharmony_ci    }
2953af6ab5fSopenharmony_ci    const name = this.tsTypeChecker.getFullyQualifiedName(symbol);
2963af6ab5fSopenharmony_ci    if (this.isGlobalSymbol(symbol) && TYPED_ARRAYS.includes(name)) {
2973af6ab5fSopenharmony_ci      return true;
2983af6ab5fSopenharmony_ci    }
2993af6ab5fSopenharmony_ci    const decl = TsUtils.getDeclaration(symbol);
3003af6ab5fSopenharmony_ci    return (
3013af6ab5fSopenharmony_ci      !!decl && TsUtils.isArkTSCollectionsClassOrInterfaceDeclaration(decl) && TYPED_ARRAYS.includes(symbol.getName())
3023af6ab5fSopenharmony_ci    );
3033af6ab5fSopenharmony_ci  }
3043af6ab5fSopenharmony_ci
3053af6ab5fSopenharmony_ci  isArray(tsType: ts.Type): boolean {
3063af6ab5fSopenharmony_ci    return this.isGenericArrayType(tsType) || this.isReadonlyArrayType(tsType) || this.isTypedArray(tsType);
3073af6ab5fSopenharmony_ci  }
3083af6ab5fSopenharmony_ci
3093af6ab5fSopenharmony_ci  isIndexableArray(tsType: ts.Type): boolean {
3103af6ab5fSopenharmony_ci    return (
3113af6ab5fSopenharmony_ci      this.isGenericArrayType(tsType) ||
3123af6ab5fSopenharmony_ci      this.isReadonlyArrayType(tsType) ||
3133af6ab5fSopenharmony_ci      TsUtils.isConcatArrayType(tsType) ||
3143af6ab5fSopenharmony_ci      TsUtils.isArrayLikeType(tsType) ||
3153af6ab5fSopenharmony_ci      this.isTypedArray(tsType)
3163af6ab5fSopenharmony_ci    );
3173af6ab5fSopenharmony_ci  }
3183af6ab5fSopenharmony_ci
3193af6ab5fSopenharmony_ci  static isTuple(tsType: ts.Type): boolean {
3203af6ab5fSopenharmony_ci    return TsUtils.isTypeReference(tsType) && !!(tsType.objectFlags & ts.ObjectFlags.Tuple);
3213af6ab5fSopenharmony_ci  }
3223af6ab5fSopenharmony_ci
3233af6ab5fSopenharmony_ci  // does something similar to relatedByInheritanceOrIdentical function
3243af6ab5fSopenharmony_ci  isOrDerivedFrom(tsType: ts.Type, checkType: CheckType, checkedBaseTypes?: Set<ts.Type>): boolean {
3253af6ab5fSopenharmony_ci    // eslint-disable-next-line no-param-reassign
3263af6ab5fSopenharmony_ci    tsType = TsUtils.reduceReference(tsType);
3273af6ab5fSopenharmony_ci
3283af6ab5fSopenharmony_ci    if (checkType.call(this, tsType)) {
3293af6ab5fSopenharmony_ci      return true;
3303af6ab5fSopenharmony_ci    }
3313af6ab5fSopenharmony_ci
3323af6ab5fSopenharmony_ci    if (!tsType.symbol?.declarations) {
3333af6ab5fSopenharmony_ci      return false;
3343af6ab5fSopenharmony_ci    }
3353af6ab5fSopenharmony_ci
3363af6ab5fSopenharmony_ci    // Avoid type recursion in heritage by caching checked types.
3373af6ab5fSopenharmony_ci    // eslint-disable-next-line no-param-reassign
3383af6ab5fSopenharmony_ci    (checkedBaseTypes ||= new Set<ts.Type>()).add(tsType);
3393af6ab5fSopenharmony_ci
3403af6ab5fSopenharmony_ci    for (const tsTypeDecl of tsType.symbol.declarations) {
3413af6ab5fSopenharmony_ci      const isClassOrInterfaceDecl = ts.isClassDeclaration(tsTypeDecl) || ts.isInterfaceDeclaration(tsTypeDecl);
3423af6ab5fSopenharmony_ci      const isDerived = isClassOrInterfaceDecl && !!tsTypeDecl.heritageClauses;
3433af6ab5fSopenharmony_ci      if (!isDerived) {
3443af6ab5fSopenharmony_ci        continue;
3453af6ab5fSopenharmony_ci      }
3463af6ab5fSopenharmony_ci      for (const heritageClause of tsTypeDecl.heritageClauses) {
3473af6ab5fSopenharmony_ci        if (this.processParentTypesCheck(heritageClause.types, checkType, checkedBaseTypes)) {
3483af6ab5fSopenharmony_ci          return true;
3493af6ab5fSopenharmony_ci        }
3503af6ab5fSopenharmony_ci      }
3513af6ab5fSopenharmony_ci    }
3523af6ab5fSopenharmony_ci
3533af6ab5fSopenharmony_ci    return false;
3543af6ab5fSopenharmony_ci  }
3553af6ab5fSopenharmony_ci
3563af6ab5fSopenharmony_ci  static isTypeReference(tsType: ts.Type): tsType is ts.TypeReference {
3573af6ab5fSopenharmony_ci    return (
3583af6ab5fSopenharmony_ci      (tsType.getFlags() & ts.TypeFlags.Object) !== 0 &&
3593af6ab5fSopenharmony_ci      ((tsType as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference) !== 0
3603af6ab5fSopenharmony_ci    );
3613af6ab5fSopenharmony_ci  }
3623af6ab5fSopenharmony_ci
3633af6ab5fSopenharmony_ci  static isPrototypeSymbol(symbol: ts.Symbol | undefined): boolean {
3643af6ab5fSopenharmony_ci    return !!symbol && !!symbol.flags && (symbol.flags & ts.SymbolFlags.Prototype) !== 0;
3653af6ab5fSopenharmony_ci  }
3663af6ab5fSopenharmony_ci
3673af6ab5fSopenharmony_ci  static isFunctionSymbol(symbol: ts.Symbol | undefined): boolean {
3683af6ab5fSopenharmony_ci    return !!symbol && !!symbol.flags && (symbol.flags & ts.SymbolFlags.Function) !== 0;
3693af6ab5fSopenharmony_ci  }
3703af6ab5fSopenharmony_ci
3713af6ab5fSopenharmony_ci  static isInterfaceType(tsType: ts.Type | undefined): boolean {
3723af6ab5fSopenharmony_ci    return (
3733af6ab5fSopenharmony_ci      !!tsType && !!tsType.symbol && !!tsType.symbol.flags && (tsType.symbol.flags & ts.SymbolFlags.Interface) !== 0
3743af6ab5fSopenharmony_ci    );
3753af6ab5fSopenharmony_ci  }
3763af6ab5fSopenharmony_ci
3773af6ab5fSopenharmony_ci  static isAnyType(tsType: ts.Type): tsType is ts.TypeReference {
3783af6ab5fSopenharmony_ci    return (tsType.getFlags() & ts.TypeFlags.Any) !== 0;
3793af6ab5fSopenharmony_ci  }
3803af6ab5fSopenharmony_ci
3813af6ab5fSopenharmony_ci  static isUnknownType(tsType: ts.Type): boolean {
3823af6ab5fSopenharmony_ci    return (tsType.getFlags() & ts.TypeFlags.Unknown) !== 0;
3833af6ab5fSopenharmony_ci  }
3843af6ab5fSopenharmony_ci
3853af6ab5fSopenharmony_ci  static isUnsupportedType(tsType: ts.Type): boolean {
3863af6ab5fSopenharmony_ci    return (
3873af6ab5fSopenharmony_ci      !!tsType.flags &&
3883af6ab5fSopenharmony_ci      ((tsType.flags & ts.TypeFlags.Any) !== 0 ||
3893af6ab5fSopenharmony_ci        (tsType.flags & ts.TypeFlags.Unknown) !== 0 ||
3903af6ab5fSopenharmony_ci        (tsType.flags & ts.TypeFlags.Intersection) !== 0)
3913af6ab5fSopenharmony_ci    );
3923af6ab5fSopenharmony_ci  }
3933af6ab5fSopenharmony_ci
3943af6ab5fSopenharmony_ci  isUnsupportedTypeArkts2(tsType: ts.Type): boolean {
3953af6ab5fSopenharmony_ci    const typenode = this.tsTypeChecker.typeToTypeNode(tsType, undefined, ts.NodeBuilderFlags.None);
3963af6ab5fSopenharmony_ci    return !!typenode && !this.isSupportedType(typenode);
3973af6ab5fSopenharmony_ci  }
3983af6ab5fSopenharmony_ci
3993af6ab5fSopenharmony_ci  static isNullableUnionType(type: ts.Type): boolean {
4003af6ab5fSopenharmony_ci    if (type.isUnion()) {
4013af6ab5fSopenharmony_ci      for (const t of type.types) {
4023af6ab5fSopenharmony_ci        if (!!(t.flags & ts.TypeFlags.Undefined) || !!(t.flags & ts.TypeFlags.Null)) {
4033af6ab5fSopenharmony_ci          return true;
4043af6ab5fSopenharmony_ci        }
4053af6ab5fSopenharmony_ci      }
4063af6ab5fSopenharmony_ci    }
4073af6ab5fSopenharmony_ci    return false;
4083af6ab5fSopenharmony_ci  }
4093af6ab5fSopenharmony_ci
4103af6ab5fSopenharmony_ci  static isMethodAssignment(tsSymbol: ts.Symbol | undefined): boolean {
4113af6ab5fSopenharmony_ci    return (
4123af6ab5fSopenharmony_ci      !!tsSymbol && (tsSymbol.flags & ts.SymbolFlags.Method) !== 0 && (tsSymbol.flags & ts.SymbolFlags.Assignment) !== 0
4133af6ab5fSopenharmony_ci    );
4143af6ab5fSopenharmony_ci  }
4153af6ab5fSopenharmony_ci
4163af6ab5fSopenharmony_ci  static getDeclaration(tsSymbol: ts.Symbol | undefined): ts.Declaration | undefined {
4173af6ab5fSopenharmony_ci    if (tsSymbol?.declarations && tsSymbol.declarations.length > 0) {
4183af6ab5fSopenharmony_ci      return tsSymbol.declarations[0];
4193af6ab5fSopenharmony_ci    }
4203af6ab5fSopenharmony_ci    return undefined;
4213af6ab5fSopenharmony_ci  }
4223af6ab5fSopenharmony_ci
4233af6ab5fSopenharmony_ci  private static isVarDeclaration(tsDecl: ts.Node): boolean {
4243af6ab5fSopenharmony_ci    return ts.isVariableDeclaration(tsDecl) && ts.isVariableDeclarationList(tsDecl.parent);
4253af6ab5fSopenharmony_ci  }
4263af6ab5fSopenharmony_ci
4273af6ab5fSopenharmony_ci  isValidEnumMemberInit(tsExpr: ts.Expression): boolean {
4283af6ab5fSopenharmony_ci    if (this.isNumberConstantValue(tsExpr.parent as ts.EnumMember)) {
4293af6ab5fSopenharmony_ci      return true;
4303af6ab5fSopenharmony_ci    }
4313af6ab5fSopenharmony_ci    if (this.isStringConstantValue(tsExpr.parent as ts.EnumMember)) {
4323af6ab5fSopenharmony_ci      return true;
4333af6ab5fSopenharmony_ci    }
4343af6ab5fSopenharmony_ci    return this.isCompileTimeExpression(tsExpr);
4353af6ab5fSopenharmony_ci  }
4363af6ab5fSopenharmony_ci
4373af6ab5fSopenharmony_ci  private isCompileTimeExpressionHandlePropertyAccess(tsExpr: ts.Expression): boolean {
4383af6ab5fSopenharmony_ci    if (!ts.isPropertyAccessExpression(tsExpr)) {
4393af6ab5fSopenharmony_ci      return false;
4403af6ab5fSopenharmony_ci    }
4413af6ab5fSopenharmony_ci
4423af6ab5fSopenharmony_ci    /*
4433af6ab5fSopenharmony_ci     * if enum member is in current enum declaration try to get value
4443af6ab5fSopenharmony_ci     * if it comes from another enum consider as constant
4453af6ab5fSopenharmony_ci     */
4463af6ab5fSopenharmony_ci    const propertyAccess = tsExpr;
4473af6ab5fSopenharmony_ci    if (this.isNumberConstantValue(propertyAccess)) {
4483af6ab5fSopenharmony_ci      return true;
4493af6ab5fSopenharmony_ci    }
4503af6ab5fSopenharmony_ci    const leftHandSymbol = this.trueSymbolAtLocation(propertyAccess.expression);
4513af6ab5fSopenharmony_ci    if (!leftHandSymbol) {
4523af6ab5fSopenharmony_ci      return false;
4533af6ab5fSopenharmony_ci    }
4543af6ab5fSopenharmony_ci    const decls = leftHandSymbol.getDeclarations();
4553af6ab5fSopenharmony_ci    if (!decls || decls.length !== 1) {
4563af6ab5fSopenharmony_ci      return false;
4573af6ab5fSopenharmony_ci    }
4583af6ab5fSopenharmony_ci    return ts.isEnumDeclaration(decls[0]);
4593af6ab5fSopenharmony_ci  }
4603af6ab5fSopenharmony_ci
4613af6ab5fSopenharmony_ci  isCompileTimeExpression(tsExpr: ts.Expression): boolean {
4623af6ab5fSopenharmony_ci    if (
4633af6ab5fSopenharmony_ci      ts.isParenthesizedExpression(tsExpr) ||
4643af6ab5fSopenharmony_ci      ts.isAsExpression(tsExpr) && tsExpr.type.kind === ts.SyntaxKind.NumberKeyword
4653af6ab5fSopenharmony_ci    ) {
4663af6ab5fSopenharmony_ci      return this.isCompileTimeExpression(tsExpr.expression);
4673af6ab5fSopenharmony_ci    }
4683af6ab5fSopenharmony_ci
4693af6ab5fSopenharmony_ci    switch (tsExpr.kind) {
4703af6ab5fSopenharmony_ci      case ts.SyntaxKind.PrefixUnaryExpression:
4713af6ab5fSopenharmony_ci        return this.isPrefixUnaryExprValidEnumMemberInit(tsExpr as ts.PrefixUnaryExpression);
4723af6ab5fSopenharmony_ci      case ts.SyntaxKind.ParenthesizedExpression:
4733af6ab5fSopenharmony_ci      case ts.SyntaxKind.BinaryExpression:
4743af6ab5fSopenharmony_ci        return this.isBinaryExprValidEnumMemberInit(tsExpr as ts.BinaryExpression);
4753af6ab5fSopenharmony_ci      case ts.SyntaxKind.ConditionalExpression:
4763af6ab5fSopenharmony_ci        return this.isConditionalExprValidEnumMemberInit(tsExpr as ts.ConditionalExpression);
4773af6ab5fSopenharmony_ci      case ts.SyntaxKind.Identifier:
4783af6ab5fSopenharmony_ci        return this.isIdentifierValidEnumMemberInit(tsExpr as ts.Identifier);
4793af6ab5fSopenharmony_ci      case ts.SyntaxKind.NumericLiteral:
4803af6ab5fSopenharmony_ci        return true;
4813af6ab5fSopenharmony_ci      case ts.SyntaxKind.StringLiteral:
4823af6ab5fSopenharmony_ci        return true;
4833af6ab5fSopenharmony_ci      case ts.SyntaxKind.PropertyAccessExpression:
4843af6ab5fSopenharmony_ci        return this.isCompileTimeExpressionHandlePropertyAccess(tsExpr);
4853af6ab5fSopenharmony_ci      default:
4863af6ab5fSopenharmony_ci        return false;
4873af6ab5fSopenharmony_ci    }
4883af6ab5fSopenharmony_ci  }
4893af6ab5fSopenharmony_ci
4903af6ab5fSopenharmony_ci  private isPrefixUnaryExprValidEnumMemberInit(tsExpr: ts.PrefixUnaryExpression): boolean {
4913af6ab5fSopenharmony_ci    return TsUtils.isUnaryOpAllowedForEnumMemberInit(tsExpr.operator) && this.isCompileTimeExpression(tsExpr.operand);
4923af6ab5fSopenharmony_ci  }
4933af6ab5fSopenharmony_ci
4943af6ab5fSopenharmony_ci  private isBinaryExprValidEnumMemberInit(tsExpr: ts.BinaryExpression): boolean {
4953af6ab5fSopenharmony_ci    return (
4963af6ab5fSopenharmony_ci      TsUtils.isBinaryOpAllowedForEnumMemberInit(tsExpr.operatorToken) &&
4973af6ab5fSopenharmony_ci      this.isCompileTimeExpression(tsExpr.left) &&
4983af6ab5fSopenharmony_ci      this.isCompileTimeExpression(tsExpr.right)
4993af6ab5fSopenharmony_ci    );
5003af6ab5fSopenharmony_ci  }
5013af6ab5fSopenharmony_ci
5023af6ab5fSopenharmony_ci  private isConditionalExprValidEnumMemberInit(tsExpr: ts.ConditionalExpression): boolean {
5033af6ab5fSopenharmony_ci    return this.isCompileTimeExpression(tsExpr.whenTrue) && this.isCompileTimeExpression(tsExpr.whenFalse);
5043af6ab5fSopenharmony_ci  }
5053af6ab5fSopenharmony_ci
5063af6ab5fSopenharmony_ci  private isIdentifierValidEnumMemberInit(tsExpr: ts.Identifier): boolean {
5073af6ab5fSopenharmony_ci    const tsSymbol = this.trueSymbolAtLocation(tsExpr);
5083af6ab5fSopenharmony_ci    const tsDecl = TsUtils.getDeclaration(tsSymbol);
5093af6ab5fSopenharmony_ci    return (
5103af6ab5fSopenharmony_ci      !!tsDecl &&
5113af6ab5fSopenharmony_ci      (TsUtils.isVarDeclaration(tsDecl) && TsUtils.isConst(tsDecl.parent) || tsDecl.kind === ts.SyntaxKind.EnumMember)
5123af6ab5fSopenharmony_ci    );
5133af6ab5fSopenharmony_ci  }
5143af6ab5fSopenharmony_ci
5153af6ab5fSopenharmony_ci  private static isUnaryOpAllowedForEnumMemberInit(tsPrefixUnaryOp: ts.PrefixUnaryOperator): boolean {
5163af6ab5fSopenharmony_ci    return (
5173af6ab5fSopenharmony_ci      tsPrefixUnaryOp === ts.SyntaxKind.PlusToken ||
5183af6ab5fSopenharmony_ci      tsPrefixUnaryOp === ts.SyntaxKind.MinusToken ||
5193af6ab5fSopenharmony_ci      tsPrefixUnaryOp === ts.SyntaxKind.TildeToken
5203af6ab5fSopenharmony_ci    );
5213af6ab5fSopenharmony_ci  }
5223af6ab5fSopenharmony_ci
5233af6ab5fSopenharmony_ci  private static isBinaryOpAllowedForEnumMemberInit(tsBinaryOp: ts.BinaryOperatorToken): boolean {
5243af6ab5fSopenharmony_ci    return (
5253af6ab5fSopenharmony_ci      tsBinaryOp.kind === ts.SyntaxKind.AsteriskToken ||
5263af6ab5fSopenharmony_ci      tsBinaryOp.kind === ts.SyntaxKind.SlashToken ||
5273af6ab5fSopenharmony_ci      tsBinaryOp.kind === ts.SyntaxKind.PercentToken ||
5283af6ab5fSopenharmony_ci      tsBinaryOp.kind === ts.SyntaxKind.MinusToken ||
5293af6ab5fSopenharmony_ci      tsBinaryOp.kind === ts.SyntaxKind.PlusToken ||
5303af6ab5fSopenharmony_ci      tsBinaryOp.kind === ts.SyntaxKind.LessThanLessThanToken ||
5313af6ab5fSopenharmony_ci      tsBinaryOp.kind === ts.SyntaxKind.GreaterThanGreaterThanToken ||
5323af6ab5fSopenharmony_ci      tsBinaryOp.kind === ts.SyntaxKind.BarBarToken ||
5333af6ab5fSopenharmony_ci      tsBinaryOp.kind === ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken ||
5343af6ab5fSopenharmony_ci      tsBinaryOp.kind === ts.SyntaxKind.AmpersandToken ||
5353af6ab5fSopenharmony_ci      tsBinaryOp.kind === ts.SyntaxKind.CaretToken ||
5363af6ab5fSopenharmony_ci      tsBinaryOp.kind === ts.SyntaxKind.BarToken ||
5373af6ab5fSopenharmony_ci      tsBinaryOp.kind === ts.SyntaxKind.AmpersandAmpersandToken
5383af6ab5fSopenharmony_ci    );
5393af6ab5fSopenharmony_ci  }
5403af6ab5fSopenharmony_ci
5413af6ab5fSopenharmony_ci  static isConst(tsNode: ts.Node): boolean {
5423af6ab5fSopenharmony_ci    return !!(ts.getCombinedNodeFlags(tsNode) & ts.NodeFlags.Const);
5433af6ab5fSopenharmony_ci  }
5443af6ab5fSopenharmony_ci
5453af6ab5fSopenharmony_ci  isNumberConstantValue(
5463af6ab5fSopenharmony_ci    tsExpr: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression | ts.NumericLiteral
5473af6ab5fSopenharmony_ci  ): boolean {
5483af6ab5fSopenharmony_ci    const tsConstValue =
5493af6ab5fSopenharmony_ci      tsExpr.kind === ts.SyntaxKind.NumericLiteral ?
5503af6ab5fSopenharmony_ci        Number(tsExpr.getText()) :
5513af6ab5fSopenharmony_ci        this.tsTypeChecker.getConstantValue(tsExpr);
5523af6ab5fSopenharmony_ci
5533af6ab5fSopenharmony_ci    return tsConstValue !== undefined && typeof tsConstValue === 'number';
5543af6ab5fSopenharmony_ci  }
5553af6ab5fSopenharmony_ci
5563af6ab5fSopenharmony_ci  isIntegerConstantValue(
5573af6ab5fSopenharmony_ci    tsExpr: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression | ts.NumericLiteral
5583af6ab5fSopenharmony_ci  ): boolean {
5593af6ab5fSopenharmony_ci    const tsConstValue =
5603af6ab5fSopenharmony_ci      tsExpr.kind === ts.SyntaxKind.NumericLiteral ?
5613af6ab5fSopenharmony_ci        Number(tsExpr.getText()) :
5623af6ab5fSopenharmony_ci        this.tsTypeChecker.getConstantValue(tsExpr);
5633af6ab5fSopenharmony_ci    return (
5643af6ab5fSopenharmony_ci      tsConstValue !== undefined &&
5653af6ab5fSopenharmony_ci      typeof tsConstValue === 'number' &&
5663af6ab5fSopenharmony_ci      tsConstValue.toFixed(0) === tsConstValue.toString()
5673af6ab5fSopenharmony_ci    );
5683af6ab5fSopenharmony_ci  }
5693af6ab5fSopenharmony_ci
5703af6ab5fSopenharmony_ci  isStringConstantValue(tsExpr: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression): boolean {
5713af6ab5fSopenharmony_ci    const tsConstValue = this.tsTypeChecker.getConstantValue(tsExpr);
5723af6ab5fSopenharmony_ci    return tsConstValue !== undefined && typeof tsConstValue === 'string';
5733af6ab5fSopenharmony_ci  }
5743af6ab5fSopenharmony_ci
5753af6ab5fSopenharmony_ci  // Returns true if typeA is a subtype of typeB
5763af6ab5fSopenharmony_ci  relatedByInheritanceOrIdentical(typeA: ts.Type, typeB: ts.Type): boolean {
5773af6ab5fSopenharmony_ci    // eslint-disable-next-line no-param-reassign
5783af6ab5fSopenharmony_ci    typeA = TsUtils.reduceReference(typeA);
5793af6ab5fSopenharmony_ci    // eslint-disable-next-line no-param-reassign
5803af6ab5fSopenharmony_ci    typeB = TsUtils.reduceReference(typeB);
5813af6ab5fSopenharmony_ci
5823af6ab5fSopenharmony_ci    if (typeA === typeB || this.isObject(typeB)) {
5833af6ab5fSopenharmony_ci      return true;
5843af6ab5fSopenharmony_ci    }
5853af6ab5fSopenharmony_ci    if (!typeA.symbol?.declarations) {
5863af6ab5fSopenharmony_ci      return false;
5873af6ab5fSopenharmony_ci    }
5883af6ab5fSopenharmony_ci    const isBISendable = TsUtils.isISendableInterface(typeB);
5893af6ab5fSopenharmony_ci    for (const typeADecl of typeA.symbol.declarations) {
5903af6ab5fSopenharmony_ci      if (isBISendable && ts.isClassDeclaration(typeADecl) && TsUtils.hasSendableDecorator(typeADecl)) {
5913af6ab5fSopenharmony_ci        return true;
5923af6ab5fSopenharmony_ci      }
5933af6ab5fSopenharmony_ci      if (!ts.isClassDeclaration(typeADecl) && !ts.isInterfaceDeclaration(typeADecl)) {
5943af6ab5fSopenharmony_ci        continue;
5953af6ab5fSopenharmony_ci      }
5963af6ab5fSopenharmony_ci      if (this.processExtendedParentTypes(typeA, typeB)) {
5973af6ab5fSopenharmony_ci        return true;
5983af6ab5fSopenharmony_ci      }
5993af6ab5fSopenharmony_ci      if (!typeADecl.heritageClauses) {
6003af6ab5fSopenharmony_ci        continue;
6013af6ab5fSopenharmony_ci      }
6023af6ab5fSopenharmony_ci      for (const heritageClause of typeADecl.heritageClauses) {
6033af6ab5fSopenharmony_ci        const processInterfaces = typeA.isClass() ? heritageClause.token !== ts.SyntaxKind.ExtendsKeyword : true;
6043af6ab5fSopenharmony_ci        if (this.processParentTypes(heritageClause.types, typeB, processInterfaces)) {
6053af6ab5fSopenharmony_ci          return true;
6063af6ab5fSopenharmony_ci        }
6073af6ab5fSopenharmony_ci      }
6083af6ab5fSopenharmony_ci    }
6093af6ab5fSopenharmony_ci    return false;
6103af6ab5fSopenharmony_ci  }
6113af6ab5fSopenharmony_ci
6123af6ab5fSopenharmony_ci  static reduceReference(t: ts.Type): ts.Type {
6133af6ab5fSopenharmony_ci    return TsUtils.isTypeReference(t) && t.target !== t ? t.target : t;
6143af6ab5fSopenharmony_ci  }
6153af6ab5fSopenharmony_ci
6163af6ab5fSopenharmony_ci  private needToDeduceStructuralIdentityHandleUnions(
6173af6ab5fSopenharmony_ci    lhsType: ts.Type,
6183af6ab5fSopenharmony_ci    rhsType: ts.Type,
6193af6ab5fSopenharmony_ci    rhsExpr: ts.Expression,
6203af6ab5fSopenharmony_ci    isStrict: boolean
6213af6ab5fSopenharmony_ci  ): boolean {
6223af6ab5fSopenharmony_ci    if (rhsType.isUnion()) {
6233af6ab5fSopenharmony_ci      // Each Class/Interface of the RHS union type must be compatible with LHS type.
6243af6ab5fSopenharmony_ci      for (const compType of rhsType.types) {
6253af6ab5fSopenharmony_ci        if (this.needToDeduceStructuralIdentity(lhsType, compType, rhsExpr, isStrict)) {
6263af6ab5fSopenharmony_ci          return true;
6273af6ab5fSopenharmony_ci        }
6283af6ab5fSopenharmony_ci      }
6293af6ab5fSopenharmony_ci      return false;
6303af6ab5fSopenharmony_ci    }
6313af6ab5fSopenharmony_ci    if (lhsType.isUnion()) {
6323af6ab5fSopenharmony_ci      // RHS type needs to be compatible with at least one type of the LHS union.
6333af6ab5fSopenharmony_ci      for (const compType of lhsType.types) {
6343af6ab5fSopenharmony_ci        if (!this.needToDeduceStructuralIdentity(compType, rhsType, rhsExpr, isStrict)) {
6353af6ab5fSopenharmony_ci          return false;
6363af6ab5fSopenharmony_ci        }
6373af6ab5fSopenharmony_ci      }
6383af6ab5fSopenharmony_ci      return true;
6393af6ab5fSopenharmony_ci    }
6403af6ab5fSopenharmony_ci    // should be unreachable
6413af6ab5fSopenharmony_ci    return false;
6423af6ab5fSopenharmony_ci  }
6433af6ab5fSopenharmony_ci
6443af6ab5fSopenharmony_ci  // return true if two class types are not related by inheritance and structural identity check is needed
6453af6ab5fSopenharmony_ci  needToDeduceStructuralIdentity(
6463af6ab5fSopenharmony_ci    lhsType: ts.Type,
6473af6ab5fSopenharmony_ci    rhsType: ts.Type,
6483af6ab5fSopenharmony_ci    rhsExpr: ts.Expression,
6493af6ab5fSopenharmony_ci    isStrict: boolean = false
6503af6ab5fSopenharmony_ci  ): boolean {
6513af6ab5fSopenharmony_ci    // eslint-disable-next-line no-param-reassign
6523af6ab5fSopenharmony_ci    lhsType = this.getNonNullableType(lhsType);
6533af6ab5fSopenharmony_ci    // eslint-disable-next-line no-param-reassign
6543af6ab5fSopenharmony_ci    rhsType = this.getNonNullableType(rhsType);
6553af6ab5fSopenharmony_ci    if (this.isLibraryType(lhsType)) {
6563af6ab5fSopenharmony_ci      return false;
6573af6ab5fSopenharmony_ci    }
6583af6ab5fSopenharmony_ci    if (this.isDynamicObjectAssignedToStdType(lhsType, rhsExpr)) {
6593af6ab5fSopenharmony_ci      return false;
6603af6ab5fSopenharmony_ci    }
6613af6ab5fSopenharmony_ci    // #14569: Check for Function type.
6623af6ab5fSopenharmony_ci    if (this.areCompatibleFunctionals(lhsType, rhsType)) {
6633af6ab5fSopenharmony_ci      return false;
6643af6ab5fSopenharmony_ci    }
6653af6ab5fSopenharmony_ci    if (rhsType.isUnion() || lhsType.isUnion()) {
6663af6ab5fSopenharmony_ci      return this.needToDeduceStructuralIdentityHandleUnions(lhsType, rhsType, rhsExpr, isStrict);
6673af6ab5fSopenharmony_ci    }
6683af6ab5fSopenharmony_ci    if (
6693af6ab5fSopenharmony_ci      this.advancedClassChecks &&
6703af6ab5fSopenharmony_ci      TsUtils.isClassValueType(rhsType) &&
6713af6ab5fSopenharmony_ci      lhsType !== rhsType &&
6723af6ab5fSopenharmony_ci      !TsUtils.isObjectType(lhsType)
6733af6ab5fSopenharmony_ci    ) {
6743af6ab5fSopenharmony_ci      // missing exact rule
6753af6ab5fSopenharmony_ci      return true;
6763af6ab5fSopenharmony_ci    }
6773af6ab5fSopenharmony_ci    // if isStrict, things like generics need to be checked
6783af6ab5fSopenharmony_ci    if (isStrict) {
6793af6ab5fSopenharmony_ci      if (TsUtils.isTypeReference(rhsType) && !!(rhsType.objectFlags & ts.ObjectFlags.ArrayLiteral)) {
6803af6ab5fSopenharmony_ci        // The 'arkts-sendable-obj-init' rule already exists. Wait for the new 'strict type' to be modified.
6813af6ab5fSopenharmony_ci        return false;
6823af6ab5fSopenharmony_ci      }
6833af6ab5fSopenharmony_ci      // eslint-disable-next-line no-param-reassign
6843af6ab5fSopenharmony_ci      lhsType = TsUtils.reduceReference(lhsType);
6853af6ab5fSopenharmony_ci      // eslint-disable-next-line no-param-reassign
6863af6ab5fSopenharmony_ci      rhsType = TsUtils.reduceReference(rhsType);
6873af6ab5fSopenharmony_ci    }
6883af6ab5fSopenharmony_ci    return (
6893af6ab5fSopenharmony_ci      lhsType.isClassOrInterface() &&
6903af6ab5fSopenharmony_ci      rhsType.isClassOrInterface() &&
6913af6ab5fSopenharmony_ci      !this.relatedByInheritanceOrIdentical(rhsType, lhsType)
6923af6ab5fSopenharmony_ci    );
6933af6ab5fSopenharmony_ci  }
6943af6ab5fSopenharmony_ci
6953af6ab5fSopenharmony_ci  // Does the 'arkts-no-structural-typing' rule need to be strictly enforced to complete previously missed scenarios
6963af6ab5fSopenharmony_ci  needStrictMatchType(lhsType: ts.Type, rhsType: ts.Type): boolean {
6973af6ab5fSopenharmony_ci    if (this.arkts2) {
6983af6ab5fSopenharmony_ci      return true;
6993af6ab5fSopenharmony_ci    }
7003af6ab5fSopenharmony_ci    if (this.isStrictSendableMatch(lhsType, rhsType)) {
7013af6ab5fSopenharmony_ci      return true;
7023af6ab5fSopenharmony_ci    }
7033af6ab5fSopenharmony_ci    // add other requirements with strict type requirements here
7043af6ab5fSopenharmony_ci    return false;
7053af6ab5fSopenharmony_ci  }
7063af6ab5fSopenharmony_ci
7073af6ab5fSopenharmony_ci  // For compatibility, left must all ClassOrInterface is sendable, right must has non-sendable ClassorInterface
7083af6ab5fSopenharmony_ci  private isStrictSendableMatch(lhsType: ts.Type, rhsType: ts.Type): boolean {
7093af6ab5fSopenharmony_ci    let isStrictLhs = false;
7103af6ab5fSopenharmony_ci    if (lhsType.isUnion()) {
7113af6ab5fSopenharmony_ci      for (let compType of lhsType.types) {
7123af6ab5fSopenharmony_ci        compType = TsUtils.reduceReference(compType);
7133af6ab5fSopenharmony_ci        if (!compType.isClassOrInterface()) {
7143af6ab5fSopenharmony_ci          continue;
7153af6ab5fSopenharmony_ci        }
7163af6ab5fSopenharmony_ci        if (!this.isSendableClassOrInterface(compType)) {
7173af6ab5fSopenharmony_ci          return false;
7183af6ab5fSopenharmony_ci        }
7193af6ab5fSopenharmony_ci        isStrictLhs = true;
7203af6ab5fSopenharmony_ci      }
7213af6ab5fSopenharmony_ci    } else {
7223af6ab5fSopenharmony_ci      isStrictLhs = this.isSendableClassOrInterface(lhsType);
7233af6ab5fSopenharmony_ci    }
7243af6ab5fSopenharmony_ci    return isStrictLhs && this.typeContainsNonSendableClassOrInterface(rhsType);
7253af6ab5fSopenharmony_ci  }
7263af6ab5fSopenharmony_ci
7273af6ab5fSopenharmony_ci  private processExtendedParentTypes(typeA: ts.Type, typeB: ts.Type): boolean {
7283af6ab5fSopenharmony_ci
7293af6ab5fSopenharmony_ci    /*
7303af6ab5fSopenharmony_ci     * Most standard types in TS Stdlib do not use explicit inheritance and rely on
7313af6ab5fSopenharmony_ci     * structural compatibility. In contrast, the type definitions in ArkTS stdlib
7323af6ab5fSopenharmony_ci     * use inheritance with explicit base types. We check the inheritance hierarchy
7333af6ab5fSopenharmony_ci     * for such types according to how they are defined in ArkTS Stdlib.
7343af6ab5fSopenharmony_ci     */
7353af6ab5fSopenharmony_ci
7363af6ab5fSopenharmony_ci    if (!this.arkts2) {
7373af6ab5fSopenharmony_ci      return false;
7383af6ab5fSopenharmony_ci    }
7393af6ab5fSopenharmony_ci    if (!isStdLibrarySymbol(typeA.symbol) && !isStdLibrarySymbol(typeB.symbol)) {
7403af6ab5fSopenharmony_ci      return false;
7413af6ab5fSopenharmony_ci    }
7423af6ab5fSopenharmony_ci    return this.checkExtendedParentTypes(typeA.symbol.name, typeB.symbol.name);
7433af6ab5fSopenharmony_ci  }
7443af6ab5fSopenharmony_ci
7453af6ab5fSopenharmony_ci  private checkExtendedParentTypes(typeA: string, typeB: string): boolean {
7463af6ab5fSopenharmony_ci    if (typeA === typeB) {
7473af6ab5fSopenharmony_ci      return true;
7483af6ab5fSopenharmony_ci    }
7493af6ab5fSopenharmony_ci    const extBaseTypes = EXTENDED_BASE_TYPES.get(typeA);
7503af6ab5fSopenharmony_ci    if (!extBaseTypes) {
7513af6ab5fSopenharmony_ci      return false;
7523af6ab5fSopenharmony_ci    }
7533af6ab5fSopenharmony_ci    for (const extBaseType of extBaseTypes) {
7543af6ab5fSopenharmony_ci      if (this.checkExtendedParentTypes(extBaseType, typeB)) {
7553af6ab5fSopenharmony_ci        return true;
7563af6ab5fSopenharmony_ci      }
7573af6ab5fSopenharmony_ci    }
7583af6ab5fSopenharmony_ci    return false;
7593af6ab5fSopenharmony_ci  }
7603af6ab5fSopenharmony_ci
7613af6ab5fSopenharmony_ci  private processParentTypes(
7623af6ab5fSopenharmony_ci    parentTypes: ts.NodeArray<ts.Expression>,
7633af6ab5fSopenharmony_ci    typeB: ts.Type,
7643af6ab5fSopenharmony_ci    processInterfaces: boolean
7653af6ab5fSopenharmony_ci  ): boolean {
7663af6ab5fSopenharmony_ci    for (const baseTypeExpr of parentTypes) {
7673af6ab5fSopenharmony_ci      const baseType = TsUtils.reduceReference(this.tsTypeChecker.getTypeAtLocation(baseTypeExpr));
7683af6ab5fSopenharmony_ci      if (
7693af6ab5fSopenharmony_ci        baseType &&
7703af6ab5fSopenharmony_ci        baseType.isClass() !== processInterfaces &&
7713af6ab5fSopenharmony_ci        this.relatedByInheritanceOrIdentical(baseType, typeB)
7723af6ab5fSopenharmony_ci      ) {
7733af6ab5fSopenharmony_ci        return true;
7743af6ab5fSopenharmony_ci      }
7753af6ab5fSopenharmony_ci    }
7763af6ab5fSopenharmony_ci    return false;
7773af6ab5fSopenharmony_ci  }
7783af6ab5fSopenharmony_ci
7793af6ab5fSopenharmony_ci  private processParentTypesCheck(
7803af6ab5fSopenharmony_ci    parentTypes: ts.NodeArray<ts.Expression>,
7813af6ab5fSopenharmony_ci    checkType: CheckType,
7823af6ab5fSopenharmony_ci    checkedBaseTypes: Set<ts.Type>
7833af6ab5fSopenharmony_ci  ): boolean {
7843af6ab5fSopenharmony_ci    for (const baseTypeExpr of parentTypes) {
7853af6ab5fSopenharmony_ci      const baseType = TsUtils.reduceReference(this.tsTypeChecker.getTypeAtLocation(baseTypeExpr));
7863af6ab5fSopenharmony_ci      if (baseType && !checkedBaseTypes.has(baseType) && this.isOrDerivedFrom(baseType, checkType, checkedBaseTypes)) {
7873af6ab5fSopenharmony_ci        return true;
7883af6ab5fSopenharmony_ci      }
7893af6ab5fSopenharmony_ci    }
7903af6ab5fSopenharmony_ci    return false;
7913af6ab5fSopenharmony_ci  }
7923af6ab5fSopenharmony_ci
7933af6ab5fSopenharmony_ci  isObject(tsType: ts.Type): boolean {
7943af6ab5fSopenharmony_ci    if (!tsType) {
7953af6ab5fSopenharmony_ci      return false;
7963af6ab5fSopenharmony_ci    }
7973af6ab5fSopenharmony_ci    if (tsType.symbol && tsType.isClassOrInterface() && tsType.symbol.name === 'Object') {
7983af6ab5fSopenharmony_ci      return true;
7993af6ab5fSopenharmony_ci    }
8003af6ab5fSopenharmony_ci    const node = this.tsTypeChecker.typeToTypeNode(tsType, undefined, undefined);
8013af6ab5fSopenharmony_ci    return node !== undefined && node.kind === ts.SyntaxKind.ObjectKeyword;
8023af6ab5fSopenharmony_ci  }
8033af6ab5fSopenharmony_ci
8043af6ab5fSopenharmony_ci  isCallToFunctionWithOmittedReturnType(tsExpr: ts.Expression): boolean {
8053af6ab5fSopenharmony_ci    if (ts.isCallExpression(tsExpr)) {
8063af6ab5fSopenharmony_ci      const tsCallSignature = this.tsTypeChecker.getResolvedSignature(tsExpr);
8073af6ab5fSopenharmony_ci      if (tsCallSignature) {
8083af6ab5fSopenharmony_ci        const tsSignDecl = tsCallSignature.getDeclaration();
8093af6ab5fSopenharmony_ci        // `tsSignDecl` is undefined when `getResolvedSignature` returns `unknownSignature`
8103af6ab5fSopenharmony_ci        if (!tsSignDecl?.type) {
8113af6ab5fSopenharmony_ci          return true;
8123af6ab5fSopenharmony_ci        }
8133af6ab5fSopenharmony_ci      }
8143af6ab5fSopenharmony_ci    }
8153af6ab5fSopenharmony_ci
8163af6ab5fSopenharmony_ci    return false;
8173af6ab5fSopenharmony_ci  }
8183af6ab5fSopenharmony_ci
8193af6ab5fSopenharmony_ci  private static hasReadonlyFields(type: ts.Type): boolean {
8203af6ab5fSopenharmony_ci    // No members -> no readonly fields
8213af6ab5fSopenharmony_ci    if (type.symbol.members === undefined) {
8223af6ab5fSopenharmony_ci      return false;
8233af6ab5fSopenharmony_ci    }
8243af6ab5fSopenharmony_ci
8253af6ab5fSopenharmony_ci    let result: boolean = false;
8263af6ab5fSopenharmony_ci
8273af6ab5fSopenharmony_ci    type.symbol.members.forEach((value) => {
8283af6ab5fSopenharmony_ci      if (
8293af6ab5fSopenharmony_ci        value.declarations !== undefined &&
8303af6ab5fSopenharmony_ci        value.declarations.length > 0 &&
8313af6ab5fSopenharmony_ci        ts.isPropertyDeclaration(value.declarations[0])
8323af6ab5fSopenharmony_ci      ) {
8333af6ab5fSopenharmony_ci        const propmMods = ts.getModifiers(value.declarations[0]);
8343af6ab5fSopenharmony_ci        if (TsUtils.hasModifier(propmMods, ts.SyntaxKind.ReadonlyKeyword)) {
8353af6ab5fSopenharmony_ci          result = true;
8363af6ab5fSopenharmony_ci        }
8373af6ab5fSopenharmony_ci      }
8383af6ab5fSopenharmony_ci    });
8393af6ab5fSopenharmony_ci
8403af6ab5fSopenharmony_ci    return result;
8413af6ab5fSopenharmony_ci  }
8423af6ab5fSopenharmony_ci
8433af6ab5fSopenharmony_ci  private static hasDefaultCtor(type: ts.Type): boolean {
8443af6ab5fSopenharmony_ci    // No members -> no explicit constructors -> there is default ctor
8453af6ab5fSopenharmony_ci    if (type.symbol.members === undefined) {
8463af6ab5fSopenharmony_ci      return true;
8473af6ab5fSopenharmony_ci    }
8483af6ab5fSopenharmony_ci
8493af6ab5fSopenharmony_ci    // has any constructor
8503af6ab5fSopenharmony_ci    let hasCtor: boolean = false;
8513af6ab5fSopenharmony_ci    // has default constructor
8523af6ab5fSopenharmony_ci    let hasDefaultCtor: boolean = false;
8533af6ab5fSopenharmony_ci
8543af6ab5fSopenharmony_ci    type.symbol.members.forEach((value) => {
8553af6ab5fSopenharmony_ci      if ((value.flags & ts.SymbolFlags.Constructor) === 0) {
8563af6ab5fSopenharmony_ci        return;
8573af6ab5fSopenharmony_ci      }
8583af6ab5fSopenharmony_ci      hasCtor = true;
8593af6ab5fSopenharmony_ci
8603af6ab5fSopenharmony_ci      if (value.declarations === undefined || value.declarations.length <= 0) {
8613af6ab5fSopenharmony_ci        return;
8623af6ab5fSopenharmony_ci      }
8633af6ab5fSopenharmony_ci
8643af6ab5fSopenharmony_ci      const declCtor = value.declarations[0] as ts.ConstructorDeclaration;
8653af6ab5fSopenharmony_ci      if (declCtor.parameters.length === 0) {
8663af6ab5fSopenharmony_ci        hasDefaultCtor = true;
8673af6ab5fSopenharmony_ci      }
8683af6ab5fSopenharmony_ci    });
8693af6ab5fSopenharmony_ci
8703af6ab5fSopenharmony_ci    // Has no any explicit constructor -> has implicit default constructor.
8713af6ab5fSopenharmony_ci    return !hasCtor || hasDefaultCtor;
8723af6ab5fSopenharmony_ci  }
8733af6ab5fSopenharmony_ci
8743af6ab5fSopenharmony_ci  private static isAbstractClass(type: ts.Type): boolean {
8753af6ab5fSopenharmony_ci    if (type.isClass() && type.symbol.declarations && type.symbol.declarations.length > 0) {
8763af6ab5fSopenharmony_ci      const declClass = type.symbol.declarations[0] as ts.ClassDeclaration;
8773af6ab5fSopenharmony_ci      const classMods = ts.getModifiers(declClass);
8783af6ab5fSopenharmony_ci      if (TsUtils.hasModifier(classMods, ts.SyntaxKind.AbstractKeyword)) {
8793af6ab5fSopenharmony_ci        return true;
8803af6ab5fSopenharmony_ci      }
8813af6ab5fSopenharmony_ci    }
8823af6ab5fSopenharmony_ci
8833af6ab5fSopenharmony_ci    return false;
8843af6ab5fSopenharmony_ci  }
8853af6ab5fSopenharmony_ci
8863af6ab5fSopenharmony_ci  static validateObjectLiteralType(type: ts.Type | undefined): boolean {
8873af6ab5fSopenharmony_ci    if (!type) {
8883af6ab5fSopenharmony_ci      return false;
8893af6ab5fSopenharmony_ci    }
8903af6ab5fSopenharmony_ci    // eslint-disable-next-line no-param-reassign
8913af6ab5fSopenharmony_ci    type = TsUtils.reduceReference(type);
8923af6ab5fSopenharmony_ci    return (
8933af6ab5fSopenharmony_ci      type.isClassOrInterface() &&
8943af6ab5fSopenharmony_ci      TsUtils.hasDefaultCtor(type) &&
8953af6ab5fSopenharmony_ci      !TsUtils.hasReadonlyFields(type) &&
8963af6ab5fSopenharmony_ci      !TsUtils.isAbstractClass(type)
8973af6ab5fSopenharmony_ci    );
8983af6ab5fSopenharmony_ci  }
8993af6ab5fSopenharmony_ci
9003af6ab5fSopenharmony_ci  hasMethods(type: ts.Type): boolean {
9013af6ab5fSopenharmony_ci    const properties = this.tsTypeChecker.getPropertiesOfType(type);
9023af6ab5fSopenharmony_ci    if (properties?.length) {
9033af6ab5fSopenharmony_ci      for (const prop of properties) {
9043af6ab5fSopenharmony_ci        if (prop.getFlags() & ts.SymbolFlags.Method) {
9053af6ab5fSopenharmony_ci          return true;
9063af6ab5fSopenharmony_ci        }
9073af6ab5fSopenharmony_ci      }
9083af6ab5fSopenharmony_ci    }
9093af6ab5fSopenharmony_ci    return false;
9103af6ab5fSopenharmony_ci  }
9113af6ab5fSopenharmony_ci
9123af6ab5fSopenharmony_ci  findProperty(type: ts.Type, name: string): ts.Symbol | undefined {
9133af6ab5fSopenharmony_ci    const properties = this.tsTypeChecker.getPropertiesOfType(type);
9143af6ab5fSopenharmony_ci    if (properties?.length) {
9153af6ab5fSopenharmony_ci      for (const prop of properties) {
9163af6ab5fSopenharmony_ci        if (prop.name === name) {
9173af6ab5fSopenharmony_ci          return prop;
9183af6ab5fSopenharmony_ci        }
9193af6ab5fSopenharmony_ci      }
9203af6ab5fSopenharmony_ci    }
9213af6ab5fSopenharmony_ci
9223af6ab5fSopenharmony_ci    return undefined;
9233af6ab5fSopenharmony_ci  }
9243af6ab5fSopenharmony_ci
9253af6ab5fSopenharmony_ci  checkTypeSet(typeSet: ts.Type, predicate: CheckType): boolean {
9263af6ab5fSopenharmony_ci    if (!typeSet.isUnionOrIntersection()) {
9273af6ab5fSopenharmony_ci      return predicate.call(this, typeSet);
9283af6ab5fSopenharmony_ci    }
9293af6ab5fSopenharmony_ci    for (const elemType of typeSet.types) {
9303af6ab5fSopenharmony_ci      if (this.checkTypeSet(elemType, predicate)) {
9313af6ab5fSopenharmony_ci        return true;
9323af6ab5fSopenharmony_ci      }
9333af6ab5fSopenharmony_ci    }
9343af6ab5fSopenharmony_ci    return false;
9353af6ab5fSopenharmony_ci  }
9363af6ab5fSopenharmony_ci
9373af6ab5fSopenharmony_ci  getNonNullableType(t: ts.Type): ts.Type {
9383af6ab5fSopenharmony_ci    const isNullableUnionType = this.useSdkLogic ? t.isUnion() : TsUtils.isNullableUnionType(t);
9393af6ab5fSopenharmony_ci    if (isNullableUnionType) {
9403af6ab5fSopenharmony_ci      return t.getNonNullableType();
9413af6ab5fSopenharmony_ci    }
9423af6ab5fSopenharmony_ci    return t;
9433af6ab5fSopenharmony_ci  }
9443af6ab5fSopenharmony_ci
9453af6ab5fSopenharmony_ci  private isObjectLiteralAssignableToUnion(lhsType: ts.UnionType, rhsExpr: ts.ObjectLiteralExpression): boolean {
9463af6ab5fSopenharmony_ci    for (const compType of lhsType.types) {
9473af6ab5fSopenharmony_ci      if (this.isObjectLiteralAssignable(compType, rhsExpr)) {
9483af6ab5fSopenharmony_ci        return true;
9493af6ab5fSopenharmony_ci      }
9503af6ab5fSopenharmony_ci    }
9513af6ab5fSopenharmony_ci    return false;
9523af6ab5fSopenharmony_ci  }
9533af6ab5fSopenharmony_ci
9543af6ab5fSopenharmony_ci  isObjectLiteralAssignable(lhsType: ts.Type | undefined, rhsExpr: ts.ObjectLiteralExpression): boolean {
9553af6ab5fSopenharmony_ci    if (lhsType === undefined) {
9563af6ab5fSopenharmony_ci      return false;
9573af6ab5fSopenharmony_ci    }
9583af6ab5fSopenharmony_ci    // Always check with the non-nullable variant of lhs type.
9593af6ab5fSopenharmony_ci    // eslint-disable-next-line no-param-reassign
9603af6ab5fSopenharmony_ci    lhsType = this.getNonNullableType(lhsType);
9613af6ab5fSopenharmony_ci    if (lhsType.isUnion() && this.isObjectLiteralAssignableToUnion(lhsType, rhsExpr)) {
9623af6ab5fSopenharmony_ci      return true;
9633af6ab5fSopenharmony_ci    }
9643af6ab5fSopenharmony_ci
9653af6ab5fSopenharmony_ci    /*
9663af6ab5fSopenharmony_ci     * Allow initializing with anything when the type
9673af6ab5fSopenharmony_ci     * originates from the library.
9683af6ab5fSopenharmony_ci     */
9693af6ab5fSopenharmony_ci    if (TsUtils.isAnyType(lhsType) || this.isLibraryType(lhsType)) {
9703af6ab5fSopenharmony_ci      return true;
9713af6ab5fSopenharmony_ci    }
9723af6ab5fSopenharmony_ci
9733af6ab5fSopenharmony_ci    /*
9743af6ab5fSopenharmony_ci     * issue 13412:
9753af6ab5fSopenharmony_ci     * Allow initializing with a dynamic object when the LHS type
9763af6ab5fSopenharmony_ci     * is primitive or defined in standard library.
9773af6ab5fSopenharmony_ci     */
9783af6ab5fSopenharmony_ci    if (this.isDynamicObjectAssignedToStdType(lhsType, rhsExpr)) {
9793af6ab5fSopenharmony_ci      return true;
9803af6ab5fSopenharmony_ci    }
9813af6ab5fSopenharmony_ci    // For Partial<T>, Required<T>, Readonly<T> types, validate their argument type.
9823af6ab5fSopenharmony_ci    if (this.isStdPartialType(lhsType) || this.isStdRequiredType(lhsType) || this.isStdReadonlyType(lhsType)) {
9833af6ab5fSopenharmony_ci      if (lhsType.aliasTypeArguments && lhsType.aliasTypeArguments.length === 1) {
9843af6ab5fSopenharmony_ci        // eslint-disable-next-line no-param-reassign
9853af6ab5fSopenharmony_ci        lhsType = lhsType.aliasTypeArguments[0];
9863af6ab5fSopenharmony_ci      } else {
9873af6ab5fSopenharmony_ci        return false;
9883af6ab5fSopenharmony_ci      }
9893af6ab5fSopenharmony_ci    }
9903af6ab5fSopenharmony_ci
9913af6ab5fSopenharmony_ci    /*
9923af6ab5fSopenharmony_ci     * Allow initializing Record objects with object initializer.
9933af6ab5fSopenharmony_ci     * Record supports any type for a its value, but the key value
9943af6ab5fSopenharmony_ci     * must be either a string or number literal.
9953af6ab5fSopenharmony_ci     */
9963af6ab5fSopenharmony_ci    if (this.isStdRecordType(lhsType)) {
9973af6ab5fSopenharmony_ci      return this.validateRecordObjectKeys(rhsExpr);
9983af6ab5fSopenharmony_ci    }
9993af6ab5fSopenharmony_ci    return (
10003af6ab5fSopenharmony_ci      TsUtils.validateObjectLiteralType(lhsType) && !this.hasMethods(lhsType) && this.validateFields(lhsType, rhsExpr)
10013af6ab5fSopenharmony_ci    );
10023af6ab5fSopenharmony_ci  }
10033af6ab5fSopenharmony_ci
10043af6ab5fSopenharmony_ci  private isDynamicObjectAssignedToStdType(lhsType: ts.Type, rhsExpr: ts.Expression): boolean {
10053af6ab5fSopenharmony_ci    if (isStdLibraryType(lhsType) || TsUtils.isPrimitiveType(lhsType)) {
10063af6ab5fSopenharmony_ci      // eslint-disable-next-line no-nested-ternary
10073af6ab5fSopenharmony_ci      const rhsSym = ts.isCallExpression(rhsExpr) ?
10083af6ab5fSopenharmony_ci        this.getSymbolOfCallExpression(rhsExpr) :
10093af6ab5fSopenharmony_ci        this.useSdkLogic ?
10103af6ab5fSopenharmony_ci          this.tsTypeChecker.getSymbolAtLocation(rhsExpr) :
10113af6ab5fSopenharmony_ci          this.trueSymbolAtLocation(rhsExpr);
10123af6ab5fSopenharmony_ci      if (rhsSym && this.isLibrarySymbol(rhsSym)) {
10133af6ab5fSopenharmony_ci        return true;
10143af6ab5fSopenharmony_ci      }
10153af6ab5fSopenharmony_ci    }
10163af6ab5fSopenharmony_ci    return false;
10173af6ab5fSopenharmony_ci  }
10183af6ab5fSopenharmony_ci
10193af6ab5fSopenharmony_ci  validateFields(objectType: ts.Type, objectLiteral: ts.ObjectLiteralExpression): boolean {
10203af6ab5fSopenharmony_ci    for (const prop of objectLiteral.properties) {
10213af6ab5fSopenharmony_ci      if (ts.isPropertyAssignment(prop)) {
10223af6ab5fSopenharmony_ci        if (!this.validateField(objectType, prop)) {
10233af6ab5fSopenharmony_ci          return false;
10243af6ab5fSopenharmony_ci        }
10253af6ab5fSopenharmony_ci      }
10263af6ab5fSopenharmony_ci    }
10273af6ab5fSopenharmony_ci
10283af6ab5fSopenharmony_ci    return true;
10293af6ab5fSopenharmony_ci  }
10303af6ab5fSopenharmony_ci
10313af6ab5fSopenharmony_ci  getPropertySymbol(type: ts.Type, prop: ts.PropertyAssignment): ts.Symbol | undefined {
10323af6ab5fSopenharmony_ci    const propNameSymbol = this.tsTypeChecker.getSymbolAtLocation(prop.name);
10333af6ab5fSopenharmony_ci    // eslint-disable-next-line no-nested-ternary
10343af6ab5fSopenharmony_ci    const propName = propNameSymbol ?
10353af6ab5fSopenharmony_ci      ts.symbolName(propNameSymbol) :
10363af6ab5fSopenharmony_ci      ts.isMemberName(prop.name) ?
10373af6ab5fSopenharmony_ci        ts.idText(prop.name) :
10383af6ab5fSopenharmony_ci        prop.name.getText();
10393af6ab5fSopenharmony_ci    const propSym = this.findProperty(type, propName);
10403af6ab5fSopenharmony_ci    return propSym;
10413af6ab5fSopenharmony_ci  }
10423af6ab5fSopenharmony_ci
10433af6ab5fSopenharmony_ci  private validateField(type: ts.Type, prop: ts.PropertyAssignment): boolean {
10443af6ab5fSopenharmony_ci    // Issue 15497: Use unescaped property name to find correpsponding property.
10453af6ab5fSopenharmony_ci    const propSym = this.getPropertySymbol(type, prop);
10463af6ab5fSopenharmony_ci    if (!propSym?.declarations?.length) {
10473af6ab5fSopenharmony_ci      return false;
10483af6ab5fSopenharmony_ci    }
10493af6ab5fSopenharmony_ci
10503af6ab5fSopenharmony_ci    const propType = this.tsTypeChecker.getTypeOfSymbolAtLocation(propSym, propSym.declarations[0]);
10513af6ab5fSopenharmony_ci    const initExpr = TsUtils.unwrapParenthesized(prop.initializer);
10523af6ab5fSopenharmony_ci    const rhsType = this.tsTypeChecker.getTypeAtLocation(initExpr);
10533af6ab5fSopenharmony_ci    if (ts.isObjectLiteralExpression(initExpr)) {
10543af6ab5fSopenharmony_ci      if (!this.isObjectLiteralAssignable(propType, initExpr)) {
10553af6ab5fSopenharmony_ci        return false;
10563af6ab5fSopenharmony_ci      }
10573af6ab5fSopenharmony_ci    } else {
10583af6ab5fSopenharmony_ci      // Only check for structural sub-typing.
10593af6ab5fSopenharmony_ci      if (
10603af6ab5fSopenharmony_ci        this.needToDeduceStructuralIdentity(propType, rhsType, initExpr, this.needStrictMatchType(propType, rhsType))
10613af6ab5fSopenharmony_ci      ) {
10623af6ab5fSopenharmony_ci        return false;
10633af6ab5fSopenharmony_ci      }
10643af6ab5fSopenharmony_ci      if (this.isWrongSendableFunctionAssignment(propType, rhsType)) {
10653af6ab5fSopenharmony_ci        return false;
10663af6ab5fSopenharmony_ci      }
10673af6ab5fSopenharmony_ci    }
10683af6ab5fSopenharmony_ci
10693af6ab5fSopenharmony_ci    return true;
10703af6ab5fSopenharmony_ci  }
10713af6ab5fSopenharmony_ci
10723af6ab5fSopenharmony_ci  validateRecordObjectKeys(objectLiteral: ts.ObjectLiteralExpression): boolean {
10733af6ab5fSopenharmony_ci    for (const prop of objectLiteral.properties) {
10743af6ab5fSopenharmony_ci      if (!prop.name || !this.isValidRecordObjectLiteralKey(prop.name)) {
10753af6ab5fSopenharmony_ci        return false;
10763af6ab5fSopenharmony_ci      }
10773af6ab5fSopenharmony_ci    }
10783af6ab5fSopenharmony_ci    return true;
10793af6ab5fSopenharmony_ci  }
10803af6ab5fSopenharmony_ci
10813af6ab5fSopenharmony_ci  isValidRecordObjectLiteralKey(propName: ts.PropertyName): boolean {
10823af6ab5fSopenharmony_ci    if (ts.isComputedPropertyName(propName)) {
10833af6ab5fSopenharmony_ci      return this.isValidComputedPropertyName(propName, true);
10843af6ab5fSopenharmony_ci    }
10853af6ab5fSopenharmony_ci    return ts.isStringLiteral(propName) || ts.isNumericLiteral(propName);
10863af6ab5fSopenharmony_ci  }
10873af6ab5fSopenharmony_ci
10883af6ab5fSopenharmony_ci  private static isSupportedTypeNodeKind(kind: ts.SyntaxKind): boolean {
10893af6ab5fSopenharmony_ci    return (
10903af6ab5fSopenharmony_ci      kind !== ts.SyntaxKind.AnyKeyword &&
10913af6ab5fSopenharmony_ci      kind !== ts.SyntaxKind.UnknownKeyword &&
10923af6ab5fSopenharmony_ci      kind !== ts.SyntaxKind.SymbolKeyword &&
10933af6ab5fSopenharmony_ci      kind !== ts.SyntaxKind.IndexedAccessType &&
10943af6ab5fSopenharmony_ci      kind !== ts.SyntaxKind.ConditionalType &&
10953af6ab5fSopenharmony_ci      kind !== ts.SyntaxKind.MappedType &&
10963af6ab5fSopenharmony_ci      kind !== ts.SyntaxKind.InferType
10973af6ab5fSopenharmony_ci    );
10983af6ab5fSopenharmony_ci  }
10993af6ab5fSopenharmony_ci
11003af6ab5fSopenharmony_ci  private isSupportedTypeHandleUnionTypeNode(typeNode: ts.UnionTypeNode): boolean {
11013af6ab5fSopenharmony_ci    for (const unionTypeElem of typeNode.types) {
11023af6ab5fSopenharmony_ci      if (!this.isSupportedType(unionTypeElem)) {
11033af6ab5fSopenharmony_ci        return false;
11043af6ab5fSopenharmony_ci      }
11053af6ab5fSopenharmony_ci    }
11063af6ab5fSopenharmony_ci    return true;
11073af6ab5fSopenharmony_ci  }
11083af6ab5fSopenharmony_ci
11093af6ab5fSopenharmony_ci  private isSupportedTypeHandleTupleTypeNode(typeNode: ts.TupleTypeNode): boolean {
11103af6ab5fSopenharmony_ci    for (const elem of typeNode.elements) {
11113af6ab5fSopenharmony_ci      if (ts.isTypeNode(elem) && !this.isSupportedType(elem)) {
11123af6ab5fSopenharmony_ci        return false;
11133af6ab5fSopenharmony_ci      }
11143af6ab5fSopenharmony_ci      if (ts.isNamedTupleMember(elem) && !this.isSupportedType(elem.type)) {
11153af6ab5fSopenharmony_ci        return false;
11163af6ab5fSopenharmony_ci      }
11173af6ab5fSopenharmony_ci    }
11183af6ab5fSopenharmony_ci    return true;
11193af6ab5fSopenharmony_ci  }
11203af6ab5fSopenharmony_ci
11213af6ab5fSopenharmony_ci  isSupportedType(typeNode: ts.TypeNode): boolean {
11223af6ab5fSopenharmony_ci    if (ts.isParenthesizedTypeNode(typeNode)) {
11233af6ab5fSopenharmony_ci      return this.isSupportedType(typeNode.type);
11243af6ab5fSopenharmony_ci    }
11253af6ab5fSopenharmony_ci
11263af6ab5fSopenharmony_ci    if (ts.isArrayTypeNode(typeNode)) {
11273af6ab5fSopenharmony_ci      return this.isSupportedType(typeNode.elementType);
11283af6ab5fSopenharmony_ci    }
11293af6ab5fSopenharmony_ci
11303af6ab5fSopenharmony_ci    if (ts.isTypeReferenceNode(typeNode) && typeNode.typeArguments) {
11313af6ab5fSopenharmony_ci      for (const typeArg of typeNode.typeArguments) {
11323af6ab5fSopenharmony_ci        if (!this.isSupportedType(typeArg)) {
11333af6ab5fSopenharmony_ci          return false;
11343af6ab5fSopenharmony_ci        }
11353af6ab5fSopenharmony_ci      }
11363af6ab5fSopenharmony_ci      return true;
11373af6ab5fSopenharmony_ci    }
11383af6ab5fSopenharmony_ci
11393af6ab5fSopenharmony_ci    if (ts.isUnionTypeNode(typeNode)) {
11403af6ab5fSopenharmony_ci      return this.isSupportedTypeHandleUnionTypeNode(typeNode);
11413af6ab5fSopenharmony_ci    }
11423af6ab5fSopenharmony_ci
11433af6ab5fSopenharmony_ci    if (ts.isTupleTypeNode(typeNode)) {
11443af6ab5fSopenharmony_ci      return this.isSupportedTypeHandleTupleTypeNode(typeNode);
11453af6ab5fSopenharmony_ci    }
11463af6ab5fSopenharmony_ci
11473af6ab5fSopenharmony_ci    return (
11483af6ab5fSopenharmony_ci      !ts.isTypeLiteralNode(typeNode) &&
11493af6ab5fSopenharmony_ci      (this.advancedClassChecks || !ts.isTypeQueryNode(typeNode)) &&
11503af6ab5fSopenharmony_ci      !ts.isIntersectionTypeNode(typeNode) &&
11513af6ab5fSopenharmony_ci      TsUtils.isSupportedTypeNodeKind(typeNode.kind)
11523af6ab5fSopenharmony_ci    );
11533af6ab5fSopenharmony_ci  }
11543af6ab5fSopenharmony_ci
11553af6ab5fSopenharmony_ci  isStructObjectInitializer(objectLiteral: ts.ObjectLiteralExpression): boolean {
11563af6ab5fSopenharmony_ci    if (ts.isCallLikeExpression(objectLiteral.parent)) {
11573af6ab5fSopenharmony_ci      const signature = this.tsTypeChecker.getResolvedSignature(objectLiteral.parent);
11583af6ab5fSopenharmony_ci      const signDecl = signature?.declaration;
11593af6ab5fSopenharmony_ci      return !!signDecl && ts.isConstructorDeclaration(signDecl) && isStructDeclaration(signDecl.parent);
11603af6ab5fSopenharmony_ci    }
11613af6ab5fSopenharmony_ci    return false;
11623af6ab5fSopenharmony_ci  }
11633af6ab5fSopenharmony_ci
11643af6ab5fSopenharmony_ci  parentSymbolCache = new Map<ts.Symbol, string | undefined>();
11653af6ab5fSopenharmony_ci
11663af6ab5fSopenharmony_ci  getParentSymbolName(symbol: ts.Symbol): string | undefined {
11673af6ab5fSopenharmony_ci    const cached = this.parentSymbolCache.get(symbol);
11683af6ab5fSopenharmony_ci    if (cached) {
11693af6ab5fSopenharmony_ci      return cached;
11703af6ab5fSopenharmony_ci    }
11713af6ab5fSopenharmony_ci
11723af6ab5fSopenharmony_ci    const name = this.tsTypeChecker.getFullyQualifiedName(symbol);
11733af6ab5fSopenharmony_ci    const dotPosition = name.lastIndexOf('.');
11743af6ab5fSopenharmony_ci    const result = dotPosition === -1 ? undefined : name.substring(0, dotPosition);
11753af6ab5fSopenharmony_ci    this.parentSymbolCache.set(symbol, result);
11763af6ab5fSopenharmony_ci    return result;
11773af6ab5fSopenharmony_ci  }
11783af6ab5fSopenharmony_ci
11793af6ab5fSopenharmony_ci  isGlobalSymbol(symbol: ts.Symbol): boolean {
11803af6ab5fSopenharmony_ci    const parentName = this.getParentSymbolName(symbol);
11813af6ab5fSopenharmony_ci    return !parentName || parentName === 'global';
11823af6ab5fSopenharmony_ci  }
11833af6ab5fSopenharmony_ci
11843af6ab5fSopenharmony_ci  isStdSymbol(symbol: ts.Symbol): boolean {
11853af6ab5fSopenharmony_ci    const name = this.tsTypeChecker.getFullyQualifiedName(symbol);
11863af6ab5fSopenharmony_ci    return name === SYMBOL || name === SYMBOL_CONSTRUCTOR;
11873af6ab5fSopenharmony_ci  }
11883af6ab5fSopenharmony_ci
11893af6ab5fSopenharmony_ci  isStdSymbolAPI(symbol: ts.Symbol): boolean {
11903af6ab5fSopenharmony_ci    const parentName = this.getParentSymbolName(symbol);
11913af6ab5fSopenharmony_ci    if (this.useSdkLogic) {
11923af6ab5fSopenharmony_ci      const name = parentName ? parentName : symbol.escapedName;
11933af6ab5fSopenharmony_ci      return name === SYMBOL || name === SYMBOL_CONSTRUCTOR;
11943af6ab5fSopenharmony_ci    }
11953af6ab5fSopenharmony_ci    return !!parentName && (parentName === SYMBOL || parentName === SYMBOL_CONSTRUCTOR);
11963af6ab5fSopenharmony_ci  }
11973af6ab5fSopenharmony_ci
11983af6ab5fSopenharmony_ci  isSymbolIterator(symbol: ts.Symbol): boolean {
11993af6ab5fSopenharmony_ci    if (this.useSdkLogic) {
12003af6ab5fSopenharmony_ci      const name = symbol.name;
12013af6ab5fSopenharmony_ci      const parName = this.getParentSymbolName(symbol);
12023af6ab5fSopenharmony_ci      return (parName === SYMBOL || parName === SYMBOL_CONSTRUCTOR) && name === ITERATOR;
12033af6ab5fSopenharmony_ci    }
12043af6ab5fSopenharmony_ci    return this.isStdSymbolAPI(symbol) && symbol.name === ITERATOR;
12053af6ab5fSopenharmony_ci  }
12063af6ab5fSopenharmony_ci
12073af6ab5fSopenharmony_ci  isSymbolIteratorExpression(expr: ts.Expression): boolean {
12083af6ab5fSopenharmony_ci    const symbol = this.trueSymbolAtLocation(expr);
12093af6ab5fSopenharmony_ci    return !!symbol && this.isSymbolIterator(symbol);
12103af6ab5fSopenharmony_ci  }
12113af6ab5fSopenharmony_ci
12123af6ab5fSopenharmony_ci  static isDefaultImport(importSpec: ts.ImportSpecifier): boolean {
12133af6ab5fSopenharmony_ci    return importSpec?.propertyName?.text === 'default';
12143af6ab5fSopenharmony_ci  }
12153af6ab5fSopenharmony_ci
12163af6ab5fSopenharmony_ci  static getStartPos(nodeOrComment: ts.Node | ts.CommentRange): number {
12173af6ab5fSopenharmony_ci    return nodeOrComment.kind === ts.SyntaxKind.SingleLineCommentTrivia ||
12183af6ab5fSopenharmony_ci      nodeOrComment.kind === ts.SyntaxKind.MultiLineCommentTrivia ?
12193af6ab5fSopenharmony_ci      (nodeOrComment as ts.CommentRange).pos :
12203af6ab5fSopenharmony_ci      (nodeOrComment as ts.Node).getStart();
12213af6ab5fSopenharmony_ci  }
12223af6ab5fSopenharmony_ci
12233af6ab5fSopenharmony_ci  static getEndPos(nodeOrComment: ts.Node | ts.CommentRange): number {
12243af6ab5fSopenharmony_ci    return nodeOrComment.kind === ts.SyntaxKind.SingleLineCommentTrivia ||
12253af6ab5fSopenharmony_ci      nodeOrComment.kind === ts.SyntaxKind.MultiLineCommentTrivia ?
12263af6ab5fSopenharmony_ci      (nodeOrComment as ts.CommentRange).end :
12273af6ab5fSopenharmony_ci      (nodeOrComment as ts.Node).getEnd();
12283af6ab5fSopenharmony_ci  }
12293af6ab5fSopenharmony_ci
12303af6ab5fSopenharmony_ci  static getHighlightRange(nodeOrComment: ts.Node | ts.CommentRange, faultId: number): [number, number] {
12313af6ab5fSopenharmony_ci    return (
12323af6ab5fSopenharmony_ci      this.highlightRangeHandlers.get(faultId)?.call(this, nodeOrComment) ?? [
12333af6ab5fSopenharmony_ci        this.getStartPos(nodeOrComment),
12343af6ab5fSopenharmony_ci        this.getEndPos(nodeOrComment)
12353af6ab5fSopenharmony_ci      ]
12363af6ab5fSopenharmony_ci    );
12373af6ab5fSopenharmony_ci  }
12383af6ab5fSopenharmony_ci
12393af6ab5fSopenharmony_ci  static highlightRangeHandlers = new Map([
12403af6ab5fSopenharmony_ci    [FaultID.VarDeclaration, TsUtils.getVarDeclarationHighlightRange],
12413af6ab5fSopenharmony_ci    [FaultID.CatchWithUnsupportedType, TsUtils.getCatchWithUnsupportedTypeHighlightRange],
12423af6ab5fSopenharmony_ci    [FaultID.ForInStatement, TsUtils.getForInStatementHighlightRange],
12433af6ab5fSopenharmony_ci    [FaultID.WithStatement, TsUtils.getWithStatementHighlightRange],
12443af6ab5fSopenharmony_ci    [FaultID.DeleteOperator, TsUtils.getDeleteOperatorHighlightRange],
12453af6ab5fSopenharmony_ci    [FaultID.TypeQuery, TsUtils.getTypeQueryHighlightRange],
12463af6ab5fSopenharmony_ci    [FaultID.InstanceofUnsupported, TsUtils.getInstanceofUnsupportedHighlightRange],
12473af6ab5fSopenharmony_ci    [FaultID.ConstAssertion, TsUtils.getConstAssertionHighlightRange],
12483af6ab5fSopenharmony_ci    [FaultID.LimitedReturnTypeInference, TsUtils.getLimitedReturnTypeInferenceHighlightRange],
12493af6ab5fSopenharmony_ci    [FaultID.LocalFunction, TsUtils.getLocalFunctionHighlightRange],
12503af6ab5fSopenharmony_ci    [FaultID.FunctionBind, TsUtils.getFunctionApplyCallHighlightRange],
12513af6ab5fSopenharmony_ci    [FaultID.FunctionBindError, TsUtils.getFunctionApplyCallHighlightRange],
12523af6ab5fSopenharmony_ci    [FaultID.FunctionApplyCall, TsUtils.getFunctionApplyCallHighlightRange],
12533af6ab5fSopenharmony_ci    [FaultID.DeclWithDuplicateName, TsUtils.getDeclWithDuplicateNameHighlightRange],
12543af6ab5fSopenharmony_ci    [FaultID.ObjectLiteralNoContextType, TsUtils.getObjectLiteralNoContextTypeHighlightRange],
12553af6ab5fSopenharmony_ci    [FaultID.ClassExpression, TsUtils.getClassExpressionHighlightRange],
12563af6ab5fSopenharmony_ci    [FaultID.MultipleStaticBlocks, TsUtils.getMultipleStaticBlocksHighlightRange],
12573af6ab5fSopenharmony_ci    [FaultID.ParameterProperties, TsUtils.getParameterPropertiesHighlightRange],
12583af6ab5fSopenharmony_ci    [FaultID.SendableDefiniteAssignment, TsUtils.getSendableDefiniteAssignmentHighlightRange],
12593af6ab5fSopenharmony_ci    [FaultID.ObjectTypeLiteral, TsUtils.getObjectTypeLiteralHighlightRange],
12603af6ab5fSopenharmony_ci    [FaultID.StructuralIdentity, TsUtils.getStructuralIdentityHighlightRange]
12613af6ab5fSopenharmony_ci  ]);
12623af6ab5fSopenharmony_ci
12633af6ab5fSopenharmony_ci  static getKeywordHighlightRange(nodeOrComment: ts.Node | ts.CommentRange, keyword: string): [number, number] {
12643af6ab5fSopenharmony_ci    const start = this.getStartPos(nodeOrComment);
12653af6ab5fSopenharmony_ci    return [start, start + keyword.length];
12663af6ab5fSopenharmony_ci  }
12673af6ab5fSopenharmony_ci
12683af6ab5fSopenharmony_ci  static getVarDeclarationHighlightRange(nodeOrComment: ts.Node | ts.CommentRange): [number, number] | undefined {
12693af6ab5fSopenharmony_ci    return this.getKeywordHighlightRange(nodeOrComment, 'var');
12703af6ab5fSopenharmony_ci  }
12713af6ab5fSopenharmony_ci
12723af6ab5fSopenharmony_ci  static getCatchWithUnsupportedTypeHighlightRange(
12733af6ab5fSopenharmony_ci    nodeOrComment: ts.Node | ts.CommentRange
12743af6ab5fSopenharmony_ci  ): [number, number] | undefined {
12753af6ab5fSopenharmony_ci    const catchClauseNode = (nodeOrComment as ts.CatchClause).variableDeclaration;
12763af6ab5fSopenharmony_ci    if (catchClauseNode !== undefined) {
12773af6ab5fSopenharmony_ci      return [catchClauseNode.getStart(), catchClauseNode.getEnd()];
12783af6ab5fSopenharmony_ci    }
12793af6ab5fSopenharmony_ci
12803af6ab5fSopenharmony_ci    return undefined;
12813af6ab5fSopenharmony_ci  }
12823af6ab5fSopenharmony_ci
12833af6ab5fSopenharmony_ci  static getForInStatementHighlightRange(nodeOrComment: ts.Node | ts.CommentRange): [number, number] | undefined {
12843af6ab5fSopenharmony_ci    return [
12853af6ab5fSopenharmony_ci      this.getEndPos((nodeOrComment as ts.ForInStatement).initializer) + 1,
12863af6ab5fSopenharmony_ci      this.getStartPos((nodeOrComment as ts.ForInStatement).expression) - 1
12873af6ab5fSopenharmony_ci    ];
12883af6ab5fSopenharmony_ci  }
12893af6ab5fSopenharmony_ci
12903af6ab5fSopenharmony_ci  static getWithStatementHighlightRange(nodeOrComment: ts.Node | ts.CommentRange): [number, number] | undefined {
12913af6ab5fSopenharmony_ci    return [this.getStartPos(nodeOrComment), (nodeOrComment as ts.WithStatement).statement.getStart() - 1];
12923af6ab5fSopenharmony_ci  }
12933af6ab5fSopenharmony_ci
12943af6ab5fSopenharmony_ci  static getDeleteOperatorHighlightRange(nodeOrComment: ts.Node | ts.CommentRange): [number, number] | undefined {
12953af6ab5fSopenharmony_ci    return this.getKeywordHighlightRange(nodeOrComment, 'delete');
12963af6ab5fSopenharmony_ci  }
12973af6ab5fSopenharmony_ci
12983af6ab5fSopenharmony_ci  static getTypeQueryHighlightRange(nodeOrComment: ts.Node | ts.CommentRange): [number, number] | undefined {
12993af6ab5fSopenharmony_ci    return this.getKeywordHighlightRange(nodeOrComment, 'typeof');
13003af6ab5fSopenharmony_ci  }
13013af6ab5fSopenharmony_ci
13023af6ab5fSopenharmony_ci  static getInstanceofUnsupportedHighlightRange(
13033af6ab5fSopenharmony_ci    nodeOrComment: ts.Node | ts.CommentRange
13043af6ab5fSopenharmony_ci  ): [number, number] | undefined {
13053af6ab5fSopenharmony_ci    return this.getKeywordHighlightRange((nodeOrComment as ts.BinaryExpression).operatorToken, 'instanceof');
13063af6ab5fSopenharmony_ci  }
13073af6ab5fSopenharmony_ci
13083af6ab5fSopenharmony_ci  static getConstAssertionHighlightRange(nodeOrComment: ts.Node | ts.CommentRange): [number, number] | undefined {
13093af6ab5fSopenharmony_ci    if (nodeOrComment.kind === ts.SyntaxKind.AsExpression) {
13103af6ab5fSopenharmony_ci      return [
13113af6ab5fSopenharmony_ci        (nodeOrComment as ts.AsExpression).expression.getEnd() + 1,
13123af6ab5fSopenharmony_ci        (nodeOrComment as ts.AsExpression).type.getStart() - 1
13133af6ab5fSopenharmony_ci      ];
13143af6ab5fSopenharmony_ci    }
13153af6ab5fSopenharmony_ci    return [
13163af6ab5fSopenharmony_ci      (nodeOrComment as ts.TypeAssertion).expression.getEnd() + 1,
13173af6ab5fSopenharmony_ci      (nodeOrComment as ts.TypeAssertion).type.getEnd() + 1
13183af6ab5fSopenharmony_ci    ];
13193af6ab5fSopenharmony_ci  }
13203af6ab5fSopenharmony_ci
13213af6ab5fSopenharmony_ci  static getLimitedReturnTypeInferenceHighlightRange(
13223af6ab5fSopenharmony_ci    nodeOrComment: ts.Node | ts.CommentRange
13233af6ab5fSopenharmony_ci  ): [number, number] | undefined {
13243af6ab5fSopenharmony_ci    let node: ts.Node | undefined;
13253af6ab5fSopenharmony_ci    if (nodeOrComment.kind === ts.SyntaxKind.FunctionExpression) {
13263af6ab5fSopenharmony_ci      // we got error about return type so it should be present
13273af6ab5fSopenharmony_ci      node = (nodeOrComment as ts.FunctionExpression).type;
13283af6ab5fSopenharmony_ci    } else if (nodeOrComment.kind === ts.SyntaxKind.FunctionDeclaration) {
13293af6ab5fSopenharmony_ci      node = (nodeOrComment as ts.FunctionDeclaration).name;
13303af6ab5fSopenharmony_ci    } else if (nodeOrComment.kind === ts.SyntaxKind.MethodDeclaration) {
13313af6ab5fSopenharmony_ci      node = (nodeOrComment as ts.MethodDeclaration).name;
13323af6ab5fSopenharmony_ci    }
13333af6ab5fSopenharmony_ci
13343af6ab5fSopenharmony_ci    if (node !== undefined) {
13353af6ab5fSopenharmony_ci      return [node.getStart(), node.getEnd()];
13363af6ab5fSopenharmony_ci    }
13373af6ab5fSopenharmony_ci
13383af6ab5fSopenharmony_ci    return undefined;
13393af6ab5fSopenharmony_ci  }
13403af6ab5fSopenharmony_ci
13413af6ab5fSopenharmony_ci  static getLocalFunctionHighlightRange(nodeOrComment: ts.Node | ts.CommentRange): [number, number] | undefined {
13423af6ab5fSopenharmony_ci    return this.getKeywordHighlightRange(nodeOrComment, 'function');
13433af6ab5fSopenharmony_ci  }
13443af6ab5fSopenharmony_ci
13453af6ab5fSopenharmony_ci  static getFunctionApplyCallHighlightRange(nodeOrComment: ts.Node | ts.CommentRange): [number, number] | undefined {
13463af6ab5fSopenharmony_ci    const pointPos = (nodeOrComment as ts.Node).getText().lastIndexOf('.');
13473af6ab5fSopenharmony_ci    return [this.getStartPos(nodeOrComment) + pointPos + 1, this.getEndPos(nodeOrComment)];
13483af6ab5fSopenharmony_ci  }
13493af6ab5fSopenharmony_ci
13503af6ab5fSopenharmony_ci  static getDeclWithDuplicateNameHighlightRange(
13513af6ab5fSopenharmony_ci    nodeOrComment: ts.Node | ts.CommentRange
13523af6ab5fSopenharmony_ci  ): [number, number] | undefined {
13533af6ab5fSopenharmony_ci    // in case of private identifier no range update is needed
13543af6ab5fSopenharmony_ci    const nameNode: ts.Node | undefined = (nodeOrComment as ts.NamedDeclaration).name;
13553af6ab5fSopenharmony_ci    if (nameNode !== undefined) {
13563af6ab5fSopenharmony_ci      return [nameNode.getStart(), nameNode.getEnd()];
13573af6ab5fSopenharmony_ci    }
13583af6ab5fSopenharmony_ci
13593af6ab5fSopenharmony_ci    return undefined;
13603af6ab5fSopenharmony_ci  }
13613af6ab5fSopenharmony_ci
13623af6ab5fSopenharmony_ci  static getObjectLiteralNoContextTypeHighlightRange(
13633af6ab5fSopenharmony_ci    nodeOrComment: ts.Node | ts.CommentRange
13643af6ab5fSopenharmony_ci  ): [number, number] | undefined {
13653af6ab5fSopenharmony_ci    return this.getKeywordHighlightRange(nodeOrComment, '{');
13663af6ab5fSopenharmony_ci  }
13673af6ab5fSopenharmony_ci
13683af6ab5fSopenharmony_ci  static getClassExpressionHighlightRange(nodeOrComment: ts.Node | ts.CommentRange): [number, number] | undefined {
13693af6ab5fSopenharmony_ci    return this.getKeywordHighlightRange(nodeOrComment, 'class');
13703af6ab5fSopenharmony_ci  }
13713af6ab5fSopenharmony_ci
13723af6ab5fSopenharmony_ci  static getMultipleStaticBlocksHighlightRange(nodeOrComment: ts.Node | ts.CommentRange): [number, number] | undefined {
13733af6ab5fSopenharmony_ci    return this.getKeywordHighlightRange(nodeOrComment, 'static');
13743af6ab5fSopenharmony_ci  }
13753af6ab5fSopenharmony_ci
13763af6ab5fSopenharmony_ci  static getParameterPropertiesHighlightRange(nodeOrComment: ts.Node | ts.CommentRange): [number, number] | undefined {
13773af6ab5fSopenharmony_ci    const param = nodeOrComment as ts.ParameterDeclaration;
13783af6ab5fSopenharmony_ci    const modifier = TsUtils.getAccessModifier(ts.getModifiers(param));
13793af6ab5fSopenharmony_ci    if (modifier !== undefined) {
13803af6ab5fSopenharmony_ci      return [modifier.getStart(), modifier.getEnd()];
13813af6ab5fSopenharmony_ci    }
13823af6ab5fSopenharmony_ci    return undefined;
13833af6ab5fSopenharmony_ci  }
13843af6ab5fSopenharmony_ci
13853af6ab5fSopenharmony_ci  static getObjectTypeLiteralHighlightRange(nodeOrComment: ts.Node | ts.CommentRange): [number, number] | undefined {
13863af6ab5fSopenharmony_ci    return this.getKeywordHighlightRange(nodeOrComment, '{');
13873af6ab5fSopenharmony_ci  }
13883af6ab5fSopenharmony_ci
13893af6ab5fSopenharmony_ci  // highlight ranges for Sendable rules
13903af6ab5fSopenharmony_ci
13913af6ab5fSopenharmony_ci  static getSendableDefiniteAssignmentHighlightRange(
13923af6ab5fSopenharmony_ci    nodeOrComment: ts.Node | ts.CommentRange
13933af6ab5fSopenharmony_ci  ): [number, number] | undefined {
13943af6ab5fSopenharmony_ci    const name = (nodeOrComment as ts.PropertyDeclaration).name;
13953af6ab5fSopenharmony_ci    const exclamationToken = (nodeOrComment as ts.PropertyDeclaration).exclamationToken;
13963af6ab5fSopenharmony_ci    return [name.getStart(), exclamationToken ? exclamationToken.getEnd() : name.getEnd()];
13973af6ab5fSopenharmony_ci  }
13983af6ab5fSopenharmony_ci
13993af6ab5fSopenharmony_ci  static getStructuralIdentityHighlightRange(nodeOrComment: ts.Node | ts.CommentRange): [number, number] | undefined {
14003af6ab5fSopenharmony_ci    let node: ts.Node | undefined;
14013af6ab5fSopenharmony_ci    if (nodeOrComment.kind === ts.SyntaxKind.ReturnStatement) {
14023af6ab5fSopenharmony_ci      node = (nodeOrComment as ts.ReturnStatement).expression;
14033af6ab5fSopenharmony_ci    } else if (nodeOrComment.kind === ts.SyntaxKind.PropertyDeclaration) {
14043af6ab5fSopenharmony_ci      node = (nodeOrComment as ts.PropertyDeclaration).name;
14053af6ab5fSopenharmony_ci    }
14063af6ab5fSopenharmony_ci
14073af6ab5fSopenharmony_ci    if (node !== undefined) {
14083af6ab5fSopenharmony_ci      return [node.getStart(), node.getEnd()];
14093af6ab5fSopenharmony_ci    }
14103af6ab5fSopenharmony_ci
14113af6ab5fSopenharmony_ci    return undefined;
14123af6ab5fSopenharmony_ci  }
14133af6ab5fSopenharmony_ci
14143af6ab5fSopenharmony_ci  isStdRecordType(type: ts.Type): boolean {
14153af6ab5fSopenharmony_ci
14163af6ab5fSopenharmony_ci    /*
14173af6ab5fSopenharmony_ci     * In TypeScript, 'Record<K, T>' is defined as type alias to a mapped type.
14183af6ab5fSopenharmony_ci     * Thus, it should have 'aliasSymbol' and 'target' properties. The 'target'
14193af6ab5fSopenharmony_ci     * in this case will resolve to origin 'Record' symbol.
14203af6ab5fSopenharmony_ci     */
14213af6ab5fSopenharmony_ci    if (type.aliasSymbol) {
14223af6ab5fSopenharmony_ci      const target = (type as ts.TypeReference).target;
14233af6ab5fSopenharmony_ci      if (target) {
14243af6ab5fSopenharmony_ci        const sym = target.aliasSymbol;
14253af6ab5fSopenharmony_ci        return !!sym && sym.getName() === 'Record' && this.isGlobalSymbol(sym);
14263af6ab5fSopenharmony_ci      }
14273af6ab5fSopenharmony_ci    }
14283af6ab5fSopenharmony_ci
14293af6ab5fSopenharmony_ci    return false;
14303af6ab5fSopenharmony_ci  }
14313af6ab5fSopenharmony_ci
14323af6ab5fSopenharmony_ci  isStdErrorType(type: ts.Type): boolean {
14333af6ab5fSopenharmony_ci    const symbol = type.symbol;
14343af6ab5fSopenharmony_ci    if (!symbol) {
14353af6ab5fSopenharmony_ci      return false;
14363af6ab5fSopenharmony_ci    }
14373af6ab5fSopenharmony_ci    const name = this.tsTypeChecker.getFullyQualifiedName(symbol);
14383af6ab5fSopenharmony_ci    return name === 'Error' && this.isGlobalSymbol(symbol);
14393af6ab5fSopenharmony_ci  }
14403af6ab5fSopenharmony_ci
14413af6ab5fSopenharmony_ci  isStdPartialType(type: ts.Type): boolean {
14423af6ab5fSopenharmony_ci    const sym = type.aliasSymbol;
14433af6ab5fSopenharmony_ci    return !!sym && sym.getName() === 'Partial' && this.isGlobalSymbol(sym);
14443af6ab5fSopenharmony_ci  }
14453af6ab5fSopenharmony_ci
14463af6ab5fSopenharmony_ci  isStdRequiredType(type: ts.Type): boolean {
14473af6ab5fSopenharmony_ci    const sym = type.aliasSymbol;
14483af6ab5fSopenharmony_ci    return !!sym && sym.getName() === 'Required' && this.isGlobalSymbol(sym);
14493af6ab5fSopenharmony_ci  }
14503af6ab5fSopenharmony_ci
14513af6ab5fSopenharmony_ci  isStdReadonlyType(type: ts.Type): boolean {
14523af6ab5fSopenharmony_ci    const sym = type.aliasSymbol;
14533af6ab5fSopenharmony_ci    return !!sym && sym.getName() === 'Readonly' && this.isGlobalSymbol(sym);
14543af6ab5fSopenharmony_ci  }
14553af6ab5fSopenharmony_ci
14563af6ab5fSopenharmony_ci  isLibraryType(type: ts.Type): boolean {
14573af6ab5fSopenharmony_ci    const nonNullableType = type.getNonNullableType();
14583af6ab5fSopenharmony_ci    if (nonNullableType.isUnion()) {
14593af6ab5fSopenharmony_ci      for (const componentType of nonNullableType.types) {
14603af6ab5fSopenharmony_ci        if (!this.isLibraryType(componentType)) {
14613af6ab5fSopenharmony_ci          return false;
14623af6ab5fSopenharmony_ci        }
14633af6ab5fSopenharmony_ci      }
14643af6ab5fSopenharmony_ci      return true;
14653af6ab5fSopenharmony_ci    }
14663af6ab5fSopenharmony_ci    return this.isLibrarySymbol(nonNullableType.aliasSymbol ?? nonNullableType.getSymbol());
14673af6ab5fSopenharmony_ci  }
14683af6ab5fSopenharmony_ci
14693af6ab5fSopenharmony_ci  hasLibraryType(node: ts.Node): boolean {
14703af6ab5fSopenharmony_ci    return this.isLibraryType(this.tsTypeChecker.getTypeAtLocation(node));
14713af6ab5fSopenharmony_ci  }
14723af6ab5fSopenharmony_ci
14733af6ab5fSopenharmony_ci  isLibrarySymbol(sym: ts.Symbol | undefined): boolean {
14743af6ab5fSopenharmony_ci    if (sym?.declarations && sym.declarations.length > 0) {
14753af6ab5fSopenharmony_ci      const srcFile = sym.declarations[0].getSourceFile();
14763af6ab5fSopenharmony_ci      if (!srcFile) {
14773af6ab5fSopenharmony_ci        return false;
14783af6ab5fSopenharmony_ci      }
14793af6ab5fSopenharmony_ci      const fileName = srcFile.fileName;
14803af6ab5fSopenharmony_ci
14813af6ab5fSopenharmony_ci      /*
14823af6ab5fSopenharmony_ci       * Symbols from both *.ts and *.d.ts files should obey interop rules.
14833af6ab5fSopenharmony_ci       * We disable such behavior for *.ts files in the test mode due to lack of 'ets'
14843af6ab5fSopenharmony_ci       * extension support.
14853af6ab5fSopenharmony_ci       */
14863af6ab5fSopenharmony_ci      const ext = path.extname(fileName).toLowerCase();
14873af6ab5fSopenharmony_ci      const isThirdPartyCode =
14883af6ab5fSopenharmony_ci        ARKTS_IGNORE_DIRS.some((ignore) => {
14893af6ab5fSopenharmony_ci          return srcFilePathContainsDirectory(srcFile, ignore);
14903af6ab5fSopenharmony_ci        }) ||
14913af6ab5fSopenharmony_ci        ARKTS_IGNORE_FILES.some((ignore) => {
14923af6ab5fSopenharmony_ci          return path.basename(fileName) === ignore;
14933af6ab5fSopenharmony_ci        });
14943af6ab5fSopenharmony_ci      const isEts = ext === '.ets';
14953af6ab5fSopenharmony_ci      const isTs = ext === '.ts' && !srcFile.isDeclarationFile;
14963af6ab5fSopenharmony_ci      const isStatic = (isEts || isTs && this.testMode) && !isThirdPartyCode;
14973af6ab5fSopenharmony_ci      const isStdLib = STANDARD_LIBRARIES.includes(path.basename(fileName).toLowerCase());
14983af6ab5fSopenharmony_ci
14993af6ab5fSopenharmony_ci      /*
15003af6ab5fSopenharmony_ci       * We still need to confirm support for certain API from the
15013af6ab5fSopenharmony_ci       * TypeScript standard library in ArkTS. Thus, for now do not
15023af6ab5fSopenharmony_ci       * count standard library modules as dynamic.
15033af6ab5fSopenharmony_ci       */
15043af6ab5fSopenharmony_ci      return !isStatic && !isStdLib;
15053af6ab5fSopenharmony_ci    }
15063af6ab5fSopenharmony_ci    return false;
15073af6ab5fSopenharmony_ci  }
15083af6ab5fSopenharmony_ci
15093af6ab5fSopenharmony_ci  isDynamicType(type: ts.Type | undefined): boolean | undefined {
15103af6ab5fSopenharmony_ci    if (type === undefined) {
15113af6ab5fSopenharmony_ci      return false;
15123af6ab5fSopenharmony_ci    }
15133af6ab5fSopenharmony_ci
15143af6ab5fSopenharmony_ci    /*
15153af6ab5fSopenharmony_ci     * Return 'true' if it is an object of library type initialization, otherwise
15163af6ab5fSopenharmony_ci     * return 'false' if it is not an object of standard library type one.
15173af6ab5fSopenharmony_ci     * In the case of standard library type we need to determine context.
15183af6ab5fSopenharmony_ci     */
15193af6ab5fSopenharmony_ci
15203af6ab5fSopenharmony_ci    /*
15213af6ab5fSopenharmony_ci     * Check the non-nullable version of type to eliminate 'undefined' type
15223af6ab5fSopenharmony_ci     * from the union type elements.
15233af6ab5fSopenharmony_ci     */
15243af6ab5fSopenharmony_ci    // eslint-disable-next-line no-param-reassign
15253af6ab5fSopenharmony_ci    type = type.getNonNullableType();
15263af6ab5fSopenharmony_ci
15273af6ab5fSopenharmony_ci    if (type.isUnion()) {
15283af6ab5fSopenharmony_ci      for (const compType of type.types) {
15293af6ab5fSopenharmony_ci        const isDynamic = this.isDynamicType(compType);
15303af6ab5fSopenharmony_ci        if (isDynamic || isDynamic === undefined) {
15313af6ab5fSopenharmony_ci          return isDynamic;
15323af6ab5fSopenharmony_ci        }
15333af6ab5fSopenharmony_ci      }
15343af6ab5fSopenharmony_ci      return false;
15353af6ab5fSopenharmony_ci    }
15363af6ab5fSopenharmony_ci
15373af6ab5fSopenharmony_ci    if (this.isLibraryType(type)) {
15383af6ab5fSopenharmony_ci      return true;
15393af6ab5fSopenharmony_ci    }
15403af6ab5fSopenharmony_ci
15413af6ab5fSopenharmony_ci    if (!isStdLibraryType(type) && !isIntrinsicObjectType(type) && !TsUtils.isAnyType(type)) {
15423af6ab5fSopenharmony_ci      return false;
15433af6ab5fSopenharmony_ci    }
15443af6ab5fSopenharmony_ci
15453af6ab5fSopenharmony_ci    return undefined;
15463af6ab5fSopenharmony_ci  }
15473af6ab5fSopenharmony_ci
15483af6ab5fSopenharmony_ci  static isObjectType(type: ts.Type): type is ts.ObjectType {
15493af6ab5fSopenharmony_ci    return !!(type.flags & ts.TypeFlags.Object);
15503af6ab5fSopenharmony_ci  }
15513af6ab5fSopenharmony_ci
15523af6ab5fSopenharmony_ci  private static isAnonymous(type: ts.Type): boolean {
15533af6ab5fSopenharmony_ci    if (TsUtils.isObjectType(type)) {
15543af6ab5fSopenharmony_ci      return !!(type.objectFlags & ts.ObjectFlags.Anonymous);
15553af6ab5fSopenharmony_ci    }
15563af6ab5fSopenharmony_ci    return false;
15573af6ab5fSopenharmony_ci  }
15583af6ab5fSopenharmony_ci
15593af6ab5fSopenharmony_ci  private isDynamicLiteralInitializerHandleCallExpression(callExpr: ts.CallExpression): boolean {
15603af6ab5fSopenharmony_ci    const type = this.tsTypeChecker.getTypeAtLocation(callExpr.expression);
15613af6ab5fSopenharmony_ci
15623af6ab5fSopenharmony_ci    if (TsUtils.isAnyType(type)) {
15633af6ab5fSopenharmony_ci      return true;
15643af6ab5fSopenharmony_ci    }
15653af6ab5fSopenharmony_ci
15663af6ab5fSopenharmony_ci    let sym: ts.Symbol | undefined = type.symbol;
15673af6ab5fSopenharmony_ci    if (this.isLibrarySymbol(sym)) {
15683af6ab5fSopenharmony_ci      return true;
15693af6ab5fSopenharmony_ci    }
15703af6ab5fSopenharmony_ci
15713af6ab5fSopenharmony_ci    /*
15723af6ab5fSopenharmony_ci     * #13483:
15733af6ab5fSopenharmony_ci     * x.foo({ ... }), where 'x' is exported from some library:
15743af6ab5fSopenharmony_ci     */
15753af6ab5fSopenharmony_ci    if (ts.isPropertyAccessExpression(callExpr.expression)) {
15763af6ab5fSopenharmony_ci      sym = this.trueSymbolAtLocation(callExpr.expression.expression);
15773af6ab5fSopenharmony_ci      if (sym && this.isLibrarySymbol(sym)) {
15783af6ab5fSopenharmony_ci        return true;
15793af6ab5fSopenharmony_ci      }
15803af6ab5fSopenharmony_ci    }
15813af6ab5fSopenharmony_ci
15823af6ab5fSopenharmony_ci    return false;
15833af6ab5fSopenharmony_ci  }
15843af6ab5fSopenharmony_ci
15853af6ab5fSopenharmony_ci  isDynamicLiteralInitializer(expr: ts.Expression): boolean {
15863af6ab5fSopenharmony_ci    if (!ts.isObjectLiteralExpression(expr) && !ts.isArrayLiteralExpression(expr)) {
15873af6ab5fSopenharmony_ci      return false;
15883af6ab5fSopenharmony_ci    }
15893af6ab5fSopenharmony_ci
15903af6ab5fSopenharmony_ci    /*
15913af6ab5fSopenharmony_ci     * Handle nested literals:
15923af6ab5fSopenharmony_ci     * { f: { ... } }
15933af6ab5fSopenharmony_ci     */
15943af6ab5fSopenharmony_ci    let curNode: ts.Node = expr;
15953af6ab5fSopenharmony_ci    while (ts.isObjectLiteralExpression(curNode) || ts.isArrayLiteralExpression(curNode)) {
15963af6ab5fSopenharmony_ci      const exprType = this.tsTypeChecker.getContextualType(curNode);
15973af6ab5fSopenharmony_ci      if (exprType !== undefined && !TsUtils.isAnonymous(exprType)) {
15983af6ab5fSopenharmony_ci        const res = this.isDynamicType(exprType);
15993af6ab5fSopenharmony_ci        if (res !== undefined) {
16003af6ab5fSopenharmony_ci          return res;
16013af6ab5fSopenharmony_ci        }
16023af6ab5fSopenharmony_ci      }
16033af6ab5fSopenharmony_ci
16043af6ab5fSopenharmony_ci      curNode = curNode.parent;
16053af6ab5fSopenharmony_ci      if (ts.isPropertyAssignment(curNode)) {
16063af6ab5fSopenharmony_ci        curNode = curNode.parent;
16073af6ab5fSopenharmony_ci      }
16083af6ab5fSopenharmony_ci    }
16093af6ab5fSopenharmony_ci
16103af6ab5fSopenharmony_ci    /*
16113af6ab5fSopenharmony_ci     * Handle calls with literals:
16123af6ab5fSopenharmony_ci     * foo({ ... })
16133af6ab5fSopenharmony_ci     */
16143af6ab5fSopenharmony_ci    if (ts.isCallExpression(curNode) && this.isDynamicLiteralInitializerHandleCallExpression(curNode)) {
16153af6ab5fSopenharmony_ci      return true;
16163af6ab5fSopenharmony_ci    }
16173af6ab5fSopenharmony_ci
16183af6ab5fSopenharmony_ci    /*
16193af6ab5fSopenharmony_ci     * Handle property assignments with literals:
16203af6ab5fSopenharmony_ci     * obj.f = { ... }
16213af6ab5fSopenharmony_ci     */
16223af6ab5fSopenharmony_ci    if (ts.isBinaryExpression(curNode)) {
16233af6ab5fSopenharmony_ci      const binExpr = curNode;
16243af6ab5fSopenharmony_ci      if (ts.isPropertyAccessExpression(binExpr.left)) {
16253af6ab5fSopenharmony_ci        const propAccessExpr = binExpr.left;
16263af6ab5fSopenharmony_ci        const type = this.tsTypeChecker.getTypeAtLocation(propAccessExpr.expression);
16273af6ab5fSopenharmony_ci        return this.isLibrarySymbol(type.symbol);
16283af6ab5fSopenharmony_ci      }
16293af6ab5fSopenharmony_ci    }
16303af6ab5fSopenharmony_ci
16313af6ab5fSopenharmony_ci    return false;
16323af6ab5fSopenharmony_ci  }
16333af6ab5fSopenharmony_ci
16343af6ab5fSopenharmony_ci  static isEsObjectType(typeNode: ts.TypeNode | undefined): boolean {
16353af6ab5fSopenharmony_ci    return (
16363af6ab5fSopenharmony_ci      !!typeNode &&
16373af6ab5fSopenharmony_ci      ts.isTypeReferenceNode(typeNode) &&
16383af6ab5fSopenharmony_ci      ts.isIdentifier(typeNode.typeName) &&
16393af6ab5fSopenharmony_ci      typeNode.typeName.text === ES_OBJECT
16403af6ab5fSopenharmony_ci    );
16413af6ab5fSopenharmony_ci  }
16423af6ab5fSopenharmony_ci
16433af6ab5fSopenharmony_ci  static isInsideBlock(node: ts.Node): boolean {
16443af6ab5fSopenharmony_ci    let par = node.parent;
16453af6ab5fSopenharmony_ci    while (par) {
16463af6ab5fSopenharmony_ci      if (ts.isBlock(par)) {
16473af6ab5fSopenharmony_ci        return true;
16483af6ab5fSopenharmony_ci      }
16493af6ab5fSopenharmony_ci      par = par.parent;
16503af6ab5fSopenharmony_ci    }
16513af6ab5fSopenharmony_ci    return false;
16523af6ab5fSopenharmony_ci  }
16533af6ab5fSopenharmony_ci
16543af6ab5fSopenharmony_ci  static isEsObjectPossiblyAllowed(typeRef: ts.TypeReferenceNode): boolean {
16553af6ab5fSopenharmony_ci    return ts.isVariableDeclaration(typeRef.parent);
16563af6ab5fSopenharmony_ci  }
16573af6ab5fSopenharmony_ci
16583af6ab5fSopenharmony_ci  isValueAssignableToESObject(node: ts.Node): boolean {
16593af6ab5fSopenharmony_ci    if (ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node)) {
16603af6ab5fSopenharmony_ci      return false;
16613af6ab5fSopenharmony_ci    }
16623af6ab5fSopenharmony_ci    const valueType = this.tsTypeChecker.getTypeAtLocation(node);
16633af6ab5fSopenharmony_ci    return TsUtils.isUnsupportedType(valueType) || TsUtils.isAnonymousType(valueType);
16643af6ab5fSopenharmony_ci  }
16653af6ab5fSopenharmony_ci
16663af6ab5fSopenharmony_ci  getVariableDeclarationTypeNode(node: ts.Node): ts.TypeNode | undefined {
16673af6ab5fSopenharmony_ci    const sym = this.trueSymbolAtLocation(node);
16683af6ab5fSopenharmony_ci    if (sym === undefined) {
16693af6ab5fSopenharmony_ci      return undefined;
16703af6ab5fSopenharmony_ci    }
16713af6ab5fSopenharmony_ci    return TsUtils.getSymbolDeclarationTypeNode(sym);
16723af6ab5fSopenharmony_ci  }
16733af6ab5fSopenharmony_ci
16743af6ab5fSopenharmony_ci  static getSymbolDeclarationTypeNode(sym: ts.Symbol): ts.TypeNode | undefined {
16753af6ab5fSopenharmony_ci    const decl = TsUtils.getDeclaration(sym);
16763af6ab5fSopenharmony_ci    if (!!decl && ts.isVariableDeclaration(decl)) {
16773af6ab5fSopenharmony_ci      return decl.type;
16783af6ab5fSopenharmony_ci    }
16793af6ab5fSopenharmony_ci    return undefined;
16803af6ab5fSopenharmony_ci  }
16813af6ab5fSopenharmony_ci
16823af6ab5fSopenharmony_ci  hasEsObjectType(node: ts.Node): boolean {
16833af6ab5fSopenharmony_ci    const typeNode = this.getVariableDeclarationTypeNode(node);
16843af6ab5fSopenharmony_ci    return typeNode !== undefined && TsUtils.isEsObjectType(typeNode);
16853af6ab5fSopenharmony_ci  }
16863af6ab5fSopenharmony_ci
16873af6ab5fSopenharmony_ci  static symbolHasEsObjectType(sym: ts.Symbol): boolean {
16883af6ab5fSopenharmony_ci    const typeNode = TsUtils.getSymbolDeclarationTypeNode(sym);
16893af6ab5fSopenharmony_ci    return typeNode !== undefined && TsUtils.isEsObjectType(typeNode);
16903af6ab5fSopenharmony_ci  }
16913af6ab5fSopenharmony_ci
16923af6ab5fSopenharmony_ci  static isEsObjectSymbol(sym: ts.Symbol): boolean {
16933af6ab5fSopenharmony_ci    const decl = TsUtils.getDeclaration(sym);
16943af6ab5fSopenharmony_ci    return (
16953af6ab5fSopenharmony_ci      !!decl &&
16963af6ab5fSopenharmony_ci      ts.isTypeAliasDeclaration(decl) &&
16973af6ab5fSopenharmony_ci      decl.name.escapedText === ES_OBJECT &&
16983af6ab5fSopenharmony_ci      decl.type.kind === ts.SyntaxKind.AnyKeyword
16993af6ab5fSopenharmony_ci    );
17003af6ab5fSopenharmony_ci  }
17013af6ab5fSopenharmony_ci
17023af6ab5fSopenharmony_ci  static isAnonymousType(type: ts.Type): boolean {
17033af6ab5fSopenharmony_ci    if (type.isUnionOrIntersection()) {
17043af6ab5fSopenharmony_ci      for (const compType of type.types) {
17053af6ab5fSopenharmony_ci        if (TsUtils.isAnonymousType(compType)) {
17063af6ab5fSopenharmony_ci          return true;
17073af6ab5fSopenharmony_ci        }
17083af6ab5fSopenharmony_ci      }
17093af6ab5fSopenharmony_ci      return false;
17103af6ab5fSopenharmony_ci    }
17113af6ab5fSopenharmony_ci
17123af6ab5fSopenharmony_ci    return (
17133af6ab5fSopenharmony_ci      (type.flags & ts.TypeFlags.Object) !== 0 && ((type as ts.ObjectType).objectFlags & ts.ObjectFlags.Anonymous) !== 0
17143af6ab5fSopenharmony_ci    );
17153af6ab5fSopenharmony_ci  }
17163af6ab5fSopenharmony_ci
17173af6ab5fSopenharmony_ci  getSymbolOfCallExpression(callExpr: ts.CallExpression): ts.Symbol | undefined {
17183af6ab5fSopenharmony_ci    const signature = this.tsTypeChecker.getResolvedSignature(callExpr);
17193af6ab5fSopenharmony_ci    const signDecl = signature?.getDeclaration();
17203af6ab5fSopenharmony_ci    if (signDecl?.name) {
17213af6ab5fSopenharmony_ci      return this.trueSymbolAtLocation(signDecl.name);
17223af6ab5fSopenharmony_ci    }
17233af6ab5fSopenharmony_ci    return undefined;
17243af6ab5fSopenharmony_ci  }
17253af6ab5fSopenharmony_ci
17263af6ab5fSopenharmony_ci  static isClassValueType(type: ts.Type): boolean {
17273af6ab5fSopenharmony_ci    if (
17283af6ab5fSopenharmony_ci      (type.flags & ts.TypeFlags.Object) === 0 ||
17293af6ab5fSopenharmony_ci      ((type as ts.ObjectType).objectFlags & ts.ObjectFlags.Anonymous) === 0
17303af6ab5fSopenharmony_ci    ) {
17313af6ab5fSopenharmony_ci      return false;
17323af6ab5fSopenharmony_ci    }
17333af6ab5fSopenharmony_ci    return type.symbol && (type.symbol.flags & ts.SymbolFlags.Class) !== 0;
17343af6ab5fSopenharmony_ci  }
17353af6ab5fSopenharmony_ci
17363af6ab5fSopenharmony_ci  isClassObjectExpression(expr: ts.Expression): boolean {
17373af6ab5fSopenharmony_ci    if (!TsUtils.isClassValueType(this.tsTypeChecker.getTypeAtLocation(expr))) {
17383af6ab5fSopenharmony_ci      return false;
17393af6ab5fSopenharmony_ci    }
17403af6ab5fSopenharmony_ci    const symbol = this.trueSymbolAtLocation(expr);
17413af6ab5fSopenharmony_ci    return !symbol || (symbol.flags & ts.SymbolFlags.Class) === 0;
17423af6ab5fSopenharmony_ci  }
17433af6ab5fSopenharmony_ci
17443af6ab5fSopenharmony_ci  isClassTypeExpression(expr: ts.Expression): boolean {
17453af6ab5fSopenharmony_ci    const sym = this.trueSymbolAtLocation(expr);
17463af6ab5fSopenharmony_ci    return sym !== undefined && (sym.flags & ts.SymbolFlags.Class) !== 0;
17473af6ab5fSopenharmony_ci  }
17483af6ab5fSopenharmony_ci
17493af6ab5fSopenharmony_ci  isFunctionCalledRecursively(funcExpr: ts.FunctionExpression): boolean {
17503af6ab5fSopenharmony_ci    if (!funcExpr.name) {
17513af6ab5fSopenharmony_ci      return false;
17523af6ab5fSopenharmony_ci    }
17533af6ab5fSopenharmony_ci
17543af6ab5fSopenharmony_ci    const sym = this.tsTypeChecker.getSymbolAtLocation(funcExpr.name);
17553af6ab5fSopenharmony_ci    if (!sym) {
17563af6ab5fSopenharmony_ci      return false;
17573af6ab5fSopenharmony_ci    }
17583af6ab5fSopenharmony_ci
17593af6ab5fSopenharmony_ci    let found = false;
17603af6ab5fSopenharmony_ci    const callback = (node: ts.Node): void => {
17613af6ab5fSopenharmony_ci      if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
17623af6ab5fSopenharmony_ci        const callSym = this.tsTypeChecker.getSymbolAtLocation(node.expression);
17633af6ab5fSopenharmony_ci        if (callSym && callSym === sym) {
17643af6ab5fSopenharmony_ci          found = true;
17653af6ab5fSopenharmony_ci        }
17663af6ab5fSopenharmony_ci      }
17673af6ab5fSopenharmony_ci    };
17683af6ab5fSopenharmony_ci
17693af6ab5fSopenharmony_ci    const stopCondition = (node: ts.Node): boolean => {
17703af6ab5fSopenharmony_ci      void node;
17713af6ab5fSopenharmony_ci      return found;
17723af6ab5fSopenharmony_ci    };
17733af6ab5fSopenharmony_ci
17743af6ab5fSopenharmony_ci    forEachNodeInSubtree(funcExpr, callback, stopCondition);
17753af6ab5fSopenharmony_ci    return found;
17763af6ab5fSopenharmony_ci  }
17773af6ab5fSopenharmony_ci
17783af6ab5fSopenharmony_ci  getTypeOrTypeConstraintAtLocation(expr: ts.Expression): ts.Type {
17793af6ab5fSopenharmony_ci    const type = this.tsTypeChecker.getTypeAtLocation(expr);
17803af6ab5fSopenharmony_ci    if (type.isTypeParameter()) {
17813af6ab5fSopenharmony_ci      const constraint = type.getConstraint();
17823af6ab5fSopenharmony_ci      if (constraint) {
17833af6ab5fSopenharmony_ci        return constraint;
17843af6ab5fSopenharmony_ci      }
17853af6ab5fSopenharmony_ci    }
17863af6ab5fSopenharmony_ci    return type;
17873af6ab5fSopenharmony_ci  }
17883af6ab5fSopenharmony_ci
17893af6ab5fSopenharmony_ci  private areCompatibleFunctionals(lhsType: ts.Type, rhsType: ts.Type): boolean {
17903af6ab5fSopenharmony_ci    return (
17913af6ab5fSopenharmony_ci      (this.isStdFunctionType(lhsType) || TsUtils.isFunctionalType(lhsType)) &&
17923af6ab5fSopenharmony_ci      (this.isStdFunctionType(rhsType) || TsUtils.isFunctionalType(rhsType))
17933af6ab5fSopenharmony_ci    );
17943af6ab5fSopenharmony_ci  }
17953af6ab5fSopenharmony_ci
17963af6ab5fSopenharmony_ci  private static isFunctionalType(type: ts.Type): boolean {
17973af6ab5fSopenharmony_ci    const callSigns = type.getCallSignatures();
17983af6ab5fSopenharmony_ci    return callSigns && callSigns.length > 0;
17993af6ab5fSopenharmony_ci  }
18003af6ab5fSopenharmony_ci
18013af6ab5fSopenharmony_ci  private isStdFunctionType(type: ts.Type): boolean {
18023af6ab5fSopenharmony_ci    const sym = type.getSymbol();
18033af6ab5fSopenharmony_ci    return !!sym && sym.getName() === 'Function' && this.isGlobalSymbol(sym);
18043af6ab5fSopenharmony_ci  }
18053af6ab5fSopenharmony_ci
18063af6ab5fSopenharmony_ci  isStdBigIntType(type: ts.Type): boolean {
18073af6ab5fSopenharmony_ci    const sym = type.symbol;
18083af6ab5fSopenharmony_ci    return !!sym && sym.getName() === 'BigInt' && this.isGlobalSymbol(sym);
18093af6ab5fSopenharmony_ci  }
18103af6ab5fSopenharmony_ci
18113af6ab5fSopenharmony_ci  isStdNumberType(type: ts.Type): boolean {
18123af6ab5fSopenharmony_ci    const sym = type.symbol;
18133af6ab5fSopenharmony_ci    return !!sym && sym.getName() === 'Number' && this.isGlobalSymbol(sym);
18143af6ab5fSopenharmony_ci  }
18153af6ab5fSopenharmony_ci
18163af6ab5fSopenharmony_ci  isStdBooleanType(type: ts.Type): boolean {
18173af6ab5fSopenharmony_ci    const sym = type.symbol;
18183af6ab5fSopenharmony_ci    return !!sym && sym.getName() === 'Boolean' && this.isGlobalSymbol(sym);
18193af6ab5fSopenharmony_ci  }
18203af6ab5fSopenharmony_ci
18213af6ab5fSopenharmony_ci  isEnumStringLiteral(expr: ts.Expression): boolean {
18223af6ab5fSopenharmony_ci    const symbol = this.trueSymbolAtLocation(expr);
18233af6ab5fSopenharmony_ci    const isEnumMember = !!symbol && !!(symbol.flags & ts.SymbolFlags.EnumMember);
18243af6ab5fSopenharmony_ci    const type = this.tsTypeChecker.getTypeAtLocation(expr);
18253af6ab5fSopenharmony_ci    const isStringEnumLiteral = TsUtils.isEnumType(type) && !!(type.flags & ts.TypeFlags.StringLiteral);
18263af6ab5fSopenharmony_ci    return isEnumMember && isStringEnumLiteral;
18273af6ab5fSopenharmony_ci  }
18283af6ab5fSopenharmony_ci
18293af6ab5fSopenharmony_ci  isValidComputedPropertyName(computedProperty: ts.ComputedPropertyName, isRecordObjectInitializer = false): boolean {
18303af6ab5fSopenharmony_ci    const expr = computedProperty.expression;
18313af6ab5fSopenharmony_ci    if (!isRecordObjectInitializer) {
18323af6ab5fSopenharmony_ci      if (this.isSymbolIteratorExpression(expr)) {
18333af6ab5fSopenharmony_ci        return true;
18343af6ab5fSopenharmony_ci      }
18353af6ab5fSopenharmony_ci    }
18363af6ab5fSopenharmony_ci    // We allow computed property names if expression is string literal or string Enum member
18373af6ab5fSopenharmony_ci    return ts.isStringLiteralLike(expr) || this.isEnumStringLiteral(computedProperty.expression);
18383af6ab5fSopenharmony_ci  }
18393af6ab5fSopenharmony_ci
18403af6ab5fSopenharmony_ci  skipPropertyInferredTypeCheck(
18413af6ab5fSopenharmony_ci    decl: ts.PropertyDeclaration,
18423af6ab5fSopenharmony_ci    sourceFile: ts.SourceFile | undefined,
18433af6ab5fSopenharmony_ci    isEtsFileCb: IsEtsFileCallback | undefined
18443af6ab5fSopenharmony_ci  ): boolean {
18453af6ab5fSopenharmony_ci    if (!sourceFile) {
18463af6ab5fSopenharmony_ci      return false;
18473af6ab5fSopenharmony_ci    }
18483af6ab5fSopenharmony_ci
18493af6ab5fSopenharmony_ci    const isEts = this.useSdkLogic ?
18503af6ab5fSopenharmony_ci      getScriptKind(sourceFile) === ts.ScriptKind.ETS :
18513af6ab5fSopenharmony_ci      !!isEtsFileCb && isEtsFileCb(sourceFile);
18523af6ab5fSopenharmony_ci    return (
18533af6ab5fSopenharmony_ci      isEts &&
18543af6ab5fSopenharmony_ci      sourceFile.isDeclarationFile &&
18553af6ab5fSopenharmony_ci      !!decl.modifiers?.some((m) => {
18563af6ab5fSopenharmony_ci        return m.kind === ts.SyntaxKind.PrivateKeyword;
18573af6ab5fSopenharmony_ci      })
18583af6ab5fSopenharmony_ci    );
18593af6ab5fSopenharmony_ci  }
18603af6ab5fSopenharmony_ci
18613af6ab5fSopenharmony_ci  hasAccessModifier(decl: ts.HasModifiers): boolean {
18623af6ab5fSopenharmony_ci    const modifiers = ts.getModifiers(decl);
18633af6ab5fSopenharmony_ci    return (
18643af6ab5fSopenharmony_ci      !!modifiers &&
18653af6ab5fSopenharmony_ci      (this.useSdkLogic && TsUtils.hasModifier(modifiers, ts.SyntaxKind.ReadonlyKeyword) ||
18663af6ab5fSopenharmony_ci        TsUtils.hasModifier(modifiers, ts.SyntaxKind.PublicKeyword) ||
18673af6ab5fSopenharmony_ci        TsUtils.hasModifier(modifiers, ts.SyntaxKind.ProtectedKeyword) ||
18683af6ab5fSopenharmony_ci        TsUtils.hasModifier(modifiers, ts.SyntaxKind.PrivateKeyword))
18693af6ab5fSopenharmony_ci    );
18703af6ab5fSopenharmony_ci  }
18713af6ab5fSopenharmony_ci
18723af6ab5fSopenharmony_ci  static getModifier(
18733af6ab5fSopenharmony_ci    modifiers: readonly ts.Modifier[] | undefined,
18743af6ab5fSopenharmony_ci    modifierKind: ts.SyntaxKind
18753af6ab5fSopenharmony_ci  ): ts.Modifier | undefined {
18763af6ab5fSopenharmony_ci    if (!modifiers) {
18773af6ab5fSopenharmony_ci      return undefined;
18783af6ab5fSopenharmony_ci    }
18793af6ab5fSopenharmony_ci    return modifiers.find((x) => {
18803af6ab5fSopenharmony_ci      return x.kind === modifierKind;
18813af6ab5fSopenharmony_ci    });
18823af6ab5fSopenharmony_ci  }
18833af6ab5fSopenharmony_ci
18843af6ab5fSopenharmony_ci  static getAccessModifier(modifiers: readonly ts.Modifier[] | undefined): ts.Modifier | undefined {
18853af6ab5fSopenharmony_ci    return (
18863af6ab5fSopenharmony_ci      TsUtils.getModifier(modifiers, ts.SyntaxKind.PublicKeyword) ??
18873af6ab5fSopenharmony_ci      TsUtils.getModifier(modifiers, ts.SyntaxKind.ProtectedKeyword) ??
18883af6ab5fSopenharmony_ci      TsUtils.getModifier(modifiers, ts.SyntaxKind.PrivateKeyword)
18893af6ab5fSopenharmony_ci    );
18903af6ab5fSopenharmony_ci  }
18913af6ab5fSopenharmony_ci
18923af6ab5fSopenharmony_ci  static getBaseClassType(type: ts.Type): ts.InterfaceType | undefined {
18933af6ab5fSopenharmony_ci    const baseTypes = type.getBaseTypes();
18943af6ab5fSopenharmony_ci    if (baseTypes) {
18953af6ab5fSopenharmony_ci      for (const baseType of baseTypes) {
18963af6ab5fSopenharmony_ci        if (baseType.isClass()) {
18973af6ab5fSopenharmony_ci          return baseType;
18983af6ab5fSopenharmony_ci        }
18993af6ab5fSopenharmony_ci      }
19003af6ab5fSopenharmony_ci    }
19013af6ab5fSopenharmony_ci
19023af6ab5fSopenharmony_ci    return undefined;
19033af6ab5fSopenharmony_ci  }
19043af6ab5fSopenharmony_ci
19053af6ab5fSopenharmony_ci  static destructuringAssignmentHasSpreadOperator(node: ts.AssignmentPattern): boolean {
19063af6ab5fSopenharmony_ci    if (ts.isArrayLiteralExpression(node)) {
19073af6ab5fSopenharmony_ci      return node.elements.some((x) => {
19083af6ab5fSopenharmony_ci        if (ts.isSpreadElement(x)) {
19093af6ab5fSopenharmony_ci          return true;
19103af6ab5fSopenharmony_ci        }
19113af6ab5fSopenharmony_ci        if (ts.isObjectLiteralExpression(x) || ts.isArrayLiteralExpression(x)) {
19123af6ab5fSopenharmony_ci          return TsUtils.destructuringAssignmentHasSpreadOperator(x);
19133af6ab5fSopenharmony_ci        }
19143af6ab5fSopenharmony_ci        return false;
19153af6ab5fSopenharmony_ci      });
19163af6ab5fSopenharmony_ci    }
19173af6ab5fSopenharmony_ci
19183af6ab5fSopenharmony_ci    return node.properties.some((x) => {
19193af6ab5fSopenharmony_ci      if (ts.isSpreadAssignment(x)) {
19203af6ab5fSopenharmony_ci        return true;
19213af6ab5fSopenharmony_ci      }
19223af6ab5fSopenharmony_ci      if (
19233af6ab5fSopenharmony_ci        ts.isPropertyAssignment(x) &&
19243af6ab5fSopenharmony_ci        (ts.isObjectLiteralExpression(x.initializer) || ts.isArrayLiteralExpression(x.initializer))
19253af6ab5fSopenharmony_ci      ) {
19263af6ab5fSopenharmony_ci        return TsUtils.destructuringAssignmentHasSpreadOperator(x.initializer);
19273af6ab5fSopenharmony_ci      }
19283af6ab5fSopenharmony_ci      return false;
19293af6ab5fSopenharmony_ci    });
19303af6ab5fSopenharmony_ci  }
19313af6ab5fSopenharmony_ci
19323af6ab5fSopenharmony_ci  static destructuringDeclarationHasSpreadOperator(node: ts.BindingPattern): boolean {
19333af6ab5fSopenharmony_ci    return node.elements.some((x) => {
19343af6ab5fSopenharmony_ci      if (ts.isBindingElement(x)) {
19353af6ab5fSopenharmony_ci        if (x.dotDotDotToken) {
19363af6ab5fSopenharmony_ci          return true;
19373af6ab5fSopenharmony_ci        }
19383af6ab5fSopenharmony_ci        if (ts.isArrayBindingPattern(x.name) || ts.isObjectBindingPattern(x.name)) {
19393af6ab5fSopenharmony_ci          return TsUtils.destructuringDeclarationHasSpreadOperator(x.name);
19403af6ab5fSopenharmony_ci        }
19413af6ab5fSopenharmony_ci      }
19423af6ab5fSopenharmony_ci      return false;
19433af6ab5fSopenharmony_ci    });
19443af6ab5fSopenharmony_ci  }
19453af6ab5fSopenharmony_ci
19463af6ab5fSopenharmony_ci  static hasNestedObjectDestructuring(node: ts.ArrayBindingOrAssignmentPattern): boolean {
19473af6ab5fSopenharmony_ci    if (ts.isArrayLiteralExpression(node)) {
19483af6ab5fSopenharmony_ci      return node.elements.some((x) => {
19493af6ab5fSopenharmony_ci        const elem = ts.isSpreadElement(x) ? x.expression : x;
19503af6ab5fSopenharmony_ci        if (ts.isArrayLiteralExpression(elem)) {
19513af6ab5fSopenharmony_ci          return TsUtils.hasNestedObjectDestructuring(elem);
19523af6ab5fSopenharmony_ci        }
19533af6ab5fSopenharmony_ci        return ts.isObjectLiteralExpression(elem);
19543af6ab5fSopenharmony_ci      });
19553af6ab5fSopenharmony_ci    }
19563af6ab5fSopenharmony_ci
19573af6ab5fSopenharmony_ci    return node.elements.some((x) => {
19583af6ab5fSopenharmony_ci      if (ts.isBindingElement(x)) {
19593af6ab5fSopenharmony_ci        if (ts.isArrayBindingPattern(x.name)) {
19603af6ab5fSopenharmony_ci          return TsUtils.hasNestedObjectDestructuring(x.name);
19613af6ab5fSopenharmony_ci        }
19623af6ab5fSopenharmony_ci        return ts.isObjectBindingPattern(x.name);
19633af6ab5fSopenharmony_ci      }
19643af6ab5fSopenharmony_ci      return false;
19653af6ab5fSopenharmony_ci    });
19663af6ab5fSopenharmony_ci  }
19673af6ab5fSopenharmony_ci
19683af6ab5fSopenharmony_ci  static getDecoratorName(decorator: ts.Decorator): string {
19693af6ab5fSopenharmony_ci    let decoratorName = '';
19703af6ab5fSopenharmony_ci    if (ts.isIdentifier(decorator.expression)) {
19713af6ab5fSopenharmony_ci      decoratorName = decorator.expression.text;
19723af6ab5fSopenharmony_ci    } else if (ts.isCallExpression(decorator.expression) && ts.isIdentifier(decorator.expression.expression)) {
19733af6ab5fSopenharmony_ci      decoratorName = decorator.expression.expression.text;
19743af6ab5fSopenharmony_ci    }
19753af6ab5fSopenharmony_ci    return decoratorName;
19763af6ab5fSopenharmony_ci  }
19773af6ab5fSopenharmony_ci
19783af6ab5fSopenharmony_ci  static unwrapParenthesizedTypeNode(typeNode: ts.TypeNode): ts.TypeNode {
19793af6ab5fSopenharmony_ci    let unwrappedTypeNode = typeNode;
19803af6ab5fSopenharmony_ci    while (ts.isParenthesizedTypeNode(unwrappedTypeNode)) {
19813af6ab5fSopenharmony_ci      unwrappedTypeNode = unwrappedTypeNode.type;
19823af6ab5fSopenharmony_ci    }
19833af6ab5fSopenharmony_ci
19843af6ab5fSopenharmony_ci    return unwrappedTypeNode;
19853af6ab5fSopenharmony_ci  }
19863af6ab5fSopenharmony_ci
19873af6ab5fSopenharmony_ci  isSendableTypeNode(typeNode: ts.TypeNode, isShared: boolean = false): boolean {
19883af6ab5fSopenharmony_ci
19893af6ab5fSopenharmony_ci    /*
19903af6ab5fSopenharmony_ci     * In order to correctly identify the usage of the enum member or
19913af6ab5fSopenharmony_ci     * const enum in type annotation, we need to handle union type and
19923af6ab5fSopenharmony_ci     * type alias cases by processing the type node and checking the
19933af6ab5fSopenharmony_ci     * symbol in case of type reference node.
19943af6ab5fSopenharmony_ci     */
19953af6ab5fSopenharmony_ci
19963af6ab5fSopenharmony_ci    // eslint-disable-next-line no-param-reassign
19973af6ab5fSopenharmony_ci    typeNode = TsUtils.unwrapParenthesizedTypeNode(typeNode);
19983af6ab5fSopenharmony_ci
19993af6ab5fSopenharmony_ci    // Only a sendable union type is supported
20003af6ab5fSopenharmony_ci    if (ts.isUnionTypeNode(typeNode)) {
20013af6ab5fSopenharmony_ci      return typeNode.types.every((elemType) => {
20023af6ab5fSopenharmony_ci        return this.isSendableTypeNode(elemType, isShared);
20033af6ab5fSopenharmony_ci      });
20043af6ab5fSopenharmony_ci    }
20053af6ab5fSopenharmony_ci
20063af6ab5fSopenharmony_ci    const sym = ts.isTypeReferenceNode(typeNode) ? this.trueSymbolAtLocation(typeNode.typeName) : undefined;
20073af6ab5fSopenharmony_ci
20083af6ab5fSopenharmony_ci    if (sym && sym.getFlags() & ts.SymbolFlags.TypeAlias) {
20093af6ab5fSopenharmony_ci      const typeDecl = TsUtils.getDeclaration(sym);
20103af6ab5fSopenharmony_ci      if (typeDecl && ts.isTypeAliasDeclaration(typeDecl)) {
20113af6ab5fSopenharmony_ci        const typeArgs = (typeNode as ts.TypeReferenceNode).typeArguments;
20123af6ab5fSopenharmony_ci        if (
20133af6ab5fSopenharmony_ci          typeArgs &&
20143af6ab5fSopenharmony_ci          !typeArgs.every((typeArg) => {
20153af6ab5fSopenharmony_ci            return this.isSendableTypeNode(typeArg);
20163af6ab5fSopenharmony_ci          })
20173af6ab5fSopenharmony_ci        ) {
20183af6ab5fSopenharmony_ci          return false;
20193af6ab5fSopenharmony_ci        }
20203af6ab5fSopenharmony_ci        return this.isSendableTypeNode(typeDecl.type, isShared);
20213af6ab5fSopenharmony_ci      }
20223af6ab5fSopenharmony_ci    }
20233af6ab5fSopenharmony_ci
20243af6ab5fSopenharmony_ci    // Const enum type is supported
20253af6ab5fSopenharmony_ci    if (TsUtils.isConstEnum(sym)) {
20263af6ab5fSopenharmony_ci      return true;
20273af6ab5fSopenharmony_ci    }
20283af6ab5fSopenharmony_ci    const type: ts.Type = this.tsTypeChecker.getTypeFromTypeNode(typeNode);
20293af6ab5fSopenharmony_ci
20303af6ab5fSopenharmony_ci    // In shared module, literal forms of primitive data types can be exported
20313af6ab5fSopenharmony_ci    if (isShared && TsUtils.isPurePrimitiveLiteralType(type)) {
20323af6ab5fSopenharmony_ci      return true;
20333af6ab5fSopenharmony_ci    }
20343af6ab5fSopenharmony_ci
20353af6ab5fSopenharmony_ci    return this.isSendableType(type);
20363af6ab5fSopenharmony_ci  }
20373af6ab5fSopenharmony_ci
20383af6ab5fSopenharmony_ci  isSendableType(type: ts.Type): boolean {
20393af6ab5fSopenharmony_ci    if (
20403af6ab5fSopenharmony_ci      (type.flags &
20413af6ab5fSopenharmony_ci        (ts.TypeFlags.Boolean |
20423af6ab5fSopenharmony_ci          ts.TypeFlags.Number |
20433af6ab5fSopenharmony_ci          ts.TypeFlags.String |
20443af6ab5fSopenharmony_ci          ts.TypeFlags.BigInt |
20453af6ab5fSopenharmony_ci          ts.TypeFlags.Null |
20463af6ab5fSopenharmony_ci          ts.TypeFlags.Undefined |
20473af6ab5fSopenharmony_ci          ts.TypeFlags.TypeParameter)) !==
20483af6ab5fSopenharmony_ci      0
20493af6ab5fSopenharmony_ci    ) {
20503af6ab5fSopenharmony_ci      return true;
20513af6ab5fSopenharmony_ci    }
20523af6ab5fSopenharmony_ci    if (this.isSendableTypeAlias(type)) {
20533af6ab5fSopenharmony_ci      return true;
20543af6ab5fSopenharmony_ci    }
20553af6ab5fSopenharmony_ci    if (TsUtils.isSendableFunction(type)) {
20563af6ab5fSopenharmony_ci      return true;
20573af6ab5fSopenharmony_ci    }
20583af6ab5fSopenharmony_ci
20593af6ab5fSopenharmony_ci    return this.isSendableClassOrInterface(type);
20603af6ab5fSopenharmony_ci  }
20613af6ab5fSopenharmony_ci
20623af6ab5fSopenharmony_ci  isShareableType(tsType: ts.Type): boolean {
20633af6ab5fSopenharmony_ci    const sym = tsType.getSymbol();
20643af6ab5fSopenharmony_ci    if (TsUtils.isConstEnum(sym)) {
20653af6ab5fSopenharmony_ci      return true;
20663af6ab5fSopenharmony_ci    }
20673af6ab5fSopenharmony_ci
20683af6ab5fSopenharmony_ci    if (tsType.isUnion()) {
20693af6ab5fSopenharmony_ci      return tsType.types.every((elemType) => {
20703af6ab5fSopenharmony_ci        return this.isShareableType(elemType);
20713af6ab5fSopenharmony_ci      });
20723af6ab5fSopenharmony_ci    }
20733af6ab5fSopenharmony_ci
20743af6ab5fSopenharmony_ci    if (TsUtils.isPurePrimitiveLiteralType(tsType)) {
20753af6ab5fSopenharmony_ci      return true;
20763af6ab5fSopenharmony_ci    }
20773af6ab5fSopenharmony_ci
20783af6ab5fSopenharmony_ci    return this.isSendableType(tsType);
20793af6ab5fSopenharmony_ci  }
20803af6ab5fSopenharmony_ci
20813af6ab5fSopenharmony_ci  isSendableClassOrInterface(type: ts.Type): boolean {
20823af6ab5fSopenharmony_ci    const sym = type.getSymbol();
20833af6ab5fSopenharmony_ci    if (!sym) {
20843af6ab5fSopenharmony_ci      return false;
20853af6ab5fSopenharmony_ci    }
20863af6ab5fSopenharmony_ci
20873af6ab5fSopenharmony_ci    const targetType = TsUtils.reduceReference(type);
20883af6ab5fSopenharmony_ci
20893af6ab5fSopenharmony_ci    // class with @Sendable decorator
20903af6ab5fSopenharmony_ci    if (targetType.isClass()) {
20913af6ab5fSopenharmony_ci      if (sym.declarations?.length) {
20923af6ab5fSopenharmony_ci        const decl = sym.declarations[0];
20933af6ab5fSopenharmony_ci        if (ts.isClassDeclaration(decl)) {
20943af6ab5fSopenharmony_ci          return TsUtils.hasSendableDecorator(decl);
20953af6ab5fSopenharmony_ci        }
20963af6ab5fSopenharmony_ci      }
20973af6ab5fSopenharmony_ci    }
20983af6ab5fSopenharmony_ci    // ISendable interface, or a class/interface that implements/extends ISendable interface
20993af6ab5fSopenharmony_ci    return this.isOrDerivedFrom(type, TsUtils.isISendableInterface);
21003af6ab5fSopenharmony_ci  }
21013af6ab5fSopenharmony_ci
21023af6ab5fSopenharmony_ci  typeContainsSendableClassOrInterface(type: ts.Type): boolean {
21033af6ab5fSopenharmony_ci    // Only check type contains sendable class / interface
21043af6ab5fSopenharmony_ci    if ((type.flags & ts.TypeFlags.Union) !== 0) {
21053af6ab5fSopenharmony_ci      return !!(type as ts.UnionType)?.types?.some((type) => {
21063af6ab5fSopenharmony_ci        return this.typeContainsSendableClassOrInterface(type);
21073af6ab5fSopenharmony_ci      });
21083af6ab5fSopenharmony_ci    }
21093af6ab5fSopenharmony_ci
21103af6ab5fSopenharmony_ci    return this.isSendableClassOrInterface(type);
21113af6ab5fSopenharmony_ci  }
21123af6ab5fSopenharmony_ci
21133af6ab5fSopenharmony_ci  typeContainsNonSendableClassOrInterface(type: ts.Type): boolean {
21143af6ab5fSopenharmony_ci    if (type.isUnion()) {
21153af6ab5fSopenharmony_ci      return type.types.some((compType) => {
21163af6ab5fSopenharmony_ci        return this.typeContainsNonSendableClassOrInterface(compType);
21173af6ab5fSopenharmony_ci      });
21183af6ab5fSopenharmony_ci    }
21193af6ab5fSopenharmony_ci    // eslint-disable-next-line no-param-reassign
21203af6ab5fSopenharmony_ci    type = TsUtils.reduceReference(type);
21213af6ab5fSopenharmony_ci    return type.isClassOrInterface() && !this.isSendableClassOrInterface(type);
21223af6ab5fSopenharmony_ci  }
21233af6ab5fSopenharmony_ci
21243af6ab5fSopenharmony_ci  static isConstEnum(sym: ts.Symbol | undefined): boolean {
21253af6ab5fSopenharmony_ci    return !!sym && sym.flags === ts.SymbolFlags.ConstEnum;
21263af6ab5fSopenharmony_ci  }
21273af6ab5fSopenharmony_ci
21283af6ab5fSopenharmony_ci  isSendableUnionType(type: ts.UnionType): boolean {
21293af6ab5fSopenharmony_ci    const types = type?.types;
21303af6ab5fSopenharmony_ci    if (!types) {
21313af6ab5fSopenharmony_ci      return false;
21323af6ab5fSopenharmony_ci    }
21333af6ab5fSopenharmony_ci
21343af6ab5fSopenharmony_ci    return types.every((type) => {
21353af6ab5fSopenharmony_ci      return this.isSendableType(type);
21363af6ab5fSopenharmony_ci    });
21373af6ab5fSopenharmony_ci  }
21383af6ab5fSopenharmony_ci
21393af6ab5fSopenharmony_ci  static hasSendableDecorator(decl: ts.ClassDeclaration | ts.FunctionDeclaration | ts.TypeAliasDeclaration): boolean {
21403af6ab5fSopenharmony_ci    return !!TsUtils.getSendableDecorator(decl);
21413af6ab5fSopenharmony_ci  }
21423af6ab5fSopenharmony_ci
21433af6ab5fSopenharmony_ci  static getNonSendableDecorators(
21443af6ab5fSopenharmony_ci    decl: ts.ClassDeclaration | ts.FunctionDeclaration | ts.TypeAliasDeclaration
21453af6ab5fSopenharmony_ci  ): ts.Decorator[] | undefined {
21463af6ab5fSopenharmony_ci    const decorators = ts.getAllDecorators(decl);
21473af6ab5fSopenharmony_ci    return decorators?.filter((x) => {
21483af6ab5fSopenharmony_ci      return TsUtils.getDecoratorName(x) !== SENDABLE_DECORATOR;
21493af6ab5fSopenharmony_ci    });
21503af6ab5fSopenharmony_ci  }
21513af6ab5fSopenharmony_ci
21523af6ab5fSopenharmony_ci  static getSendableDecorator(
21533af6ab5fSopenharmony_ci    decl: ts.ClassDeclaration | ts.FunctionDeclaration | ts.TypeAliasDeclaration
21543af6ab5fSopenharmony_ci  ): ts.Decorator | undefined {
21553af6ab5fSopenharmony_ci    const decorators = ts.getAllDecorators(decl);
21563af6ab5fSopenharmony_ci    return decorators?.find((x) => {
21573af6ab5fSopenharmony_ci      return TsUtils.getDecoratorName(x) === SENDABLE_DECORATOR;
21583af6ab5fSopenharmony_ci    });
21593af6ab5fSopenharmony_ci  }
21603af6ab5fSopenharmony_ci
21613af6ab5fSopenharmony_ci  static getDecoratorsIfInSendableClass(declaration: ts.HasDecorators): readonly ts.Decorator[] | undefined {
21623af6ab5fSopenharmony_ci    const classNode = TsUtils.getClassNodeFromDeclaration(declaration);
21633af6ab5fSopenharmony_ci    if (classNode === undefined || !TsUtils.hasSendableDecorator(classNode)) {
21643af6ab5fSopenharmony_ci      return undefined;
21653af6ab5fSopenharmony_ci    }
21663af6ab5fSopenharmony_ci    return ts.getDecorators(declaration);
21673af6ab5fSopenharmony_ci  }
21683af6ab5fSopenharmony_ci
21693af6ab5fSopenharmony_ci  private static getClassNodeFromDeclaration(declaration: ts.HasDecorators): ts.ClassDeclaration | undefined {
21703af6ab5fSopenharmony_ci    if (declaration.kind === ts.SyntaxKind.Parameter) {
21713af6ab5fSopenharmony_ci      return ts.isClassDeclaration(declaration.parent.parent) ? declaration.parent.parent : undefined;
21723af6ab5fSopenharmony_ci    }
21733af6ab5fSopenharmony_ci    return ts.isClassDeclaration(declaration.parent) ? declaration.parent : undefined;
21743af6ab5fSopenharmony_ci  }
21753af6ab5fSopenharmony_ci
21763af6ab5fSopenharmony_ci  static isISendableInterface(type: ts.Type): boolean {
21773af6ab5fSopenharmony_ci    const symbol = type.aliasSymbol ?? type.getSymbol();
21783af6ab5fSopenharmony_ci    if (symbol?.declarations === undefined || symbol.declarations.length < 1) {
21793af6ab5fSopenharmony_ci      return false;
21803af6ab5fSopenharmony_ci    }
21813af6ab5fSopenharmony_ci
21823af6ab5fSopenharmony_ci    return TsUtils.isArkTSISendableDeclaration(symbol.declarations[0]);
21833af6ab5fSopenharmony_ci  }
21843af6ab5fSopenharmony_ci
21853af6ab5fSopenharmony_ci  private static isArkTSISendableDeclaration(decl: ts.Declaration): boolean {
21863af6ab5fSopenharmony_ci    if (!ts.isInterfaceDeclaration(decl) || !decl.name || decl.name.text !== ISENDABLE_TYPE) {
21873af6ab5fSopenharmony_ci      return false;
21883af6ab5fSopenharmony_ci    }
21893af6ab5fSopenharmony_ci
21903af6ab5fSopenharmony_ci    if (!ts.isModuleBlock(decl.parent) || decl.parent.parent.name.text !== LANG_NAMESPACE) {
21913af6ab5fSopenharmony_ci      return false;
21923af6ab5fSopenharmony_ci    }
21933af6ab5fSopenharmony_ci
21943af6ab5fSopenharmony_ci    if (path.basename(decl.getSourceFile().fileName).toLowerCase() !== ARKTS_LANG_D_ETS) {
21953af6ab5fSopenharmony_ci      return false;
21963af6ab5fSopenharmony_ci    }
21973af6ab5fSopenharmony_ci
21983af6ab5fSopenharmony_ci    return true;
21993af6ab5fSopenharmony_ci  }
22003af6ab5fSopenharmony_ci
22013af6ab5fSopenharmony_ci  isAllowedIndexSignature(node: ts.IndexSignatureDeclaration): boolean {
22023af6ab5fSopenharmony_ci
22033af6ab5fSopenharmony_ci    /*
22043af6ab5fSopenharmony_ci     * For now, relax index signature only for specific array-like types
22053af6ab5fSopenharmony_ci     * with the following signature: 'collections.Array<T>.[_: number]: T'.
22063af6ab5fSopenharmony_ci     */
22073af6ab5fSopenharmony_ci
22083af6ab5fSopenharmony_ci    if (node.parameters.length !== 1) {
22093af6ab5fSopenharmony_ci      return false;
22103af6ab5fSopenharmony_ci    }
22113af6ab5fSopenharmony_ci
22123af6ab5fSopenharmony_ci    const paramType = this.tsTypeChecker.getTypeAtLocation(node.parameters[0]);
22133af6ab5fSopenharmony_ci    if ((paramType.flags & ts.TypeFlags.Number) === 0) {
22143af6ab5fSopenharmony_ci      return false;
22153af6ab5fSopenharmony_ci    }
22163af6ab5fSopenharmony_ci
22173af6ab5fSopenharmony_ci    return this.isArkTSCollectionsArrayLikeDeclaration(node.parent);
22183af6ab5fSopenharmony_ci  }
22193af6ab5fSopenharmony_ci
22203af6ab5fSopenharmony_ci  isArkTSCollectionsArrayLikeType(type: ts.Type): boolean {
22213af6ab5fSopenharmony_ci    const symbol = type.aliasSymbol ?? type.getSymbol();
22223af6ab5fSopenharmony_ci    if (symbol?.declarations === undefined || symbol.declarations.length < 1) {
22233af6ab5fSopenharmony_ci      return false;
22243af6ab5fSopenharmony_ci    }
22253af6ab5fSopenharmony_ci
22263af6ab5fSopenharmony_ci    return this.isArkTSCollectionsArrayLikeDeclaration(symbol.declarations[0]);
22273af6ab5fSopenharmony_ci  }
22283af6ab5fSopenharmony_ci
22293af6ab5fSopenharmony_ci  private isArkTSCollectionsArrayLikeDeclaration(decl: ts.Declaration): boolean {
22303af6ab5fSopenharmony_ci    if (!TsUtils.isArkTSCollectionsClassOrInterfaceDeclaration(decl)) {
22313af6ab5fSopenharmony_ci      return false;
22323af6ab5fSopenharmony_ci    }
22333af6ab5fSopenharmony_ci    if (!this.tsTypeChecker.getTypeAtLocation(decl).getNumberIndexType()) {
22343af6ab5fSopenharmony_ci      return false;
22353af6ab5fSopenharmony_ci    }
22363af6ab5fSopenharmony_ci    return true;
22373af6ab5fSopenharmony_ci  }
22383af6ab5fSopenharmony_ci
22393af6ab5fSopenharmony_ci  static isArkTSCollectionsClassOrInterfaceDeclaration(decl: ts.Node): boolean {
22403af6ab5fSopenharmony_ci    if (!ts.isClassDeclaration(decl) && !ts.isInterfaceDeclaration(decl) || !decl.name) {
22413af6ab5fSopenharmony_ci      return false;
22423af6ab5fSopenharmony_ci    }
22433af6ab5fSopenharmony_ci    if (!ts.isModuleBlock(decl.parent) || decl.parent.parent.name.text !== COLLECTIONS_NAMESPACE) {
22443af6ab5fSopenharmony_ci      return false;
22453af6ab5fSopenharmony_ci    }
22463af6ab5fSopenharmony_ci    if (path.basename(decl.getSourceFile().fileName).toLowerCase() !== ARKTS_COLLECTIONS_D_ETS) {
22473af6ab5fSopenharmony_ci      return false;
22483af6ab5fSopenharmony_ci    }
22493af6ab5fSopenharmony_ci    return true;
22503af6ab5fSopenharmony_ci  }
22513af6ab5fSopenharmony_ci
22523af6ab5fSopenharmony_ci  private proceedConstructorDeclaration(
22533af6ab5fSopenharmony_ci    isFromPrivateIdentifierOrSdk: boolean,
22543af6ab5fSopenharmony_ci    targetMember: ts.ClassElement,
22553af6ab5fSopenharmony_ci    classMember: ts.ClassElement,
22563af6ab5fSopenharmony_ci    isFromPrivateIdentifier: boolean
22573af6ab5fSopenharmony_ci  ): boolean | undefined {
22583af6ab5fSopenharmony_ci    if (
22593af6ab5fSopenharmony_ci      isFromPrivateIdentifierOrSdk &&
22603af6ab5fSopenharmony_ci      ts.isConstructorDeclaration(classMember) &&
22613af6ab5fSopenharmony_ci      classMember.parameters.some((x) => {
22623af6ab5fSopenharmony_ci        return (
22633af6ab5fSopenharmony_ci          ts.isIdentifier(x.name) &&
22643af6ab5fSopenharmony_ci          this.hasAccessModifier(x) &&
22653af6ab5fSopenharmony_ci          this.isPrivateIdentifierDuplicateOfIdentifier(
22663af6ab5fSopenharmony_ci            targetMember.name as ts.Identifier,
22673af6ab5fSopenharmony_ci            x.name,
22683af6ab5fSopenharmony_ci            isFromPrivateIdentifier
22693af6ab5fSopenharmony_ci          )
22703af6ab5fSopenharmony_ci        );
22713af6ab5fSopenharmony_ci      })
22723af6ab5fSopenharmony_ci    ) {
22733af6ab5fSopenharmony_ci      return true;
22743af6ab5fSopenharmony_ci    }
22753af6ab5fSopenharmony_ci    return undefined;
22763af6ab5fSopenharmony_ci  }
22773af6ab5fSopenharmony_ci
22783af6ab5fSopenharmony_ci  private proceedClassType(
22793af6ab5fSopenharmony_ci    targetMember: ts.ClassElement,
22803af6ab5fSopenharmony_ci    classType: ts.Type,
22813af6ab5fSopenharmony_ci    isFromPrivateIdentifier: boolean
22823af6ab5fSopenharmony_ci  ): boolean | undefined {
22833af6ab5fSopenharmony_ci    if (classType) {
22843af6ab5fSopenharmony_ci      const baseType = TsUtils.getBaseClassType(classType);
22853af6ab5fSopenharmony_ci      if (baseType) {
22863af6ab5fSopenharmony_ci        const baseDecl = baseType.getSymbol()?.valueDeclaration as ts.ClassLikeDeclaration;
22873af6ab5fSopenharmony_ci        if (baseDecl) {
22883af6ab5fSopenharmony_ci          return this.classMemberHasDuplicateName(targetMember, baseDecl, isFromPrivateIdentifier);
22893af6ab5fSopenharmony_ci        }
22903af6ab5fSopenharmony_ci      }
22913af6ab5fSopenharmony_ci    }
22923af6ab5fSopenharmony_ci    return undefined;
22933af6ab5fSopenharmony_ci  }
22943af6ab5fSopenharmony_ci
22953af6ab5fSopenharmony_ci  classMemberHasDuplicateName(
22963af6ab5fSopenharmony_ci    targetMember: ts.ClassElement,
22973af6ab5fSopenharmony_ci    tsClassLikeDecl: ts.ClassLikeDeclaration,
22983af6ab5fSopenharmony_ci    isFromPrivateIdentifier: boolean,
22993af6ab5fSopenharmony_ci    classType?: ts.Type
23003af6ab5fSopenharmony_ci  ): boolean {
23013af6ab5fSopenharmony_ci
23023af6ab5fSopenharmony_ci    /*
23033af6ab5fSopenharmony_ci     * If two class members have the same name where one is a private identifer,
23043af6ab5fSopenharmony_ci     * then such members are considered to have duplicate names.
23053af6ab5fSopenharmony_ci     */
23063af6ab5fSopenharmony_ci    if (!TsUtils.isIdentifierOrPrivateIdentifier(targetMember.name)) {
23073af6ab5fSopenharmony_ci      return false;
23083af6ab5fSopenharmony_ci    }
23093af6ab5fSopenharmony_ci
23103af6ab5fSopenharmony_ci    const isFromPrivateIdentifierOrSdk = this.isFromPrivateIdentifierOrSdk(isFromPrivateIdentifier);
23113af6ab5fSopenharmony_ci    for (const classMember of tsClassLikeDecl.members) {
23123af6ab5fSopenharmony_ci      if (targetMember === classMember) {
23133af6ab5fSopenharmony_ci        continue;
23143af6ab5fSopenharmony_ci      }
23153af6ab5fSopenharmony_ci
23163af6ab5fSopenharmony_ci      // Check constructor parameter properties.
23173af6ab5fSopenharmony_ci      const constructorDeclarationProceedResult = this.proceedConstructorDeclaration(
23183af6ab5fSopenharmony_ci        isFromPrivateIdentifierOrSdk,
23193af6ab5fSopenharmony_ci        targetMember,
23203af6ab5fSopenharmony_ci        classMember,
23213af6ab5fSopenharmony_ci        isFromPrivateIdentifier
23223af6ab5fSopenharmony_ci      );
23233af6ab5fSopenharmony_ci      if (constructorDeclarationProceedResult) {
23243af6ab5fSopenharmony_ci        return constructorDeclarationProceedResult;
23253af6ab5fSopenharmony_ci      }
23263af6ab5fSopenharmony_ci      if (!TsUtils.isIdentifierOrPrivateIdentifier(classMember.name)) {
23273af6ab5fSopenharmony_ci        continue;
23283af6ab5fSopenharmony_ci      }
23293af6ab5fSopenharmony_ci      if (this.isPrivateIdentifierDuplicateOfIdentifier(targetMember.name, classMember.name, isFromPrivateIdentifier)) {
23303af6ab5fSopenharmony_ci        return true;
23313af6ab5fSopenharmony_ci      }
23323af6ab5fSopenharmony_ci    }
23333af6ab5fSopenharmony_ci
23343af6ab5fSopenharmony_ci    if (isFromPrivateIdentifierOrSdk) {
23353af6ab5fSopenharmony_ci      // eslint-disable-next-line no-param-reassign
23363af6ab5fSopenharmony_ci      classType ??= this.tsTypeChecker.getTypeAtLocation(tsClassLikeDecl);
23373af6ab5fSopenharmony_ci      const proceedClassTypeResult = this.proceedClassType(targetMember, classType, isFromPrivateIdentifier);
23383af6ab5fSopenharmony_ci      if (proceedClassTypeResult) {
23393af6ab5fSopenharmony_ci        return proceedClassTypeResult;
23403af6ab5fSopenharmony_ci      }
23413af6ab5fSopenharmony_ci    }
23423af6ab5fSopenharmony_ci
23433af6ab5fSopenharmony_ci    return false;
23443af6ab5fSopenharmony_ci  }
23453af6ab5fSopenharmony_ci
23463af6ab5fSopenharmony_ci  private isFromPrivateIdentifierOrSdk(isFromPrivateIdentifier: boolean): boolean {
23473af6ab5fSopenharmony_ci    return !this.useSdkLogic || isFromPrivateIdentifier;
23483af6ab5fSopenharmony_ci  }
23493af6ab5fSopenharmony_ci
23503af6ab5fSopenharmony_ci  private static isIdentifierOrPrivateIdentifier(node?: ts.PropertyName): node is ts.Identifier | ts.PrivateIdentifier {
23513af6ab5fSopenharmony_ci    if (!node) {
23523af6ab5fSopenharmony_ci      return false;
23533af6ab5fSopenharmony_ci    }
23543af6ab5fSopenharmony_ci    return ts.isIdentifier(node) || ts.isPrivateIdentifier(node);
23553af6ab5fSopenharmony_ci  }
23563af6ab5fSopenharmony_ci
23573af6ab5fSopenharmony_ci  private isPrivateIdentifierDuplicateOfIdentifier(
23583af6ab5fSopenharmony_ci    ident1: ts.Identifier | ts.PrivateIdentifier,
23593af6ab5fSopenharmony_ci    ident2: ts.Identifier | ts.PrivateIdentifier,
23603af6ab5fSopenharmony_ci    isFromPrivateIdentifier: boolean
23613af6ab5fSopenharmony_ci  ): boolean {
23623af6ab5fSopenharmony_ci    if (ts.isIdentifier(ident1) && ts.isPrivateIdentifier(ident2)) {
23633af6ab5fSopenharmony_ci      return ident1.text === ident2.text.substring(1);
23643af6ab5fSopenharmony_ci    }
23653af6ab5fSopenharmony_ci    if (ts.isIdentifier(ident2) && ts.isPrivateIdentifier(ident1)) {
23663af6ab5fSopenharmony_ci      return ident2.text === ident1.text.substring(1);
23673af6ab5fSopenharmony_ci    }
23683af6ab5fSopenharmony_ci    if (
23693af6ab5fSopenharmony_ci      this.isFromPrivateIdentifierOrSdk(isFromPrivateIdentifier) &&
23703af6ab5fSopenharmony_ci      ts.isPrivateIdentifier(ident1) &&
23713af6ab5fSopenharmony_ci      ts.isPrivateIdentifier(ident2)
23723af6ab5fSopenharmony_ci    ) {
23733af6ab5fSopenharmony_ci      return ident1.text.substring(1) === ident2.text.substring(1);
23743af6ab5fSopenharmony_ci    }
23753af6ab5fSopenharmony_ci    return false;
23763af6ab5fSopenharmony_ci  }
23773af6ab5fSopenharmony_ci
23783af6ab5fSopenharmony_ci  findIdentifierNameForSymbol(symbol: ts.Symbol): string | undefined {
23793af6ab5fSopenharmony_ci    let name = TsUtils.getIdentifierNameFromString(symbol.name);
23803af6ab5fSopenharmony_ci    if (name === undefined || name === symbol.name) {
23813af6ab5fSopenharmony_ci      return name;
23823af6ab5fSopenharmony_ci    }
23833af6ab5fSopenharmony_ci
23843af6ab5fSopenharmony_ci    const parentType = this.getTypeByProperty(symbol);
23853af6ab5fSopenharmony_ci    if (parentType === undefined) {
23863af6ab5fSopenharmony_ci      return undefined;
23873af6ab5fSopenharmony_ci    }
23883af6ab5fSopenharmony_ci
23893af6ab5fSopenharmony_ci    while (this.findProperty(parentType, name) !== undefined) {
23903af6ab5fSopenharmony_ci      name = '_' + name;
23913af6ab5fSopenharmony_ci    }
23923af6ab5fSopenharmony_ci
23933af6ab5fSopenharmony_ci    return name;
23943af6ab5fSopenharmony_ci  }
23953af6ab5fSopenharmony_ci
23963af6ab5fSopenharmony_ci  private static getIdentifierNameFromString(str: string): string | undefined {
23973af6ab5fSopenharmony_ci    let result: string = '';
23983af6ab5fSopenharmony_ci
23993af6ab5fSopenharmony_ci    let offset = 0;
24003af6ab5fSopenharmony_ci    while (offset < str.length) {
24013af6ab5fSopenharmony_ci      const codePoint = str.codePointAt(offset);
24023af6ab5fSopenharmony_ci      if (!codePoint) {
24033af6ab5fSopenharmony_ci        return undefined;
24043af6ab5fSopenharmony_ci      }
24053af6ab5fSopenharmony_ci
24063af6ab5fSopenharmony_ci      const charSize = TsUtils.charSize(codePoint);
24073af6ab5fSopenharmony_ci
24083af6ab5fSopenharmony_ci      if (offset === 0 && !ts.isIdentifierStart(codePoint, undefined)) {
24093af6ab5fSopenharmony_ci        result = '__';
24103af6ab5fSopenharmony_ci      }
24113af6ab5fSopenharmony_ci
24123af6ab5fSopenharmony_ci      if (!ts.isIdentifierPart(codePoint, undefined)) {
24133af6ab5fSopenharmony_ci        if (codePoint === 0x20) {
24143af6ab5fSopenharmony_ci          result += '_';
24153af6ab5fSopenharmony_ci        } else {
24163af6ab5fSopenharmony_ci          result += 'x' + codePoint.toString(16);
24173af6ab5fSopenharmony_ci        }
24183af6ab5fSopenharmony_ci      } else {
24193af6ab5fSopenharmony_ci        for (let i = 0; i < charSize; i++) {
24203af6ab5fSopenharmony_ci          result += str.charAt(offset + i);
24213af6ab5fSopenharmony_ci        }
24223af6ab5fSopenharmony_ci      }
24233af6ab5fSopenharmony_ci
24243af6ab5fSopenharmony_ci      offset += charSize;
24253af6ab5fSopenharmony_ci    }
24263af6ab5fSopenharmony_ci
24273af6ab5fSopenharmony_ci    return result;
24283af6ab5fSopenharmony_ci  }
24293af6ab5fSopenharmony_ci
24303af6ab5fSopenharmony_ci  private static charSize(codePoint: number): number {
24313af6ab5fSopenharmony_ci    return codePoint >= 0x10000 ? 2 : 1;
24323af6ab5fSopenharmony_ci  }
24333af6ab5fSopenharmony_ci
24343af6ab5fSopenharmony_ci  private getTypeByProperty(symbol: ts.Symbol): ts.Type | undefined {
24353af6ab5fSopenharmony_ci    if (symbol.declarations === undefined) {
24363af6ab5fSopenharmony_ci      return undefined;
24373af6ab5fSopenharmony_ci    }
24383af6ab5fSopenharmony_ci
24393af6ab5fSopenharmony_ci    for (const propDecl of symbol.declarations) {
24403af6ab5fSopenharmony_ci      if (
24413af6ab5fSopenharmony_ci        !ts.isPropertyDeclaration(propDecl) &&
24423af6ab5fSopenharmony_ci        !ts.isPropertyAssignment(propDecl) &&
24433af6ab5fSopenharmony_ci        !ts.isPropertySignature(propDecl)
24443af6ab5fSopenharmony_ci      ) {
24453af6ab5fSopenharmony_ci        return undefined;
24463af6ab5fSopenharmony_ci      }
24473af6ab5fSopenharmony_ci
24483af6ab5fSopenharmony_ci      const type = this.tsTypeChecker.getTypeAtLocation(propDecl.parent);
24493af6ab5fSopenharmony_ci      if (type !== undefined) {
24503af6ab5fSopenharmony_ci        return type;
24513af6ab5fSopenharmony_ci      }
24523af6ab5fSopenharmony_ci    }
24533af6ab5fSopenharmony_ci
24543af6ab5fSopenharmony_ci    return undefined;
24553af6ab5fSopenharmony_ci  }
24563af6ab5fSopenharmony_ci
24573af6ab5fSopenharmony_ci  static isPropertyOfInternalClassOrInterface(symbol: ts.Symbol): boolean {
24583af6ab5fSopenharmony_ci    if (symbol.declarations === undefined) {
24593af6ab5fSopenharmony_ci      return false;
24603af6ab5fSopenharmony_ci    }
24613af6ab5fSopenharmony_ci
24623af6ab5fSopenharmony_ci    for (const propDecl of symbol.declarations) {
24633af6ab5fSopenharmony_ci      if (!ts.isPropertyDeclaration(propDecl) && !ts.isPropertySignature(propDecl)) {
24643af6ab5fSopenharmony_ci        return false;
24653af6ab5fSopenharmony_ci      }
24663af6ab5fSopenharmony_ci
24673af6ab5fSopenharmony_ci      if (!ts.isClassDeclaration(propDecl.parent) && !ts.isInterfaceDeclaration(propDecl.parent)) {
24683af6ab5fSopenharmony_ci        return false;
24693af6ab5fSopenharmony_ci      }
24703af6ab5fSopenharmony_ci
24713af6ab5fSopenharmony_ci      if (TsUtils.hasModifier(ts.getModifiers(propDecl.parent), ts.SyntaxKind.ExportKeyword)) {
24723af6ab5fSopenharmony_ci        return false;
24733af6ab5fSopenharmony_ci      }
24743af6ab5fSopenharmony_ci    }
24753af6ab5fSopenharmony_ci
24763af6ab5fSopenharmony_ci    return true;
24773af6ab5fSopenharmony_ci  }
24783af6ab5fSopenharmony_ci
24793af6ab5fSopenharmony_ci  static isIntrinsicObjectType(type: ts.Type): boolean {
24803af6ab5fSopenharmony_ci    return !!(type.flags & ts.TypeFlags.NonPrimitive);
24813af6ab5fSopenharmony_ci  }
24823af6ab5fSopenharmony_ci
24833af6ab5fSopenharmony_ci  isStringType(tsType: ts.Type): boolean {
24843af6ab5fSopenharmony_ci    if ((tsType.getFlags() & ts.TypeFlags.String) !== 0) {
24853af6ab5fSopenharmony_ci      return true;
24863af6ab5fSopenharmony_ci    }
24873af6ab5fSopenharmony_ci
24883af6ab5fSopenharmony_ci    if (!TsUtils.isTypeReference(tsType)) {
24893af6ab5fSopenharmony_ci      return false;
24903af6ab5fSopenharmony_ci    }
24913af6ab5fSopenharmony_ci
24923af6ab5fSopenharmony_ci    const symbol = tsType.symbol;
24933af6ab5fSopenharmony_ci    const name = this.tsTypeChecker.getFullyQualifiedName(symbol);
24943af6ab5fSopenharmony_ci    return name === 'String' && this.isGlobalSymbol(symbol);
24953af6ab5fSopenharmony_ci  }
24963af6ab5fSopenharmony_ci
24973af6ab5fSopenharmony_ci  isStdMapType(type: ts.Type): boolean {
24983af6ab5fSopenharmony_ci    const sym = type.symbol;
24993af6ab5fSopenharmony_ci    return !!sym && sym.getName() === 'Map' && this.isGlobalSymbol(sym);
25003af6ab5fSopenharmony_ci  }
25013af6ab5fSopenharmony_ci
25023af6ab5fSopenharmony_ci  hasGenericTypeParameter(type: ts.Type): boolean {
25033af6ab5fSopenharmony_ci    if (type.isUnionOrIntersection()) {
25043af6ab5fSopenharmony_ci      return type.types.some((x) => {
25053af6ab5fSopenharmony_ci        return this.hasGenericTypeParameter(x);
25063af6ab5fSopenharmony_ci      });
25073af6ab5fSopenharmony_ci    }
25083af6ab5fSopenharmony_ci    if (TsUtils.isTypeReference(type)) {
25093af6ab5fSopenharmony_ci      const typeArgs = this.tsTypeChecker.getTypeArguments(type);
25103af6ab5fSopenharmony_ci      return typeArgs.some((x) => {
25113af6ab5fSopenharmony_ci        return this.hasGenericTypeParameter(x);
25123af6ab5fSopenharmony_ci      });
25133af6ab5fSopenharmony_ci    }
25143af6ab5fSopenharmony_ci    return type.isTypeParameter();
25153af6ab5fSopenharmony_ci  }
25163af6ab5fSopenharmony_ci
25173af6ab5fSopenharmony_ci  static getEnclosingTopLevelStatement(node: ts.Node): ts.Node | undefined {
25183af6ab5fSopenharmony_ci    return ts.findAncestor(node, (ancestor) => {
25193af6ab5fSopenharmony_ci      return ts.isSourceFile(ancestor.parent);
25203af6ab5fSopenharmony_ci    });
25213af6ab5fSopenharmony_ci  }
25223af6ab5fSopenharmony_ci
25233af6ab5fSopenharmony_ci  static isDeclarationStatement(node: ts.Node): node is ts.DeclarationStatement {
25243af6ab5fSopenharmony_ci    const kind = node.kind;
25253af6ab5fSopenharmony_ci    return (
25263af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.FunctionDeclaration ||
25273af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.ModuleDeclaration ||
25283af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.ClassDeclaration ||
25293af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.StructDeclaration ||
25303af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.TypeAliasDeclaration ||
25313af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.InterfaceDeclaration ||
25323af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.EnumDeclaration ||
25333af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.MissingDeclaration ||
25343af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.ImportEqualsDeclaration ||
25353af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.ImportDeclaration ||
25363af6ab5fSopenharmony_ci      kind === ts.SyntaxKind.NamespaceExportDeclaration
25373af6ab5fSopenharmony_ci    );
25383af6ab5fSopenharmony_ci  }
25393af6ab5fSopenharmony_ci
25403af6ab5fSopenharmony_ci  static declarationNameExists(srcFile: ts.SourceFile, name: string): boolean {
25413af6ab5fSopenharmony_ci    return srcFile.statements.some((stmt) => {
25423af6ab5fSopenharmony_ci      if (!ts.isImportDeclaration(stmt)) {
25433af6ab5fSopenharmony_ci        return (
25443af6ab5fSopenharmony_ci          TsUtils.isDeclarationStatement(stmt) &&
25453af6ab5fSopenharmony_ci          stmt.name !== undefined &&
25463af6ab5fSopenharmony_ci          ts.isIdentifier(stmt.name) &&
25473af6ab5fSopenharmony_ci          stmt.name.text === name
25483af6ab5fSopenharmony_ci        );
25493af6ab5fSopenharmony_ci      }
25503af6ab5fSopenharmony_ci
25513af6ab5fSopenharmony_ci      if (!stmt.importClause) {
25523af6ab5fSopenharmony_ci        return false;
25533af6ab5fSopenharmony_ci      }
25543af6ab5fSopenharmony_ci
25553af6ab5fSopenharmony_ci      if (!stmt.importClause.namedBindings) {
25563af6ab5fSopenharmony_ci        return stmt.importClause.name?.text === name;
25573af6ab5fSopenharmony_ci      }
25583af6ab5fSopenharmony_ci
25593af6ab5fSopenharmony_ci      if (ts.isNamespaceImport(stmt.importClause.namedBindings)) {
25603af6ab5fSopenharmony_ci        return stmt.importClause.namedBindings.name.text === name;
25613af6ab5fSopenharmony_ci      }
25623af6ab5fSopenharmony_ci      return stmt.importClause.namedBindings.elements.some((x) => {
25633af6ab5fSopenharmony_ci        return x.name.text === name;
25643af6ab5fSopenharmony_ci      });
25653af6ab5fSopenharmony_ci    });
25663af6ab5fSopenharmony_ci  }
25673af6ab5fSopenharmony_ci
25683af6ab5fSopenharmony_ci  static generateUniqueName(nameGenerator: NameGenerator, srcFile: ts.SourceFile): string | undefined {
25693af6ab5fSopenharmony_ci    let newName: string | undefined;
25703af6ab5fSopenharmony_ci
25713af6ab5fSopenharmony_ci    do {
25723af6ab5fSopenharmony_ci      newName = nameGenerator.getName();
25733af6ab5fSopenharmony_ci      if (newName !== undefined && TsUtils.declarationNameExists(srcFile, newName)) {
25743af6ab5fSopenharmony_ci        continue;
25753af6ab5fSopenharmony_ci      }
25763af6ab5fSopenharmony_ci      break;
25773af6ab5fSopenharmony_ci    } while (newName !== undefined);
25783af6ab5fSopenharmony_ci
25793af6ab5fSopenharmony_ci    return newName;
25803af6ab5fSopenharmony_ci  }
25813af6ab5fSopenharmony_ci
25823af6ab5fSopenharmony_ci  static isSharedModule(sourceFile: ts.SourceFile): boolean {
25833af6ab5fSopenharmony_ci    const statements = sourceFile.statements;
25843af6ab5fSopenharmony_ci    for (const statement of statements) {
25853af6ab5fSopenharmony_ci      if (ts.isImportDeclaration(statement)) {
25863af6ab5fSopenharmony_ci        continue;
25873af6ab5fSopenharmony_ci      }
25883af6ab5fSopenharmony_ci
25893af6ab5fSopenharmony_ci      return (
25903af6ab5fSopenharmony_ci        ts.isExpressionStatement(statement) &&
25913af6ab5fSopenharmony_ci        ts.isStringLiteral(statement.expression) &&
25923af6ab5fSopenharmony_ci        statement.expression.text === USE_SHARED
25933af6ab5fSopenharmony_ci      );
25943af6ab5fSopenharmony_ci    }
25953af6ab5fSopenharmony_ci    return false;
25963af6ab5fSopenharmony_ci  }
25973af6ab5fSopenharmony_ci
25983af6ab5fSopenharmony_ci  getDeclarationNode(node: ts.Node): ts.Declaration | undefined {
25993af6ab5fSopenharmony_ci    const sym = this.trueSymbolAtLocation(node);
26003af6ab5fSopenharmony_ci    return TsUtils.getDeclaration(sym);
26013af6ab5fSopenharmony_ci  }
26023af6ab5fSopenharmony_ci
26033af6ab5fSopenharmony_ci  static isFunctionLikeDeclaration(node: ts.Declaration): boolean {
26043af6ab5fSopenharmony_ci    return (
26053af6ab5fSopenharmony_ci      ts.isFunctionDeclaration(node) ||
26063af6ab5fSopenharmony_ci      ts.isMethodDeclaration(node) ||
26073af6ab5fSopenharmony_ci      ts.isGetAccessorDeclaration(node) ||
26083af6ab5fSopenharmony_ci      ts.isSetAccessorDeclaration(node) ||
26093af6ab5fSopenharmony_ci      ts.isConstructorDeclaration(node) ||
26103af6ab5fSopenharmony_ci      ts.isFunctionExpression(node) ||
26113af6ab5fSopenharmony_ci      ts.isArrowFunction(node)
26123af6ab5fSopenharmony_ci    );
26133af6ab5fSopenharmony_ci  }
26143af6ab5fSopenharmony_ci
26153af6ab5fSopenharmony_ci  isShareableEntity(node: ts.Node): boolean {
26163af6ab5fSopenharmony_ci    const decl = this.getDeclarationNode(node);
26173af6ab5fSopenharmony_ci    const typeNode = (decl as any)?.type;
26183af6ab5fSopenharmony_ci    return typeNode && !TsUtils.isFunctionLikeDeclaration(decl!) ?
26193af6ab5fSopenharmony_ci      this.isSendableTypeNode(typeNode, true) :
26203af6ab5fSopenharmony_ci      this.isShareableType(this.tsTypeChecker.getTypeAtLocation(decl ? decl : node));
26213af6ab5fSopenharmony_ci  }
26223af6ab5fSopenharmony_ci
26233af6ab5fSopenharmony_ci  isSendableClassOrInterfaceEntity(node: ts.Node): boolean {
26243af6ab5fSopenharmony_ci    const decl = this.getDeclarationNode(node);
26253af6ab5fSopenharmony_ci    if (!decl) {
26263af6ab5fSopenharmony_ci      return false;
26273af6ab5fSopenharmony_ci    }
26283af6ab5fSopenharmony_ci    if (ts.isClassDeclaration(decl)) {
26293af6ab5fSopenharmony_ci      return TsUtils.hasSendableDecorator(decl);
26303af6ab5fSopenharmony_ci    }
26313af6ab5fSopenharmony_ci    if (ts.isInterfaceDeclaration(decl)) {
26323af6ab5fSopenharmony_ci      return this.isOrDerivedFrom(this.tsTypeChecker.getTypeAtLocation(decl), TsUtils.isISendableInterface);
26333af6ab5fSopenharmony_ci    }
26343af6ab5fSopenharmony_ci    return false;
26353af6ab5fSopenharmony_ci  }
26363af6ab5fSopenharmony_ci
26373af6ab5fSopenharmony_ci  static isInImportWhiteList(resolvedModule: ts.ResolvedModuleFull): boolean {
26383af6ab5fSopenharmony_ci    if (
26393af6ab5fSopenharmony_ci      !resolvedModule.resolvedFileName ||
26403af6ab5fSopenharmony_ci      path.basename(resolvedModule.resolvedFileName).toLowerCase() !== ARKTS_LANG_D_ETS &&
26413af6ab5fSopenharmony_ci        path.basename(resolvedModule.resolvedFileName).toLowerCase() !== ARKTS_COLLECTIONS_D_ETS
26423af6ab5fSopenharmony_ci    ) {
26433af6ab5fSopenharmony_ci      return false;
26443af6ab5fSopenharmony_ci    }
26453af6ab5fSopenharmony_ci    return true;
26463af6ab5fSopenharmony_ci  }
26473af6ab5fSopenharmony_ci
26483af6ab5fSopenharmony_ci  // If it is an overloaded function, all declarations for that function are found
26493af6ab5fSopenharmony_ci  static hasSendableDecoratorFunctionOverload(decl: ts.FunctionDeclaration): boolean {
26503af6ab5fSopenharmony_ci    const decorators = TsUtils.getFunctionOverloadDecorators(decl);
26513af6ab5fSopenharmony_ci    return !!decorators?.some((x) => {
26523af6ab5fSopenharmony_ci      return TsUtils.getDecoratorName(x) === SENDABLE_DECORATOR;
26533af6ab5fSopenharmony_ci    });
26543af6ab5fSopenharmony_ci  }
26553af6ab5fSopenharmony_ci
26563af6ab5fSopenharmony_ci  static getFunctionOverloadDecorators(funcDecl: ts.FunctionDeclaration): readonly ts.Decorator[] | undefined {
26573af6ab5fSopenharmony_ci    const decls = funcDecl.symbol.getDeclarations();
26583af6ab5fSopenharmony_ci    if (!decls?.length) {
26593af6ab5fSopenharmony_ci      return undefined;
26603af6ab5fSopenharmony_ci    }
26613af6ab5fSopenharmony_ci    let result: ts.Decorator[] = [];
26623af6ab5fSopenharmony_ci    decls.forEach((decl) => {
26633af6ab5fSopenharmony_ci      if (!ts.isFunctionDeclaration(decl)) {
26643af6ab5fSopenharmony_ci        return;
26653af6ab5fSopenharmony_ci      }
26663af6ab5fSopenharmony_ci      const decorators = ts.getAllDecorators(decl);
26673af6ab5fSopenharmony_ci      if (decorators?.length) {
26683af6ab5fSopenharmony_ci        result = result.concat(decorators);
26693af6ab5fSopenharmony_ci      }
26703af6ab5fSopenharmony_ci    });
26713af6ab5fSopenharmony_ci    return result.length ? result : undefined;
26723af6ab5fSopenharmony_ci  }
26733af6ab5fSopenharmony_ci
26743af6ab5fSopenharmony_ci  static isSendableFunction(type: ts.Type): boolean {
26753af6ab5fSopenharmony_ci    const callSigns = type.getCallSignatures();
26763af6ab5fSopenharmony_ci    if (!callSigns?.length) {
26773af6ab5fSopenharmony_ci      return false;
26783af6ab5fSopenharmony_ci    }
26793af6ab5fSopenharmony_ci    const decl = callSigns[0].declaration;
26803af6ab5fSopenharmony_ci    if (!decl || !ts.isFunctionDeclaration(decl)) {
26813af6ab5fSopenharmony_ci      return false;
26823af6ab5fSopenharmony_ci    }
26833af6ab5fSopenharmony_ci    return TsUtils.hasSendableDecoratorFunctionOverload(decl);
26843af6ab5fSopenharmony_ci  }
26853af6ab5fSopenharmony_ci
26863af6ab5fSopenharmony_ci  isSendableTypeAlias(type: ts.Type): boolean {
26873af6ab5fSopenharmony_ci    const decl = this.getTypsAliasOriginalDecl(type);
26883af6ab5fSopenharmony_ci    return !!decl && TsUtils.hasSendableDecorator(decl);
26893af6ab5fSopenharmony_ci  }
26903af6ab5fSopenharmony_ci
26913af6ab5fSopenharmony_ci  hasSendableTypeAlias(type: ts.Type): boolean {
26923af6ab5fSopenharmony_ci    if (type.isUnion()) {
26933af6ab5fSopenharmony_ci      return type.types.some((compType) => {
26943af6ab5fSopenharmony_ci        return this.hasSendableTypeAlias(compType);
26953af6ab5fSopenharmony_ci      });
26963af6ab5fSopenharmony_ci    }
26973af6ab5fSopenharmony_ci    return this.isSendableTypeAlias(type);
26983af6ab5fSopenharmony_ci  }
26993af6ab5fSopenharmony_ci
27003af6ab5fSopenharmony_ci  isNonSendableFunctionTypeAlias(type: ts.Type): boolean {
27013af6ab5fSopenharmony_ci    const decl = this.getTypsAliasOriginalDecl(type);
27023af6ab5fSopenharmony_ci    return !!decl && ts.isFunctionTypeNode(decl.type) && !TsUtils.hasSendableDecorator(decl);
27033af6ab5fSopenharmony_ci  }
27043af6ab5fSopenharmony_ci
27053af6ab5fSopenharmony_ci  // If the alias refers to another alias, the search continues
27063af6ab5fSopenharmony_ci  private getTypsAliasOriginalDecl(type: ts.Type): ts.TypeAliasDeclaration | undefined {
27073af6ab5fSopenharmony_ci    if (!type.aliasSymbol) {
27083af6ab5fSopenharmony_ci      return undefined;
27093af6ab5fSopenharmony_ci    }
27103af6ab5fSopenharmony_ci    const decl = TsUtils.getDeclaration(type.aliasSymbol);
27113af6ab5fSopenharmony_ci    if (!decl || !ts.isTypeAliasDeclaration(decl)) {
27123af6ab5fSopenharmony_ci      return undefined;
27133af6ab5fSopenharmony_ci    }
27143af6ab5fSopenharmony_ci    if (ts.isTypeReferenceNode(decl.type)) {
27153af6ab5fSopenharmony_ci      const targetType = this.tsTypeChecker.getTypeAtLocation(decl.type.typeName);
27163af6ab5fSopenharmony_ci      if (targetType.aliasSymbol && targetType.aliasSymbol.getFlags() & ts.SymbolFlags.TypeAlias) {
27173af6ab5fSopenharmony_ci        return this.getTypsAliasOriginalDecl(targetType);
27183af6ab5fSopenharmony_ci      }
27193af6ab5fSopenharmony_ci    }
27203af6ab5fSopenharmony_ci    return decl;
27213af6ab5fSopenharmony_ci  }
27223af6ab5fSopenharmony_ci
27233af6ab5fSopenharmony_ci  // not allow 'lhsType' contains 'sendable typeAlias' && 'rhsType' contains 'non-sendable function/non-sendable function typeAlias'
27243af6ab5fSopenharmony_ci  isWrongSendableFunctionAssignment(lhsType: ts.Type, rhsType: ts.Type): boolean {
27253af6ab5fSopenharmony_ci    // eslint-disable-next-line no-param-reassign
27263af6ab5fSopenharmony_ci    lhsType = this.getNonNullableType(lhsType);
27273af6ab5fSopenharmony_ci    // eslint-disable-next-line no-param-reassign
27283af6ab5fSopenharmony_ci    rhsType = this.getNonNullableType(rhsType);
27293af6ab5fSopenharmony_ci    if (!this.hasSendableTypeAlias(lhsType)) {
27303af6ab5fSopenharmony_ci      return false;
27313af6ab5fSopenharmony_ci    }
27323af6ab5fSopenharmony_ci
27333af6ab5fSopenharmony_ci    if (rhsType.isUnion()) {
27343af6ab5fSopenharmony_ci      return rhsType.types.some((compType) => {
27353af6ab5fSopenharmony_ci        return this.isInvalidSendableFunctionAssignmentType(compType);
27363af6ab5fSopenharmony_ci      });
27373af6ab5fSopenharmony_ci    }
27383af6ab5fSopenharmony_ci    return this.isInvalidSendableFunctionAssignmentType(rhsType);
27393af6ab5fSopenharmony_ci  }
27403af6ab5fSopenharmony_ci
27413af6ab5fSopenharmony_ci  private isInvalidSendableFunctionAssignmentType(type: ts.Type): boolean {
27423af6ab5fSopenharmony_ci    if (type.aliasSymbol) {
27433af6ab5fSopenharmony_ci      return this.isNonSendableFunctionTypeAlias(type);
27443af6ab5fSopenharmony_ci    }
27453af6ab5fSopenharmony_ci    if (TsUtils.isFunctionalType(type)) {
27463af6ab5fSopenharmony_ci      return !TsUtils.isSendableFunction(type);
27473af6ab5fSopenharmony_ci    }
27483af6ab5fSopenharmony_ci    return false;
27493af6ab5fSopenharmony_ci  }
27503af6ab5fSopenharmony_ci
27513af6ab5fSopenharmony_ci  static isSetExpression(accessExpr: ts.ElementAccessExpression): boolean {
27523af6ab5fSopenharmony_ci    if (!ts.isBinaryExpression(accessExpr.parent)) {
27533af6ab5fSopenharmony_ci      return false;
27543af6ab5fSopenharmony_ci    }
27553af6ab5fSopenharmony_ci    const binaryExpr = accessExpr.parent;
27563af6ab5fSopenharmony_ci    return binaryExpr.operatorToken.kind === ts.SyntaxKind.EqualsToken && binaryExpr.left === accessExpr;
27573af6ab5fSopenharmony_ci  }
27583af6ab5fSopenharmony_ci
27593af6ab5fSopenharmony_ci  haveSameBaseType(type1: ts.Type, type2: ts.Type): boolean {
27603af6ab5fSopenharmony_ci    return this.tsTypeChecker.getBaseTypeOfLiteralType(type1) === this.tsTypeChecker.getBaseTypeOfLiteralType(type2);
27613af6ab5fSopenharmony_ci  }
27623af6ab5fSopenharmony_ci
27633af6ab5fSopenharmony_ci  isGetIndexableType(type: ts.Type, indexType: ts.Type): boolean {
27643af6ab5fSopenharmony_ci    const getDecls = type.getProperty('$_get')?.getDeclarations();
27653af6ab5fSopenharmony_ci    if (getDecls?.length !== 1 || getDecls[0].kind !== ts.SyntaxKind.MethodDeclaration) {
27663af6ab5fSopenharmony_ci      return false;
27673af6ab5fSopenharmony_ci    }
27683af6ab5fSopenharmony_ci    const getMethodDecl = getDecls[0] as ts.MethodDeclaration;
27693af6ab5fSopenharmony_ci    const getParams = getMethodDecl.parameters;
27703af6ab5fSopenharmony_ci    if (getMethodDecl.type === undefined || getParams.length !== 1 || getParams[0].type === undefined) {
27713af6ab5fSopenharmony_ci      return false;
27723af6ab5fSopenharmony_ci    }
27733af6ab5fSopenharmony_ci
27743af6ab5fSopenharmony_ci    return this.haveSameBaseType(this.tsTypeChecker.getTypeFromTypeNode(getParams[0].type), indexType);
27753af6ab5fSopenharmony_ci  }
27763af6ab5fSopenharmony_ci
27773af6ab5fSopenharmony_ci  isSetIndexableType(type: ts.Type, indexType: ts.Type, valueType: ts.Type): boolean {
27783af6ab5fSopenharmony_ci    const setProp = type.getProperty('$_set');
27793af6ab5fSopenharmony_ci    const setDecls = setProp?.getDeclarations();
27803af6ab5fSopenharmony_ci    if (setDecls?.length !== 1 || setDecls[0].kind !== ts.SyntaxKind.MethodDeclaration) {
27813af6ab5fSopenharmony_ci      return false;
27823af6ab5fSopenharmony_ci    }
27833af6ab5fSopenharmony_ci    const setMethodDecl = setDecls[0] as ts.MethodDeclaration;
27843af6ab5fSopenharmony_ci    const setParams = setMethodDecl.parameters;
27853af6ab5fSopenharmony_ci    if (
27863af6ab5fSopenharmony_ci      setMethodDecl.type !== undefined ||
27873af6ab5fSopenharmony_ci      setParams.length !== 2 ||
27883af6ab5fSopenharmony_ci      setParams[0].type === undefined ||
27893af6ab5fSopenharmony_ci      setParams[1].type === undefined
27903af6ab5fSopenharmony_ci    ) {
27913af6ab5fSopenharmony_ci      return false;
27923af6ab5fSopenharmony_ci    }
27933af6ab5fSopenharmony_ci
27943af6ab5fSopenharmony_ci    return (
27953af6ab5fSopenharmony_ci      this.haveSameBaseType(this.tsTypeChecker.getTypeFromTypeNode(setParams[0].type), indexType) &&
27963af6ab5fSopenharmony_ci      this.haveSameBaseType(this.tsTypeChecker.getTypeFromTypeNode(setParams[1].type), valueType)
27973af6ab5fSopenharmony_ci    );
27983af6ab5fSopenharmony_ci  }
27993af6ab5fSopenharmony_ci
28003af6ab5fSopenharmony_ci  // Search for and save the exported declaration in the specified file, re-exporting another module will not be included.
28013af6ab5fSopenharmony_ci  searchFileExportDecl(sourceFile: ts.SourceFile, targetDecls?: ts.SyntaxKind[]): Set<ts.Node> {
28023af6ab5fSopenharmony_ci    const exportDeclSet = new Set<ts.Node>();
28033af6ab5fSopenharmony_ci    const appendDecl = (decl: ts.Node | undefined): void => {
28043af6ab5fSopenharmony_ci      if (!decl || targetDecls && !targetDecls.includes(decl.kind)) {
28053af6ab5fSopenharmony_ci        return;
28063af6ab5fSopenharmony_ci      }
28073af6ab5fSopenharmony_ci      exportDeclSet.add(decl);
28083af6ab5fSopenharmony_ci    };
28093af6ab5fSopenharmony_ci
28103af6ab5fSopenharmony_ci    sourceFile.statements.forEach((statement: ts.Statement) => {
28113af6ab5fSopenharmony_ci      if (ts.isExportAssignment(statement)) {
28123af6ab5fSopenharmony_ci        // handle the case:"export default declName;"
28133af6ab5fSopenharmony_ci        if (statement.isExportEquals) {
28143af6ab5fSopenharmony_ci          return;
28153af6ab5fSopenharmony_ci        }
28163af6ab5fSopenharmony_ci        appendDecl(this.getDeclarationNode(statement.expression));
28173af6ab5fSopenharmony_ci      } else if (ts.isExportDeclaration(statement)) {
28183af6ab5fSopenharmony_ci        // handle the case:"export { declName1, declName2 };"
28193af6ab5fSopenharmony_ci        if (!statement.exportClause || !ts.isNamedExports(statement.exportClause)) {
28203af6ab5fSopenharmony_ci          return;
28213af6ab5fSopenharmony_ci        }
28223af6ab5fSopenharmony_ci        statement.exportClause.elements.forEach((specifier) => {
28233af6ab5fSopenharmony_ci          appendDecl(this.getDeclarationNode(specifier.propertyName ?? specifier.name));
28243af6ab5fSopenharmony_ci        });
28253af6ab5fSopenharmony_ci      } else if (ts.canHaveModifiers(statement)) {
28263af6ab5fSopenharmony_ci        // handle the case:"export const/class/function... decalName;"
28273af6ab5fSopenharmony_ci        if (!TsUtils.hasModifier(ts.getModifiers(statement), ts.SyntaxKind.ExportKeyword)) {
28283af6ab5fSopenharmony_ci          return;
28293af6ab5fSopenharmony_ci        }
28303af6ab5fSopenharmony_ci        if (!ts.isVariableStatement(statement)) {
28313af6ab5fSopenharmony_ci          appendDecl(statement);
28323af6ab5fSopenharmony_ci          return;
28333af6ab5fSopenharmony_ci        }
28343af6ab5fSopenharmony_ci        for (const exportDecl of statement.declarationList.declarations) {
28353af6ab5fSopenharmony_ci          appendDecl(exportDecl);
28363af6ab5fSopenharmony_ci        }
28373af6ab5fSopenharmony_ci      }
28383af6ab5fSopenharmony_ci    });
28393af6ab5fSopenharmony_ci    return exportDeclSet;
28403af6ab5fSopenharmony_ci  }
28413af6ab5fSopenharmony_ci
28423af6ab5fSopenharmony_ci  static isAmbientNode(node: ts.Node): boolean {
28433af6ab5fSopenharmony_ci    // Ambient flag is not exposed, so we apply dirty hack to make it visible
28443af6ab5fSopenharmony_ci    return !!(node.flags & (ts.NodeFlags as any).Ambient);
28453af6ab5fSopenharmony_ci  }
28463af6ab5fSopenharmony_ci}
2847