@effect/language-service 0.3.0 → 0.3.1
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/index.cjs +111 -83
- package/index.cjs.map +1 -1
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -739,7 +739,7 @@ function pipeableType(ts, typeChecker) {
|
|
|
739
739
|
return some2(type);
|
|
740
740
|
};
|
|
741
741
|
}
|
|
742
|
-
function
|
|
742
|
+
function varianceStructCovariantType(ts, typeChecker) {
|
|
743
743
|
return (type, atLocation, propertyName) => gen(function* (_) {
|
|
744
744
|
const propertySymbol = yield* fromNullable(
|
|
745
745
|
typeChecker.getPropertyOfType(type, propertyName)
|
|
@@ -750,12 +750,12 @@ function varianceStructCovariant(ts, typeChecker) {
|
|
|
750
750
|
}
|
|
751
751
|
function effectVarianceStruct(ts, typeChecker) {
|
|
752
752
|
return (type, atLocation) => all({
|
|
753
|
-
A:
|
|
754
|
-
E:
|
|
755
|
-
R:
|
|
753
|
+
A: varianceStructCovariantType(ts, typeChecker)(type, atLocation, "_A"),
|
|
754
|
+
E: varianceStructCovariantType(ts, typeChecker)(type, atLocation, "_E"),
|
|
755
|
+
R: varianceStructCovariantType(ts, typeChecker)(type, atLocation, "_R")
|
|
756
756
|
});
|
|
757
757
|
}
|
|
758
|
-
function
|
|
758
|
+
function effectType(ts, typeChecker) {
|
|
759
759
|
return (type, atLocation) => gen(function* (_) {
|
|
760
760
|
yield* pipeableType(ts, typeChecker)(type, atLocation);
|
|
761
761
|
for (const propertySymbol of typeChecker.getPropertiesOfType(type)) {
|
|
@@ -771,6 +771,19 @@ function effectTypeArguments(ts, typeChecker) {
|
|
|
771
771
|
return yield* none2();
|
|
772
772
|
});
|
|
773
773
|
}
|
|
774
|
+
function fiberType(ts, typeChecker) {
|
|
775
|
+
return (type, atLocation) => gen(function* (_) {
|
|
776
|
+
const awaitSymbol = yield* fromNullable(
|
|
777
|
+
typeChecker.getPropertyOfType(type, "await")
|
|
778
|
+
);
|
|
779
|
+
const pollSymbol = yield* fromNullable(
|
|
780
|
+
typeChecker.getPropertyOfType(type, "poll")
|
|
781
|
+
);
|
|
782
|
+
if (!awaitSymbol || !pollSymbol)
|
|
783
|
+
return yield* none2();
|
|
784
|
+
return effectType(ts, typeChecker)(type, atLocation);
|
|
785
|
+
});
|
|
786
|
+
}
|
|
774
787
|
function importedEffectModule(ts, typeChecker) {
|
|
775
788
|
return (node) => gen(function* () {
|
|
776
789
|
const type = typeChecker.getTypeAtLocation(node);
|
|
@@ -778,7 +791,7 @@ function importedEffectModule(ts, typeChecker) {
|
|
|
778
791
|
typeChecker.getPropertyOfType(type, "never")
|
|
779
792
|
);
|
|
780
793
|
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, node);
|
|
781
|
-
return yield*
|
|
794
|
+
return yield* effectType(ts, typeChecker)(propertyType, node).pipe(
|
|
782
795
|
map(() => node)
|
|
783
796
|
);
|
|
784
797
|
});
|
|
@@ -800,7 +813,10 @@ function effectGen(ts, typeChecker) {
|
|
|
800
813
|
if (propertyAccess.name.text !== "gen")
|
|
801
814
|
return yield* none2();
|
|
802
815
|
return yield* importedEffectModule(ts, typeChecker)(propertyAccess.expression).pipe(
|
|
803
|
-
map(() => ({
|
|
816
|
+
map(() => ({
|
|
817
|
+
body: generatorFunction.body,
|
|
818
|
+
functionStar: generatorFunction.getFirstToken()
|
|
819
|
+
}))
|
|
804
820
|
);
|
|
805
821
|
});
|
|
806
822
|
}
|
|
@@ -873,13 +889,16 @@ var floatingEffect = createDiagnostic({
|
|
|
873
889
|
const visit = (node) => {
|
|
874
890
|
if (ts.isExpressionStatement(node) && (ts.isBlock(node.parent) || ts.isSourceFile(node.parent))) {
|
|
875
891
|
const type = typeChecker.getTypeAtLocation(node.expression);
|
|
876
|
-
const effect =
|
|
892
|
+
const effect = effectType(ts, typeChecker)(type, node.expression);
|
|
877
893
|
if (isSome2(effect)) {
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
894
|
+
const fiber = fiberType(ts, typeChecker)(type, node.expression);
|
|
895
|
+
if (isNone2(fiber)) {
|
|
896
|
+
effectDiagnostics.push({
|
|
897
|
+
node,
|
|
898
|
+
category: ts.DiagnosticCategory.Error,
|
|
899
|
+
messageText: `Effect must be yielded or assigned to a variable.`
|
|
900
|
+
});
|
|
901
|
+
}
|
|
883
902
|
}
|
|
884
903
|
}
|
|
885
904
|
ts.forEachChild(node, visit);
|
|
@@ -1268,32 +1287,34 @@ var missingEffectContext = createDiagnostic({
|
|
|
1268
1287
|
const visit = (node) => {
|
|
1269
1288
|
const entries = expectedAndRealType(ts, typeChecker)(node);
|
|
1270
1289
|
for (const [node2, expectedType, valueNode, realType] of entries) {
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1290
|
+
const expectedEffect = effectType(ts, typeChecker)(
|
|
1291
|
+
expectedType,
|
|
1292
|
+
node2
|
|
1293
|
+
);
|
|
1294
|
+
if (isNone2(expectedEffect))
|
|
1295
|
+
continue;
|
|
1296
|
+
const realEffect = effectType(ts, typeChecker)(
|
|
1297
|
+
realType,
|
|
1298
|
+
valueNode
|
|
1299
|
+
);
|
|
1300
|
+
if (isNone2(realEffect))
|
|
1301
|
+
continue;
|
|
1302
|
+
const missingContext = getMissingTypeEntriesInTargetType(
|
|
1303
|
+
ts,
|
|
1304
|
+
typeChecker
|
|
1305
|
+
)(
|
|
1306
|
+
realEffect.value.R,
|
|
1307
|
+
expectedEffect.value.R
|
|
1308
|
+
);
|
|
1309
|
+
if (missingContext.length > 0) {
|
|
1310
|
+
effectDiagnostics.push(
|
|
1311
|
+
{
|
|
1312
|
+
node: node2,
|
|
1313
|
+
category: ts.DiagnosticCategory.Error,
|
|
1314
|
+
messageText: `Missing '${sortTypes(missingContext).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect context.`
|
|
1315
|
+
}
|
|
1286
1316
|
);
|
|
1287
|
-
|
|
1288
|
-
effectDiagnostics.push(
|
|
1289
|
-
{
|
|
1290
|
-
node: node2,
|
|
1291
|
-
category: ts.DiagnosticCategory.Error,
|
|
1292
|
-
messageText: `Missing '${sortTypes(missingContext).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect context.`
|
|
1293
|
-
}
|
|
1294
|
-
);
|
|
1295
|
-
}
|
|
1296
|
-
});
|
|
1317
|
+
}
|
|
1297
1318
|
}
|
|
1298
1319
|
ts.forEachChild(node, visit);
|
|
1299
1320
|
};
|
|
@@ -1312,32 +1333,34 @@ var missingEffectError = createDiagnostic({
|
|
|
1312
1333
|
const visit = (node) => {
|
|
1313
1334
|
const entries = expectedAndRealType(ts, typeChecker)(node);
|
|
1314
1335
|
for (const [node2, expectedType, valueNode, realType] of entries) {
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1336
|
+
const expectedEffect = effectType(ts, typeChecker)(
|
|
1337
|
+
expectedType,
|
|
1338
|
+
node2
|
|
1339
|
+
);
|
|
1340
|
+
if (isNone2(expectedEffect))
|
|
1341
|
+
continue;
|
|
1342
|
+
const realEffect = effectType(ts, typeChecker)(
|
|
1343
|
+
realType,
|
|
1344
|
+
valueNode
|
|
1345
|
+
);
|
|
1346
|
+
if (isNone2(realEffect))
|
|
1347
|
+
continue;
|
|
1348
|
+
const missingErrorTypes = getMissingTypeEntriesInTargetType(
|
|
1349
|
+
ts,
|
|
1350
|
+
typeChecker
|
|
1351
|
+
)(
|
|
1352
|
+
realEffect.value.E,
|
|
1353
|
+
expectedEffect.value.E
|
|
1354
|
+
);
|
|
1355
|
+
if (missingErrorTypes.length > 0) {
|
|
1356
|
+
effectDiagnostics.push(
|
|
1357
|
+
{
|
|
1358
|
+
node: node2,
|
|
1359
|
+
category: ts.DiagnosticCategory.Error,
|
|
1360
|
+
messageText: `Missing '${sortTypes(missingErrorTypes).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect errors.`
|
|
1361
|
+
}
|
|
1330
1362
|
);
|
|
1331
|
-
|
|
1332
|
-
effectDiagnostics.push(
|
|
1333
|
-
{
|
|
1334
|
-
node: node2,
|
|
1335
|
-
category: ts.DiagnosticCategory.Error,
|
|
1336
|
-
messageText: `Missing '${sortTypes(missingErrorTypes).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect errors.`
|
|
1337
|
-
}
|
|
1338
|
-
);
|
|
1339
|
-
}
|
|
1340
|
-
});
|
|
1363
|
+
}
|
|
1341
1364
|
}
|
|
1342
1365
|
ts.forEachChild(node, visit);
|
|
1343
1366
|
};
|
|
@@ -1352,36 +1375,41 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
1352
1375
|
apply: (ts, program) => (sourceFile) => {
|
|
1353
1376
|
const typeChecker = program.getTypeChecker();
|
|
1354
1377
|
const effectDiagnostics = [];
|
|
1355
|
-
const
|
|
1356
|
-
|
|
1378
|
+
const brokenGenerators = /* @__PURE__ */ new Set();
|
|
1379
|
+
const brokenYields = /* @__PURE__ */ new Set();
|
|
1380
|
+
const visit = (functionStarNode) => (node) => {
|
|
1381
|
+
if (functionStarNode && ts.isYieldExpression(node) && node.expression && node.asteriskToken === void 0) {
|
|
1357
1382
|
const type = typeChecker.getTypeAtLocation(node.expression);
|
|
1358
|
-
const effect =
|
|
1383
|
+
const effect = effectType(ts, typeChecker)(type, node.expression);
|
|
1359
1384
|
if (isSome2(effect)) {
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
category: ts.DiagnosticCategory.Error,
|
|
1363
|
-
messageText: `When yielding Effects inside Effect.gen, you should use yield* instead of yield.`
|
|
1364
|
-
});
|
|
1385
|
+
brokenGenerators.add(functionStarNode);
|
|
1386
|
+
brokenYields.add(node);
|
|
1365
1387
|
}
|
|
1366
1388
|
}
|
|
1367
1389
|
const effectGen2 = effectGen(ts, typeChecker)(node);
|
|
1368
1390
|
if (isSome2(effectGen2)) {
|
|
1369
|
-
ts.forEachChild(effectGen2.value.body,
|
|
1391
|
+
ts.forEachChild(effectGen2.value.body, visit(effectGen2.value.functionStar));
|
|
1370
1392
|
} else if ((ts.isFunctionExpression(node) || ts.isMethodDeclaration(node)) && node.asteriskToken !== void 0) {
|
|
1371
|
-
ts.forEachChild(node, visit);
|
|
1372
|
-
} else {
|
|
1373
|
-
ts.forEachChild(node, visitWhileInGenerator);
|
|
1374
|
-
}
|
|
1375
|
-
};
|
|
1376
|
-
const visit = (node) => {
|
|
1377
|
-
const effectGen2 = effectGen(ts, typeChecker)(node);
|
|
1378
|
-
if (isSome2(effectGen2)) {
|
|
1379
|
-
ts.forEachChild(effectGen2.value.body, visitWhileInGenerator);
|
|
1393
|
+
ts.forEachChild(node, visit(void 0));
|
|
1380
1394
|
} else {
|
|
1381
|
-
ts.forEachChild(node, visit);
|
|
1395
|
+
ts.forEachChild(node, visit(functionStarNode));
|
|
1382
1396
|
}
|
|
1383
1397
|
};
|
|
1384
|
-
ts.forEachChild(sourceFile, visit);
|
|
1398
|
+
ts.forEachChild(sourceFile, visit(void 0));
|
|
1399
|
+
brokenGenerators.forEach(
|
|
1400
|
+
(node) => effectDiagnostics.push({
|
|
1401
|
+
node,
|
|
1402
|
+
category: ts.DiagnosticCategory.Error,
|
|
1403
|
+
messageText: `Seems like you used yield instead of yield* inside this Effect.gen.`
|
|
1404
|
+
})
|
|
1405
|
+
);
|
|
1406
|
+
brokenYields.forEach(
|
|
1407
|
+
(node) => effectDiagnostics.push({
|
|
1408
|
+
node,
|
|
1409
|
+
category: ts.DiagnosticCategory.Error,
|
|
1410
|
+
messageText: `When yielding Effects inside Effect.gen, you should use yield* instead of yield.`
|
|
1411
|
+
})
|
|
1412
|
+
);
|
|
1385
1413
|
return effectDiagnostics;
|
|
1386
1414
|
}
|
|
1387
1415
|
});
|