• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 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 { AliasType, ArrayType, ClassType, FunctionType, GenericType, TupleType, Type, UnclearReferenceType, UnionType } from 'arkanalyzer';
17
18/**
19 * 检查类型是否为指定类型
20 *
21 * @param appointType 指定类型
22 * @param type 被检查类型
23 * @returns
24 */
25export function isAppointType(appointType: Type, type: Type): boolean {
26
27  if (appointType.getTypeString() === type.getTypeString()) {
28    return true;
29  }
30
31  if (type instanceof ArrayType) {
32    return isAppointType(appointType, type.getBaseType());
33  }
34
35  if (type instanceof UnclearReferenceType) {
36    return generic(appointType, type.getGenericTypes());
37  }
38
39  if (type instanceof UnionType) {
40    return generic(appointType, type.getTypes());
41  }
42
43  if (type instanceof FunctionType) {
44    return generic(appointType, type.getRealGenericTypes());
45  }
46
47  if (type instanceof ClassType) {
48    return generic(appointType, type.getRealGenericTypes());
49  }
50
51  if (type instanceof TupleType) {
52    return generic(appointType, type.getTypes());
53  }
54
55  if (type instanceof AliasType) {
56    return isAppointType(appointType, type.getOriginalType());
57  }
58
59  if (type instanceof GenericType) {
60    let defType = type.getDefaultType();
61    let constraintType = type.getConstraint();
62    return (defType ? isAppointType(appointType, defType) : false) ||
63      (constraintType ? isAppointType(appointType, constraintType) : false);
64  }
65  return false;
66}
67
68function generic(appointType: Type, type: Type[] | undefined): boolean {
69  if (!type) {
70    return false;
71  }
72  for (const t of type) {
73    if (isAppointType(appointType, t)) {
74      return true;
75    }
76  }
77  return false;
78}
79
80/**
81 * 递归替换类型中的指定类型
82 *
83 * @param appointType 指定类型
84 * @param type 需要被替换的类型
85 * @param newType 新的类型
86 * @returns
87 */
88export function fixAppointType(appointType: Type, type: Type, newType: Type): Type {
89  if (appointType.getTypeString() === type.getTypeString()) {
90    return newType;
91  }
92
93  if (type instanceof ArrayType) {
94    type.setBaseType(fixAppointType(appointType, type.getBaseType(), newType));
95    return type;
96  }
97
98  if (type instanceof UnclearReferenceType) {
99    return handleUnclearReferenceType(appointType, type, newType);
100  }
101
102  if (type instanceof UnionType) {
103    return handleUnionType(appointType, type, newType);
104  }
105
106  if (type instanceof FunctionType) {
107    return handleFunctionType(appointType, type, newType);
108  }
109
110  if (type instanceof ClassType) {
111    return handleClassType(appointType, type, newType);
112  }
113
114  if (type instanceof TupleType) {
115    return handleTupleType(appointType, type, newType);
116  }
117
118  if (type instanceof AliasType) {
119    type.setOriginalType(fixAppointType(appointType, type.getOriginalType(), newType));
120    return type;
121  }
122
123  if (type instanceof GenericType) {
124    return handleGenericType(appointType, type, newType);
125  }
126  return type;
127}
128
129// 处理 UnclearReferenceType 的逻辑
130function handleUnclearReferenceType(appointType: Type, type: UnclearReferenceType, newType: Type): Type {
131  const genericTypes = type.getGenericTypes() || [];
132  for (let i = 0; i < genericTypes.length; i++) {
133    genericTypes[i] = fixAppointType(appointType, genericTypes[i], newType);
134  }
135  return new UnclearReferenceType(type.getName(), genericTypes);
136}
137
138// 处理 UnionType 的逻辑
139function handleUnionType(appointType: Type, type: UnionType, newType: Type): Type {
140  const unionTypes = type.getTypes() || [];
141  for (let i = 0; i < unionTypes.length; i++) {
142    unionTypes[i] = fixAppointType(appointType, unionTypes[i], newType);
143  }
144  return new UnionType(unionTypes);
145}
146
147// 处理 FunctionType 的逻辑
148function handleFunctionType(appointType: Type, type: FunctionType, newType: Type): Type {
149  const realGenericTypes = type.getRealGenericTypes() || [];
150  for (let i = 0; i < realGenericTypes.length; i++) {
151    realGenericTypes[i] = fixAppointType(appointType, realGenericTypes[i], newType);
152  }
153  return new FunctionType(type.getMethodSignature(), realGenericTypes);
154}
155
156// 处理 ClassType 的逻辑
157function handleClassType(appointType: Type, type: ClassType, newType: Type): Type {
158  const realGenericTypes = type.getRealGenericTypes() || [];
159  for (let i = 0; i < realGenericTypes.length; i++) {
160    realGenericTypes[i] = fixAppointType(appointType, realGenericTypes[i], newType);
161  }
162  type.setRealGenericTypes(realGenericTypes);
163  return type;
164}
165
166// 处理 TupleType 的逻辑
167function handleTupleType(appointType: Type, type: TupleType, newType: Type): Type {
168  const tupleTypes = type.getTypes() || [];
169  for (let i = 0; i < tupleTypes.length; i++) {
170    tupleTypes[i] = fixAppointType(appointType, tupleTypes[i], newType);
171  }
172  return new TupleType(tupleTypes);
173}
174
175// 处理 GenericType 的逻辑
176function handleGenericType(appointType: Type, type: GenericType, newType: Type): Type {
177  let defType = type.getDefaultType();
178  let constraintType = type.getConstraint();
179  if (defType) {
180    defType = fixAppointType(appointType, defType, newType);
181  }
182  if (constraintType) {
183    constraintType = fixAppointType(appointType, constraintType, newType);
184  }
185  if (defType) {
186    type.setDefaultType(defType);
187  }
188
189  if (constraintType) {
190    type.setConstraint(constraintType);
191  }
192  return type;
193}
194