@effect/language-service 0.30.0 → 0.31.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect/language-service",
3
- "version": "0.30.0",
3
+ "version": "0.31.0",
4
4
  "description": "A Language-Service Plugin to Refactor and Diagnostic effect-ts projects",
5
5
  "main": "index.cjs",
6
6
  "bin": {
package/transform.js CHANGED
@@ -2901,6 +2901,7 @@ function make2(ts, tsUtils, typeChecker) {
2901
2901
  );
2902
2902
  if (isSome2(parsedContextTag)) {
2903
2903
  let accessors2 = void 0;
2904
+ let dependencies = void 0;
2904
2905
  if (wholeCall.arguments.length >= 2) {
2905
2906
  const args2 = wholeCall.arguments[1];
2906
2907
  if (ts.isObjectLiteralExpression(args2)) {
@@ -2908,6 +2909,9 @@ function make2(ts, tsUtils, typeChecker) {
2908
2909
  if (ts.isPropertyAssignment(property) && property.name && ts.isIdentifier(property.name) && property.name.text === "accessors" && property.initializer && property.initializer.kind === ts.SyntaxKind.TrueKeyword) {
2909
2910
  accessors2 = true;
2910
2911
  }
2912
+ if (ts.isPropertyAssignment(property) && property.name && ts.isIdentifier(property.name) && property.name.text === "dependencies" && property.initializer && ts.isArrayLiteralExpression(property.initializer)) {
2913
+ dependencies = property.initializer.elements;
2914
+ }
2911
2915
  }
2912
2916
  }
2913
2917
  }
@@ -2916,7 +2920,8 @@ function make2(ts, tsUtils, typeChecker) {
2916
2920
  className: atLocation.name,
2917
2921
  selfTypeNode,
2918
2922
  args: wholeCall.arguments,
2919
- accessors: accessors2
2923
+ accessors: accessors2,
2924
+ dependencies
2920
2925
  };
2921
2926
  }
2922
2927
  }
@@ -3638,6 +3643,89 @@ var missingEffectError = createDiagnostic({
3638
3643
  })
3639
3644
  });
3640
3645
 
3646
+ // src/diagnostics/missingEffectServiceDependency.ts
3647
+ var missingEffectServiceDependency = createDiagnostic({
3648
+ name: "missingEffectServiceDependency",
3649
+ code: 21,
3650
+ severity: "off",
3651
+ apply: fn("missingEffectServiceDependency.apply")(function* (sourceFile, report) {
3652
+ const ts = yield* service(TypeScriptApi);
3653
+ const typeChecker = yield* service(TypeCheckerApi);
3654
+ const typeParser = yield* service(TypeParser);
3655
+ const nodeToVisit = [];
3656
+ const appendNodeToVisit = (node) => {
3657
+ nodeToVisit.push(node);
3658
+ return void 0;
3659
+ };
3660
+ ts.forEachChild(sourceFile, appendNodeToVisit);
3661
+ while (nodeToVisit.length > 0) {
3662
+ const node = nodeToVisit.shift();
3663
+ if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
3664
+ const serviceResult = yield* pipe(
3665
+ typeParser.extendsEffectService(node),
3666
+ orElse2(() => void_)
3667
+ );
3668
+ if (serviceResult) {
3669
+ const { className, dependencies } = serviceResult;
3670
+ const classSymbol = typeChecker.getSymbolAtLocation(className);
3671
+ if (classSymbol) {
3672
+ const classType = typeChecker.getTypeOfSymbol(classSymbol);
3673
+ const defaultWithoutDepsProperty = typeChecker.getPropertyOfType(classType, "DefaultWithoutDependencies");
3674
+ const defaultProperty = defaultWithoutDepsProperty || typeChecker.getPropertyOfType(classType, "Default");
3675
+ if (defaultProperty) {
3676
+ const defaultType = typeChecker.getTypeOfSymbolAtLocation(defaultProperty, node);
3677
+ const layerResult = yield* pipe(
3678
+ typeParser.layerType(defaultType, node),
3679
+ orElse2(() => void_)
3680
+ );
3681
+ if (layerResult) {
3682
+ const servicesMemory = /* @__PURE__ */ new Map();
3683
+ const excludeNever = (type) => succeed((type.flags & ts.TypeFlags.Never) !== 0);
3684
+ const { allIndexes: requiredIndexes } = yield* appendToUniqueTypesMap(
3685
+ servicesMemory,
3686
+ layerResult.RIn,
3687
+ excludeNever
3688
+ );
3689
+ const providedIndexes = /* @__PURE__ */ new Set();
3690
+ const dependenciesToProcess = dependencies || [];
3691
+ for (const depExpression of dependenciesToProcess) {
3692
+ const depType = typeChecker.getTypeAtLocation(depExpression);
3693
+ const depLayerResult = yield* pipe(
3694
+ typeParser.layerType(depType, depExpression),
3695
+ orElse2(() => void_)
3696
+ );
3697
+ if (depLayerResult) {
3698
+ const { allIndexes } = yield* appendToUniqueTypesMap(
3699
+ servicesMemory,
3700
+ depLayerResult.ROut,
3701
+ excludeNever
3702
+ );
3703
+ for (const index of allIndexes) {
3704
+ providedIndexes.add(index);
3705
+ }
3706
+ }
3707
+ }
3708
+ const missingIndexes = requiredIndexes.filter((index) => !providedIndexes.has(index));
3709
+ if (missingIndexes.length > 0) {
3710
+ const missingTypes = missingIndexes.map((index) => servicesMemory.get(index));
3711
+ const missingTypeNames = missingTypes.map((t) => typeChecker.typeToString(t));
3712
+ const message = missingTypeNames.length === 1 ? `Service '${missingTypeNames[0]}' is required but not provided by dependencies` : `Services ${missingTypeNames.map((s) => `'${s}'`).join(", ")} are required but not provided by dependencies`;
3713
+ report({
3714
+ location: className,
3715
+ messageText: message,
3716
+ fixes: []
3717
+ });
3718
+ }
3719
+ }
3720
+ }
3721
+ }
3722
+ }
3723
+ }
3724
+ ts.forEachChild(node, appendNodeToVisit);
3725
+ }
3726
+ })
3727
+ });
3728
+
3641
3729
  // src/diagnostics/missingReturnYieldStar.ts
3642
3730
  var missingReturnYieldStar = createDiagnostic({
3643
3731
  name: "missingReturnYieldStar",
@@ -4694,6 +4782,7 @@ var diagnostics = [
4694
4782
  duplicatePackage,
4695
4783
  missingEffectContext,
4696
4784
  missingEffectError,
4785
+ missingEffectServiceDependency,
4697
4786
  floatingEffect,
4698
4787
  missingStarInYieldEffectGen,
4699
4788
  unnecessaryEffectGen,