• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import type * as ts from 'typescript';
17
18/**
19 * NOTE: hack for typecheck of readonly arrays.
20 * See more here https://github.com/microsoft/TypeScript/issues/17002
21 */
22declare global {
23  interface ArrayConstructor {
24    isArray(arg: unknown): arg is unknown[] | readonly unknown[];
25  }
26}
27
28export function isVisitResultNode(vr: ts.VisitResult<ts.Node>): vr is ts.Node {
29  return vr !== undefined && !Array.isArray(vr);
30}
31
32export function isVisitResultNodeArray(vr: ts.VisitResult<ts.Node>): vr is readonly ts.Node[] {
33  return Array.isArray(vr);
34}
35
36export function visitVisitResult(result: ts.VisitResult<ts.Node>, visitor: ts.Visitor): ts.VisitResult<ts.Node> {
37  if (result === undefined) {
38    return undefined;
39  }
40
41  if (isVisitResultNode(result)) {
42    return visitor(result);
43  }
44
45  if (!isVisitResultNodeArray(result)) {
46    throw new Error('Unreachable');
47  }
48
49  const newResult: ts.Node[] = [];
50  for (const node of result) {
51    const fixedNode = visitor(node);
52
53    if (fixedNode === undefined) {
54      continue;
55    }
56
57    if (Array.isArray(fixedNode)) {
58      newResult.push(...fixedNode);
59      continue;
60    }
61
62    newResult.push(fixedNode);
63  }
64
65  if (newResult.length === 0) {
66    return undefined;
67  }
68
69  if (newResult.length === 1) {
70    return newResult[0];
71  }
72
73  return newResult;
74}
75