@effect/language-service 0.21.3 → 0.21.4

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.js CHANGED
@@ -2939,6 +2939,54 @@ var floatingEffect = createDiagnostic({
2939
2939
  })
2940
2940
  });
2941
2941
 
2942
+ // src/diagnostics/genericEffectServices.ts
2943
+ var genericEffectServices = createDiagnostic({
2944
+ name: "genericEffectServices",
2945
+ code: 10,
2946
+ apply: fn("genericEffectServices.apply")(function* (sourceFile) {
2947
+ const ts = yield* service(TypeScriptApi);
2948
+ const typeParser = yield* service(TypeParser);
2949
+ const typeChecker = yield* service(TypeCheckerApi);
2950
+ const effectDiagnostics = [];
2951
+ const nodeToVisit = [];
2952
+ const appendNodeToVisit = (node) => {
2953
+ nodeToVisit.push(node);
2954
+ return void 0;
2955
+ };
2956
+ ts.forEachChild(sourceFile, appendNodeToVisit);
2957
+ while (nodeToVisit.length > 0) {
2958
+ const node = nodeToVisit.shift();
2959
+ const typesToCheck = [];
2960
+ if (ts.isClassDeclaration(node) && node.name && node.typeParameters && node.heritageClauses) {
2961
+ const classSym = typeChecker.getSymbolAtLocation(node.name);
2962
+ if (classSym) {
2963
+ const type = typeChecker.getTypeOfSymbol(classSym);
2964
+ typesToCheck.push([type, node.name]);
2965
+ }
2966
+ } else {
2967
+ ts.forEachChild(node, appendNodeToVisit);
2968
+ continue;
2969
+ }
2970
+ for (const [type, reportAt] of typesToCheck) {
2971
+ yield* pipe(
2972
+ typeParser.contextTag(type, node),
2973
+ map4(() => {
2974
+ effectDiagnostics.push({
2975
+ node: reportAt,
2976
+ category: ts.DiagnosticCategory.Warning,
2977
+ messageText: `Effect Services with type parameters are not supported because they cannot be properly discriminated at runtime, which may cause unexpected behavior.`,
2978
+ fixes: []
2979
+ });
2980
+ }),
2981
+ orElse3(() => sync(() => ts.forEachChild(node, appendNodeToVisit))),
2982
+ ignore
2983
+ );
2984
+ }
2985
+ }
2986
+ return effectDiagnostics;
2987
+ })
2988
+ });
2989
+
2942
2990
  // src/diagnostics/leakingRequirements.ts
2943
2991
  var leakingRequirements = createDiagnostic({
2944
2992
  name: "leakingRequirements",
@@ -3017,7 +3065,7 @@ var leakingRequirements = createDiagnostic({
3017
3065
  const typesToCheck = [];
3018
3066
  if (ts.isCallExpression(node)) {
3019
3067
  typesToCheck.push([typeChecker.getTypeAtLocation(node), node]);
3020
- } else if (ts.isClassDeclaration(node) && node.name) {
3068
+ } else if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
3021
3069
  const classSym = typeChecker.getSymbolAtLocation(node.name);
3022
3070
  if (classSym) {
3023
3071
  const type = typeChecker.getTypeOfSymbol(classSym);
@@ -3297,6 +3345,78 @@ var missingStarInYieldEffectGen = createDiagnostic({
3297
3345
  })
3298
3346
  });
3299
3347
 
3348
+ // src/diagnostics/returnEffectInGen.ts
3349
+ var returnEffectInGen = createDiagnostic({
3350
+ name: "returnEffectInGen",
3351
+ code: 11,
3352
+ apply: fn("returnEffectInGen.apply")(function* (sourceFile) {
3353
+ const ts = yield* service(TypeScriptApi);
3354
+ const typeChecker = yield* service(TypeCheckerApi);
3355
+ const typeParser = yield* service(TypeParser);
3356
+ const effectDiagnostics = [];
3357
+ const brokenReturnStatements = /* @__PURE__ */ new Set();
3358
+ const nodeToVisit = [];
3359
+ const appendNodeToVisit = (node) => {
3360
+ nodeToVisit.push(node);
3361
+ return void 0;
3362
+ };
3363
+ ts.forEachChild(sourceFile, appendNodeToVisit);
3364
+ while (nodeToVisit.length > 0) {
3365
+ const node = nodeToVisit.shift();
3366
+ ts.forEachChild(node, appendNodeToVisit);
3367
+ if (ts.isReturnStatement(node) && node.expression) {
3368
+ if (ts.isYieldExpression(node.expression)) continue;
3369
+ const generatorOrRegularFunction = ts.findAncestor(
3370
+ node,
3371
+ (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isArrowFunction(_) || ts.isGetAccessor(_)
3372
+ );
3373
+ if (!(generatorOrRegularFunction && "asteriskToken" in generatorOrRegularFunction && generatorOrRegularFunction.asteriskToken)) continue;
3374
+ const type = typeChecker.getTypeAtLocation(node.expression);
3375
+ const maybeEffect = yield* option(typeParser.effectType(type, node.expression));
3376
+ if (isSome2(maybeEffect)) {
3377
+ const maybeEffectSubtype = yield* option(typeParser.effectSubtype(type, node.expression));
3378
+ if (isNone2(maybeEffectSubtype)) {
3379
+ if (generatorOrRegularFunction && generatorOrRegularFunction.parent) {
3380
+ const effectGenNode = generatorOrRegularFunction.parent;
3381
+ yield* pipe(
3382
+ typeParser.effectGen(effectGenNode),
3383
+ orElse3(() => typeParser.effectFnUntracedGen(effectGenNode)),
3384
+ orElse3(() => typeParser.effectFnGen(effectGenNode)),
3385
+ map4(() => brokenReturnStatements.add(node)),
3386
+ ignore
3387
+ );
3388
+ }
3389
+ }
3390
+ }
3391
+ }
3392
+ }
3393
+ brokenReturnStatements.forEach((node) => {
3394
+ const fix = node.expression ? [{
3395
+ fixName: "returnEffectInGen_fix",
3396
+ description: "Add yield* statement",
3397
+ apply: gen2(function* () {
3398
+ const changeTracker = yield* service(ChangeTracker);
3399
+ changeTracker.replaceNode(
3400
+ sourceFile,
3401
+ node.expression,
3402
+ ts.factory.createYieldExpression(
3403
+ ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
3404
+ node.expression
3405
+ )
3406
+ );
3407
+ })
3408
+ }] : [];
3409
+ effectDiagnostics.push({
3410
+ node,
3411
+ category: ts.DiagnosticCategory.Suggestion,
3412
+ messageText: `You are returning an Effect-able type inside a generator function, and will result in nested Effect<Effect<...>>. Maybe you wanted to return yield* instead? Nested Effect-able types may be intended if you plan to later manually flatten or unwrap this Effect.`,
3413
+ fixes: fix
3414
+ });
3415
+ });
3416
+ return effectDiagnostics;
3417
+ })
3418
+ });
3419
+
3300
3420
  // src/diagnostics/unnecessaryEffectGen.ts
3301
3421
  var unnecessaryEffectGen = createDiagnostic({
3302
3422
  name: "unnecessaryEffectGen",
@@ -3401,7 +3521,9 @@ var diagnostics = [
3401
3521
  unnecessaryEffectGen,
3402
3522
  missingReturnYieldStar,
3403
3523
  leakingRequirements,
3404
- unnecessaryPipe
3524
+ unnecessaryPipe,
3525
+ genericEffectServices,
3526
+ returnEffectInGen
3405
3527
  ];
3406
3528
 
3407
3529
  // src/goto/effectRpcDefinition.ts