@effect/language-service 0.84.0 → 0.84.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.js CHANGED
@@ -7751,12 +7751,14 @@ var getParameterName = (typescript, name) => {
7751
7751
  }
7752
7752
  return "parameter";
7753
7753
  };
7754
- var hasOuterContextualFunctionType = (typescript, typeChecker, node) => {
7754
+ var hasOuterContextualFunctionType = (typescript, typeChecker, typeCheckerUtils, node) => {
7755
7755
  const contextualType = typeChecker.getContextualType(node);
7756
7756
  if (!contextualType) {
7757
7757
  return false;
7758
7758
  }
7759
- return typeChecker.getSignaturesOfType(contextualType, typescript.SignatureKind.Call).length > 0;
7759
+ return typeCheckerUtils.unrollUnionMembers(contextualType).some(
7760
+ (type) => typeChecker.getSignaturesOfType(type, typescript.SignatureKind.Call).length > 0
7761
+ );
7760
7762
  };
7761
7763
  var effectFnImplicitAny = createDiagnostic({
7762
7764
  name: "effectFnImplicitAny",
@@ -7770,6 +7772,7 @@ var effectFnImplicitAny = createDiagnostic({
7770
7772
  const ts = yield* service(TypeScriptApi);
7771
7773
  const program = yield* service(TypeScriptProgram);
7772
7774
  const typeChecker = yield* service(TypeCheckerApi);
7775
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
7773
7776
  const typeParser = yield* service(TypeParser);
7774
7777
  const noImplicitAny = program.getCompilerOptions().noImplicitAny ?? program.getCompilerOptions().strict ?? false;
7775
7778
  if (!noImplicitAny) {
@@ -7809,7 +7812,7 @@ var effectFnImplicitAny = createDiagnostic({
7809
7812
  ),
7810
7813
  orUndefined
7811
7814
  );
7812
- if (!parsed || hasOuterContextualFunctionType(ts, typeChecker, parsed.call)) {
7815
+ if (!parsed || hasOuterContextualFunctionType(ts, typeChecker, typeCheckerUtils, parsed.call)) {
7813
7816
  continue;
7814
7817
  }
7815
7818
  for (const parameter of parsed.fn.parameters) {
@@ -11904,16 +11907,16 @@ Nested Effect-able types may be intended if you plan to later manually flatten o
11904
11907
  var runEffectInsideEffect = createDiagnostic({
11905
11908
  name: "runEffectInsideEffect",
11906
11909
  code: 32,
11907
- description: "Suggests using Runtime methods instead of Effect.run* inside Effect contexts",
11910
+ description: "Suggests using Runtime or Effect.run*With methods instead of Effect.run* inside Effect contexts",
11908
11911
  group: "antipattern",
11909
11912
  severity: "suggestion",
11910
11913
  fixable: true,
11911
- supportedEffect: ["v3"],
11914
+ supportedEffect: ["v3", "v4"],
11912
11915
  apply: fn("runEffectInsideEffect.apply")(function* (sourceFile, report) {
11913
11916
  const ts = yield* service(TypeScriptApi);
11914
11917
  const typeParser = yield* service(TypeParser);
11915
11918
  const tsUtils = yield* service(TypeScriptUtils);
11916
- if (typeParser.supportedEffect() === "v4") return;
11919
+ const supportedEffect = typeParser.supportedEffect();
11917
11920
  const parseEffectMethod = (node, methodName) => pipe(
11918
11921
  typeParser.isNodeReferenceToEffectModuleApi(methodName)(node),
11919
11922
  map5(() => ({ node, methodName }))
@@ -11946,9 +11949,10 @@ var runEffectInsideEffect = createDiagnostic({
11946
11949
  if (scopeNode && scopeNode !== effectGen.generatorFunction) {
11947
11950
  const fixAddRuntime = gen(function* () {
11948
11951
  const changeTracker = yield* service(ChangeTracker);
11949
- const runtimeModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", "Runtime") || "Runtime";
11950
11952
  const effectModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", "Effect") || "Effect";
11953
+ const runtimeModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", "Runtime") || "Runtime";
11951
11954
  let runtimeIdentifier = void 0;
11955
+ let servicesIdentifier = void 0;
11952
11956
  for (const statement of effectGen.generatorFunction.body.statements) {
11953
11957
  if (ts.isVariableStatement(statement) && statement.declarationList.declarations.length === 1) {
11954
11958
  const declaration = statement.declarationList.declarations[0];
@@ -11962,11 +11966,46 @@ var runEffectInsideEffect = createDiagnostic({
11962
11966
  if (isSome2(maybeEffectRuntime) && ts.isIdentifier(declaration.name)) {
11963
11967
  runtimeIdentifier = ts.idText(declaration.name);
11964
11968
  }
11969
+ const maybeEffectServices = yield* pipe(
11970
+ typeParser.isNodeReferenceToEffectModuleApi("services")(yieldedExpression.expression),
11971
+ option
11972
+ );
11973
+ if (isSome2(maybeEffectServices) && ts.isIdentifier(declaration.name)) {
11974
+ servicesIdentifier = ts.idText(declaration.name);
11975
+ }
11965
11976
  }
11966
11977
  }
11967
11978
  }
11968
11979
  }
11969
- if (!runtimeIdentifier) {
11980
+ if (supportedEffect === "v4" && !servicesIdentifier) {
11981
+ changeTracker.insertNodeAt(
11982
+ sourceFile,
11983
+ effectGen.body.statements[0].pos,
11984
+ ts.factory.createVariableStatement(
11985
+ void 0,
11986
+ ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(
11987
+ "effectServices",
11988
+ void 0,
11989
+ void 0,
11990
+ ts.factory.createYieldExpression(
11991
+ ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
11992
+ ts.factory.createCallExpression(
11993
+ ts.factory.createPropertyAccessExpression(
11994
+ ts.factory.createIdentifier(effectModuleIdentifier),
11995
+ "services"
11996
+ ),
11997
+ [ts.factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword)],
11998
+ []
11999
+ )
12000
+ )
12001
+ )], ts.NodeFlags.Const)
12002
+ ),
12003
+ {
12004
+ prefix: "\n",
12005
+ suffix: "\n"
12006
+ }
12007
+ );
12008
+ } else if (supportedEffect === "v3" && !runtimeIdentifier) {
11970
12009
  changeTracker.insertNodeAt(
11971
12010
  sourceFile,
11972
12011
  effectGen.body.statements[0].pos,
@@ -12002,16 +12041,19 @@ var runEffectInsideEffect = createDiagnostic({
12002
12041
  changeTracker.insertText(
12003
12042
  sourceFile,
12004
12043
  node.arguments[0].pos,
12005
- `${runtimeModuleIdentifier}.${isEffectRunCall.value.methodName}(${runtimeIdentifier || "effectRuntime"}, `
12044
+ supportedEffect === "v4" ? `${effectModuleIdentifier}.${isEffectRunCall.value.methodName}With(${servicesIdentifier || "effectServices"})(` : `${runtimeModuleIdentifier}.${isEffectRunCall.value.methodName}(${runtimeIdentifier || "effectRuntime"}, `
12006
12045
  );
12007
12046
  });
12047
+ const v4MethodName = `${isEffectRunCall.value.methodName}With`;
12048
+ const messageText = supportedEffect === "v4" ? `Using ${nodeText} inside an Effect is not recommended. The same services should generally be used instead to run child effects.
12049
+ Consider extracting the current services by using for example Effect.services and then use Effect.${v4MethodName} with the extracted services instead.` : `Using ${nodeText} inside an Effect is not recommended. The same runtime should generally be used instead to run child effects.
12050
+ Consider extracting the Runtime by using for example Effect.runtime and then use Runtime.${isEffectRunCall.value.methodName} with the extracted runtime instead.`;
12008
12051
  report({
12009
12052
  location: node.expression,
12010
- messageText: `Using ${nodeText} inside an Effect is not recommended. The same runtime should generally be used instead to run child effects.
12011
- Consider extracting the Runtime by using for example Effect.runtime and then use Runtime.${isEffectRunCall.value.methodName} with the extracted runtime instead.`,
12053
+ messageText,
12012
12054
  fixes: [{
12013
12055
  fixName: "runEffectInsideEffect_fix",
12014
- description: "Use a runtime to run the Effect",
12056
+ description: supportedEffect === "v4" ? "Use the current services to run the Effect" : "Use a runtime to run the Effect",
12015
12057
  apply: fixAddRuntime
12016
12058
  }]
12017
12059
  });