@effect/language-service 0.28.3 → 0.30.0
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/README.md +6 -0
- package/cli.js +1398 -615
- package/cli.js.map +1 -1
- package/index.js +1779 -1302
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +1398 -619
- package/transform.js.map +1 -1
package/transform.js
CHANGED
|
@@ -745,10 +745,6 @@ var none2 = () => none;
|
|
|
745
745
|
var some2 = some;
|
|
746
746
|
var isNone2 = isNone;
|
|
747
747
|
var isSome2 = isSome;
|
|
748
|
-
var match = /* @__PURE__ */ dual(2, (self, {
|
|
749
|
-
onNone,
|
|
750
|
-
onSome
|
|
751
|
-
}) => isNone2(self) ? onNone() : onSome(self.value));
|
|
752
748
|
var orElse = /* @__PURE__ */ dual(2, (self, that) => isNone2(self) ? that() : self);
|
|
753
749
|
var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nullableValue);
|
|
754
750
|
|
|
@@ -995,7 +991,7 @@ var MatchProto = {
|
|
|
995
991
|
return this[args];
|
|
996
992
|
}
|
|
997
993
|
};
|
|
998
|
-
var
|
|
994
|
+
var match = (fa, opts) => {
|
|
999
995
|
const nano = Object.create(MatchProto);
|
|
1000
996
|
nano[args] = fa;
|
|
1001
997
|
nano[contA] = opts.onSuccess;
|
|
@@ -1018,7 +1014,7 @@ var ProvideServiceProto = {
|
|
|
1018
1014
|
...fiber._services,
|
|
1019
1015
|
[tag.key]: value
|
|
1020
1016
|
};
|
|
1021
|
-
return
|
|
1017
|
+
return match(fa, {
|
|
1022
1018
|
onSuccess: (_) => {
|
|
1023
1019
|
fiber._services = prevServices;
|
|
1024
1020
|
return succeed(_);
|
|
@@ -1061,7 +1057,7 @@ var CachedProto = {
|
|
|
1061
1057
|
fiber._cache[type] = cache;
|
|
1062
1058
|
const cached2 = cache.get(key);
|
|
1063
1059
|
if (cached2) return cached2;
|
|
1064
|
-
return
|
|
1060
|
+
return match(fa, {
|
|
1065
1061
|
onSuccess: (_) => {
|
|
1066
1062
|
cache.set(key, succeed(_));
|
|
1067
1063
|
return succeed(_);
|
|
@@ -1137,44 +1133,50 @@ function parse(config) {
|
|
|
1137
1133
|
var TypeScriptApi = Tag("TypeScriptApi");
|
|
1138
1134
|
var TypeScriptProgram = Tag("TypeScriptProgram");
|
|
1139
1135
|
var ChangeTracker = Tag("ChangeTracker");
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1136
|
+
|
|
1137
|
+
// src/core/TypeScriptUtils.ts
|
|
1138
|
+
var TypeScriptUtils = Tag("TypeScriptUtils");
|
|
1139
|
+
var nanoLayer = (fa) => pipe(
|
|
1140
|
+
service(TypeScriptApi),
|
|
1141
|
+
flatMap2((ts) => pipe(fa, provideService(TypeScriptUtils, makeTypeScriptUtils(ts))))
|
|
1142
|
+
);
|
|
1143
|
+
function makeTypeScriptUtils(ts) {
|
|
1144
|
+
function parsePackageContentNameAndVersionFromScope(v) {
|
|
1145
|
+
if (!isObject(v)) return;
|
|
1146
|
+
if (!hasProperty(v, "packageJsonScope")) return;
|
|
1147
|
+
if (!v.packageJsonScope) return;
|
|
1148
|
+
const packageJsonScope = v.packageJsonScope;
|
|
1149
|
+
if (!hasProperty(packageJsonScope, "contents")) return;
|
|
1150
|
+
if (!hasProperty(packageJsonScope.contents, "packageJsonContent")) return;
|
|
1151
|
+
const packageJsonContent = packageJsonScope.contents.packageJsonContent;
|
|
1152
|
+
if (!hasProperty(packageJsonContent, "name")) return;
|
|
1153
|
+
if (!hasProperty(packageJsonContent, "version")) return;
|
|
1154
|
+
if (!hasProperty(packageJsonScope, "packageDirectory")) return;
|
|
1155
|
+
if (!isString(packageJsonScope.packageDirectory)) return;
|
|
1156
|
+
const { name, version } = packageJsonContent;
|
|
1157
|
+
if (!isString(name)) return;
|
|
1158
|
+
if (!isString(version)) return;
|
|
1159
|
+
const hasEffectInPeerDependencies = hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) && hasProperty(packageJsonContent.peerDependencies, "effect");
|
|
1160
|
+
const referencedPackages = Object.keys({
|
|
1161
|
+
...hasProperty(packageJsonContent, "dependencies") && isObject(packageJsonContent.dependencies) ? packageJsonContent.dependencies : {},
|
|
1162
|
+
...hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) ? packageJsonContent.peerDependencies : {},
|
|
1163
|
+
...hasProperty(packageJsonContent, "devDependencies") && isObject(packageJsonContent.devDependencies) ? packageJsonContent.devDependencies : {}
|
|
1164
|
+
});
|
|
1165
|
+
const exportsKeys = Object.keys(
|
|
1166
|
+
hasProperty(packageJsonContent, "exports") && isObject(packageJsonContent.exports) ? packageJsonContent.exports : {}
|
|
1167
|
+
);
|
|
1168
|
+
return {
|
|
1169
|
+
name: name.toLowerCase(),
|
|
1170
|
+
version: version.toLowerCase(),
|
|
1171
|
+
hasEffectInPeerDependencies,
|
|
1172
|
+
contents: packageJsonContent,
|
|
1173
|
+
packageDirectory: packageJsonScope.packageDirectory,
|
|
1174
|
+
referencedPackages,
|
|
1175
|
+
exportsKeys
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
function resolveModulePattern(sourceFile, pattern) {
|
|
1176
1179
|
if (pattern.indexOf("*") === -1) return [pattern.toLowerCase()];
|
|
1177
|
-
const ts = yield* service(TypeScriptApi);
|
|
1178
1180
|
const packageJsonScope = parsePackageContentNameAndVersionFromScope(sourceFile);
|
|
1179
1181
|
const referencedPackages = [];
|
|
1180
1182
|
for (const statement of sourceFile.statements) {
|
|
@@ -1193,19 +1195,338 @@ var resolveModulePattern = fn("resolveModulePattern")(
|
|
|
1193
1195
|
)
|
|
1194
1196
|
);
|
|
1195
1197
|
}
|
|
1196
|
-
)
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1198
|
+
function makeGetModuleSpecifier() {
|
|
1199
|
+
if (!(hasProperty(ts, "moduleSpecifiers") && hasProperty(ts.moduleSpecifiers, "getModuleSpecifier") && isFunction2(ts.moduleSpecifiers.getModuleSpecifier))) return;
|
|
1200
|
+
const _internal = ts.moduleSpecifiers.getModuleSpecifier;
|
|
1201
|
+
return (compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, options) => {
|
|
1202
|
+
return _internal(
|
|
1203
|
+
compilerOptions,
|
|
1204
|
+
importingSourceFile,
|
|
1205
|
+
importingSourceFileName,
|
|
1206
|
+
toFileName,
|
|
1207
|
+
host,
|
|
1208
|
+
options
|
|
1209
|
+
);
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
function findNodeWithLeadingCommentAtPosition(sourceFile, position) {
|
|
1213
|
+
const sourceText = sourceFile.text;
|
|
1214
|
+
let result;
|
|
1215
|
+
function find(node) {
|
|
1216
|
+
const leading = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
1217
|
+
if (leading) {
|
|
1218
|
+
for (const commentRange of leading) {
|
|
1219
|
+
if (commentRange.pos <= position && position < commentRange.end) {
|
|
1220
|
+
result = { node, commentRange };
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
if (node.getFullStart() <= position && position < node.getEnd()) {
|
|
1226
|
+
node.forEachChild(find);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
find(sourceFile);
|
|
1230
|
+
return result;
|
|
1231
|
+
}
|
|
1232
|
+
function collectSelfAndAncestorNodesInRange(node, textRange) {
|
|
1233
|
+
let result = empty();
|
|
1234
|
+
let parent = node;
|
|
1235
|
+
while (parent) {
|
|
1236
|
+
if (parent.end >= textRange.end) {
|
|
1237
|
+
result = pipe(result, append(parent));
|
|
1238
|
+
}
|
|
1239
|
+
parent = parent.parent;
|
|
1240
|
+
}
|
|
1241
|
+
return result;
|
|
1242
|
+
}
|
|
1243
|
+
function findNodeAtPosition(sourceFile, position) {
|
|
1244
|
+
function find(node) {
|
|
1245
|
+
if (position >= node.getStart() && position < node.getEnd()) {
|
|
1246
|
+
return ts.forEachChild(node, find) || node;
|
|
1247
|
+
}
|
|
1248
|
+
return void 0;
|
|
1249
|
+
}
|
|
1250
|
+
return find(sourceFile);
|
|
1251
|
+
}
|
|
1252
|
+
function findNodeAtPositionIncludingTrivia(sourceFile, position) {
|
|
1253
|
+
function find(node) {
|
|
1254
|
+
if (position >= node.pos && position < node.end) {
|
|
1255
|
+
return ts.forEachChild(node, find) || node;
|
|
1256
|
+
}
|
|
1257
|
+
return void 0;
|
|
1258
|
+
}
|
|
1259
|
+
return find(sourceFile);
|
|
1260
|
+
}
|
|
1261
|
+
function getAncestorNodesInRange(sourceFile, textRange) {
|
|
1262
|
+
const nodeAtPosition = findNodeAtPosition(sourceFile, textRange.pos);
|
|
1263
|
+
if (!nodeAtPosition) return empty();
|
|
1264
|
+
return collectSelfAndAncestorNodesInRange(nodeAtPosition, textRange);
|
|
1265
|
+
}
|
|
1266
|
+
function getCommentAtPosition(sourceFile, pos) {
|
|
1267
|
+
const token = findNodeAtPositionIncludingTrivia(sourceFile, pos);
|
|
1268
|
+
if (token === void 0 || token.kind === ts.SyntaxKind.JsxText || pos >= token.end - (ts.tokenToString(token.kind) || "").length) {
|
|
1269
|
+
return;
|
|
1270
|
+
}
|
|
1271
|
+
const startPos = token.pos === 0 ? (ts.getShebang(sourceFile.text) || "").length : token.pos;
|
|
1272
|
+
if (startPos === 0) return;
|
|
1273
|
+
const result = ts.forEachTrailingCommentRange(sourceFile.text, startPos, isCommentInRange, pos) || ts.forEachLeadingCommentRange(sourceFile.text, startPos, isCommentInRange, pos);
|
|
1274
|
+
return result;
|
|
1275
|
+
}
|
|
1276
|
+
function isCommentInRange(pos, end, kind, _nl, at) {
|
|
1277
|
+
return at >= pos && at < end ? { pos, end, kind } : void 0;
|
|
1278
|
+
}
|
|
1279
|
+
function toTextRange(positionOrRange) {
|
|
1280
|
+
return typeof positionOrRange === "number" ? { end: positionOrRange, pos: positionOrRange } : positionOrRange;
|
|
1281
|
+
}
|
|
1282
|
+
function isNodeInRange(textRange) {
|
|
1283
|
+
return (node) => node.pos <= textRange.pos && node.end >= textRange.end;
|
|
1284
|
+
}
|
|
1285
|
+
function transformAsyncAwaitToEffectGen(node, effectModuleName, onAwait) {
|
|
1286
|
+
function visitor(_) {
|
|
1287
|
+
if (ts.isAwaitExpression(_)) {
|
|
1288
|
+
const expression = ts.visitEachChild(_.expression, visitor, ts.nullTransformationContext);
|
|
1289
|
+
return ts.factory.createYieldExpression(
|
|
1290
|
+
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
1291
|
+
onAwait(expression)
|
|
1292
|
+
);
|
|
1293
|
+
}
|
|
1294
|
+
return ts.visitEachChild(_, visitor, ts.nullTransformationContext);
|
|
1295
|
+
}
|
|
1296
|
+
const generatorBody = visitor(node.body);
|
|
1297
|
+
const effectGenCallExp = createEffectGenCallExpression(effectModuleName, generatorBody);
|
|
1298
|
+
let currentFlags = ts.getCombinedModifierFlags(node);
|
|
1299
|
+
currentFlags &= ~ts.ModifierFlags.Async;
|
|
1300
|
+
const newModifiers = ts.factory.createModifiersFromModifierFlags(currentFlags);
|
|
1301
|
+
if (ts.isArrowFunction(node)) {
|
|
1302
|
+
return ts.factory.createArrowFunction(
|
|
1303
|
+
newModifiers,
|
|
1304
|
+
node.typeParameters,
|
|
1305
|
+
node.parameters,
|
|
1306
|
+
void 0,
|
|
1307
|
+
node.equalsGreaterThanToken,
|
|
1308
|
+
effectGenCallExp
|
|
1309
|
+
);
|
|
1310
|
+
}
|
|
1311
|
+
const newBody = ts.factory.createBlock([
|
|
1312
|
+
ts.factory.createReturnStatement(effectGenCallExp)
|
|
1313
|
+
]);
|
|
1314
|
+
if (ts.isFunctionDeclaration(node)) {
|
|
1315
|
+
return ts.factory.createFunctionDeclaration(
|
|
1316
|
+
newModifiers,
|
|
1317
|
+
node.asteriskToken,
|
|
1318
|
+
node.name,
|
|
1319
|
+
node.typeParameters,
|
|
1320
|
+
node.parameters,
|
|
1321
|
+
void 0,
|
|
1322
|
+
newBody
|
|
1323
|
+
);
|
|
1324
|
+
}
|
|
1325
|
+
return ts.factory.createFunctionExpression(
|
|
1326
|
+
newModifiers,
|
|
1327
|
+
node.asteriskToken,
|
|
1328
|
+
node.name,
|
|
1329
|
+
node.typeParameters,
|
|
1330
|
+
node.parameters,
|
|
1331
|
+
void 0,
|
|
1332
|
+
newBody
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
function findImportedModuleIdentifier(sourceFile, test) {
|
|
1336
|
+
for (const statement of sourceFile.statements) {
|
|
1337
|
+
if (!ts.isImportDeclaration(statement)) continue;
|
|
1338
|
+
const importClause = statement.importClause;
|
|
1339
|
+
if (!importClause) continue;
|
|
1340
|
+
const namedBindings = importClause.namedBindings;
|
|
1341
|
+
if (!namedBindings) continue;
|
|
1342
|
+
if (ts.isNamespaceImport(namedBindings)) {
|
|
1343
|
+
if (test(namedBindings.name, statement.moduleSpecifier, none2())) {
|
|
1344
|
+
return namedBindings.name.text;
|
|
1345
|
+
}
|
|
1346
|
+
} else if (ts.isNamedImports(namedBindings)) {
|
|
1347
|
+
for (const importSpecifier of namedBindings.elements) {
|
|
1348
|
+
const importProperty = fromNullable(importSpecifier.propertyName).pipe(
|
|
1349
|
+
orElse(() => some2(importSpecifier.name))
|
|
1350
|
+
);
|
|
1351
|
+
if (test(importSpecifier.name, statement.moduleSpecifier, importProperty)) {
|
|
1352
|
+
return importSpecifier.name.text;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
function findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, packageName, moduleName) {
|
|
1359
|
+
return findImportedModuleIdentifier(
|
|
1360
|
+
sourceFile,
|
|
1361
|
+
(_, fromModule, importProperty) => {
|
|
1362
|
+
if (isNone2(importProperty) && ts.isStringLiteral(fromModule) && fromModule.text === packageName + "/" + moduleName) {
|
|
1363
|
+
return true;
|
|
1364
|
+
}
|
|
1365
|
+
if (isSome2(importProperty) && ts.isIdentifier(importProperty.value) && importProperty.value.text === moduleName && ts.isStringLiteral(fromModule) && fromModule.text === packageName) {
|
|
1366
|
+
return true;
|
|
1367
|
+
}
|
|
1368
|
+
return false;
|
|
1369
|
+
}
|
|
1208
1370
|
);
|
|
1371
|
+
}
|
|
1372
|
+
function simplifyTypeNode(typeNode) {
|
|
1373
|
+
function collectCallable(typeNode2) {
|
|
1374
|
+
if (ts.isParenthesizedTypeNode(typeNode2)) return collectCallable(typeNode2.type);
|
|
1375
|
+
if (ts.isFunctionTypeNode(typeNode2)) {
|
|
1376
|
+
return some2([
|
|
1377
|
+
ts.factory.createCallSignature(typeNode2.typeParameters, typeNode2.parameters, typeNode2.type)
|
|
1378
|
+
]);
|
|
1379
|
+
}
|
|
1380
|
+
if (ts.isTypeLiteralNode(typeNode2)) {
|
|
1381
|
+
const allCallSignatures = typeNode2.members.every(ts.isCallSignatureDeclaration);
|
|
1382
|
+
if (allCallSignatures) {
|
|
1383
|
+
return some2(typeNode2.members);
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
if (ts.isIntersectionTypeNode(typeNode2)) {
|
|
1387
|
+
const members = typeNode2.types.map((node) => collectCallable(node));
|
|
1388
|
+
if (members.every(isSome2)) {
|
|
1389
|
+
return some2(members.map((_) => isSome2(_) ? _.value : []).flat());
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
return none2();
|
|
1393
|
+
}
|
|
1394
|
+
const callSignatures = collectCallable(typeNode);
|
|
1395
|
+
if (isSome2(callSignatures) && callSignatures.value.length > 1) {
|
|
1396
|
+
return ts.factory.createTypeLiteralNode(callSignatures.value);
|
|
1397
|
+
}
|
|
1398
|
+
return typeNode;
|
|
1399
|
+
}
|
|
1400
|
+
function tryPreserveDeclarationSemantics(nodeToReplace, node) {
|
|
1401
|
+
if (!ts.isExpression(node)) return node;
|
|
1402
|
+
if (ts.isFunctionDeclaration(nodeToReplace)) {
|
|
1403
|
+
if (!nodeToReplace.name) return node;
|
|
1404
|
+
return ts.factory.createVariableStatement(
|
|
1405
|
+
nodeToReplace.modifiers,
|
|
1406
|
+
ts.factory.createVariableDeclarationList(
|
|
1407
|
+
[ts.factory.createVariableDeclaration(
|
|
1408
|
+
nodeToReplace.name,
|
|
1409
|
+
void 0,
|
|
1410
|
+
void 0,
|
|
1411
|
+
node
|
|
1412
|
+
)],
|
|
1413
|
+
ts.NodeFlags.Const
|
|
1414
|
+
)
|
|
1415
|
+
);
|
|
1416
|
+
} else if (ts.isMethodDeclaration(nodeToReplace)) {
|
|
1417
|
+
return ts.factory.createPropertyDeclaration(
|
|
1418
|
+
nodeToReplace.modifiers,
|
|
1419
|
+
nodeToReplace.name,
|
|
1420
|
+
void 0,
|
|
1421
|
+
void 0,
|
|
1422
|
+
node
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
return node;
|
|
1426
|
+
}
|
|
1427
|
+
function parseAccessedExpressionForCompletion(sourceFile, position) {
|
|
1428
|
+
const precedingToken = ts.findPrecedingToken(position, sourceFile, void 0, true);
|
|
1429
|
+
if (!precedingToken) return;
|
|
1430
|
+
let accessedObject = precedingToken;
|
|
1431
|
+
let replacementSpan = ts.createTextSpan(position, 0);
|
|
1432
|
+
let outerNode = precedingToken;
|
|
1433
|
+
if (ts.isIdentifier(precedingToken) && precedingToken.parent && ts.isPropertyAccessExpression(precedingToken.parent)) {
|
|
1434
|
+
replacementSpan = ts.createTextSpan(
|
|
1435
|
+
precedingToken.parent.getStart(sourceFile),
|
|
1436
|
+
precedingToken.end - precedingToken.parent.getStart(sourceFile)
|
|
1437
|
+
);
|
|
1438
|
+
accessedObject = precedingToken.parent.expression;
|
|
1439
|
+
outerNode = precedingToken.parent;
|
|
1440
|
+
} else if (ts.isToken(precedingToken) && precedingToken.kind === ts.SyntaxKind.DotToken && ts.isPropertyAccessExpression(precedingToken.parent)) {
|
|
1441
|
+
replacementSpan = ts.createTextSpan(
|
|
1442
|
+
precedingToken.parent.getStart(sourceFile),
|
|
1443
|
+
precedingToken.end - precedingToken.parent.getStart(sourceFile)
|
|
1444
|
+
);
|
|
1445
|
+
accessedObject = precedingToken.parent.expression;
|
|
1446
|
+
outerNode = precedingToken.parent;
|
|
1447
|
+
} else if (ts.isIdentifier(precedingToken) && precedingToken.parent) {
|
|
1448
|
+
replacementSpan = ts.createTextSpan(
|
|
1449
|
+
precedingToken.getStart(sourceFile),
|
|
1450
|
+
precedingToken.end - precedingToken.getStart(sourceFile)
|
|
1451
|
+
);
|
|
1452
|
+
accessedObject = precedingToken;
|
|
1453
|
+
outerNode = precedingToken;
|
|
1454
|
+
} else {
|
|
1455
|
+
return;
|
|
1456
|
+
}
|
|
1457
|
+
return { accessedObject, outerNode, replacementSpan };
|
|
1458
|
+
}
|
|
1459
|
+
function parseDataForExtendsClassCompletion(sourceFile, position) {
|
|
1460
|
+
const maybeInfos = parseAccessedExpressionForCompletion(sourceFile, position);
|
|
1461
|
+
if (!maybeInfos) return;
|
|
1462
|
+
const { accessedObject, outerNode, replacementSpan } = maybeInfos;
|
|
1463
|
+
if (!ts.isIdentifier(accessedObject)) return;
|
|
1464
|
+
let classDeclaration = outerNode.parent;
|
|
1465
|
+
while (ts.isExpressionWithTypeArguments(classDeclaration) || ts.isHeritageClause(classDeclaration)) {
|
|
1466
|
+
if (!classDeclaration.parent) break;
|
|
1467
|
+
classDeclaration = classDeclaration.parent;
|
|
1468
|
+
}
|
|
1469
|
+
if (!ts.isClassDeclaration(classDeclaration)) return;
|
|
1470
|
+
if (!classDeclaration.name) return;
|
|
1471
|
+
return {
|
|
1472
|
+
accessedObject,
|
|
1473
|
+
classDeclaration,
|
|
1474
|
+
className: classDeclaration.name,
|
|
1475
|
+
replacementSpan
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1478
|
+
function createEffectGenCallExpression(effectModuleIdentifierName, node) {
|
|
1479
|
+
const generator = ts.factory.createFunctionExpression(
|
|
1480
|
+
void 0,
|
|
1481
|
+
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
1482
|
+
void 0,
|
|
1483
|
+
[],
|
|
1484
|
+
[],
|
|
1485
|
+
void 0,
|
|
1486
|
+
node
|
|
1487
|
+
// NOTE(mattia): intended, to use same routine for both ConciseBody and Body
|
|
1488
|
+
);
|
|
1489
|
+
return ts.factory.createCallExpression(
|
|
1490
|
+
ts.factory.createPropertyAccessExpression(
|
|
1491
|
+
ts.factory.createIdentifier(effectModuleIdentifierName),
|
|
1492
|
+
"gen"
|
|
1493
|
+
),
|
|
1494
|
+
void 0,
|
|
1495
|
+
[generator]
|
|
1496
|
+
);
|
|
1497
|
+
}
|
|
1498
|
+
function createEffectGenCallExpressionWithBlock(effectModuleIdentifierName, statement) {
|
|
1499
|
+
return createEffectGenCallExpression(
|
|
1500
|
+
effectModuleIdentifierName,
|
|
1501
|
+
ts.factory.createBlock(isArray(statement) ? statement : [statement], false)
|
|
1502
|
+
);
|
|
1503
|
+
}
|
|
1504
|
+
function createReturnYieldStarStatement(expr) {
|
|
1505
|
+
return ts.factory.createReturnStatement(
|
|
1506
|
+
ts.factory.createYieldExpression(
|
|
1507
|
+
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
1508
|
+
expr
|
|
1509
|
+
)
|
|
1510
|
+
);
|
|
1511
|
+
}
|
|
1512
|
+
return {
|
|
1513
|
+
findNodeAtPositionIncludingTrivia,
|
|
1514
|
+
parsePackageContentNameAndVersionFromScope,
|
|
1515
|
+
resolveModulePattern,
|
|
1516
|
+
findNodeWithLeadingCommentAtPosition,
|
|
1517
|
+
getCommentAtPosition,
|
|
1518
|
+
getAncestorNodesInRange,
|
|
1519
|
+
toTextRange,
|
|
1520
|
+
isNodeInRange,
|
|
1521
|
+
transformAsyncAwaitToEffectGen,
|
|
1522
|
+
findImportedModuleIdentifierByPackageAndNameOrBarrel,
|
|
1523
|
+
simplifyTypeNode,
|
|
1524
|
+
tryPreserveDeclarationSemantics,
|
|
1525
|
+
parseDataForExtendsClassCompletion,
|
|
1526
|
+
createEffectGenCallExpressionWithBlock,
|
|
1527
|
+
createReturnYieldStarStatement,
|
|
1528
|
+
makeGetModuleSpecifier,
|
|
1529
|
+
parseAccessedExpressionForCompletion
|
|
1209
1530
|
};
|
|
1210
1531
|
}
|
|
1211
1532
|
|
|
@@ -1213,6 +1534,9 @@ function makeGetModuleSpecifier(ts) {
|
|
|
1213
1534
|
var RefactorNotApplicableError = class {
|
|
1214
1535
|
_tag = "@effect/language-service/RefactorNotApplicableError";
|
|
1215
1536
|
};
|
|
1537
|
+
function createRefactor(definition) {
|
|
1538
|
+
return definition;
|
|
1539
|
+
}
|
|
1216
1540
|
function createDiagnostic(definition) {
|
|
1217
1541
|
return definition;
|
|
1218
1542
|
}
|
|
@@ -1275,27 +1599,8 @@ var getCompletionsAtPosition = fn("LSP.getCompletionsAtPosition")(function* (com
|
|
|
1275
1599
|
var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
1276
1600
|
function* (sourceFile) {
|
|
1277
1601
|
const ts = yield* service(TypeScriptApi);
|
|
1602
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
1278
1603
|
const pluginOptions = yield* service(LanguageServicePluginOptions);
|
|
1279
|
-
function findNodeWithLeadingCommentAtPosition(position) {
|
|
1280
|
-
const sourceText = sourceFile.text;
|
|
1281
|
-
let result;
|
|
1282
|
-
function find(node) {
|
|
1283
|
-
const leading = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
1284
|
-
if (leading) {
|
|
1285
|
-
for (const r of leading) {
|
|
1286
|
-
if (r.pos <= position && position < r.end) {
|
|
1287
|
-
result = node;
|
|
1288
|
-
return;
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
if (node.getFullStart() <= position && position < node.getEnd()) {
|
|
1293
|
-
node.forEachChild(find);
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
|
-
find(sourceFile);
|
|
1297
|
-
return result;
|
|
1298
|
-
}
|
|
1299
1604
|
function findParentStatementForDisableNextLine(node) {
|
|
1300
1605
|
let result;
|
|
1301
1606
|
function find(node2) {
|
|
@@ -1313,10 +1618,10 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1313
1618
|
const sectionOverrides = {};
|
|
1314
1619
|
const skippedRules = [];
|
|
1315
1620
|
const regex = /@effect-diagnostics(-next-line)?((?:\s[a-zA-Z0-9/]+:(?:off|warning|error|message|suggestion|skip-file))+)?/gm;
|
|
1316
|
-
let
|
|
1317
|
-
while ((
|
|
1318
|
-
const nextLineCaptureGroup =
|
|
1319
|
-
const rulesCaptureGroup =
|
|
1621
|
+
let match2;
|
|
1622
|
+
while ((match2 = regex.exec(sourceFile.text)) !== null) {
|
|
1623
|
+
const nextLineCaptureGroup = match2[1];
|
|
1624
|
+
const rulesCaptureGroup = match2[2];
|
|
1320
1625
|
if (rulesCaptureGroup) {
|
|
1321
1626
|
const trimmedRuleString = rulesCaptureGroup.trim();
|
|
1322
1627
|
if (trimmedRuleString) {
|
|
@@ -1328,19 +1633,19 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1328
1633
|
if (ruleLevel === "skip-file") skippedRules.push(ruleName);
|
|
1329
1634
|
const isOverrideNextLine = nextLineCaptureGroup && nextLineCaptureGroup.trim().toLowerCase() === "-next-line";
|
|
1330
1635
|
if (isOverrideNextLine) {
|
|
1331
|
-
const
|
|
1332
|
-
if (
|
|
1636
|
+
const foundNode = tsUtils.findNodeWithLeadingCommentAtPosition(sourceFile, match2.index);
|
|
1637
|
+
if (foundNode) {
|
|
1333
1638
|
lineOverrides[ruleName] = lineOverrides[ruleName] || [];
|
|
1334
1639
|
lineOverrides[ruleName].unshift({
|
|
1335
|
-
pos: node.getFullStart(),
|
|
1336
|
-
end: node.end,
|
|
1640
|
+
pos: foundNode.node.getFullStart(),
|
|
1641
|
+
end: foundNode.node.end,
|
|
1337
1642
|
level: ruleLevel
|
|
1338
1643
|
});
|
|
1339
1644
|
}
|
|
1340
1645
|
} else {
|
|
1341
1646
|
sectionOverrides[ruleName] = sectionOverrides[ruleName] || [];
|
|
1342
1647
|
sectionOverrides[ruleName].unshift({
|
|
1343
|
-
pos:
|
|
1648
|
+
pos: match2.index,
|
|
1344
1649
|
level: ruleLevel
|
|
1345
1650
|
});
|
|
1346
1651
|
}
|
|
@@ -1355,7 +1660,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1355
1660
|
message: ts.DiagnosticCategory.Message,
|
|
1356
1661
|
suggestion: ts.DiagnosticCategory.Suggestion
|
|
1357
1662
|
};
|
|
1358
|
-
const execute =
|
|
1663
|
+
const execute = (rule) => gen(function* () {
|
|
1359
1664
|
const diagnostics2 = [];
|
|
1360
1665
|
const codeFixes = [];
|
|
1361
1666
|
const ruleNameLowered = rule.name.toLowerCase();
|
|
@@ -1364,13 +1669,13 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1364
1669
|
if (defaultLevel === "off" && (lineOverrides[ruleNameLowered] || sectionOverrides[ruleNameLowered] || []).length === 0) {
|
|
1365
1670
|
return { diagnostics: diagnostics2, codeFixes };
|
|
1366
1671
|
}
|
|
1367
|
-
const fixByDisableNextLine = (
|
|
1672
|
+
const fixByDisableNextLine = (node) => ({
|
|
1368
1673
|
fixName: rule.name + "_skipNextLine",
|
|
1369
1674
|
description: "Disable " + rule.name + " for this line",
|
|
1370
1675
|
apply: flatMap2(
|
|
1371
1676
|
service(ChangeTracker),
|
|
1372
|
-
(changeTracker) =>
|
|
1373
|
-
const disableAtNode = findParentStatementForDisableNextLine(
|
|
1677
|
+
(changeTracker) => gen(function* () {
|
|
1678
|
+
const disableAtNode = findParentStatementForDisableNextLine(node);
|
|
1374
1679
|
const { line } = ts.getLineAndCharacterOfPosition(sourceFile, disableAtNode.getStart());
|
|
1375
1680
|
changeTracker.insertCommentBeforeLine(
|
|
1376
1681
|
sourceFile,
|
|
@@ -1398,29 +1703,30 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1398
1703
|
};
|
|
1399
1704
|
const applicableDiagnostics = [];
|
|
1400
1705
|
yield* rule.apply(sourceFile, (entry) => {
|
|
1706
|
+
const range = "getEnd" in entry.location ? { pos: entry.location.getStart(sourceFile), end: entry.location.getEnd() } : entry.location;
|
|
1707
|
+
const node = "getEnd" in entry.location ? entry.location : tsUtils.findNodeAtPositionIncludingTrivia(sourceFile, entry.location.pos);
|
|
1401
1708
|
applicableDiagnostics.push({
|
|
1402
|
-
|
|
1403
|
-
|
|
1709
|
+
range,
|
|
1710
|
+
messageText: entry.messageText,
|
|
1711
|
+
fixes: entry.fixes.concat(node ? [fixByDisableNextLine(node)] : []).concat([fixByDisableEntireFile])
|
|
1404
1712
|
});
|
|
1405
1713
|
});
|
|
1406
1714
|
for (const emitted of applicableDiagnostics.slice(0)) {
|
|
1407
1715
|
let newLevel = defaultLevel;
|
|
1408
1716
|
const lineOverride = (lineOverrides[ruleNameLowered] || []).find(
|
|
1409
|
-
(_) => _.pos < emitted.
|
|
1717
|
+
(_) => _.pos < emitted.range.pos && _.end >= emitted.range.end
|
|
1410
1718
|
);
|
|
1411
1719
|
if (lineOverride) {
|
|
1412
1720
|
newLevel = lineOverride.level;
|
|
1413
1721
|
} else {
|
|
1414
|
-
const sectionOverride = (sectionOverrides[ruleNameLowered] || []).find(
|
|
1415
|
-
(_) => _.pos < emitted.node.getStart(sourceFile)
|
|
1416
|
-
);
|
|
1722
|
+
const sectionOverride = (sectionOverrides[ruleNameLowered] || []).find((_) => _.pos < emitted.range.pos);
|
|
1417
1723
|
if (sectionOverride) newLevel = sectionOverride.level;
|
|
1418
1724
|
}
|
|
1419
1725
|
if (!(newLevel in levelToDiagnosticCategory)) continue;
|
|
1420
1726
|
diagnostics2.push({
|
|
1421
1727
|
file: sourceFile,
|
|
1422
|
-
start: emitted.
|
|
1423
|
-
length: emitted.
|
|
1728
|
+
start: emitted.range.pos,
|
|
1729
|
+
length: emitted.range.end - emitted.range.pos,
|
|
1424
1730
|
messageText: emitted.messageText,
|
|
1425
1731
|
category: levelToDiagnosticCategory[newLevel],
|
|
1426
1732
|
code: rule.code,
|
|
@@ -1430,8 +1736,8 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1430
1736
|
codeFixes.push({
|
|
1431
1737
|
...fix,
|
|
1432
1738
|
code: rule.code,
|
|
1433
|
-
start: emitted.
|
|
1434
|
-
end: emitted.
|
|
1739
|
+
start: emitted.range.pos,
|
|
1740
|
+
end: emitted.range.end
|
|
1435
1741
|
});
|
|
1436
1742
|
}
|
|
1437
1743
|
}
|
|
@@ -1440,15 +1746,85 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1440
1746
|
return { execute };
|
|
1441
1747
|
}
|
|
1442
1748
|
);
|
|
1749
|
+
var cyrb53 = (str, seed = 0) => {
|
|
1750
|
+
let h1 = 3735928559 ^ seed, h2 = 1103547991 ^ seed;
|
|
1751
|
+
for (let i = 0, ch; i < str.length; i++) {
|
|
1752
|
+
ch = str.charCodeAt(i);
|
|
1753
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
1754
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
1755
|
+
}
|
|
1756
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507);
|
|
1757
|
+
h1 ^= Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
1758
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507);
|
|
1759
|
+
h2 ^= Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
1760
|
+
return (h2 >>> 0).toString(16).padStart(8, "0") + (h1 >>> 0).toString(16).padStart(8, "0");
|
|
1761
|
+
};
|
|
1762
|
+
var CodegenNotApplicableError = class {
|
|
1763
|
+
constructor(cause) {
|
|
1764
|
+
this.cause = cause;
|
|
1765
|
+
}
|
|
1766
|
+
_tag = "@effect/language-service/CodegenNotApplicableError";
|
|
1767
|
+
};
|
|
1768
|
+
function createCodegen(definition) {
|
|
1769
|
+
return definition;
|
|
1770
|
+
}
|
|
1771
|
+
var getCodegensForSourceFile = fn("LSP.getApplicableCodegens")(function* (codegens2, sourceFile) {
|
|
1772
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
1773
|
+
const result = [];
|
|
1774
|
+
const regex = /@effect-codegens((?:\s[a-zA-Z0-9]+(?::(?:[a-zA-Z0-9]+))?)+)+/gmid;
|
|
1775
|
+
let match2;
|
|
1776
|
+
while ((match2 = regex.exec(sourceFile.text)) !== null) {
|
|
1777
|
+
const pos = match2.indices?.[0]?.[0];
|
|
1778
|
+
if (!pos) continue;
|
|
1779
|
+
const commentRange = tsUtils.getCommentAtPosition(sourceFile, pos);
|
|
1780
|
+
if (!commentRange) continue;
|
|
1781
|
+
const commentText = sourceFile.text.slice(pos, commentRange.end);
|
|
1782
|
+
const codegenRegex = /(\s+)(\w+)(?::(\w+))?/gmi;
|
|
1783
|
+
let codegenMatch;
|
|
1784
|
+
while ((codegenMatch = codegenRegex.exec(commentText)) !== null) {
|
|
1785
|
+
const whitespace = codegenMatch[1] || "";
|
|
1786
|
+
const codegenName = codegenMatch[2] || "";
|
|
1787
|
+
const codegenHash = codegenMatch[3] || "";
|
|
1788
|
+
const range = {
|
|
1789
|
+
pos: codegenMatch.index + pos + whitespace.length,
|
|
1790
|
+
end: codegenMatch.index + pos + codegenMatch[0].length
|
|
1791
|
+
};
|
|
1792
|
+
const codegen = codegens2.find((codegen2) => codegen2.name === codegenName);
|
|
1793
|
+
if (!codegen) continue;
|
|
1794
|
+
result.push({ codegen, hash: codegenHash, range });
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
return result;
|
|
1798
|
+
});
|
|
1799
|
+
var getEditsForCodegen = fn("LSP.getEditsForCodegen")(function* (codegens2, sourceFile, textRange) {
|
|
1800
|
+
const applicableCodegens = yield* getCodegensForSourceFile(codegens2, sourceFile);
|
|
1801
|
+
const inRangeCodegens = applicableCodegens.filter(
|
|
1802
|
+
(codegen2) => codegen2.range.pos <= textRange.pos && codegen2.range.end >= textRange.end
|
|
1803
|
+
);
|
|
1804
|
+
if (inRangeCodegens.length !== 1) {
|
|
1805
|
+
return yield* fail(new CodegenNotApplicableError("zero or multiple codegens in range"));
|
|
1806
|
+
}
|
|
1807
|
+
const { codegen, range } = inRangeCodegens[0];
|
|
1808
|
+
const edit = yield* codegen.apply(sourceFile, range);
|
|
1809
|
+
const updateHashComment = pipe(
|
|
1810
|
+
service(ChangeTracker),
|
|
1811
|
+
map3((changeTracker) => {
|
|
1812
|
+
changeTracker.deleteRange(sourceFile, range);
|
|
1813
|
+
changeTracker.insertText(sourceFile, range.pos, `${codegen.name}:${edit.hash}`);
|
|
1814
|
+
})
|
|
1815
|
+
);
|
|
1816
|
+
return {
|
|
1817
|
+
...edit,
|
|
1818
|
+
apply: pipe(
|
|
1819
|
+
edit.apply,
|
|
1820
|
+
flatMap2(() => updateHashComment)
|
|
1821
|
+
),
|
|
1822
|
+
ignore: updateHashComment
|
|
1823
|
+
};
|
|
1824
|
+
});
|
|
1443
1825
|
|
|
1444
1826
|
// src/core/TypeCheckerApi.ts
|
|
1445
1827
|
var TypeCheckerApi = Tag("TypeChecker");
|
|
1446
|
-
var TypeCheckerApiCache = Tag("TypeCheckerApiCache");
|
|
1447
|
-
function makeTypeCheckerApiCache() {
|
|
1448
|
-
return {
|
|
1449
|
-
expectedAndRealType: /* @__PURE__ */ new WeakMap()
|
|
1450
|
-
};
|
|
1451
|
-
}
|
|
1452
1828
|
var deterministicTypeOrder = gen(function* () {
|
|
1453
1829
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
1454
1830
|
return make((a, b) => {
|
|
@@ -1547,106 +1923,106 @@ var getInferredReturnType = fn("TypeCheckerApi.getInferredReturnType")(function*
|
|
|
1547
1923
|
}
|
|
1548
1924
|
return returnType;
|
|
1549
1925
|
});
|
|
1550
|
-
var expectedAndRealType =
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
ts.
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
result.push([node, expectedType, node, realType]);
|
|
1926
|
+
var expectedAndRealType = cachedBy(
|
|
1927
|
+
fn("TypeCheckerApi.expectedAndRealType")(function* (sourceFile) {
|
|
1928
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
1929
|
+
const ts = yield* service(TypeScriptApi);
|
|
1930
|
+
const result = [];
|
|
1931
|
+
const nodeToVisit = [sourceFile];
|
|
1932
|
+
const appendNodeToVisit = (node) => {
|
|
1933
|
+
nodeToVisit.push(node);
|
|
1934
|
+
return void 0;
|
|
1935
|
+
};
|
|
1936
|
+
while (nodeToVisit.length > 0) {
|
|
1937
|
+
const node = nodeToVisit.shift();
|
|
1938
|
+
if (ts.isVariableDeclaration(node) && node.initializer) {
|
|
1939
|
+
const expectedType = typeChecker.getTypeAtLocation(node.name);
|
|
1940
|
+
const realType = typeChecker.getTypeAtLocation(node.initializer);
|
|
1941
|
+
result.push([node.name, expectedType, node.initializer, realType]);
|
|
1942
|
+
appendNodeToVisit(node.initializer);
|
|
1943
|
+
continue;
|
|
1944
|
+
} else if (ts.isCallExpression(node)) {
|
|
1945
|
+
const resolvedSignature = typeChecker.getResolvedSignature(node);
|
|
1946
|
+
if (resolvedSignature) {
|
|
1947
|
+
resolvedSignature.getParameters().map((parameter, index) => {
|
|
1948
|
+
const expectedType = typeChecker.getTypeOfSymbolAtLocation(parameter, node);
|
|
1949
|
+
const realType = typeChecker.getTypeAtLocation(node.arguments[index]);
|
|
1950
|
+
result.push([
|
|
1951
|
+
node.arguments[index],
|
|
1952
|
+
expectedType,
|
|
1953
|
+
node.arguments[index],
|
|
1954
|
+
realType
|
|
1955
|
+
]);
|
|
1956
|
+
});
|
|
1957
|
+
}
|
|
1958
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
1959
|
+
continue;
|
|
1960
|
+
} else if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
|
|
1961
|
+
const parent = node.parent;
|
|
1962
|
+
if (ts.isObjectLiteralElement(parent)) {
|
|
1963
|
+
if (ts.isObjectLiteralExpression(parent.parent) && parent.name === node) {
|
|
1964
|
+
const type = typeChecker.getContextualType(parent.parent);
|
|
1965
|
+
if (type) {
|
|
1966
|
+
const symbol3 = typeChecker.getPropertyOfType(type, node.text);
|
|
1967
|
+
if (symbol3) {
|
|
1968
|
+
const expectedType = typeChecker.getTypeOfSymbolAtLocation(symbol3, node);
|
|
1969
|
+
const realType = typeChecker.getTypeAtLocation(node);
|
|
1970
|
+
result.push([node, expectedType, node, realType]);
|
|
1971
|
+
}
|
|
1597
1972
|
}
|
|
1598
1973
|
}
|
|
1599
1974
|
}
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1975
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
1976
|
+
continue;
|
|
1977
|
+
} else if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
1978
|
+
const expectedType = typeChecker.getTypeAtLocation(node.left);
|
|
1979
|
+
const realType = typeChecker.getTypeAtLocation(node.right);
|
|
1980
|
+
result.push([node.left, expectedType, node.right, realType]);
|
|
1981
|
+
appendNodeToVisit(node.right);
|
|
1982
|
+
continue;
|
|
1983
|
+
} else if (ts.isReturnStatement(node) && node.expression) {
|
|
1984
|
+
const parentDeclaration = yield* option(getAncestorConvertibleDeclaration(node));
|
|
1985
|
+
if (isSome2(parentDeclaration)) {
|
|
1986
|
+
const expectedType = yield* option(getInferredReturnType(parentDeclaration.value));
|
|
1987
|
+
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
1988
|
+
if (isSome2(expectedType)) {
|
|
1989
|
+
result.push([node, expectedType.value, node, realType]);
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
1993
|
+
continue;
|
|
1994
|
+
} else if (ts.isArrowFunction(node) && (node.typeParameters || []).length === 0 && ts.isExpression(node.body)) {
|
|
1995
|
+
const body = node.body;
|
|
1996
|
+
const expectedType = typeChecker.getContextualType(body);
|
|
1997
|
+
const realType = typeChecker.getTypeAtLocation(body);
|
|
1998
|
+
if (expectedType) {
|
|
1999
|
+
result.push([body, expectedType, body, realType]);
|
|
2000
|
+
}
|
|
2001
|
+
ts.forEachChild(body, appendNodeToVisit);
|
|
2002
|
+
continue;
|
|
2003
|
+
} else if (ts.isArrowFunction(node) && (node.typeParameters || []).length > 0 && ts.isExpression(node.body)) {
|
|
2004
|
+
const body = node.body;
|
|
2005
|
+
const expectedType = yield* option(getInferredReturnType(node));
|
|
2006
|
+
const realType = typeChecker.getTypeAtLocation(body);
|
|
1614
2007
|
if (isSome2(expectedType)) {
|
|
1615
|
-
result.push([
|
|
2008
|
+
result.push([body, expectedType.value, body, realType]);
|
|
1616
2009
|
}
|
|
2010
|
+
ts.forEachChild(body, appendNodeToVisit);
|
|
2011
|
+
continue;
|
|
2012
|
+
} else if (ts.isSatisfiesExpression(node)) {
|
|
2013
|
+
const expectedType = typeChecker.getTypeAtLocation(node.type);
|
|
2014
|
+
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
2015
|
+
result.push([node.expression, expectedType, node.expression, realType]);
|
|
2016
|
+
appendNodeToVisit(node.expression);
|
|
2017
|
+
continue;
|
|
1617
2018
|
}
|
|
1618
2019
|
ts.forEachChild(node, appendNodeToVisit);
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
result.push([body, expectedType, body, realType]);
|
|
1626
|
-
}
|
|
1627
|
-
ts.forEachChild(body, appendNodeToVisit);
|
|
1628
|
-
continue;
|
|
1629
|
-
} else if (ts.isArrowFunction(node) && (node.typeParameters || []).length > 0 && ts.isExpression(node.body)) {
|
|
1630
|
-
const body = node.body;
|
|
1631
|
-
const expectedType = yield* option(getInferredReturnType(node));
|
|
1632
|
-
const realType = typeChecker.getTypeAtLocation(body);
|
|
1633
|
-
if (isSome2(expectedType)) {
|
|
1634
|
-
result.push([body, expectedType.value, body, realType]);
|
|
1635
|
-
}
|
|
1636
|
-
ts.forEachChild(body, appendNodeToVisit);
|
|
1637
|
-
continue;
|
|
1638
|
-
} else if (ts.isSatisfiesExpression(node)) {
|
|
1639
|
-
const expectedType = typeChecker.getTypeAtLocation(node.type);
|
|
1640
|
-
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
1641
|
-
result.push([node.expression, expectedType, node.expression, realType]);
|
|
1642
|
-
appendNodeToVisit(node.expression);
|
|
1643
|
-
continue;
|
|
1644
|
-
}
|
|
1645
|
-
ts.forEachChild(node, appendNodeToVisit);
|
|
1646
|
-
}
|
|
1647
|
-
cache.expectedAndRealType.set(sourceFile, result);
|
|
1648
|
-
return result;
|
|
1649
|
-
});
|
|
2020
|
+
}
|
|
2021
|
+
return result;
|
|
2022
|
+
}),
|
|
2023
|
+
"TypeCheckerApi.expectedAndRealType",
|
|
2024
|
+
(sourceFile) => sourceFile
|
|
2025
|
+
);
|
|
1650
2026
|
var unrollUnionMembers = (type) => {
|
|
1651
2027
|
const result = [];
|
|
1652
2028
|
let toTest = [type];
|
|
@@ -1714,350 +2090,17 @@ function makeResolveExternalModuleName(typeChecker) {
|
|
|
1714
2090
|
};
|
|
1715
2091
|
}
|
|
1716
2092
|
|
|
1717
|
-
// src/core/
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
let result = empty();
|
|
1721
|
-
let parent = node;
|
|
1722
|
-
while (parent) {
|
|
1723
|
-
if (parent.end >= textRange.end) {
|
|
1724
|
-
result = pipe(result, append(parent));
|
|
1725
|
-
}
|
|
1726
|
-
parent = parent.parent;
|
|
1727
|
-
}
|
|
1728
|
-
return result;
|
|
1729
|
-
});
|
|
1730
|
-
}
|
|
1731
|
-
var getAncestorNodesInRange = fn("AST.getAncestorNodesInRange")(function* (sourceFile, textRange) {
|
|
1732
|
-
const nodeAtPosition = yield* option(findNodeAtPosition(sourceFile, textRange.pos));
|
|
1733
|
-
if (isNone2(nodeAtPosition)) return empty();
|
|
1734
|
-
return yield* collectSelfAndAncestorNodesInRange(nodeAtPosition.value, textRange);
|
|
1735
|
-
});
|
|
1736
|
-
var NodeNotFoundError = class {
|
|
1737
|
-
_tag = "@effect/language-service/NodeNotFoundError";
|
|
1738
|
-
};
|
|
1739
|
-
var findNodeAtPosition = fn("AST.findNodeAtPosition")(function* (sourceFile, position) {
|
|
1740
|
-
const ts = yield* service(TypeScriptApi);
|
|
1741
|
-
function find(node) {
|
|
1742
|
-
if (position >= node.getStart() && position < node.getEnd()) {
|
|
1743
|
-
return ts.forEachChild(node, find) || node;
|
|
1744
|
-
}
|
|
1745
|
-
return void 0;
|
|
1746
|
-
}
|
|
1747
|
-
const result = find(sourceFile);
|
|
1748
|
-
if (!result) return yield* fail(new NodeNotFoundError());
|
|
1749
|
-
return result;
|
|
1750
|
-
});
|
|
1751
|
-
var getCommentAtPosition = fn("TypeScriptApi.getCommentAtPosition")(function* (sourceFile, pos) {
|
|
1752
|
-
const ts = yield* service(TypeScriptApi);
|
|
1753
|
-
const token = yield* findNodeAtPosition(sourceFile, pos);
|
|
1754
|
-
if (token === void 0 || token.kind === ts.SyntaxKind.JsxText || pos >= token.end - (ts.tokenToString(token.kind) || "").length) {
|
|
1755
|
-
return yield* fail(new NodeNotFoundError());
|
|
1756
|
-
}
|
|
1757
|
-
const startPos = token.pos === 0 ? (ts.getShebang(sourceFile.text) || "").length : token.pos;
|
|
1758
|
-
if (startPos === 0) return yield* fail(new NodeNotFoundError());
|
|
1759
|
-
const result = ts.forEachTrailingCommentRange(sourceFile.text, startPos, isCommentInRange, pos) || ts.forEachLeadingCommentRange(sourceFile.text, startPos, isCommentInRange, pos);
|
|
1760
|
-
if (!result) return yield* fail(new NodeNotFoundError());
|
|
1761
|
-
return result;
|
|
1762
|
-
});
|
|
1763
|
-
function isCommentInRange(pos, end, kind, _nl, at) {
|
|
1764
|
-
return at >= pos && at < end ? { pos, end, kind } : void 0;
|
|
1765
|
-
}
|
|
1766
|
-
var transformAsyncAwaitToEffectGen = fn("AST.transformAsyncAwaitToEffectGen")(
|
|
1767
|
-
function* (node, effectModuleName, onAwait) {
|
|
1768
|
-
const ts = yield* service(TypeScriptApi);
|
|
1769
|
-
function visitor(_) {
|
|
1770
|
-
if (ts.isAwaitExpression(_)) {
|
|
1771
|
-
const expression = ts.visitEachChild(_.expression, visitor, ts.nullTransformationContext);
|
|
1772
|
-
return ts.factory.createYieldExpression(
|
|
1773
|
-
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
1774
|
-
onAwait(expression)
|
|
1775
|
-
);
|
|
1776
|
-
}
|
|
1777
|
-
return ts.visitEachChild(_, visitor, ts.nullTransformationContext);
|
|
1778
|
-
}
|
|
1779
|
-
const generatorBody = visitor(node.body);
|
|
1780
|
-
const effectGenCallExp = yield* createEffectGenCallExpression(effectModuleName, generatorBody);
|
|
1781
|
-
let currentFlags = ts.getCombinedModifierFlags(node);
|
|
1782
|
-
currentFlags &= ~ts.ModifierFlags.Async;
|
|
1783
|
-
const newModifiers = ts.factory.createModifiersFromModifierFlags(currentFlags);
|
|
1784
|
-
if (ts.isArrowFunction(node)) {
|
|
1785
|
-
return ts.factory.createArrowFunction(
|
|
1786
|
-
newModifiers,
|
|
1787
|
-
node.typeParameters,
|
|
1788
|
-
node.parameters,
|
|
1789
|
-
void 0,
|
|
1790
|
-
node.equalsGreaterThanToken,
|
|
1791
|
-
effectGenCallExp
|
|
1792
|
-
);
|
|
1793
|
-
}
|
|
1794
|
-
const newBody = ts.factory.createBlock([
|
|
1795
|
-
ts.factory.createReturnStatement(effectGenCallExp)
|
|
1796
|
-
]);
|
|
1797
|
-
if (ts.isFunctionDeclaration(node)) {
|
|
1798
|
-
return ts.factory.createFunctionDeclaration(
|
|
1799
|
-
newModifiers,
|
|
1800
|
-
node.asteriskToken,
|
|
1801
|
-
node.name,
|
|
1802
|
-
node.typeParameters,
|
|
1803
|
-
node.parameters,
|
|
1804
|
-
void 0,
|
|
1805
|
-
newBody
|
|
1806
|
-
);
|
|
1807
|
-
}
|
|
1808
|
-
return ts.factory.createFunctionExpression(
|
|
1809
|
-
newModifiers,
|
|
1810
|
-
node.asteriskToken,
|
|
1811
|
-
node.name,
|
|
1812
|
-
node.typeParameters,
|
|
1813
|
-
node.parameters,
|
|
1814
|
-
void 0,
|
|
1815
|
-
newBody
|
|
1816
|
-
);
|
|
1817
|
-
}
|
|
1818
|
-
);
|
|
1819
|
-
var addReturnTypeAnnotation = fn("AST.addReturnTypeAnnotation")(function* (sourceFile, declaration, typeNode) {
|
|
1820
|
-
const ts = yield* service(TypeScriptApi);
|
|
1821
|
-
const changes = yield* service(ChangeTracker);
|
|
1822
|
-
const closeParen = ts.findChildOfKind(declaration, ts.SyntaxKind.CloseParenToken, sourceFile);
|
|
1823
|
-
const needParens = ts.isArrowFunction(declaration) && closeParen === void 0;
|
|
1824
|
-
const endNode = needParens ? declaration.parameters[0] : closeParen;
|
|
1825
|
-
if (endNode) {
|
|
1826
|
-
if (needParens) {
|
|
1827
|
-
changes.insertNodeBefore(
|
|
1828
|
-
sourceFile,
|
|
1829
|
-
endNode,
|
|
1830
|
-
ts.factory.createToken(ts.SyntaxKind.OpenParenToken)
|
|
1831
|
-
);
|
|
1832
|
-
changes.insertNodeAfter(
|
|
1833
|
-
sourceFile,
|
|
1834
|
-
endNode,
|
|
1835
|
-
ts.factory.createToken(ts.SyntaxKind.CloseParenToken)
|
|
1836
|
-
);
|
|
1837
|
-
}
|
|
1838
|
-
changes.insertNodeAt(sourceFile, endNode.end, typeNode, { prefix: ": " });
|
|
1839
|
-
}
|
|
1840
|
-
});
|
|
1841
|
-
var removeReturnTypeAnnotation = fn("AST.removeReturnTypeAnnotation")(function* (sourceFile, declaration) {
|
|
1842
|
-
const ts = yield* service(TypeScriptApi);
|
|
1843
|
-
const changes = yield* service(ChangeTracker);
|
|
1844
|
-
const closeParen = ts.findChildOfKind(declaration, ts.SyntaxKind.CloseParenToken, sourceFile);
|
|
1845
|
-
const needParens = ts.isArrowFunction(declaration) && closeParen === void 0;
|
|
1846
|
-
const endNode = needParens ? declaration.parameters[0] : closeParen;
|
|
1847
|
-
if (endNode && declaration.type) {
|
|
1848
|
-
changes.deleteRange(sourceFile, { pos: endNode.end, end: declaration.type.end });
|
|
1849
|
-
}
|
|
1850
|
-
});
|
|
1851
|
-
var ImportModuleIdentifierNotFoundError = class {
|
|
1852
|
-
_tag = "@effect/language-service/ImportModuleIdentifierNotFoundError";
|
|
1853
|
-
};
|
|
1854
|
-
var findImportedModuleIdentifier = fn("AST.findImportedModuleIdentifier")(
|
|
1855
|
-
function* (sourceFile, test) {
|
|
1856
|
-
const ts = yield* service(TypeScriptApi);
|
|
1857
|
-
for (const statement of sourceFile.statements) {
|
|
1858
|
-
if (!ts.isImportDeclaration(statement)) continue;
|
|
1859
|
-
const importClause = statement.importClause;
|
|
1860
|
-
if (!importClause) continue;
|
|
1861
|
-
const namedBindings = importClause.namedBindings;
|
|
1862
|
-
if (!namedBindings) continue;
|
|
1863
|
-
if (ts.isNamespaceImport(namedBindings)) {
|
|
1864
|
-
if (yield* test(namedBindings.name, statement.moduleSpecifier, none2())) {
|
|
1865
|
-
return namedBindings.name;
|
|
1866
|
-
}
|
|
1867
|
-
} else if (ts.isNamedImports(namedBindings)) {
|
|
1868
|
-
for (const importSpecifier of namedBindings.elements) {
|
|
1869
|
-
const importProperty = fromNullable(importSpecifier.propertyName).pipe(
|
|
1870
|
-
orElse(() => some2(importSpecifier.name))
|
|
1871
|
-
);
|
|
1872
|
-
if (yield* test(importSpecifier.name, statement.moduleSpecifier, importProperty)) {
|
|
1873
|
-
return importSpecifier.name;
|
|
1874
|
-
}
|
|
1875
|
-
}
|
|
1876
|
-
}
|
|
1877
|
-
}
|
|
1878
|
-
return yield* fail(new ImportModuleIdentifierNotFoundError());
|
|
1879
|
-
}
|
|
1880
|
-
);
|
|
1881
|
-
function findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, packageName, moduleName) {
|
|
1882
|
-
return findImportedModuleIdentifier(
|
|
1883
|
-
sourceFile,
|
|
1884
|
-
fn(
|
|
1885
|
-
"AST.findImportedModuleIdentifierByPackageAndNameOrBarrel.findImportedModuleIdentifier"
|
|
1886
|
-
)(function* (_, fromModule, importProperty) {
|
|
1887
|
-
const ts = yield* service(TypeScriptApi);
|
|
1888
|
-
if (isNone2(importProperty) && ts.isStringLiteral(fromModule) && fromModule.text === packageName + "/" + moduleName) {
|
|
1889
|
-
return true;
|
|
1890
|
-
}
|
|
1891
|
-
if (isSome2(importProperty) && ts.isIdentifier(importProperty.value) && importProperty.value.text === moduleName && ts.isStringLiteral(fromModule) && fromModule.text === packageName) {
|
|
1892
|
-
return true;
|
|
1893
|
-
}
|
|
1894
|
-
return false;
|
|
1895
|
-
})
|
|
1896
|
-
);
|
|
1897
|
-
}
|
|
1898
|
-
var simplifyTypeNode = fn("AST.simplifyTypeNode")(function* (typeNode) {
|
|
1899
|
-
const ts = yield* service(TypeScriptApi);
|
|
1900
|
-
function collectCallable(typeNode2) {
|
|
1901
|
-
if (ts.isParenthesizedTypeNode(typeNode2)) return collectCallable(typeNode2.type);
|
|
1902
|
-
if (ts.isFunctionTypeNode(typeNode2)) {
|
|
1903
|
-
return some2([
|
|
1904
|
-
ts.factory.createCallSignature(typeNode2.typeParameters, typeNode2.parameters, typeNode2.type)
|
|
1905
|
-
]);
|
|
1906
|
-
}
|
|
1907
|
-
if (ts.isTypeLiteralNode(typeNode2)) {
|
|
1908
|
-
const allCallSignatures = typeNode2.members.every(ts.isCallSignatureDeclaration);
|
|
1909
|
-
if (allCallSignatures) {
|
|
1910
|
-
return some2(typeNode2.members);
|
|
1911
|
-
}
|
|
1912
|
-
}
|
|
1913
|
-
if (ts.isIntersectionTypeNode(typeNode2)) {
|
|
1914
|
-
const members = typeNode2.types.map((node) => collectCallable(node));
|
|
1915
|
-
if (members.every(isSome2)) {
|
|
1916
|
-
return some2(members.map((_) => isSome2(_) ? _.value : []).flat());
|
|
1917
|
-
}
|
|
1918
|
-
}
|
|
1919
|
-
return none2();
|
|
1920
|
-
}
|
|
1921
|
-
const callSignatures = collectCallable(typeNode);
|
|
1922
|
-
if (isSome2(callSignatures) && callSignatures.value.length > 1) {
|
|
1923
|
-
return ts.factory.createTypeLiteralNode(callSignatures.value);
|
|
1924
|
-
}
|
|
1925
|
-
return typeNode;
|
|
1926
|
-
});
|
|
1927
|
-
var tryPreserveDeclarationSemantics = fn("AST.tryPreserveDeclarationSemantics")(
|
|
1928
|
-
function* (nodeToReplace, node) {
|
|
1929
|
-
const ts = yield* service(TypeScriptApi);
|
|
1930
|
-
if (!ts.isExpression(node)) return node;
|
|
1931
|
-
if (ts.isFunctionDeclaration(nodeToReplace)) {
|
|
1932
|
-
if (!nodeToReplace.name) return node;
|
|
1933
|
-
return ts.factory.createVariableStatement(
|
|
1934
|
-
nodeToReplace.modifiers,
|
|
1935
|
-
ts.factory.createVariableDeclarationList(
|
|
1936
|
-
[ts.factory.createVariableDeclaration(
|
|
1937
|
-
nodeToReplace.name,
|
|
1938
|
-
void 0,
|
|
1939
|
-
void 0,
|
|
1940
|
-
node
|
|
1941
|
-
)],
|
|
1942
|
-
ts.NodeFlags.Const
|
|
1943
|
-
)
|
|
1944
|
-
);
|
|
1945
|
-
} else if (ts.isMethodDeclaration(nodeToReplace)) {
|
|
1946
|
-
return ts.factory.createPropertyDeclaration(
|
|
1947
|
-
nodeToReplace.modifiers,
|
|
1948
|
-
nodeToReplace.name,
|
|
1949
|
-
void 0,
|
|
1950
|
-
void 0,
|
|
1951
|
-
node
|
|
1952
|
-
);
|
|
1953
|
-
}
|
|
1954
|
-
return node;
|
|
1955
|
-
}
|
|
1956
|
-
);
|
|
1957
|
-
var parseAccessedExpressionForCompletion = fn(
|
|
1958
|
-
"AST.parseAccessedExpressionForCompletion"
|
|
1959
|
-
)(
|
|
1960
|
-
function* (sourceFile, position) {
|
|
1961
|
-
const ts = yield* service(TypeScriptApi);
|
|
1962
|
-
const precedingToken = ts.findPrecedingToken(position, sourceFile, void 0, true);
|
|
1963
|
-
if (!precedingToken) return yield* fail(new NodeNotFoundError());
|
|
1964
|
-
let accessedObject = precedingToken;
|
|
1965
|
-
let replacementSpan = ts.createTextSpan(position, 0);
|
|
1966
|
-
let outerNode = precedingToken;
|
|
1967
|
-
if (ts.isIdentifier(precedingToken) && precedingToken.parent && ts.isPropertyAccessExpression(precedingToken.parent)) {
|
|
1968
|
-
replacementSpan = ts.createTextSpan(
|
|
1969
|
-
precedingToken.parent.getStart(sourceFile),
|
|
1970
|
-
precedingToken.end - precedingToken.parent.getStart(sourceFile)
|
|
1971
|
-
);
|
|
1972
|
-
accessedObject = precedingToken.parent.expression;
|
|
1973
|
-
outerNode = precedingToken.parent;
|
|
1974
|
-
} else if (ts.isToken(precedingToken) && precedingToken.kind === ts.SyntaxKind.DotToken && ts.isPropertyAccessExpression(precedingToken.parent)) {
|
|
1975
|
-
replacementSpan = ts.createTextSpan(
|
|
1976
|
-
precedingToken.parent.getStart(sourceFile),
|
|
1977
|
-
precedingToken.end - precedingToken.parent.getStart(sourceFile)
|
|
1978
|
-
);
|
|
1979
|
-
accessedObject = precedingToken.parent.expression;
|
|
1980
|
-
outerNode = precedingToken.parent;
|
|
1981
|
-
} else if (ts.isIdentifier(precedingToken) && precedingToken.parent) {
|
|
1982
|
-
replacementSpan = ts.createTextSpan(
|
|
1983
|
-
precedingToken.getStart(sourceFile),
|
|
1984
|
-
precedingToken.end - precedingToken.getStart(sourceFile)
|
|
1985
|
-
);
|
|
1986
|
-
accessedObject = precedingToken;
|
|
1987
|
-
outerNode = precedingToken;
|
|
1988
|
-
} else {
|
|
1989
|
-
return yield* fail(new NodeNotFoundError());
|
|
1990
|
-
}
|
|
1991
|
-
return { accessedObject, outerNode, replacementSpan };
|
|
1992
|
-
}
|
|
1993
|
-
);
|
|
1994
|
-
var parseDataForExtendsClassCompletion = fn(
|
|
1995
|
-
"AST.parseDataForExtendsClassCompletion"
|
|
1996
|
-
)(function* (sourceFile, position) {
|
|
1997
|
-
const ts = yield* service(TypeScriptApi);
|
|
1998
|
-
const { accessedObject, outerNode, replacementSpan } = yield* parseAccessedExpressionForCompletion(
|
|
1999
|
-
sourceFile,
|
|
2000
|
-
position
|
|
2001
|
-
);
|
|
2002
|
-
if (!ts.isIdentifier(accessedObject)) return yield* fail(new NodeNotFoundError());
|
|
2003
|
-
let classDeclaration = outerNode.parent;
|
|
2004
|
-
while (ts.isExpressionWithTypeArguments(classDeclaration) || ts.isHeritageClause(classDeclaration)) {
|
|
2005
|
-
if (!classDeclaration.parent) break;
|
|
2006
|
-
classDeclaration = classDeclaration.parent;
|
|
2007
|
-
}
|
|
2008
|
-
if (!ts.isClassDeclaration(classDeclaration)) return yield* fail(new NodeNotFoundError());
|
|
2009
|
-
if (!classDeclaration.name) return yield* fail(new NodeNotFoundError());
|
|
2010
|
-
return {
|
|
2011
|
-
accessedObject,
|
|
2012
|
-
classDeclaration,
|
|
2013
|
-
className: classDeclaration.name,
|
|
2014
|
-
replacementSpan
|
|
2015
|
-
};
|
|
2016
|
-
});
|
|
2017
|
-
var createEffectGenCallExpression = fn("AST.createEffectGenCallExpression")(function* (effectModuleIdentifierName, node) {
|
|
2018
|
-
const ts = yield* service(TypeScriptApi);
|
|
2019
|
-
const generator = ts.factory.createFunctionExpression(
|
|
2020
|
-
void 0,
|
|
2021
|
-
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
2022
|
-
void 0,
|
|
2023
|
-
[],
|
|
2024
|
-
[],
|
|
2025
|
-
void 0,
|
|
2026
|
-
node
|
|
2027
|
-
// NOTE(mattia): intended, to use same routine for both ConciseBody and Body
|
|
2028
|
-
);
|
|
2029
|
-
return ts.factory.createCallExpression(
|
|
2030
|
-
ts.factory.createPropertyAccessExpression(
|
|
2031
|
-
ts.factory.createIdentifier(effectModuleIdentifierName),
|
|
2032
|
-
"gen"
|
|
2033
|
-
),
|
|
2034
|
-
void 0,
|
|
2035
|
-
[generator]
|
|
2036
|
-
);
|
|
2037
|
-
});
|
|
2038
|
-
var createEffectGenCallExpressionWithBlock = fn(
|
|
2039
|
-
"AST.createEffectGenCallExpressionWithBlock"
|
|
2040
|
-
)(function* (effectModuleIdentifierName, statement) {
|
|
2093
|
+
// src/core/TypeParser.ts
|
|
2094
|
+
var TypeParser = Tag("@effect/language-service/TypeParser");
|
|
2095
|
+
var nanoLayer2 = (fa) => gen(function* () {
|
|
2041
2096
|
const ts = yield* service(TypeScriptApi);
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2097
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
2098
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
2099
|
+
return yield* pipe(
|
|
2100
|
+
fa,
|
|
2101
|
+
provideService(TypeParser, make2(ts, tsUtils, typeChecker))
|
|
2045
2102
|
);
|
|
2046
2103
|
});
|
|
2047
|
-
var createReturnYieldStarStatement = fn("AST.createReturnYieldStarStatement")(
|
|
2048
|
-
function* (expr) {
|
|
2049
|
-
const ts = yield* service(TypeScriptApi);
|
|
2050
|
-
return ts.factory.createReturnStatement(
|
|
2051
|
-
ts.factory.createYieldExpression(
|
|
2052
|
-
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
2053
|
-
expr
|
|
2054
|
-
)
|
|
2055
|
-
);
|
|
2056
|
-
}
|
|
2057
|
-
);
|
|
2058
|
-
|
|
2059
|
-
// src/core/TypeParser.ts
|
|
2060
|
-
var TypeParser = Tag("@effect/language-service/TypeParser");
|
|
2061
2104
|
var TypeParserIssue = class _TypeParserIssue {
|
|
2062
2105
|
_tag = "@effect/language-service/TypeParserIssue";
|
|
2063
2106
|
static issue = fail(new _TypeParserIssue());
|
|
@@ -2065,7 +2108,7 @@ var TypeParserIssue = class _TypeParserIssue {
|
|
|
2065
2108
|
function typeParserIssue(_message, _type, _node) {
|
|
2066
2109
|
return TypeParserIssue.issue;
|
|
2067
2110
|
}
|
|
2068
|
-
function make2(ts, typeChecker) {
|
|
2111
|
+
function make2(ts, tsUtils, typeChecker) {
|
|
2069
2112
|
function covariantTypeArgument(type) {
|
|
2070
2113
|
const signatures = type.getCallSignatures();
|
|
2071
2114
|
if (signatures.length !== 1) {
|
|
@@ -2223,6 +2266,36 @@ function make2(ts, typeChecker) {
|
|
|
2223
2266
|
"TypeParser.effectSubtype",
|
|
2224
2267
|
(type) => type
|
|
2225
2268
|
);
|
|
2269
|
+
const importedSchemaModule = cachedBy(
|
|
2270
|
+
fn("TypeParser.importedSchemaModule")(function* (node) {
|
|
2271
|
+
const type = typeChecker.getTypeAtLocation(node);
|
|
2272
|
+
const propertySymbol = typeChecker.getPropertyOfType(type, "Class");
|
|
2273
|
+
if (!propertySymbol) {
|
|
2274
|
+
return yield* typeParserIssue("Type has no 'Class' property", type, node);
|
|
2275
|
+
}
|
|
2276
|
+
if (!ts.isExpression(node)) {
|
|
2277
|
+
return yield* typeParserIssue("Node is not an expression", type, node);
|
|
2278
|
+
}
|
|
2279
|
+
return node;
|
|
2280
|
+
}),
|
|
2281
|
+
"TypeParser.importedSchemaModule",
|
|
2282
|
+
(node) => node
|
|
2283
|
+
);
|
|
2284
|
+
const importedContextModule = cachedBy(
|
|
2285
|
+
fn("TypeParser.importedContextModule")(function* (node) {
|
|
2286
|
+
const type = typeChecker.getTypeAtLocation(node);
|
|
2287
|
+
const propertySymbol = typeChecker.getPropertyOfType(type, "Tag");
|
|
2288
|
+
if (!propertySymbol) {
|
|
2289
|
+
return yield* typeParserIssue("Type has no 'Tag' property", type, node);
|
|
2290
|
+
}
|
|
2291
|
+
if (!ts.isExpression(node)) {
|
|
2292
|
+
return yield* typeParserIssue("Node is not an expression", type, node);
|
|
2293
|
+
}
|
|
2294
|
+
return node;
|
|
2295
|
+
}),
|
|
2296
|
+
"TypeParser.importedContextModule",
|
|
2297
|
+
(node) => node
|
|
2298
|
+
);
|
|
2226
2299
|
const importedEffectModule = cachedBy(
|
|
2227
2300
|
fn("TypeParser.importedEffectModule")(function* (node) {
|
|
2228
2301
|
const type = typeChecker.getTypeAtLocation(node);
|
|
@@ -2407,15 +2480,11 @@ function make2(ts, typeChecker) {
|
|
|
2407
2480
|
if (!explicitReturn && !(successType.flags & ts.TypeFlags.VoidLike)) {
|
|
2408
2481
|
replacementNode = pipe(
|
|
2409
2482
|
gen(function* () {
|
|
2410
|
-
const effectIdentifier =
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
onNone: () => "Effect",
|
|
2416
|
-
onSome: (_) => _.text
|
|
2417
|
-
})
|
|
2418
|
-
);
|
|
2483
|
+
const effectIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
2484
|
+
node.getSourceFile(),
|
|
2485
|
+
"effect",
|
|
2486
|
+
"Effect"
|
|
2487
|
+
) || "Effect";
|
|
2419
2488
|
return ts.factory.createCallExpression(
|
|
2420
2489
|
ts.factory.createPropertyAccessExpression(
|
|
2421
2490
|
ts.factory.createIdentifier(effectIdentifier),
|
|
@@ -2583,6 +2652,284 @@ function make2(ts, typeChecker) {
|
|
|
2583
2652
|
"TypeParser.promiseLike",
|
|
2584
2653
|
(type) => type
|
|
2585
2654
|
);
|
|
2655
|
+
const extendsSchemaClass = cachedBy(
|
|
2656
|
+
fn("TypeParser.extendsSchemaClass")(function* (atLocation) {
|
|
2657
|
+
if (!atLocation.name) {
|
|
2658
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
2659
|
+
}
|
|
2660
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
2661
|
+
if (!heritageClauses) {
|
|
2662
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
2663
|
+
}
|
|
2664
|
+
for (const heritageClause of heritageClauses) {
|
|
2665
|
+
for (const typeX of heritageClause.types) {
|
|
2666
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
2667
|
+
const expression = typeX.expression;
|
|
2668
|
+
if (ts.isCallExpression(expression)) {
|
|
2669
|
+
const schemaCall = expression.expression;
|
|
2670
|
+
if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
|
|
2671
|
+
const selfTypeNode = schemaCall.typeArguments[0];
|
|
2672
|
+
const schemaIdentifier = schemaCall.expression;
|
|
2673
|
+
if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && schemaIdentifier.name.text === "Class") {
|
|
2674
|
+
const parsedSchemaModule = yield* pipe(
|
|
2675
|
+
importedSchemaModule(schemaIdentifier.expression),
|
|
2676
|
+
option
|
|
2677
|
+
);
|
|
2678
|
+
if (isSome2(parsedSchemaModule)) {
|
|
2679
|
+
return {
|
|
2680
|
+
className: atLocation.name,
|
|
2681
|
+
selfTypeNode,
|
|
2682
|
+
Schema: parsedSchemaModule.value
|
|
2683
|
+
};
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2691
|
+
return yield* typeParserIssue("Class does not extend Schema.Class", void 0, atLocation);
|
|
2692
|
+
}),
|
|
2693
|
+
"TypeParser.extendsSchemaClass",
|
|
2694
|
+
(atLocation) => atLocation
|
|
2695
|
+
);
|
|
2696
|
+
const extendsSchemaTaggedClass = cachedBy(
|
|
2697
|
+
fn("TypeParser.extendsSchemaTaggedClass")(function* (atLocation) {
|
|
2698
|
+
if (!atLocation.name) {
|
|
2699
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
2700
|
+
}
|
|
2701
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
2702
|
+
if (!heritageClauses) {
|
|
2703
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
2704
|
+
}
|
|
2705
|
+
for (const heritageClause of heritageClauses) {
|
|
2706
|
+
for (const typeX of heritageClause.types) {
|
|
2707
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
2708
|
+
const expression = typeX.expression;
|
|
2709
|
+
if (ts.isCallExpression(expression)) {
|
|
2710
|
+
const tagCall = expression.expression;
|
|
2711
|
+
if (ts.isCallExpression(tagCall)) {
|
|
2712
|
+
const schemaCall = tagCall.expression;
|
|
2713
|
+
if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
|
|
2714
|
+
const selfTypeNode = schemaCall.typeArguments[0];
|
|
2715
|
+
const schemaIdentifier = schemaCall.expression;
|
|
2716
|
+
if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && schemaIdentifier.name.text === "TaggedClass") {
|
|
2717
|
+
const parsedSchemaModule = yield* pipe(
|
|
2718
|
+
importedSchemaModule(schemaIdentifier.expression),
|
|
2719
|
+
option
|
|
2720
|
+
);
|
|
2721
|
+
if (isSome2(parsedSchemaModule)) {
|
|
2722
|
+
return {
|
|
2723
|
+
className: atLocation.name,
|
|
2724
|
+
selfTypeNode,
|
|
2725
|
+
Schema: parsedSchemaModule.value
|
|
2726
|
+
};
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
return yield* typeParserIssue("Class does not extend Schema.TaggedClass", void 0, atLocation);
|
|
2736
|
+
}),
|
|
2737
|
+
"TypeParser.extendsSchemaTaggedClass",
|
|
2738
|
+
(atLocation) => atLocation
|
|
2739
|
+
);
|
|
2740
|
+
const extendsSchemaTaggedError = cachedBy(
|
|
2741
|
+
fn("TypeParser.extendsSchemaTaggedError")(function* (atLocation) {
|
|
2742
|
+
if (!atLocation.name) {
|
|
2743
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
2744
|
+
}
|
|
2745
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
2746
|
+
if (!heritageClauses) {
|
|
2747
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
2748
|
+
}
|
|
2749
|
+
for (const heritageClause of heritageClauses) {
|
|
2750
|
+
for (const typeX of heritageClause.types) {
|
|
2751
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
2752
|
+
const expression = typeX.expression;
|
|
2753
|
+
if (ts.isCallExpression(expression)) {
|
|
2754
|
+
const tagCall = expression.expression;
|
|
2755
|
+
if (ts.isCallExpression(tagCall)) {
|
|
2756
|
+
const schemaCall = tagCall.expression;
|
|
2757
|
+
if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
|
|
2758
|
+
const selfTypeNode = schemaCall.typeArguments[0];
|
|
2759
|
+
const schemaIdentifier = schemaCall.expression;
|
|
2760
|
+
if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && schemaIdentifier.name.text === "TaggedError") {
|
|
2761
|
+
const parsedSchemaModule = yield* pipe(
|
|
2762
|
+
importedSchemaModule(schemaIdentifier.expression),
|
|
2763
|
+
option
|
|
2764
|
+
);
|
|
2765
|
+
if (isSome2(parsedSchemaModule)) {
|
|
2766
|
+
return {
|
|
2767
|
+
className: atLocation.name,
|
|
2768
|
+
selfTypeNode,
|
|
2769
|
+
Schema: parsedSchemaModule.value
|
|
2770
|
+
};
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
return yield* typeParserIssue("Class does not extend Schema.TaggedError", void 0, atLocation);
|
|
2780
|
+
}),
|
|
2781
|
+
"TypeParser.extendsSchemaTaggedError",
|
|
2782
|
+
(atLocation) => atLocation
|
|
2783
|
+
);
|
|
2784
|
+
const extendsSchemaTaggedRequest = cachedBy(
|
|
2785
|
+
fn("TypeParser.extendsSchemaTaggedRequest")(function* (atLocation) {
|
|
2786
|
+
if (!atLocation.name) {
|
|
2787
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
2788
|
+
}
|
|
2789
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
2790
|
+
if (!heritageClauses) {
|
|
2791
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
2792
|
+
}
|
|
2793
|
+
for (const heritageClause of heritageClauses) {
|
|
2794
|
+
for (const typeX of heritageClause.types) {
|
|
2795
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
2796
|
+
const expression = typeX.expression;
|
|
2797
|
+
if (ts.isCallExpression(expression)) {
|
|
2798
|
+
const tagCall = expression.expression;
|
|
2799
|
+
if (ts.isCallExpression(tagCall)) {
|
|
2800
|
+
const schemaCall = tagCall.expression;
|
|
2801
|
+
if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
|
|
2802
|
+
const selfTypeNode = schemaCall.typeArguments[0];
|
|
2803
|
+
const schemaIdentifier = schemaCall.expression;
|
|
2804
|
+
if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && schemaIdentifier.name.text === "TaggedRequest") {
|
|
2805
|
+
const parsedSchemaModule = yield* pipe(
|
|
2806
|
+
importedSchemaModule(schemaIdentifier.expression),
|
|
2807
|
+
option
|
|
2808
|
+
);
|
|
2809
|
+
if (isSome2(parsedSchemaModule)) {
|
|
2810
|
+
return {
|
|
2811
|
+
className: atLocation.name,
|
|
2812
|
+
selfTypeNode,
|
|
2813
|
+
Schema: parsedSchemaModule.value
|
|
2814
|
+
};
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
}
|
|
2823
|
+
return yield* typeParserIssue("Class does not extend Schema.TaggedRequest", void 0, atLocation);
|
|
2824
|
+
}),
|
|
2825
|
+
"TypeParser.extendsSchemaTaggedRequest",
|
|
2826
|
+
(atLocation) => atLocation
|
|
2827
|
+
);
|
|
2828
|
+
const extendsContextTag = cachedBy(
|
|
2829
|
+
fn("TypeParser.extendsContextTag")(function* (atLocation) {
|
|
2830
|
+
if (!atLocation.name) {
|
|
2831
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
2832
|
+
}
|
|
2833
|
+
const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
|
|
2834
|
+
if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
|
|
2835
|
+
const type = typeChecker.getTypeOfSymbol(classSym);
|
|
2836
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
2837
|
+
if (!heritageClauses) {
|
|
2838
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
2839
|
+
}
|
|
2840
|
+
for (const heritageClause of heritageClauses) {
|
|
2841
|
+
for (const typeX of heritageClause.types) {
|
|
2842
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
2843
|
+
const wholeCall = typeX.expression;
|
|
2844
|
+
if (ts.isCallExpression(wholeCall)) {
|
|
2845
|
+
const contextTagCall = wholeCall.expression;
|
|
2846
|
+
if (ts.isCallExpression(contextTagCall) && wholeCall.typeArguments && wholeCall.typeArguments.length > 0) {
|
|
2847
|
+
const contextTagIdentifier = contextTagCall.expression;
|
|
2848
|
+
const selfTypeNode = wholeCall.typeArguments[0];
|
|
2849
|
+
if (ts.isPropertyAccessExpression(contextTagIdentifier) && ts.isIdentifier(contextTagIdentifier.name) && contextTagIdentifier.name.text === "Tag") {
|
|
2850
|
+
const parsedContextModule = yield* pipe(
|
|
2851
|
+
importedContextModule(contextTagIdentifier.expression),
|
|
2852
|
+
option
|
|
2853
|
+
);
|
|
2854
|
+
if (isSome2(parsedContextModule)) {
|
|
2855
|
+
const tagType = yield* contextTag(type, atLocation);
|
|
2856
|
+
return {
|
|
2857
|
+
className: atLocation.name,
|
|
2858
|
+
selfTypeNode,
|
|
2859
|
+
args: contextTagCall.arguments,
|
|
2860
|
+
Identifier: tagType.Identifier,
|
|
2861
|
+
Tag: parsedContextModule.value
|
|
2862
|
+
};
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
return yield* typeParserIssue("Class does not extend Context.Tag", void 0, atLocation);
|
|
2871
|
+
}),
|
|
2872
|
+
"TypeParser.extendsContextTag",
|
|
2873
|
+
(atLocation) => atLocation
|
|
2874
|
+
);
|
|
2875
|
+
const extendsEffectService = cachedBy(
|
|
2876
|
+
fn("TypeParser.extendsEffectService")(function* (atLocation) {
|
|
2877
|
+
if (!atLocation.name) {
|
|
2878
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
2879
|
+
}
|
|
2880
|
+
const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
|
|
2881
|
+
if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
|
|
2882
|
+
const type = typeChecker.getTypeOfSymbol(classSym);
|
|
2883
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
2884
|
+
if (!heritageClauses) {
|
|
2885
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
2886
|
+
}
|
|
2887
|
+
for (const heritageClause of heritageClauses) {
|
|
2888
|
+
for (const typeX of heritageClause.types) {
|
|
2889
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
2890
|
+
const wholeCall = typeX.expression;
|
|
2891
|
+
if (ts.isCallExpression(wholeCall)) {
|
|
2892
|
+
const effectServiceCall = wholeCall.expression;
|
|
2893
|
+
if (ts.isCallExpression(effectServiceCall) && effectServiceCall.typeArguments && effectServiceCall.typeArguments.length > 0) {
|
|
2894
|
+
const effectServiceIdentifier = effectServiceCall.expression;
|
|
2895
|
+
const selfTypeNode = effectServiceCall.typeArguments[0];
|
|
2896
|
+
if (ts.isPropertyAccessExpression(effectServiceIdentifier) && ts.isIdentifier(effectServiceIdentifier.name) && effectServiceIdentifier.name.text === "Service") {
|
|
2897
|
+
const parsedContextTag = yield* pipe(
|
|
2898
|
+
importedEffectModule(effectServiceIdentifier.expression),
|
|
2899
|
+
flatMap2(() => contextTag(type, atLocation)),
|
|
2900
|
+
option
|
|
2901
|
+
);
|
|
2902
|
+
if (isSome2(parsedContextTag)) {
|
|
2903
|
+
let accessors2 = void 0;
|
|
2904
|
+
if (wholeCall.arguments.length >= 2) {
|
|
2905
|
+
const args2 = wholeCall.arguments[1];
|
|
2906
|
+
if (ts.isObjectLiteralExpression(args2)) {
|
|
2907
|
+
for (const property of args2.properties) {
|
|
2908
|
+
if (ts.isPropertyAssignment(property) && property.name && ts.isIdentifier(property.name) && property.name.text === "accessors" && property.initializer && property.initializer.kind === ts.SyntaxKind.TrueKeyword) {
|
|
2909
|
+
accessors2 = true;
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
return {
|
|
2915
|
+
...parsedContextTag.value,
|
|
2916
|
+
className: atLocation.name,
|
|
2917
|
+
selfTypeNode,
|
|
2918
|
+
args: wholeCall.arguments,
|
|
2919
|
+
accessors: accessors2
|
|
2920
|
+
};
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
return yield* typeParserIssue("Class does not extend Effect.Service", void 0, atLocation);
|
|
2929
|
+
}),
|
|
2930
|
+
"TypeParser.extendsEffectService",
|
|
2931
|
+
(atLocation) => atLocation
|
|
2932
|
+
);
|
|
2586
2933
|
return {
|
|
2587
2934
|
effectType,
|
|
2588
2935
|
strictEffectType,
|
|
@@ -2599,10 +2946,79 @@ function make2(ts, typeChecker) {
|
|
|
2599
2946
|
pipeableType,
|
|
2600
2947
|
pipeCall,
|
|
2601
2948
|
scopeType,
|
|
2602
|
-
promiseLike
|
|
2949
|
+
promiseLike,
|
|
2950
|
+
extendsEffectService,
|
|
2951
|
+
extendsContextTag,
|
|
2952
|
+
extendsSchemaClass,
|
|
2953
|
+
extendsSchemaTaggedClass,
|
|
2954
|
+
extendsSchemaTaggedError,
|
|
2955
|
+
extendsSchemaTaggedRequest
|
|
2603
2956
|
};
|
|
2604
2957
|
}
|
|
2605
2958
|
|
|
2959
|
+
// src/diagnostics/classSelfMismatch.ts
|
|
2960
|
+
var classSelfMismatch = createDiagnostic({
|
|
2961
|
+
name: "classSelfMismatch",
|
|
2962
|
+
code: 20,
|
|
2963
|
+
severity: "error",
|
|
2964
|
+
apply: fn("classSelfMismatch.apply")(function* (sourceFile, report) {
|
|
2965
|
+
const ts = yield* service(TypeScriptApi);
|
|
2966
|
+
const typeParser = yield* service(TypeParser);
|
|
2967
|
+
const nodeToVisit = [];
|
|
2968
|
+
const appendNodeToVisit = (node) => {
|
|
2969
|
+
nodeToVisit.push(node);
|
|
2970
|
+
return void 0;
|
|
2971
|
+
};
|
|
2972
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
2973
|
+
while (nodeToVisit.length > 0) {
|
|
2974
|
+
const node = nodeToVisit.shift();
|
|
2975
|
+
if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
|
|
2976
|
+
const result = yield* pipe(
|
|
2977
|
+
typeParser.extendsEffectService(node),
|
|
2978
|
+
orElse2(() => typeParser.extendsContextTag(node)),
|
|
2979
|
+
orElse2(() => typeParser.extendsSchemaClass(node)),
|
|
2980
|
+
orElse2(() => typeParser.extendsSchemaTaggedClass(node)),
|
|
2981
|
+
orElse2(() => typeParser.extendsSchemaTaggedError(node)),
|
|
2982
|
+
orElse2(() => typeParser.extendsSchemaTaggedRequest(node)),
|
|
2983
|
+
orElse2(() => void_)
|
|
2984
|
+
);
|
|
2985
|
+
if (result) {
|
|
2986
|
+
const { className, selfTypeNode } = result;
|
|
2987
|
+
let actualName = "";
|
|
2988
|
+
if (ts.isTypeReferenceNode(selfTypeNode)) {
|
|
2989
|
+
if (ts.isIdentifier(selfTypeNode.typeName)) {
|
|
2990
|
+
actualName = selfTypeNode.typeName.text;
|
|
2991
|
+
} else if (ts.isQualifiedName(selfTypeNode.typeName)) {
|
|
2992
|
+
actualName = selfTypeNode.typeName.right.text;
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2995
|
+
const expectedName = className.text;
|
|
2996
|
+
if (actualName !== expectedName) {
|
|
2997
|
+
report({
|
|
2998
|
+
location: selfTypeNode,
|
|
2999
|
+
messageText: `Self type parameter should be '${expectedName}'`,
|
|
3000
|
+
fixes: [{
|
|
3001
|
+
fixName: "classSelfMismatch_fix",
|
|
3002
|
+
description: `Replace '${actualName}' with '${expectedName}'`,
|
|
3003
|
+
apply: gen(function* () {
|
|
3004
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
3005
|
+
const typeArgs = ts.isTypeReferenceNode(selfTypeNode) ? selfTypeNode.typeArguments : void 0;
|
|
3006
|
+
const newTypeReference = ts.factory.createTypeReferenceNode(
|
|
3007
|
+
ts.factory.createIdentifier(expectedName),
|
|
3008
|
+
typeArgs
|
|
3009
|
+
);
|
|
3010
|
+
changeTracker.replaceNode(sourceFile, selfTypeNode, newTypeReference);
|
|
3011
|
+
})
|
|
3012
|
+
}]
|
|
3013
|
+
});
|
|
3014
|
+
}
|
|
3015
|
+
}
|
|
3016
|
+
}
|
|
3017
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
3018
|
+
}
|
|
3019
|
+
})
|
|
3020
|
+
});
|
|
3021
|
+
|
|
2606
3022
|
// src/diagnostics/duplicatePackage.ts
|
|
2607
3023
|
var checkedPackagesCache = /* @__PURE__ */ new Map();
|
|
2608
3024
|
var programResolvedCacheSize = /* @__PURE__ */ new Map();
|
|
@@ -2612,6 +3028,7 @@ var duplicatePackage = createDiagnostic({
|
|
|
2612
3028
|
severity: "warning",
|
|
2613
3029
|
apply: fn("duplicatePackage.apply")(function* (sourceFile, report) {
|
|
2614
3030
|
const program = yield* service(TypeScriptProgram);
|
|
3031
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
2615
3032
|
const options = yield* service(LanguageServicePluginOptions);
|
|
2616
3033
|
if (sourceFile.statements.length < 1) return;
|
|
2617
3034
|
let resolvedPackages = checkedPackagesCache.get(sourceFile.fileName) || {};
|
|
@@ -2621,7 +3038,7 @@ var duplicatePackage = createDiagnostic({
|
|
|
2621
3038
|
const seenPackages = /* @__PURE__ */ new Set();
|
|
2622
3039
|
resolvedPackages = {};
|
|
2623
3040
|
program.getSourceFiles().map((_) => {
|
|
2624
|
-
const packageInfo = parsePackageContentNameAndVersionFromScope(_);
|
|
3041
|
+
const packageInfo = tsUtils.parsePackageContentNameAndVersionFromScope(_);
|
|
2625
3042
|
if (!packageInfo) return;
|
|
2626
3043
|
const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
|
|
2627
3044
|
if (seenPackages.has(packageNameAndVersion)) return;
|
|
@@ -2638,7 +3055,7 @@ var duplicatePackage = createDiagnostic({
|
|
|
2638
3055
|
if (Object.keys(resolvedPackages[packageName]).length > 1) {
|
|
2639
3056
|
const versions = Object.keys(resolvedPackages[packageName]);
|
|
2640
3057
|
report({
|
|
2641
|
-
|
|
3058
|
+
location: sourceFile.statements[0],
|
|
2642
3059
|
messageText: `Package ${packageName} is referenced multiple times with different versions (${versions.join(", ")}) and may cause unexpected type errors.
|
|
2643
3060
|
Cleanup your dependencies and your package lockfile to avoid multiple instances of this package and reload the project.
|
|
2644
3061
|
If this is intended set the LSP config "allowedDuplicatedPackages" to ${JSON.stringify(options.allowedDuplicatedPackages.concat([packageName]))}.
|
|
@@ -2685,7 +3102,7 @@ var effectInVoidSuccess = createDiagnostic({
|
|
|
2685
3102
|
map3(({ voidedEffect }) => {
|
|
2686
3103
|
report(
|
|
2687
3104
|
{
|
|
2688
|
-
node,
|
|
3105
|
+
location: node,
|
|
2689
3106
|
messageText: `There is a nested '${typeChecker.typeToString(voidedEffect)}' in the 'void' success channel, beware that this could lead to nested Effect<Effect<...>> that won't be executed.`,
|
|
2690
3107
|
fixes: []
|
|
2691
3108
|
}
|
|
@@ -2734,7 +3151,7 @@ var floatingEffect = createDiagnostic({
|
|
|
2734
3151
|
);
|
|
2735
3152
|
if (isNone2(allowedFloatingEffects)) {
|
|
2736
3153
|
report({
|
|
2737
|
-
node,
|
|
3154
|
+
location: node,
|
|
2738
3155
|
messageText: `Effect must be yielded or assigned to a variable.`,
|
|
2739
3156
|
fixes: []
|
|
2740
3157
|
});
|
|
@@ -2777,7 +3194,7 @@ var genericEffectServices = createDiagnostic({
|
|
|
2777
3194
|
typeParser.contextTag(type, node),
|
|
2778
3195
|
map3(() => {
|
|
2779
3196
|
report({
|
|
2780
|
-
|
|
3197
|
+
location: reportAt,
|
|
2781
3198
|
messageText: `Effect Services with type parameters are not supported because they cannot be properly discriminated at runtime, which may cause unexpected behavior.`,
|
|
2782
3199
|
fixes: []
|
|
2783
3200
|
});
|
|
@@ -2799,17 +3216,16 @@ var importFromBarrel = createDiagnostic({
|
|
|
2799
3216
|
const languageServicePluginOptions = yield* service(LanguageServicePluginOptions);
|
|
2800
3217
|
if (languageServicePluginOptions.namespaceImportPackages.length === 0) return;
|
|
2801
3218
|
const ts = yield* service(TypeScriptApi);
|
|
3219
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
2802
3220
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2803
3221
|
const program = yield* service(TypeScriptProgram);
|
|
2804
3222
|
const packageNamesToCheck = flatten(
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
(packageName) => resolveModulePattern(sourceFile, packageName)
|
|
2808
|
-
)
|
|
3223
|
+
languageServicePluginOptions.namespaceImportPackages.map(
|
|
3224
|
+
(packageName) => tsUtils.resolveModulePattern(sourceFile, packageName)
|
|
2809
3225
|
)
|
|
2810
3226
|
);
|
|
2811
3227
|
const isImportedFromBarrelExport = (element) => {
|
|
2812
|
-
const getModuleSpecifier = makeGetModuleSpecifier(
|
|
3228
|
+
const getModuleSpecifier = tsUtils.makeGetModuleSpecifier();
|
|
2813
3229
|
const resolveExternalModuleName = makeResolveExternalModuleName(typeChecker);
|
|
2814
3230
|
if (!(getModuleSpecifier && resolveExternalModuleName)) return;
|
|
2815
3231
|
const importDeclaration = ts.findAncestor(element, (node) => ts.isImportDeclaration(node));
|
|
@@ -2885,7 +3301,7 @@ var importFromBarrel = createDiagnostic({
|
|
|
2885
3301
|
unbarrelledFileName
|
|
2886
3302
|
} = result;
|
|
2887
3303
|
report({
|
|
2888
|
-
node,
|
|
3304
|
+
location: node,
|
|
2889
3305
|
messageText: `Importing from barrel module ${barrelModuleName} is not allowed.`,
|
|
2890
3306
|
fixes: [
|
|
2891
3307
|
{
|
|
@@ -2999,7 +3415,7 @@ var leakingRequirements = createDiagnostic({
|
|
|
2999
3415
|
function reportLeakingRequirements(node, requirements) {
|
|
3000
3416
|
if (requirements.length === 0) return;
|
|
3001
3417
|
report({
|
|
3002
|
-
node,
|
|
3418
|
+
location: node,
|
|
3003
3419
|
messageText: `This Service is leaking the ${requirements.map((_) => typeChecker.typeToString(_)).join(" | ")} requirement.
|
|
3004
3420
|
If these requirements cannot be cached and are expected to be provided per method invocation (e.g. HttpServerRequest), you can safely disable this diagnostic for this line through quickfixes.
|
|
3005
3421
|
More info at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage`,
|
|
@@ -3079,7 +3495,7 @@ var missingEffectContext = createDiagnostic({
|
|
|
3079
3495
|
map3(
|
|
3080
3496
|
(missingTypes) => missingTypes.length > 0 ? report(
|
|
3081
3497
|
{
|
|
3082
|
-
node,
|
|
3498
|
+
location: node,
|
|
3083
3499
|
messageText: `Missing '${sortTypes(missingTypes).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect context.`,
|
|
3084
3500
|
fixes: []
|
|
3085
3501
|
}
|
|
@@ -3099,18 +3515,15 @@ var missingEffectError = createDiagnostic({
|
|
|
3099
3515
|
severity: "error",
|
|
3100
3516
|
apply: fn("missingEffectError.apply")(function* (sourceFile, report) {
|
|
3101
3517
|
const ts = yield* service(TypeScriptApi);
|
|
3518
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
3102
3519
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3103
3520
|
const typeParser = yield* service(TypeParser);
|
|
3104
3521
|
const typeOrder = yield* deterministicTypeOrder;
|
|
3105
|
-
const effectModuleIdentifier =
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
),
|
|
3111
|
-
map3((_) => _.text),
|
|
3112
|
-
orElse2(() => succeed("Effect"))
|
|
3113
|
-
);
|
|
3522
|
+
const effectModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3523
|
+
sourceFile,
|
|
3524
|
+
"effect",
|
|
3525
|
+
"Effect"
|
|
3526
|
+
) || "Effect";
|
|
3114
3527
|
const createDieMessage = (message) => ts.factory.createCallExpression(
|
|
3115
3528
|
ts.factory.createPropertyAccessExpression(
|
|
3116
3529
|
ts.factory.createIdentifier(effectModuleIdentifier),
|
|
@@ -3212,7 +3625,7 @@ var missingEffectError = createDiagnostic({
|
|
|
3212
3625
|
}
|
|
3213
3626
|
report(
|
|
3214
3627
|
{
|
|
3215
|
-
node,
|
|
3628
|
+
location: node,
|
|
3216
3629
|
messageText: `Missing '${sortTypes(result.missingErrorTypes).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect errors.`,
|
|
3217
3630
|
fixes
|
|
3218
3631
|
}
|
|
@@ -3276,7 +3689,7 @@ var missingReturnYieldStar = createDiagnostic({
|
|
|
3276
3689
|
})
|
|
3277
3690
|
}] : [];
|
|
3278
3691
|
report({
|
|
3279
|
-
node,
|
|
3692
|
+
location: node,
|
|
3280
3693
|
messageText: `Yielded Effect never succeeds, so it is best to use a 'return yield*' instead.`,
|
|
3281
3694
|
fixes: fix
|
|
3282
3695
|
});
|
|
@@ -3332,7 +3745,7 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
3332
3745
|
}
|
|
3333
3746
|
brokenGenerators.forEach(
|
|
3334
3747
|
(node) => report({
|
|
3335
|
-
node,
|
|
3748
|
+
location: node,
|
|
3336
3749
|
messageText: `Seems like you used yield instead of yield* inside this Effect.gen.`,
|
|
3337
3750
|
fixes: []
|
|
3338
3751
|
})
|
|
@@ -3354,7 +3767,7 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
3354
3767
|
})
|
|
3355
3768
|
}] : [];
|
|
3356
3769
|
report({
|
|
3357
|
-
node,
|
|
3770
|
+
location: node,
|
|
3358
3771
|
messageText: `When yielding Effects inside Effect.gen, you should use yield* instead of yield.`,
|
|
3359
3772
|
fixes: fix
|
|
3360
3773
|
});
|
|
@@ -3369,26 +3782,19 @@ var multipleEffectProvide = createDiagnostic({
|
|
|
3369
3782
|
severity: "warning",
|
|
3370
3783
|
apply: fn("multipleEffectProvide.apply")(function* (sourceFile, report) {
|
|
3371
3784
|
const ts = yield* service(TypeScriptApi);
|
|
3785
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
3372
3786
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3373
3787
|
const typeParser = yield* service(TypeParser);
|
|
3374
|
-
const effectModuleIdentifier =
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3385
|
-
sourceFile,
|
|
3386
|
-
"effect",
|
|
3387
|
-
"Layer"
|
|
3388
|
-
),
|
|
3389
|
-
map3((_) => _.text),
|
|
3390
|
-
orElse2(() => succeed("Layer"))
|
|
3391
|
-
);
|
|
3788
|
+
const effectModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3789
|
+
sourceFile,
|
|
3790
|
+
"effect",
|
|
3791
|
+
"Effect"
|
|
3792
|
+
) || "Effect";
|
|
3793
|
+
const layerModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3794
|
+
sourceFile,
|
|
3795
|
+
"effect",
|
|
3796
|
+
"Layer"
|
|
3797
|
+
) || "Layer";
|
|
3392
3798
|
const parseEffectProvideLayer = (node) => {
|
|
3393
3799
|
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && node.expression.name.text === "provide" && node.arguments.length > 0) {
|
|
3394
3800
|
const layer = node.arguments[0];
|
|
@@ -3418,7 +3824,7 @@ var multipleEffectProvide = createDiagnostic({
|
|
|
3418
3824
|
for (const chunk of previousLayers) {
|
|
3419
3825
|
if (chunk.length < 2) continue;
|
|
3420
3826
|
report({
|
|
3421
|
-
|
|
3827
|
+
location: chunk[0].node,
|
|
3422
3828
|
messageText: "Avoid chaining Effect.provide calls, as this can lead to service lifecycle issues. Instead, merge layers and provide them in a single call.",
|
|
3423
3829
|
fixes: [{
|
|
3424
3830
|
fixName: "multipleEffectProvide_fix",
|
|
@@ -3466,6 +3872,327 @@ var multipleEffectProvide = createDiagnostic({
|
|
|
3466
3872
|
})
|
|
3467
3873
|
});
|
|
3468
3874
|
|
|
3875
|
+
// src/refactors/writeTagClassAccessors.ts
|
|
3876
|
+
var generate = fn("writeTagClassAccessors.generate")(function* (sourceFile, service2, className, atLocation, involvedMembers) {
|
|
3877
|
+
const ts = yield* service(TypeScriptApi);
|
|
3878
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
3879
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
3880
|
+
const typeParser = yield* service(TypeParser);
|
|
3881
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
3882
|
+
const insertLocation = atLocation.members.length > 0 ? atLocation.members[0].pos : atLocation.getEnd() - 1;
|
|
3883
|
+
const effectIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3884
|
+
sourceFile,
|
|
3885
|
+
"effect",
|
|
3886
|
+
"Effect"
|
|
3887
|
+
) || "Effect";
|
|
3888
|
+
const createFunctionProperty = (className2, propertyName, type, forceAny) => {
|
|
3889
|
+
const arrowBody = ts.factory.createCallExpression(
|
|
3890
|
+
ts.factory.createPropertyAccessExpression(
|
|
3891
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
3892
|
+
"andThen"
|
|
3893
|
+
),
|
|
3894
|
+
void 0,
|
|
3895
|
+
[
|
|
3896
|
+
ts.factory.createIdentifier(className2.text),
|
|
3897
|
+
ts.factory.createArrowFunction(
|
|
3898
|
+
void 0,
|
|
3899
|
+
void 0,
|
|
3900
|
+
[ts.factory.createParameterDeclaration(
|
|
3901
|
+
void 0,
|
|
3902
|
+
void 0,
|
|
3903
|
+
"_",
|
|
3904
|
+
void 0,
|
|
3905
|
+
forceAny ? ts.factory.createTypeReferenceNode("any") : void 0
|
|
3906
|
+
)],
|
|
3907
|
+
void 0,
|
|
3908
|
+
void 0,
|
|
3909
|
+
ts.factory.createCallExpression(
|
|
3910
|
+
ts.factory.createPropertyAccessExpression(
|
|
3911
|
+
ts.factory.createIdentifier("_"),
|
|
3912
|
+
propertyName
|
|
3913
|
+
),
|
|
3914
|
+
void 0,
|
|
3915
|
+
[
|
|
3916
|
+
ts.factory.createSpreadElement(ts.factory.createIdentifier("args"))
|
|
3917
|
+
]
|
|
3918
|
+
)
|
|
3919
|
+
)
|
|
3920
|
+
]
|
|
3921
|
+
);
|
|
3922
|
+
return ts.factory.createPropertyDeclaration(
|
|
3923
|
+
[ts.factory.createModifier(ts.SyntaxKind.StaticKeyword)],
|
|
3924
|
+
propertyName,
|
|
3925
|
+
void 0,
|
|
3926
|
+
type,
|
|
3927
|
+
ts.factory.createArrowFunction(
|
|
3928
|
+
void 0,
|
|
3929
|
+
void 0,
|
|
3930
|
+
[ts.factory.createParameterDeclaration(
|
|
3931
|
+
void 0,
|
|
3932
|
+
ts.factory.createToken(ts.SyntaxKind.DotDotDotToken),
|
|
3933
|
+
"args",
|
|
3934
|
+
void 0,
|
|
3935
|
+
forceAny ? ts.factory.createArrayTypeNode(ts.factory.createTypeReferenceNode("any")) : void 0
|
|
3936
|
+
)],
|
|
3937
|
+
void 0,
|
|
3938
|
+
void 0,
|
|
3939
|
+
forceAny ? ts.factory.createAsExpression(arrowBody, ts.factory.createTypeReferenceNode("any")) : arrowBody
|
|
3940
|
+
)
|
|
3941
|
+
);
|
|
3942
|
+
};
|
|
3943
|
+
const generateReturnType = (type, atLocation2, className2) => pipe(
|
|
3944
|
+
typeParser.effectType(type, atLocation2),
|
|
3945
|
+
flatMap2((returnedEffect) => {
|
|
3946
|
+
const contextType = returnedEffect.R.flags & ts.TypeFlags.Never ? ts.factory.createTypeReferenceNode(className2.text) : ts.factory.createUnionTypeNode(
|
|
3947
|
+
[
|
|
3948
|
+
ts.factory.createTypeReferenceNode(className2.text),
|
|
3949
|
+
typeChecker.typeToTypeNode(returnedEffect.R, atLocation2, ts.NodeBuilderFlags.NoTruncation)
|
|
3950
|
+
]
|
|
3951
|
+
);
|
|
3952
|
+
const successType = typeChecker.typeToTypeNode(
|
|
3953
|
+
returnedEffect.A,
|
|
3954
|
+
atLocation2,
|
|
3955
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
3956
|
+
);
|
|
3957
|
+
if (!successType) return fail("error generating success type");
|
|
3958
|
+
const failureType = typeChecker.typeToTypeNode(
|
|
3959
|
+
returnedEffect.E,
|
|
3960
|
+
atLocation2,
|
|
3961
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
3962
|
+
);
|
|
3963
|
+
if (!failureType) return fail("error generating failure type");
|
|
3964
|
+
const typeNode = ts.factory.createTypeReferenceNode(
|
|
3965
|
+
ts.factory.createQualifiedName(
|
|
3966
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
3967
|
+
ts.factory.createIdentifier("Effect")
|
|
3968
|
+
),
|
|
3969
|
+
[successType, failureType, contextType]
|
|
3970
|
+
);
|
|
3971
|
+
return succeed(typeNode);
|
|
3972
|
+
}),
|
|
3973
|
+
orElse2(
|
|
3974
|
+
() => pipe(
|
|
3975
|
+
typeParser.promiseLike(type, atLocation2),
|
|
3976
|
+
flatMap2(({ type: type2 }) => {
|
|
3977
|
+
const successType = typeChecker.typeToTypeNode(
|
|
3978
|
+
type2,
|
|
3979
|
+
atLocation2,
|
|
3980
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
3981
|
+
);
|
|
3982
|
+
if (!successType) return fail("error generating success type");
|
|
3983
|
+
return succeed(ts.factory.createTypeReferenceNode(
|
|
3984
|
+
ts.factory.createQualifiedName(
|
|
3985
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
3986
|
+
ts.factory.createIdentifier("Effect")
|
|
3987
|
+
),
|
|
3988
|
+
[
|
|
3989
|
+
successType,
|
|
3990
|
+
ts.factory.createTypeReferenceNode(
|
|
3991
|
+
ts.factory.createQualifiedName(
|
|
3992
|
+
ts.factory.createIdentifier("Cause"),
|
|
3993
|
+
ts.factory.createIdentifier("UnknownException")
|
|
3994
|
+
)
|
|
3995
|
+
),
|
|
3996
|
+
ts.factory.createTypeReferenceNode(className2.text)
|
|
3997
|
+
]
|
|
3998
|
+
));
|
|
3999
|
+
})
|
|
4000
|
+
)
|
|
4001
|
+
),
|
|
4002
|
+
orElse2(() => {
|
|
4003
|
+
const successType = typeChecker.typeToTypeNode(type, atLocation2, ts.NodeBuilderFlags.NoTruncation);
|
|
4004
|
+
if (!successType) return fail("error generating success type");
|
|
4005
|
+
const typeNode = ts.factory.createTypeReferenceNode(
|
|
4006
|
+
ts.factory.createQualifiedName(
|
|
4007
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
4008
|
+
ts.factory.createIdentifier("Effect")
|
|
4009
|
+
),
|
|
4010
|
+
[
|
|
4011
|
+
successType,
|
|
4012
|
+
ts.factory.createTypeReferenceNode("never"),
|
|
4013
|
+
ts.factory.createTypeReferenceNode(className2.text)
|
|
4014
|
+
]
|
|
4015
|
+
);
|
|
4016
|
+
return succeed(typeNode);
|
|
4017
|
+
})
|
|
4018
|
+
);
|
|
4019
|
+
const proxySignature = (signature, atLocation2, className2) => gen(function* () {
|
|
4020
|
+
const signatureDeclaration = typeChecker.signatureToSignatureDeclaration(
|
|
4021
|
+
signature,
|
|
4022
|
+
ts.SyntaxKind.FunctionType,
|
|
4023
|
+
atLocation2,
|
|
4024
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
4025
|
+
);
|
|
4026
|
+
if (!signatureDeclaration) return yield* fail("error generating signature");
|
|
4027
|
+
const returnType = yield* generateReturnType(signature.getReturnType(), atLocation2, className2);
|
|
4028
|
+
return ts.factory.createFunctionTypeNode(
|
|
4029
|
+
signatureDeclaration.typeParameters,
|
|
4030
|
+
signatureDeclaration.parameters,
|
|
4031
|
+
returnType
|
|
4032
|
+
);
|
|
4033
|
+
});
|
|
4034
|
+
for (const { property, propertyType } of involvedMembers) {
|
|
4035
|
+
const callSignatures = [];
|
|
4036
|
+
let propertyDeclaration = void 0;
|
|
4037
|
+
for (const signature of propertyType.getCallSignatures()) {
|
|
4038
|
+
yield* pipe(
|
|
4039
|
+
proxySignature(signature, atLocation, className),
|
|
4040
|
+
map3((sig) => {
|
|
4041
|
+
callSignatures.push(sig);
|
|
4042
|
+
}),
|
|
4043
|
+
ignore
|
|
4044
|
+
);
|
|
4045
|
+
}
|
|
4046
|
+
const allSignatures = ts.factory.createIntersectionTypeNode(callSignatures);
|
|
4047
|
+
const type = tsUtils.simplifyTypeNode(allSignatures);
|
|
4048
|
+
propertyDeclaration = createFunctionProperty(className, property.getName(), type, callSignatures.length > 1);
|
|
4049
|
+
const oldProperty = atLocation.members.filter(ts.isPropertyDeclaration).find((p) => {
|
|
4050
|
+
const symbol3 = typeChecker.getSymbolAtLocation(p.name);
|
|
4051
|
+
return symbol3?.getName() === property.getName();
|
|
4052
|
+
});
|
|
4053
|
+
if (oldProperty) {
|
|
4054
|
+
changeTracker.deleteRange(sourceFile, {
|
|
4055
|
+
pos: oldProperty.getStart(sourceFile),
|
|
4056
|
+
end: oldProperty.getEnd()
|
|
4057
|
+
});
|
|
4058
|
+
changeTracker.insertNodeAt(sourceFile, oldProperty.getStart(sourceFile), propertyDeclaration);
|
|
4059
|
+
} else {
|
|
4060
|
+
changeTracker.insertNodeAt(sourceFile, insertLocation, propertyDeclaration, { suffix: "\n" });
|
|
4061
|
+
}
|
|
4062
|
+
}
|
|
4063
|
+
});
|
|
4064
|
+
var parse2 = fn("writeTagClassAccessors.parse")(function* (node) {
|
|
4065
|
+
const ts = yield* service(TypeScriptApi);
|
|
4066
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
4067
|
+
const typeParser = yield* service(TypeParser);
|
|
4068
|
+
if (!ts.isClassDeclaration(node)) return yield* fail("not a class declaration");
|
|
4069
|
+
const { Service, accessors: accessors2, className } = yield* pipe(
|
|
4070
|
+
typeParser.extendsEffectService(node),
|
|
4071
|
+
orElse2(() => fail("not a class extending Effect.Service call"))
|
|
4072
|
+
);
|
|
4073
|
+
if (accessors2 !== true) return yield* fail("accessors are not enabled in the Effect.Service call");
|
|
4074
|
+
const involvedMembers = [];
|
|
4075
|
+
for (const property of typeChecker.getPropertiesOfType(Service)) {
|
|
4076
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(property, node);
|
|
4077
|
+
const callSignatures = propertyType.getCallSignatures();
|
|
4078
|
+
if (callSignatures.length > 0) {
|
|
4079
|
+
const withTypeParameters = callSignatures.filter((_) => _.typeParameters && _.typeParameters.length > 0);
|
|
4080
|
+
if (callSignatures.length > 1 || withTypeParameters.length > 0) involvedMembers.push({ property, propertyType });
|
|
4081
|
+
}
|
|
4082
|
+
}
|
|
4083
|
+
const hash2 = involvedMembers.map(({ property, propertyType }) => {
|
|
4084
|
+
return property.getName() + ": " + typeChecker.typeToString(propertyType);
|
|
4085
|
+
}).concat([className.text]).join("\n");
|
|
4086
|
+
return { Service, className, atLocation: node, hash: cyrb53(hash2), involvedMembers };
|
|
4087
|
+
});
|
|
4088
|
+
var writeTagClassAccessors = createRefactor({
|
|
4089
|
+
name: "writeTagClassAccessors",
|
|
4090
|
+
description: "Implement accessors methods with generics or multiple signatures",
|
|
4091
|
+
apply: fn("writeTagClassAccessors.apply")(function* (sourceFile, textRange) {
|
|
4092
|
+
const ts = yield* service(TypeScriptApi);
|
|
4093
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
4094
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
4095
|
+
const typeParser = yield* service(TypeParser);
|
|
4096
|
+
const parseNode = (node) => pipe(
|
|
4097
|
+
parse2(node),
|
|
4098
|
+
map3(({ Service, atLocation, className, involvedMembers }) => ({
|
|
4099
|
+
kind: "refactor.rewrite.effect.writeTagClassAccessors",
|
|
4100
|
+
description: "Implement Service accessors",
|
|
4101
|
+
apply: pipe(
|
|
4102
|
+
generate(sourceFile, Service, className, atLocation, involvedMembers),
|
|
4103
|
+
provideService(TypeScriptUtils, tsUtils),
|
|
4104
|
+
provideService(TypeParser, typeParser),
|
|
4105
|
+
provideService(TypeCheckerApi, typeChecker),
|
|
4106
|
+
provideService(TypeScriptApi, ts)
|
|
4107
|
+
)
|
|
4108
|
+
}))
|
|
4109
|
+
);
|
|
4110
|
+
const parentNodes = tsUtils.getAncestorNodesInRange(sourceFile, textRange);
|
|
4111
|
+
return yield* pipe(
|
|
4112
|
+
firstSuccessOf(parentNodes.map(parseNode)),
|
|
4113
|
+
orElse2(() => fail(new RefactorNotApplicableError()))
|
|
4114
|
+
);
|
|
4115
|
+
})
|
|
4116
|
+
});
|
|
4117
|
+
|
|
4118
|
+
// src/codegens/accessors.ts
|
|
4119
|
+
var accessors = createCodegen({
|
|
4120
|
+
name: "accessors",
|
|
4121
|
+
apply: fn("accessors.apply")(function* (sourceFile, textRange) {
|
|
4122
|
+
const ts = yield* service(TypeScriptApi);
|
|
4123
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
4124
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
4125
|
+
const typeParser = yield* service(TypeParser);
|
|
4126
|
+
const nodeAndCommentRange = tsUtils.findNodeWithLeadingCommentAtPosition(sourceFile, textRange.pos);
|
|
4127
|
+
if (!nodeAndCommentRange) return yield* fail(new CodegenNotApplicableError("no node and comment range"));
|
|
4128
|
+
return yield* pipe(
|
|
4129
|
+
parse2(nodeAndCommentRange.node),
|
|
4130
|
+
map3(
|
|
4131
|
+
(_) => ({
|
|
4132
|
+
hash: _.hash,
|
|
4133
|
+
description: "Generate accessors for the service",
|
|
4134
|
+
apply: pipe(
|
|
4135
|
+
generate(sourceFile, _.Service, _.className, _.atLocation, _.involvedMembers),
|
|
4136
|
+
provideService(TypeScriptApi, ts),
|
|
4137
|
+
provideService(TypeScriptUtils, tsUtils),
|
|
4138
|
+
provideService(TypeCheckerApi, typeChecker),
|
|
4139
|
+
provideService(TypeParser, typeParser)
|
|
4140
|
+
)
|
|
4141
|
+
})
|
|
4142
|
+
),
|
|
4143
|
+
orElse2((cause) => fail(new CodegenNotApplicableError(cause)))
|
|
4144
|
+
);
|
|
4145
|
+
})
|
|
4146
|
+
});
|
|
4147
|
+
|
|
4148
|
+
// src/codegens.ts
|
|
4149
|
+
var codegens = [accessors];
|
|
4150
|
+
|
|
4151
|
+
// src/diagnostics/outdatedEffectCodegen.ts
|
|
4152
|
+
var outdatedEffectCodegen = createDiagnostic({
|
|
4153
|
+
name: "outdatedEffectCodegen",
|
|
4154
|
+
code: 19,
|
|
4155
|
+
severity: "warning",
|
|
4156
|
+
apply: fn("outdatedEffectCodegen.apply")(function* (sourceFile, _report) {
|
|
4157
|
+
const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
|
|
4158
|
+
for (const { codegen, hash: hash2, range } of codegensWithRanges) {
|
|
4159
|
+
yield* pipe(
|
|
4160
|
+
getEditsForCodegen([codegen], sourceFile, range),
|
|
4161
|
+
map3((applicable) => {
|
|
4162
|
+
if (applicable.hash !== hash2) {
|
|
4163
|
+
_report({
|
|
4164
|
+
location: range,
|
|
4165
|
+
messageText: `Codegen ${codegen.name} result is outdated`,
|
|
4166
|
+
fixes: [
|
|
4167
|
+
{
|
|
4168
|
+
fixName: "outdatedEffectCodegen_fix",
|
|
4169
|
+
description: `Re-run ${codegen.name}`,
|
|
4170
|
+
apply: applicable.apply
|
|
4171
|
+
},
|
|
4172
|
+
{
|
|
4173
|
+
fixName: "outdatedEffectCodegen_ignore",
|
|
4174
|
+
description: `Ignore this ${codegen.name} update`,
|
|
4175
|
+
apply: applicable.ignore
|
|
4176
|
+
}
|
|
4177
|
+
]
|
|
4178
|
+
});
|
|
4179
|
+
}
|
|
4180
|
+
}),
|
|
4181
|
+
orElse2(
|
|
4182
|
+
(e) => sync(() => {
|
|
4183
|
+
_report({
|
|
4184
|
+
location: range,
|
|
4185
|
+
messageText: `Codegen ${codegen.name} is not applicable here: ${e.cause}`,
|
|
4186
|
+
fixes: []
|
|
4187
|
+
});
|
|
4188
|
+
})
|
|
4189
|
+
),
|
|
4190
|
+
ignore
|
|
4191
|
+
);
|
|
4192
|
+
}
|
|
4193
|
+
})
|
|
4194
|
+
});
|
|
4195
|
+
|
|
3469
4196
|
// src/diagnostics/returnEffectInGen.ts
|
|
3470
4197
|
var returnEffectInGen = createDiagnostic({
|
|
3471
4198
|
name: "returnEffectInGen",
|
|
@@ -3517,7 +4244,7 @@ var returnEffectInGen = createDiagnostic({
|
|
|
3517
4244
|
})
|
|
3518
4245
|
}] : [];
|
|
3519
4246
|
report({
|
|
3520
|
-
node,
|
|
4247
|
+
location: node,
|
|
3521
4248
|
messageText: `You are returning an Effect-able type inside a generator function, and will result in nested Effect<Effect<...>>.
|
|
3522
4249
|
Maybe you wanted to return yield* instead?
|
|
3523
4250
|
Nested Effect-able types may be intended if you plan to later manually flatten or unwrap this Effect, if so you can safely disable this diagnostic for this line through quickfixes.`,
|
|
@@ -3540,17 +4267,14 @@ var scopeInLayerEffect = createDiagnostic({
|
|
|
3540
4267
|
severity: "warning",
|
|
3541
4268
|
apply: fn("scopeInLayerEffect.apply")(function* (sourceFile, report) {
|
|
3542
4269
|
const ts = yield* service(TypeScriptApi);
|
|
4270
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
3543
4271
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3544
4272
|
const typeParser = yield* service(TypeParser);
|
|
3545
|
-
const layerModuleIdentifier =
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
),
|
|
3551
|
-
map3((_) => _.text),
|
|
3552
|
-
orElse2(() => succeed("Layer"))
|
|
3553
|
-
);
|
|
4273
|
+
const layerModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
4274
|
+
sourceFile,
|
|
4275
|
+
"effect",
|
|
4276
|
+
"Layer"
|
|
4277
|
+
) || "Layer";
|
|
3554
4278
|
function parseLayerEffectApiCall(node) {
|
|
3555
4279
|
if (!ts.isCallExpression(node)) return;
|
|
3556
4280
|
const expression = node.expression;
|
|
@@ -3576,7 +4300,7 @@ var scopeInLayerEffect = createDiagnostic({
|
|
|
3576
4300
|
firstSuccessOf(entries.map((type2) => typeParser.scopeType(type2, node))),
|
|
3577
4301
|
map3(
|
|
3578
4302
|
() => report({
|
|
3579
|
-
node,
|
|
4303
|
+
location: node,
|
|
3580
4304
|
messageText: `Seems like you are constructing a layer with a scope in the requirements.
|
|
3581
4305
|
Consider using "scoped" instead to get rid of the scope in the requirements.`,
|
|
3582
4306
|
fixes: methodIdentifier ? [{
|
|
@@ -3692,7 +4416,7 @@ var strictBooleanExpressions = createDiagnostic({
|
|
|
3692
4416
|
if (type.flags & ts.TypeFlags.BooleanLiteral) continue;
|
|
3693
4417
|
const typeName = typeChecker.typeToString(type);
|
|
3694
4418
|
report({
|
|
3695
|
-
|
|
4419
|
+
location: nodeToCheck,
|
|
3696
4420
|
messageText: `Unexpected \`${typeName}\` type in condition, expected strictly a boolean instead.`,
|
|
3697
4421
|
fixes: []
|
|
3698
4422
|
});
|
|
@@ -3734,7 +4458,7 @@ var tryCatchInEffectGen = createDiagnostic({
|
|
|
3734
4458
|
orElse2(() => typeParser.effectFnGen(effectGenNode)),
|
|
3735
4459
|
map3(() => {
|
|
3736
4460
|
report({
|
|
3737
|
-
node,
|
|
4461
|
+
location: node,
|
|
3738
4462
|
messageText: "Avoid using try/catch inside Effect generators. Use Effect's error handling mechanisms instead (e.g., Effect.try, Effect.tryPromise, Effect.catchAll, Effect.catchTag).",
|
|
3739
4463
|
fixes: []
|
|
3740
4464
|
});
|
|
@@ -3769,7 +4493,7 @@ var unnecessaryEffectGen = createDiagnostic({
|
|
|
3769
4493
|
typeParser.unnecessaryEffectGen(node),
|
|
3770
4494
|
map3(
|
|
3771
4495
|
({ replacementNode }) => report({
|
|
3772
|
-
node,
|
|
4496
|
+
location: node,
|
|
3773
4497
|
messageText: `This Effect.gen contains a single return statement.`,
|
|
3774
4498
|
fixes: [{
|
|
3775
4499
|
fixName: "unnecessaryEffectGen_fix",
|
|
@@ -3813,7 +4537,7 @@ var unnecessaryPipe = createDiagnostic({
|
|
|
3813
4537
|
map3(({ args: args2, subject }) => {
|
|
3814
4538
|
if (args2.length === 0) {
|
|
3815
4539
|
report({
|
|
3816
|
-
node,
|
|
4540
|
+
location: node,
|
|
3817
4541
|
messageText: `This pipe call contains no arguments.`,
|
|
3818
4542
|
fixes: [{
|
|
3819
4543
|
fixName: "unnecessaryPipe_fix",
|
|
@@ -3860,7 +4584,7 @@ var unnecessaryPipeChain = createDiagnostic({
|
|
|
3860
4584
|
),
|
|
3861
4585
|
map3(({ innerCall, pipeCall }) => {
|
|
3862
4586
|
report({
|
|
3863
|
-
node,
|
|
4587
|
+
location: node,
|
|
3864
4588
|
messageText: `Chained pipe calls can be simplified to a single pipe call`,
|
|
3865
4589
|
fixes: [{
|
|
3866
4590
|
fixName: "unnecessaryPipeChain_fix",
|
|
@@ -3909,8 +4633,64 @@ var unnecessaryPipeChain = createDiagnostic({
|
|
|
3909
4633
|
})
|
|
3910
4634
|
});
|
|
3911
4635
|
|
|
4636
|
+
// src/diagnostics/unsupportedServiceAccessors.ts
|
|
4637
|
+
var unsupportedServiceAccessors = createDiagnostic({
|
|
4638
|
+
name: "unsupportedServiceAccessors",
|
|
4639
|
+
code: 21,
|
|
4640
|
+
severity: "warning",
|
|
4641
|
+
apply: fn("unsupportedServiceAccessors.apply")(function* (sourceFile, report) {
|
|
4642
|
+
const ts = yield* service(TypeScriptApi);
|
|
4643
|
+
const nodeToVisit = [];
|
|
4644
|
+
const appendNodeToVisit = (node) => {
|
|
4645
|
+
nodeToVisit.push(node);
|
|
4646
|
+
return void 0;
|
|
4647
|
+
};
|
|
4648
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
4649
|
+
while (nodeToVisit.length > 0) {
|
|
4650
|
+
const node = nodeToVisit.shift();
|
|
4651
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
4652
|
+
if (ts.isClassDeclaration(node)) {
|
|
4653
|
+
const parseResult = yield* pipe(
|
|
4654
|
+
parse2(node),
|
|
4655
|
+
orElse2(() => succeed(null))
|
|
4656
|
+
);
|
|
4657
|
+
if (parseResult && parseResult.involvedMembers.length > 0) {
|
|
4658
|
+
const existingStaticMembers = /* @__PURE__ */ new Set();
|
|
4659
|
+
node.members?.forEach((member) => {
|
|
4660
|
+
if (ts.isPropertyDeclaration(member) && member.modifiers?.some((mod) => mod.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
4661
|
+
if (member.name && ts.isIdentifier(member.name)) {
|
|
4662
|
+
existingStaticMembers.add(member.name.text);
|
|
4663
|
+
}
|
|
4664
|
+
}
|
|
4665
|
+
});
|
|
4666
|
+
const missingMembers = parseResult.involvedMembers.filter(
|
|
4667
|
+
({ property }) => !existingStaticMembers.has(property.getName())
|
|
4668
|
+
);
|
|
4669
|
+
if (missingMembers.length > 0) {
|
|
4670
|
+
const memberNames = missingMembers.map(({ property }) => `'${property.getName()}'`).join(", ");
|
|
4671
|
+
report({
|
|
4672
|
+
location: parseResult.className,
|
|
4673
|
+
messageText: `Even if accessors are enabled, accessors for ${memberNames} won't be available because the signature have generic type parameters or multiple call signatures.`,
|
|
4674
|
+
fixes: [{
|
|
4675
|
+
fixName: "unsupportedServiceAccessors_enableCodegen",
|
|
4676
|
+
description: "Enable accessors codegen",
|
|
4677
|
+
apply: gen(function* () {
|
|
4678
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
4679
|
+
const comment = "// @effect-codegens accessors\n";
|
|
4680
|
+
changeTracker.insertText(sourceFile, node.getStart(sourceFile), comment);
|
|
4681
|
+
})
|
|
4682
|
+
}]
|
|
4683
|
+
});
|
|
4684
|
+
}
|
|
4685
|
+
}
|
|
4686
|
+
}
|
|
4687
|
+
}
|
|
4688
|
+
})
|
|
4689
|
+
});
|
|
4690
|
+
|
|
3912
4691
|
// src/diagnostics.ts
|
|
3913
4692
|
var diagnostics = [
|
|
4693
|
+
classSelfMismatch,
|
|
3914
4694
|
duplicatePackage,
|
|
3915
4695
|
missingEffectContext,
|
|
3916
4696
|
missingEffectError,
|
|
@@ -3928,7 +4708,9 @@ var diagnostics = [
|
|
|
3928
4708
|
effectInVoidSuccess,
|
|
3929
4709
|
unnecessaryPipeChain,
|
|
3930
4710
|
strictBooleanExpressions,
|
|
3931
|
-
multipleEffectProvide
|
|
4711
|
+
multipleEffectProvide,
|
|
4712
|
+
outdatedEffectCodegen,
|
|
4713
|
+
unsupportedServiceAccessors
|
|
3932
4714
|
];
|
|
3933
4715
|
|
|
3934
4716
|
// src/transform.ts
|
|
@@ -3937,14 +4719,11 @@ function transform_default(program, pluginConfig, { addDiagnostic, ts: tsInstanc
|
|
|
3937
4719
|
return (sourceFile) => {
|
|
3938
4720
|
pipe(
|
|
3939
4721
|
getSemanticDiagnosticsWithCodeFixes(diagnostics, sourceFile),
|
|
3940
|
-
|
|
3941
|
-
|
|
4722
|
+
nanoLayer2,
|
|
4723
|
+
nanoLayer,
|
|
3942
4724
|
provideService(TypeCheckerApi, program.getTypeChecker()),
|
|
3943
|
-
provideService(
|
|
3944
|
-
provideService(
|
|
3945
|
-
TypeCheckerApiCache,
|
|
3946
|
-
makeTypeCheckerApiCache()
|
|
3947
|
-
),
|
|
4725
|
+
provideService(TypeScriptProgram, program),
|
|
4726
|
+
provideService(TypeScriptApi, tsInstance),
|
|
3948
4727
|
provideService(
|
|
3949
4728
|
LanguageServicePluginOptions,
|
|
3950
4729
|
parse(pluginConfig)
|