@openrewrite/rewrite 8.62.3 → 8.62.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js.map +1 -1
- package/dist/java/rpc.d.ts +1 -0
- package/dist/java/rpc.d.ts.map +1 -1
- package/dist/java/rpc.js +81 -0
- package/dist/java/rpc.js.map +1 -1
- package/dist/java/tree.d.ts +12 -6
- package/dist/java/tree.d.ts.map +1 -1
- package/dist/java/tree.js +12 -92
- package/dist/java/tree.js.map +1 -1
- package/dist/java/type.d.ts +2 -0
- package/dist/java/type.d.ts.map +1 -1
- package/dist/java/type.js +12 -0
- package/dist/java/type.js.map +1 -1
- package/dist/java/visitor.d.ts +12 -4
- package/dist/java/visitor.d.ts.map +1 -1
- package/dist/java/visitor.js +23 -1
- package/dist/java/visitor.js.map +1 -1
- package/dist/javascript/format.d.ts +2 -2
- package/dist/javascript/format.d.ts.map +1 -1
- package/dist/javascript/format.js.map +1 -1
- package/dist/javascript/index.d.ts +3 -0
- package/dist/javascript/index.d.ts.map +1 -1
- package/dist/javascript/index.js +3 -0
- package/dist/javascript/index.js.map +1 -1
- package/dist/javascript/method-matcher.d.ts +16 -0
- package/dist/javascript/method-matcher.d.ts.map +1 -0
- package/dist/javascript/method-matcher.js +222 -0
- package/dist/javascript/method-matcher.js.map +1 -0
- package/dist/javascript/parser.d.ts +1 -1
- package/dist/javascript/parser.d.ts.map +1 -1
- package/dist/javascript/parser.js +27 -5
- package/dist/javascript/parser.js.map +1 -1
- package/dist/javascript/preconditions.d.ts +6 -0
- package/dist/javascript/preconditions.d.ts.map +1 -0
- package/dist/javascript/preconditions.js +58 -0
- package/dist/javascript/preconditions.js.map +1 -0
- package/dist/javascript/print.d.ts +2 -2
- package/dist/javascript/print.d.ts.map +1 -1
- package/dist/javascript/print.js.map +1 -1
- package/dist/javascript/remove-import.d.ts +56 -0
- package/dist/javascript/remove-import.d.ts.map +1 -0
- package/dist/javascript/remove-import.js +715 -0
- package/dist/javascript/remove-import.js.map +1 -0
- package/dist/javascript/rpc.js +3 -18
- package/dist/javascript/rpc.js.map +1 -1
- package/dist/javascript/search/index.d.ts +3 -0
- package/dist/javascript/search/index.d.ts.map +1 -0
- package/dist/javascript/search/index.js +19 -0
- package/dist/javascript/search/index.js.map +1 -0
- package/dist/javascript/search/uses-method.d.ts +8 -0
- package/dist/javascript/search/uses-method.d.ts.map +1 -0
- package/dist/javascript/search/uses-method.js +35 -0
- package/dist/javascript/search/uses-method.js.map +1 -0
- package/dist/javascript/search/uses-type.d.ts +8 -0
- package/dist/javascript/search/uses-type.d.ts.map +1 -0
- package/dist/javascript/search/uses-type.js +71 -0
- package/dist/javascript/search/uses-type.js.map +1 -0
- package/dist/javascript/templating.d.ts +1 -1
- package/dist/javascript/templating.d.ts.map +1 -1
- package/dist/javascript/templating.js +1 -1
- package/dist/javascript/templating.js.map +1 -1
- package/dist/javascript/tree.d.ts +3 -3
- package/dist/javascript/tree.d.ts.map +1 -1
- package/dist/javascript/tree.js +28 -0
- package/dist/javascript/tree.js.map +1 -1
- package/dist/javascript/type-mapping.d.ts +7 -18
- package/dist/javascript/type-mapping.d.ts.map +1 -1
- package/dist/javascript/type-mapping.js +290 -203
- package/dist/javascript/type-mapping.js.map +1 -1
- package/dist/javascript/visitor.d.ts +1 -1
- package/dist/javascript/visitor.d.ts.map +1 -1
- package/dist/javascript/visitor.js +1 -1
- package/dist/javascript/visitor.js.map +1 -1
- package/dist/json/print.js.map +1 -1
- package/dist/json/rpc.js +46 -17
- package/dist/json/rpc.js.map +1 -1
- package/dist/json/visitor.d.ts +2 -2
- package/dist/json/visitor.d.ts.map +1 -1
- package/dist/json/visitor.js.map +1 -1
- package/dist/print.d.ts +1 -0
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +6 -0
- package/dist/print.js.map +1 -1
- package/dist/rpc/queue.d.ts +15 -6
- package/dist/rpc/queue.d.ts.map +1 -1
- package/dist/rpc/queue.js +37 -13
- package/dist/rpc/queue.js.map +1 -1
- package/dist/rpc/request/generate.d.ts +4 -0
- package/dist/rpc/request/generate.d.ts.map +1 -1
- package/dist/rpc/request/generate.js +9 -4
- package/dist/rpc/request/generate.js.map +1 -1
- package/dist/rpc/request/get-object.d.ts +2 -2
- package/dist/rpc/request/get-object.d.ts.map +1 -1
- package/dist/rpc/request/get-object.js +4 -12
- package/dist/rpc/request/get-object.js.map +1 -1
- package/dist/rpc/request/parse.d.ts.map +1 -1
- package/dist/rpc/request/parse.js.map +1 -1
- package/dist/rpc/request/print.d.ts +1 -1
- package/dist/rpc/request/print.d.ts.map +1 -1
- package/dist/rpc/request/print.js +1 -1
- package/dist/rpc/request/print.js.map +1 -1
- package/dist/rpc/request/visit.d.ts +3 -2
- package/dist/rpc/request/visit.d.ts.map +1 -1
- package/dist/rpc/request/visit.js +5 -4
- package/dist/rpc/request/visit.js.map +1 -1
- package/dist/rpc/rewrite-rpc.d.ts +4 -4
- package/dist/rpc/rewrite-rpc.d.ts.map +1 -1
- package/dist/rpc/rewrite-rpc.js +16 -17
- package/dist/rpc/rewrite-rpc.js.map +1 -1
- package/dist/search/index.d.ts +2 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +18 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/is-source-file.d.ts +8 -0
- package/dist/search/is-source-file.d.ts.map +1 -0
- package/dist/search/is-source-file.js +70 -0
- package/dist/search/is-source-file.js.map +1 -0
- package/dist/test/rewrite-test.d.ts.map +1 -1
- package/dist/test/rewrite-test.js +3 -0
- package/dist/test/rewrite-test.js.map +1 -1
- package/dist/text/rpc.js +37 -40
- package/dist/text/rpc.js.map +1 -1
- package/dist/util.d.ts +1 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +13 -0
- package/dist/util.js.map +1 -1
- package/dist/version.txt +1 -1
- package/dist/visitor.d.ts +1 -1
- package/dist/visitor.d.ts.map +1 -1
- package/dist/visitor.js +3 -2
- package/dist/visitor.js.map +1 -1
- package/package.json +3 -1
- package/src/execution.ts +0 -2
- package/src/java/rpc.ts +68 -0
- package/src/java/tree.ts +20 -76
- package/src/java/type.ts +14 -0
- package/src/java/visitor.ts +32 -12
- package/src/javascript/format.ts +2 -2
- package/src/javascript/index.ts +4 -0
- package/src/javascript/method-matcher.ts +250 -0
- package/src/javascript/parser.ts +20 -6
- package/src/javascript/preconditions.ts +40 -0
- package/src/javascript/print.ts +3 -3
- package/src/javascript/remove-import.ts +780 -0
- package/src/javascript/rpc.ts +6 -19
- package/src/javascript/search/index.ts +2 -0
- package/src/javascript/search/uses-method.ts +21 -0
- package/src/javascript/search/uses-type.ts +27 -0
- package/src/javascript/templating.ts +4 -3
- package/src/javascript/tree.ts +47 -3
- package/src/javascript/type-mapping.ts +320 -214
- package/src/javascript/visitor.ts +126 -126
- package/src/json/print.ts +1 -1
- package/src/json/rpc.ts +40 -19
- package/src/json/visitor.ts +2 -2
- package/src/print.ts +9 -3
- package/src/rpc/queue.ts +36 -12
- package/src/rpc/request/generate.ts +18 -6
- package/src/rpc/request/get-object.ts +6 -13
- package/src/rpc/request/parse.ts +1 -1
- package/src/rpc/request/print.ts +2 -2
- package/src/rpc/request/visit.ts +6 -5
- package/src/rpc/rewrite-rpc.ts +22 -21
- package/src/search/index.ts +1 -0
- package/src/search/is-source-file.ts +26 -0
- package/src/test/rewrite-test.ts +5 -2
- package/src/text/rpc.ts +33 -37
- package/src/util.ts +19 -4
- package/src/visitor.ts +3 -3
|
@@ -30,16 +30,9 @@ class NonDraftableType {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
_a = immer_1.immerable;
|
|
33
|
-
const builtInTypes = new Set([
|
|
34
|
-
'Array', 'Object', 'Function', 'String', 'Number', 'Boolean',
|
|
35
|
-
'Date', 'RegExp', 'Error', 'Promise', 'Map', 'Set', 'WeakMap',
|
|
36
|
-
'WeakSet', 'Symbol', 'BigInt', 'HTMLElement', 'Document',
|
|
37
|
-
'Window', 'Console', 'JSON', 'Math', 'Reflect', 'Proxy'
|
|
38
|
-
]);
|
|
39
33
|
class JavaScriptTypeMapping {
|
|
40
|
-
constructor(checker
|
|
34
|
+
constructor(checker) {
|
|
41
35
|
this.checker = checker;
|
|
42
|
-
this.projectRoot = projectRoot;
|
|
43
36
|
this.typeCache = new Map();
|
|
44
37
|
this.regExpSymbol = checker.resolveName("RegExp", undefined, typescript_1.default.SymbolFlags.Type, false);
|
|
45
38
|
}
|
|
@@ -60,14 +53,8 @@ class JavaScriptTypeMapping {
|
|
|
60
53
|
if (existing) {
|
|
61
54
|
return existing;
|
|
62
55
|
}
|
|
63
|
-
// Check
|
|
64
|
-
//
|
|
65
|
-
if (this.checker.isArrayType(type)) {
|
|
66
|
-
const arrayType = this.createArrayType(type);
|
|
67
|
-
this.typeCache.set(signature, arrayType);
|
|
68
|
-
return arrayType;
|
|
69
|
-
}
|
|
70
|
-
// Check for class/interface/enum types (but not arrays)
|
|
56
|
+
// Check for class/interface/enum types (including arrays)
|
|
57
|
+
// Arrays in JavaScript are objects with methods, so we treat them as class types
|
|
71
58
|
const symbol = (_b = type.getSymbol) === null || _b === void 0 ? void 0 : _b.call(type);
|
|
72
59
|
if (symbol) {
|
|
73
60
|
if (symbol.flags & (typescript_1.default.SymbolFlags.Class | typescript_1.default.SymbolFlags.Interface | typescript_1.default.SymbolFlags.Enum | typescript_1.default.SymbolFlags.TypeAlias)) {
|
|
@@ -120,7 +107,7 @@ class JavaScriptTypeMapping {
|
|
|
120
107
|
}
|
|
121
108
|
primitiveType(node) {
|
|
122
109
|
const type = this.type(node);
|
|
123
|
-
if (java_1.Type.isClass(type) && type.fullyQualifiedName === '
|
|
110
|
+
if (java_1.Type.isClass(type) && type.fullyQualifiedName === 'RegExp') {
|
|
124
111
|
return java_1.Type.Primitive.String;
|
|
125
112
|
}
|
|
126
113
|
return java_1.Type.isPrimitive(type) ? type : java_1.Type.Primitive.None;
|
|
@@ -136,6 +123,36 @@ class JavaScriptTypeMapping {
|
|
|
136
123
|
}
|
|
137
124
|
return undefined;
|
|
138
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Helper to create a Type.Method object from common parameters
|
|
128
|
+
*/
|
|
129
|
+
createMethodType(signature, node, declaringType, name, declaredFormalTypeNames = []) {
|
|
130
|
+
const returnType = signature.getReturnType();
|
|
131
|
+
const parameters = signature.getParameters();
|
|
132
|
+
const parameterTypes = [];
|
|
133
|
+
const parameterNames = [];
|
|
134
|
+
for (const param of parameters) {
|
|
135
|
+
parameterNames.push(param.getName());
|
|
136
|
+
const paramType = this.checker.getTypeOfSymbolAtLocation(param, node);
|
|
137
|
+
parameterTypes.push(this.getType(paramType));
|
|
138
|
+
}
|
|
139
|
+
// Create the Type.Method object
|
|
140
|
+
return Object.assign(new NonDraftableType(), {
|
|
141
|
+
kind: java_1.Type.Kind.Method,
|
|
142
|
+
declaringType: declaringType,
|
|
143
|
+
name: name,
|
|
144
|
+
returnType: this.getType(returnType),
|
|
145
|
+
parameterNames: parameterNames,
|
|
146
|
+
parameterTypes: parameterTypes,
|
|
147
|
+
thrownExceptions: [], // JavaScript doesn't have checked exceptions
|
|
148
|
+
annotations: [],
|
|
149
|
+
defaultValue: undefined,
|
|
150
|
+
declaredFormalTypeNames: declaredFormalTypeNames,
|
|
151
|
+
toJSON: function () {
|
|
152
|
+
return java_1.Type.signature(this);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
139
156
|
methodType(node) {
|
|
140
157
|
let signature;
|
|
141
158
|
let methodName;
|
|
@@ -148,29 +165,136 @@ class JavaScriptTypeMapping {
|
|
|
148
165
|
if (!signature) {
|
|
149
166
|
return undefined;
|
|
150
167
|
}
|
|
151
|
-
|
|
168
|
+
let symbol = this.checker.getSymbolAtLocation(node.expression);
|
|
169
|
+
if (!symbol && typescript_1.default.isPropertyAccessExpression(node.expression)) {
|
|
170
|
+
// For property access expressions where we couldn't get a symbol,
|
|
171
|
+
// try to get the symbol from the signature's declaration
|
|
172
|
+
const declaration = signature === null || signature === void 0 ? void 0 : signature.getDeclaration();
|
|
173
|
+
if (declaration) {
|
|
174
|
+
symbol = this.checker.getSymbolAtLocation(declaration);
|
|
175
|
+
}
|
|
176
|
+
// If still no symbol but we have a signature, we can proceed with limited info
|
|
177
|
+
if (!symbol && signature) {
|
|
178
|
+
// For cases like util.isArray where the module is 'any' type
|
|
179
|
+
// We'll construct a basic method type from the signature
|
|
180
|
+
methodName = node.expression.name.getText();
|
|
181
|
+
// When there's no symbol but we have a signature, we need to work harder
|
|
182
|
+
// to find the declaring type. This happens with CommonJS require() calls
|
|
183
|
+
// where the module is typed as 'any' but methods still have signatures
|
|
184
|
+
// Try to trace back through the AST to find the require() call
|
|
185
|
+
let inferredDeclaringType;
|
|
186
|
+
const objExpr = node.expression.expression;
|
|
187
|
+
if (typescript_1.default.isIdentifier(objExpr)) {
|
|
188
|
+
// Look for the variable declaration that assigns the require() result
|
|
189
|
+
const objSymbol = this.checker.getSymbolAtLocation(objExpr);
|
|
190
|
+
if (objSymbol && objSymbol.valueDeclaration) {
|
|
191
|
+
const valueDecl = objSymbol.valueDeclaration;
|
|
192
|
+
if (typescript_1.default.isVariableDeclaration(valueDecl) && valueDecl.initializer) {
|
|
193
|
+
// Check if it's a require() call
|
|
194
|
+
if (typescript_1.default.isCallExpression(valueDecl.initializer)) {
|
|
195
|
+
const callExpr = valueDecl.initializer;
|
|
196
|
+
if (typescript_1.default.isIdentifier(callExpr.expression) &&
|
|
197
|
+
callExpr.expression.getText() === 'require' &&
|
|
198
|
+
callExpr.arguments.length > 0) {
|
|
199
|
+
// Extract the module name from require('module-name')
|
|
200
|
+
const moduleArg = callExpr.arguments[0];
|
|
201
|
+
if (typescript_1.default.isStringLiteral(moduleArg)) {
|
|
202
|
+
const moduleName = moduleArg.text;
|
|
203
|
+
inferredDeclaringType = {
|
|
204
|
+
kind: java_1.Type.Kind.Class,
|
|
205
|
+
fullyQualifiedName: moduleName
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Use the inferred type or fall back to unknown
|
|
214
|
+
declaringType = inferredDeclaringType || java_1.Type.unknownType;
|
|
215
|
+
// Create the method type using the helper
|
|
216
|
+
return this.createMethodType(signature, node, declaringType, methodName);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
152
219
|
if (!symbol) {
|
|
153
220
|
return undefined;
|
|
154
221
|
}
|
|
155
222
|
// Get the method name
|
|
156
223
|
if (typescript_1.default.isPropertyAccessExpression(node.expression)) {
|
|
157
224
|
methodName = node.expression.name.getText();
|
|
225
|
+
// Check if the object is an imported symbol
|
|
226
|
+
const objSymbol = this.checker.getSymbolAtLocation(node.expression.expression);
|
|
227
|
+
let isImport = false;
|
|
228
|
+
if (objSymbol) {
|
|
229
|
+
// Only call getAliasedSymbol if the symbol is actually an alias
|
|
230
|
+
if (objSymbol.flags & typescript_1.default.SymbolFlags.Alias) {
|
|
231
|
+
const aliasedSymbol = this.checker.getAliasedSymbol(objSymbol);
|
|
232
|
+
isImport = aliasedSymbol && aliasedSymbol !== objSymbol;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
158
235
|
const exprType = this.checker.getTypeAtLocation(node.expression.expression);
|
|
159
236
|
const mappedType = this.getType(exprType);
|
|
160
|
-
//
|
|
161
|
-
if (
|
|
162
|
-
//
|
|
237
|
+
// Handle different types
|
|
238
|
+
if (mappedType && mappedType.kind === java_1.Type.Kind.Class) {
|
|
239
|
+
// Update the declaring type with the corrected FQN
|
|
240
|
+
if (isImport && objSymbol) {
|
|
241
|
+
const importName = objSymbol.getName();
|
|
242
|
+
const origFqn = mappedType.fullyQualifiedName;
|
|
243
|
+
const lastDot = origFqn.lastIndexOf('.');
|
|
244
|
+
if (lastDot > 0) {
|
|
245
|
+
const typeName = origFqn.substring(lastDot + 1);
|
|
246
|
+
declaringType = {
|
|
247
|
+
kind: java_1.Type.Kind.Class,
|
|
248
|
+
fullyQualifiedName: `${importName}.${typeName}`
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
declaringType = mappedType;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
declaringType = mappedType;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
// Handle primitive types and other non-class types
|
|
261
|
+
if (mappedType) {
|
|
262
|
+
if (mappedType.keyword === 'String') {
|
|
263
|
+
declaringType = {
|
|
264
|
+
kind: java_1.Type.Kind.Class,
|
|
265
|
+
fullyQualifiedName: 'String'
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
else if (mappedType.keyword === 'Number') {
|
|
269
|
+
declaringType = {
|
|
270
|
+
kind: java_1.Type.Kind.Class,
|
|
271
|
+
fullyQualifiedName: 'Number'
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
// Fallback for other types
|
|
276
|
+
declaringType = mappedType;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
// Default to unknown if we can't determine the type
|
|
281
|
+
declaringType = java_1.Type.unknownType;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// For string methods like 'hello'.split(), ensure we have a proper declaring type for primitives
|
|
285
|
+
if (!isImport && declaringType === java_1.Type.unknownType) {
|
|
286
|
+
// If the expression type is a primitive string, use String as declaring type
|
|
163
287
|
const typeString = this.checker.typeToString(exprType);
|
|
164
288
|
if (typeString === 'string' || exprType.flags & typescript_1.default.TypeFlags.String || exprType.flags & typescript_1.default.TypeFlags.StringLiteral) {
|
|
165
289
|
declaringType = {
|
|
166
290
|
kind: java_1.Type.Kind.Class,
|
|
167
|
-
fullyQualifiedName: '
|
|
291
|
+
fullyQualifiedName: 'string'
|
|
168
292
|
};
|
|
169
293
|
}
|
|
170
294
|
else if (typeString === 'number' || exprType.flags & typescript_1.default.TypeFlags.Number || exprType.flags & typescript_1.default.TypeFlags.NumberLiteral) {
|
|
171
295
|
declaringType = {
|
|
172
296
|
kind: java_1.Type.Kind.Class,
|
|
173
|
-
fullyQualifiedName: '
|
|
297
|
+
fullyQualifiedName: 'number'
|
|
174
298
|
};
|
|
175
299
|
}
|
|
176
300
|
else {
|
|
@@ -178,44 +302,85 @@ class JavaScriptTypeMapping {
|
|
|
178
302
|
declaringType = java_1.Type.unknownType;
|
|
179
303
|
}
|
|
180
304
|
}
|
|
181
|
-
else {
|
|
182
|
-
declaringType = mappedType;
|
|
183
|
-
}
|
|
184
305
|
}
|
|
185
306
|
else if (typescript_1.default.isIdentifier(node.expression)) {
|
|
186
307
|
methodName = node.expression.getText();
|
|
187
|
-
//
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
if (
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if (
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
//
|
|
308
|
+
// Check if this is an import first
|
|
309
|
+
const symbol = this.checker.getSymbolAtLocation(node.expression);
|
|
310
|
+
let moduleSpecifier;
|
|
311
|
+
if (symbol) {
|
|
312
|
+
// Check if this is an aliased symbol (i.e., an import)
|
|
313
|
+
let aliasedSymbol;
|
|
314
|
+
if (symbol.flags & typescript_1.default.SymbolFlags.Alias) {
|
|
315
|
+
aliasedSymbol = this.checker.getAliasedSymbol(symbol);
|
|
316
|
+
}
|
|
317
|
+
// If getAliasedSymbol returns something different, it's an import
|
|
318
|
+
if (aliasedSymbol && aliasedSymbol !== symbol) {
|
|
319
|
+
// This is definitely an imported symbol
|
|
320
|
+
// Now find the import declaration to get the module specifier
|
|
321
|
+
if (symbol.declarations && symbol.declarations.length > 0) {
|
|
322
|
+
let importNode = symbol.declarations[0];
|
|
323
|
+
// Traverse up to find the ImportDeclaration
|
|
324
|
+
while (importNode && !typescript_1.default.isImportDeclaration(importNode)) {
|
|
325
|
+
importNode = importNode.parent;
|
|
326
|
+
}
|
|
327
|
+
if (importNode && typescript_1.default.isImportDeclaration(importNode)) {
|
|
328
|
+
const importDeclNode = importNode;
|
|
329
|
+
if (typescript_1.default.isStringLiteral(importDeclNode.moduleSpecifier)) {
|
|
330
|
+
moduleSpecifier = importDeclNode.moduleSpecifier.text;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (moduleSpecifier) {
|
|
337
|
+
// This is an imported function - use the module specifier as declaring type
|
|
338
|
+
if (moduleSpecifier.startsWith('node:')) {
|
|
339
|
+
// Node.js built-in module
|
|
199
340
|
declaringType = {
|
|
200
341
|
kind: java_1.Type.Kind.Class,
|
|
201
|
-
fullyQualifiedName:
|
|
342
|
+
fullyQualifiedName: 'node'
|
|
202
343
|
};
|
|
344
|
+
methodName = moduleSpecifier.substring(5); // Remove 'node:' prefix
|
|
203
345
|
}
|
|
204
346
|
else {
|
|
205
|
-
//
|
|
206
|
-
|
|
207
|
-
|
|
347
|
+
// Regular module import
|
|
348
|
+
declaringType = {
|
|
349
|
+
kind: java_1.Type.Kind.Class,
|
|
350
|
+
fullyQualifiedName: moduleSpecifier
|
|
351
|
+
};
|
|
352
|
+
methodName = '<default>';
|
|
208
353
|
}
|
|
209
354
|
}
|
|
210
355
|
else {
|
|
211
|
-
//
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
356
|
+
// Fall back to the original logic for non-imported functions
|
|
357
|
+
const exprType = this.checker.getTypeAtLocation(node.expression);
|
|
358
|
+
const funcType = this.getType(exprType);
|
|
359
|
+
if (funcType && funcType.kind === java_1.Type.Kind.Class) {
|
|
360
|
+
const fqn = funcType.fullyQualifiedName;
|
|
361
|
+
const lastDot = fqn.lastIndexOf('.');
|
|
362
|
+
if (lastDot > 0) {
|
|
363
|
+
// For functions from modules, use the module part as declaring type
|
|
364
|
+
declaringType = {
|
|
365
|
+
kind: java_1.Type.Kind.Class,
|
|
366
|
+
fullyQualifiedName: fqn.substring(0, lastDot)
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
// No dots in the name - the type IS the module itself
|
|
371
|
+
declaringType = funcType;
|
|
372
|
+
}
|
|
216
373
|
}
|
|
217
374
|
else {
|
|
218
|
-
|
|
375
|
+
// Try to use the symbol's parent or module
|
|
376
|
+
const parent = symbol.parent;
|
|
377
|
+
if (parent) {
|
|
378
|
+
const parentType = this.checker.getDeclaredTypeOfSymbol(parent);
|
|
379
|
+
declaringType = this.getType(parentType);
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
declaringType = java_1.Type.unknownType;
|
|
383
|
+
}
|
|
219
384
|
}
|
|
220
385
|
}
|
|
221
386
|
}
|
|
@@ -277,140 +442,96 @@ class JavaScriptTypeMapping {
|
|
|
277
442
|
// For other node types, return undefined
|
|
278
443
|
return undefined;
|
|
279
444
|
}
|
|
280
|
-
//
|
|
281
|
-
|
|
282
|
-
const parameters = signature.getParameters();
|
|
283
|
-
const parameterTypes = [];
|
|
284
|
-
const parameterNames = [];
|
|
285
|
-
for (const param of parameters) {
|
|
286
|
-
parameterNames.push(param.getName());
|
|
287
|
-
const paramType = this.checker.getTypeOfSymbolAtLocation(param, node);
|
|
288
|
-
parameterTypes.push(this.getType(paramType));
|
|
289
|
-
}
|
|
290
|
-
// Create the Type.Method object
|
|
291
|
-
return Object.assign(new NonDraftableType(), {
|
|
292
|
-
kind: java_1.Type.Kind.Method,
|
|
293
|
-
declaringType: declaringType,
|
|
294
|
-
name: methodName,
|
|
295
|
-
returnType: this.getType(returnType),
|
|
296
|
-
parameterNames: parameterNames,
|
|
297
|
-
parameterTypes: parameterTypes,
|
|
298
|
-
thrownExceptions: [], // JavaScript doesn't have checked exceptions
|
|
299
|
-
annotations: [],
|
|
300
|
-
defaultValue: undefined,
|
|
301
|
-
declaredFormalTypeNames: declaredFormalTypeNames,
|
|
302
|
-
toJSON: function () {
|
|
303
|
-
return java_1.Type.signature(this);
|
|
304
|
-
}
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Create a JavaType.Array from a TypeScript array type
|
|
309
|
-
*/
|
|
310
|
-
createArrayType(type) {
|
|
311
|
-
// Get the element type (type argument of Array<T>)
|
|
312
|
-
const typeArgs = this.checker.getTypeArguments(type);
|
|
313
|
-
const elemType = typeArgs.length > 0 ? this.getType(typeArgs[0]) : java_1.Type.unknownType;
|
|
314
|
-
return Object.assign(new NonDraftableType(), {
|
|
315
|
-
kind: java_1.Type.Kind.Array,
|
|
316
|
-
elemType: elemType,
|
|
317
|
-
annotations: [],
|
|
318
|
-
toJSON: function () {
|
|
319
|
-
return java_1.Type.signature(this);
|
|
320
|
-
}
|
|
321
|
-
});
|
|
445
|
+
// Create the method type using the helper
|
|
446
|
+
return this.createMethodType(signature, node, declaringType, methodName, declaredFormalTypeNames);
|
|
322
447
|
}
|
|
323
448
|
/**
|
|
324
449
|
* Get the fully qualified name for a TypeScript type.
|
|
325
|
-
*
|
|
450
|
+
* Uses TypeScript's built-in resolution which properly handles things like:
|
|
451
|
+
* - React.Component (not @types/react.Component)
|
|
452
|
+
* - _.LoDashStatic (not @types/lodash.LoDashStatic)
|
|
326
453
|
*/
|
|
327
454
|
getFullyQualifiedName(type) {
|
|
328
|
-
var _b
|
|
455
|
+
var _b;
|
|
329
456
|
const symbol = (_b = type.getSymbol) === null || _b === void 0 ? void 0 : _b.call(type);
|
|
330
457
|
if (!symbol) {
|
|
331
458
|
return "unknown";
|
|
332
459
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
if (
|
|
336
|
-
|
|
337
|
-
if (
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const packageName = this.extractPackageName(fileName);
|
|
357
|
-
if (packageName) {
|
|
358
|
-
// Special handling for @types/node - these are Node.js built-in modules
|
|
359
|
-
// and should be mapped to "node.*" instead of "@types/node.*"
|
|
360
|
-
if (packageName === "@types/node") {
|
|
361
|
-
// Extract the module name from the file path
|
|
362
|
-
// e.g., /node_modules/@types/node/assert.d.ts -> assert
|
|
363
|
-
// e.g., /node_modules/@types/node/fs/promises.d.ts -> fs/promises
|
|
364
|
-
const nodeMatch = fileName.match(/node_modules\/@types\/node\/([^.]+)\.d\.ts/);
|
|
365
|
-
if (nodeMatch) {
|
|
366
|
-
const modulePath = nodeMatch[1];
|
|
367
|
-
// For default exports from Node modules, we want the module to be the "class"
|
|
368
|
-
// But we still need to include the type name for proper identification
|
|
369
|
-
if (typeName === "default" || typeName === modulePath) {
|
|
370
|
-
// This is likely the default export, just use the module name
|
|
371
|
-
return `node.${modulePath}`;
|
|
372
|
-
}
|
|
373
|
-
// For named exports, include both module and type name
|
|
374
|
-
if (modulePath.includes('/')) {
|
|
375
|
-
return `node.${modulePath.replace(/\//g, '.')}.${typeName}`;
|
|
460
|
+
// First, check if this symbol is an import/alias
|
|
461
|
+
// For imported types, we want to use the module specifier instead of the file path
|
|
462
|
+
if (symbol.flags & typescript_1.default.SymbolFlags.Alias) {
|
|
463
|
+
const aliasedSymbol = this.checker.getAliasedSymbol(symbol);
|
|
464
|
+
if (aliasedSymbol && aliasedSymbol !== symbol && symbol.declarations && symbol.declarations.length > 0) {
|
|
465
|
+
// Try to find the import declaration to get the module specifier
|
|
466
|
+
let importNode = symbol.declarations[0];
|
|
467
|
+
// Traverse up to find the ImportDeclaration or ImportSpecifier
|
|
468
|
+
while (importNode && importNode.parent && !typescript_1.default.isImportDeclaration(importNode) && !typescript_1.default.isImportSpecifier(importNode)) {
|
|
469
|
+
importNode = importNode.parent;
|
|
470
|
+
}
|
|
471
|
+
let moduleSpecifier;
|
|
472
|
+
if (importNode && typescript_1.default.isImportSpecifier(importNode)) {
|
|
473
|
+
// Named import like: import { ClipLoader } from 'react-spinners'
|
|
474
|
+
// ImportSpecifier -> NamedImports -> ImportClause -> ImportDeclaration
|
|
475
|
+
const namedImports = importNode.parent; // NamedImports
|
|
476
|
+
if (namedImports && typescript_1.default.isNamedImports(namedImports)) {
|
|
477
|
+
const importClause = namedImports.parent; // ImportClause
|
|
478
|
+
if (importClause && typescript_1.default.isImportClause(importClause)) {
|
|
479
|
+
const importDecl = importClause.parent; // ImportDeclaration
|
|
480
|
+
if (importDecl && typescript_1.default.isImportDeclaration(importDecl) && typescript_1.default.isStringLiteral(importDecl.moduleSpecifier)) {
|
|
481
|
+
moduleSpecifier = importDecl.moduleSpecifier.text;
|
|
482
|
+
}
|
|
376
483
|
}
|
|
377
|
-
return `node.${modulePath}.${typeName}`;
|
|
378
484
|
}
|
|
379
|
-
// Fallback for @types/node types that don't match the pattern
|
|
380
|
-
return `node.${typeName}`;
|
|
381
485
|
}
|
|
382
|
-
|
|
486
|
+
else if (importNode && typescript_1.default.isImportDeclaration(importNode)) {
|
|
487
|
+
// Default or namespace import
|
|
488
|
+
if (typescript_1.default.isStringLiteral(importNode.moduleSpecifier)) {
|
|
489
|
+
moduleSpecifier = importNode.moduleSpecifier.text;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
if (moduleSpecifier) {
|
|
493
|
+
// Build the fully qualified name from module specifier + symbol name
|
|
494
|
+
const symbolName = symbol.getName();
|
|
495
|
+
return `${moduleSpecifier}.${symbolName}`;
|
|
496
|
+
}
|
|
383
497
|
}
|
|
384
498
|
}
|
|
385
|
-
//
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
499
|
+
// Fall back to TypeScript's built-in getFullyQualifiedName
|
|
500
|
+
// This returns names with quotes that we need to clean up
|
|
501
|
+
// e.g., '"React"."Component"' -> 'React.Component'
|
|
502
|
+
const tsQualifiedName = this.checker.getFullyQualifiedName(symbol);
|
|
503
|
+
let cleanedName = tsQualifiedName.replace(/"/g, '');
|
|
504
|
+
// Check if this is a file path from node_modules (happens with some packages)
|
|
505
|
+
// TypeScript sometimes returns full paths instead of module names
|
|
506
|
+
if (cleanedName.includes('node_modules/')) {
|
|
507
|
+
// Extract the module name from the path
|
|
508
|
+
// Example: /private/var/.../node_modules/react-spinners/src/index.ClipLoader
|
|
509
|
+
// Should become: react-spinners.ClipLoader
|
|
510
|
+
const nodeModulesIndex = cleanedName.indexOf('node_modules/');
|
|
511
|
+
const afterNodeModules = cleanedName.substring(nodeModulesIndex + 'node_modules/'.length);
|
|
512
|
+
// Split by '/' to get parts of the path
|
|
513
|
+
const pathParts = afterNodeModules.split('/');
|
|
514
|
+
if (pathParts.length > 0) {
|
|
515
|
+
// First part is the package name (might be scoped like @types)
|
|
516
|
+
let packageName = pathParts[0];
|
|
517
|
+
// Handle scoped packages
|
|
518
|
+
if (packageName.startsWith('@') && pathParts.length > 1) {
|
|
519
|
+
packageName = `${packageName}/${pathParts[1]}`;
|
|
520
|
+
}
|
|
521
|
+
// Find the symbol name (everything after the last dot in the original cleaned name)
|
|
522
|
+
const lastDotIndex = cleanedName.lastIndexOf('.');
|
|
523
|
+
if (lastDotIndex > 0) {
|
|
524
|
+
const symbolName = cleanedName.substring(lastDotIndex + 1);
|
|
525
|
+
cleanedName = `${packageName}.${symbolName}`;
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
cleanedName = packageName;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
408
531
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
relativePath = relativePath.replace(/\\/g, '/');
|
|
413
|
-
return relativePath;
|
|
532
|
+
return cleanedName.endsWith('Constructor') ?
|
|
533
|
+
cleanedName.substring(0, cleanedName.length - 'Constructor'.length) :
|
|
534
|
+
cleanedName;
|
|
414
535
|
}
|
|
415
536
|
/**
|
|
416
537
|
* Create an empty JavaType.Class shell from a TypeScript type.
|
|
@@ -418,42 +539,8 @@ class JavaScriptTypeMapping {
|
|
|
418
539
|
*/
|
|
419
540
|
createEmptyClassType(type) {
|
|
420
541
|
var _b;
|
|
421
|
-
// Use our
|
|
422
|
-
|
|
423
|
-
// If getFullyQualifiedName returned unknown, fall back to TypeScript's method
|
|
424
|
-
if (fullyQualifiedName === "unknown") {
|
|
425
|
-
const symbol = type.symbol;
|
|
426
|
-
fullyQualifiedName = symbol ? this.checker.getFullyQualifiedName(symbol) : `<anonymous>${this.checker.typeToString(type)}`;
|
|
427
|
-
// Fix FQN for types from @types packages
|
|
428
|
-
// TypeScript returns "_.LoDashStatic" but we want "@types/lodash.LoDashStatic"
|
|
429
|
-
if (symbol && symbol.declarations && symbol.declarations.length > 0) {
|
|
430
|
-
const sourceFile = symbol.declarations[0].getSourceFile();
|
|
431
|
-
const fileName = sourceFile.fileName;
|
|
432
|
-
// Check if this is from @types package
|
|
433
|
-
const typesMatch = fileName.match(/node_modules\/@types\/([^/]+)/);
|
|
434
|
-
if (typesMatch) {
|
|
435
|
-
const packageName = typesMatch[1];
|
|
436
|
-
// Special handling for @types/node - use "node" prefix instead
|
|
437
|
-
if (packageName === "node") {
|
|
438
|
-
// Extract the module name from the file path if possible
|
|
439
|
-
const nodeMatch = fileName.match(/node_modules\/@types\/node\/([^.]+)\.d\.ts/);
|
|
440
|
-
if (nodeMatch) {
|
|
441
|
-
const modulePath = nodeMatch[1];
|
|
442
|
-
// Replace the module specifier with node.module
|
|
443
|
-
fullyQualifiedName = fullyQualifiedName.replace(/^[^.]+\./, `node.${modulePath}.`);
|
|
444
|
-
}
|
|
445
|
-
else {
|
|
446
|
-
// Fallback: just use "node" prefix
|
|
447
|
-
fullyQualifiedName = fullyQualifiedName.replace(/^[^.]+\./, `node.`);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
else {
|
|
451
|
-
// Replace the module specifier part with @types/package
|
|
452
|
-
fullyQualifiedName = fullyQualifiedName.replace(/^[^.]+\./, `@types/${packageName}.`);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
}
|
|
542
|
+
// Use our getFullyQualifiedName method which uses TypeScript's built-in resolution
|
|
543
|
+
const fullyQualifiedName = this.getFullyQualifiedName(type);
|
|
457
544
|
// Determine the class kind based on symbol flags
|
|
458
545
|
let classKind = java_1.Type.Class.Kind.Interface; // Default to interface
|
|
459
546
|
const symbol = (_b = type.getSymbol) === null || _b === void 0 ? void 0 : _b.call(type);
|