@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.
Files changed (3) hide show
  1. package/index.cjs +111 -83
  2. package/index.cjs.map +1 -1
  3. 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 varianceStructCovariant(ts, typeChecker) {
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: varianceStructCovariant(ts, typeChecker)(type, atLocation, "_A"),
754
- E: varianceStructCovariant(ts, typeChecker)(type, atLocation, "_E"),
755
- R: varianceStructCovariant(ts, typeChecker)(type, atLocation, "_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 effectTypeArguments(ts, typeChecker) {
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* effectTypeArguments(ts, typeChecker)(propertyType, node).pipe(
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(() => ({ body: generatorFunction.body }))
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 = effectTypeArguments(ts, typeChecker)(type, node.expression);
892
+ const effect = effectType(ts, typeChecker)(type, node.expression);
877
893
  if (isSome2(effect)) {
878
- effectDiagnostics.push({
879
- node,
880
- category: ts.DiagnosticCategory.Error,
881
- messageText: `Effect must be yielded or assigned to a variable.`
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
- gen(function* () {
1272
- const expectedEffect = yield* effectTypeArguments(ts, typeChecker)(
1273
- expectedType,
1274
- node2
1275
- );
1276
- const realEffect = yield* effectTypeArguments(ts, typeChecker)(
1277
- realType,
1278
- valueNode
1279
- );
1280
- const missingContext = getMissingTypeEntriesInTargetType(
1281
- ts,
1282
- typeChecker
1283
- )(
1284
- realEffect.R,
1285
- expectedEffect.R
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
- if (missingContext.length > 0) {
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
- gen(function* () {
1316
- const expectedEffect = yield* effectTypeArguments(ts, typeChecker)(
1317
- expectedType,
1318
- node2
1319
- );
1320
- const realEffect = yield* effectTypeArguments(ts, typeChecker)(
1321
- realType,
1322
- valueNode
1323
- );
1324
- const missingErrorTypes = getMissingTypeEntriesInTargetType(
1325
- ts,
1326
- typeChecker
1327
- )(
1328
- realEffect.E,
1329
- expectedEffect.E
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
- if (missingErrorTypes.length > 0) {
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 visitWhileInGenerator = (node) => {
1356
- if (ts.isYieldExpression(node) && node.expression && node.asteriskToken === void 0) {
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 = effectTypeArguments(ts, typeChecker)(type, node.expression);
1383
+ const effect = effectType(ts, typeChecker)(type, node.expression);
1359
1384
  if (isSome2(effect)) {
1360
- effectDiagnostics.push({
1361
- node,
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, visitWhileInGenerator);
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
  });