@effect/language-service 0.23.5 → 0.24.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/package.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "name": "@effect/language-service",
3
- "version": "0.23.5",
3
+ "version": "0.24.1",
4
4
  "description": "A Language-Service Plugin to Refactor and Diagnostic effect-ts projects",
5
5
  "main": "index.cjs",
6
+ "bin": {
7
+ "effect-language-service": "cli.js"
8
+ },
6
9
  "repository": {
7
10
  "type": "git",
8
11
  "url": "https://github.com/Effect-TS/language-service.git"
package/transform.js CHANGED
@@ -24,7 +24,7 @@ __export(transform_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(transform_exports);
26
26
 
27
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Function.js
27
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Function.js
28
28
  var isFunction = (input) => typeof input === "function";
29
29
  var dual = function(arity, body) {
30
30
  if (typeof arity === "function") {
@@ -118,11 +118,11 @@ function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
118
118
  }
119
119
  }
120
120
 
121
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/version.js
122
- var moduleVersion = "3.16.5";
121
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/version.js
122
+ var moduleVersion = "3.16.12";
123
123
  var getCurrentVersion = () => moduleVersion;
124
124
 
125
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/GlobalValue.js
125
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/GlobalValue.js
126
126
  var globalStoreId = `effect/GlobalValue/globalStoreId/${/* @__PURE__ */ getCurrentVersion()}`;
127
127
  var globalStore;
128
128
  var globalValue = (id, compute) => {
@@ -136,7 +136,7 @@ var globalValue = (id, compute) => {
136
136
  return globalStore.get(id);
137
137
  };
138
138
 
139
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Predicate.js
139
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Predicate.js
140
140
  var isString = (input) => typeof input === "string";
141
141
  var isNumber = (input) => typeof input === "number";
142
142
  var isBoolean = (input) => typeof input === "boolean";
@@ -146,10 +146,10 @@ var isObject = (input) => isRecordOrArray(input) || isFunction2(input);
146
146
  var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObject(self) && property in self);
147
147
  var isRecord = (input) => isRecordOrArray(input) && !Array.isArray(input);
148
148
 
149
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/errors.js
149
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/errors.js
150
150
  var getBugErrorMessage = (message) => `BUG: ${message} - please report an issue at https://github.com/Effect-TS/effect/issues`;
151
151
 
152
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Utils.js
152
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Utils.js
153
153
  var GenKindTypeId = /* @__PURE__ */ Symbol.for("effect/Gen/GenKind");
154
154
  var isGenKind = (u) => isObject(u) && GenKindTypeId in u;
155
155
  var GenKindImpl = class {
@@ -278,7 +278,7 @@ var internalCall = isNotOptimizedAway ? standard.effect_internal_function : forc
278
278
  var genConstructor = function* () {
279
279
  }.constructor;
280
280
 
281
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Hash.js
281
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Hash.js
282
282
  var randomHashCache = /* @__PURE__ */ globalValue(/* @__PURE__ */ Symbol.for("effect/Hash/randomHashCache"), () => /* @__PURE__ */ new WeakMap());
283
283
  var symbol = /* @__PURE__ */ Symbol.for("effect/Hash");
284
284
  var hash = (self) => {
@@ -377,7 +377,7 @@ var cached = function() {
377
377
  return hash2;
378
378
  };
379
379
 
380
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Equal.js
380
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Equal.js
381
381
  var symbol2 = /* @__PURE__ */ Symbol.for("effect/Equal");
382
382
  function equals() {
383
383
  if (arguments.length === 1) {
@@ -431,7 +431,7 @@ function compareBoth(self, that) {
431
431
  var isEqual = (u) => hasProperty(u, symbol2);
432
432
  var equivalence = () => equals;
433
433
 
434
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Inspectable.js
434
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Inspectable.js
435
435
  var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
436
436
  var toJSON = (x) => {
437
437
  try {
@@ -483,7 +483,7 @@ var redact = (u) => {
483
483
  return u;
484
484
  };
485
485
 
486
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Pipeable.js
486
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Pipeable.js
487
487
  var pipeArguments = (self, args) => {
488
488
  switch (args.length) {
489
489
  case 0:
@@ -516,10 +516,10 @@ var pipeArguments = (self, args) => {
516
516
  }
517
517
  };
518
518
 
519
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/opCodes/effect.js
519
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/opCodes/effect.js
520
520
  var OP_COMMIT = "Commit";
521
521
 
522
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/effectable.js
522
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/effectable.js
523
523
  var EffectTypeId = /* @__PURE__ */ Symbol.for("effect/Effect");
524
524
  var StreamTypeId = /* @__PURE__ */ Symbol.for("effect/Stream");
525
525
  var SinkTypeId = /* @__PURE__ */ Symbol.for("effect/Sink");
@@ -606,7 +606,7 @@ var StructuralCommitPrototype = {
606
606
  ...StructuralPrototype
607
607
  };
608
608
 
609
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/option.js
609
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/option.js
610
610
  var TypeId = /* @__PURE__ */ Symbol.for("effect/Option");
611
611
  var CommonProto = {
612
612
  ...EffectPrototype,
@@ -664,7 +664,7 @@ var some = (value) => {
664
664
  return a;
665
665
  };
666
666
 
667
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/either.js
667
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/either.js
668
668
  var TypeId2 = /* @__PURE__ */ Symbol.for("effect/Either");
669
669
  var CommonProto2 = {
670
670
  ...EffectPrototype,
@@ -726,7 +726,7 @@ var right = (right3) => {
726
726
  return a;
727
727
  };
728
728
 
729
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Either.js
729
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Either.js
730
730
  var right2 = right;
731
731
  var left2 = left;
732
732
  var isLeft2 = isLeft;
@@ -734,13 +734,14 @@ var isRight2 = isRight;
734
734
  var map = /* @__PURE__ */ dual(2, (self, f) => isRight2(self) ? right2(f(self.right)) : left2(self.left));
735
735
  var getOrElse = /* @__PURE__ */ dual(2, (self, onLeft) => isLeft2(self) ? onLeft(self.left) : self.right);
736
736
 
737
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/array.js
737
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/array.js
738
738
  var isNonEmptyArray = (self) => self.length > 0;
739
739
 
740
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Order.js
740
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Order.js
741
741
  var make = (compare) => (self, that) => self === that ? 0 : compare(self, that);
742
+ var string2 = /* @__PURE__ */ make((self, that) => self < that ? -1 : 1);
742
743
 
743
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Option.js
744
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Option.js
744
745
  var none2 = () => none;
745
746
  var some2 = some;
746
747
  var isNone2 = isNone;
@@ -752,7 +753,7 @@ var match = /* @__PURE__ */ dual(2, (self, {
752
753
  var orElse = /* @__PURE__ */ dual(2, (self, that) => isNone2(self) ? that() : self);
753
754
  var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nullableValue);
754
755
 
755
- // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Array.js
756
+ // node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Array.js
756
757
  var fromIterable = (collection) => Array.isArray(collection) ? collection : Array.from(collection);
757
758
  var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
758
759
  var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable(self).concat(fromIterable(that)));
@@ -921,6 +922,7 @@ var orElse2 = (f) => (fa) => make2((ctx) => {
921
922
  if (result._tag === "Left") return f(result.value).run(ctx);
922
923
  return result;
923
924
  });
925
+ var firstSuccessOf = (arr) => arr.slice(1).reduce((arr2, fa) => orElse2(() => fa)(arr2), arr[0]);
924
926
  var service = (tag) => make2(
925
927
  (ctx) => tag.key in ctx.value ? ctx.value[tag.key] : makeInternalDefect(`Cannot find service ${tag.key}`)
926
928
  );
@@ -2027,22 +2029,16 @@ function make3(ts, typeChecker) {
2027
2029
  );
2028
2030
  const effectType = cachedBy(
2029
2031
  fn("TypeParser.effectType")(function* (type, atLocation) {
2030
- yield* pipeableType(type, atLocation);
2032
+ let result = typeParserIssue("Type has no effect variance struct", type, atLocation);
2031
2033
  const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2032
- (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
2034
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration && ts.isPropertySignature(_.valueDeclaration) && ts.isComputedPropertyName(_.valueDeclaration.name)
2033
2035
  );
2034
2036
  propertiesSymbols.sort((a, b) => b.name.indexOf("EffectTypeId") - a.name.indexOf("EffectTypeId"));
2035
2037
  for (const propertySymbol of propertiesSymbols) {
2036
2038
  const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2037
- const varianceArgs = yield* option(effectVarianceStruct(
2038
- propertyType,
2039
- atLocation
2040
- ));
2041
- if (isSome2(varianceArgs)) {
2042
- return varianceArgs.value;
2043
- }
2039
+ result = pipe(result, orElse2(() => effectVarianceStruct(propertyType, atLocation)));
2044
2040
  }
2045
- return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
2041
+ return yield* result;
2046
2042
  }),
2047
2043
  "TypeParser.effectType",
2048
2044
  (type) => type
@@ -2061,7 +2057,7 @@ function make3(ts, typeChecker) {
2061
2057
  fn("TypeParser.layerType")(function* (type, atLocation) {
2062
2058
  yield* pipeableType(type, atLocation);
2063
2059
  const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2064
- (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
2060
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration && ts.isPropertySignature(_.valueDeclaration) && ts.isComputedPropertyName(_.valueDeclaration.name)
2065
2061
  );
2066
2062
  propertiesSymbols.sort((a, b) => b.name.indexOf("LayerTypeId") - a.name.indexOf("LayerTypeId"));
2067
2063
  for (const propertySymbol of propertiesSymbols) {
@@ -2345,7 +2341,7 @@ function make3(ts, typeChecker) {
2345
2341
  const ast = typeChecker.getPropertyOfType(type, "ast");
2346
2342
  if (!ast) return yield* typeParserIssue("Has no 'ast' property", type, atLocation);
2347
2343
  const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2348
- (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
2344
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration && ts.isPropertySignature(_.valueDeclaration) && ts.isComputedPropertyName(_.valueDeclaration.name)
2349
2345
  );
2350
2346
  propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
2351
2347
  for (const propertySymbol of propertiesSymbols) {
@@ -2374,7 +2370,7 @@ function make3(ts, typeChecker) {
2374
2370
  fn("TypeParser.contextTag")(function* (type, atLocation) {
2375
2371
  yield* pipeableType(type, atLocation);
2376
2372
  const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2377
- (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
2373
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration && ts.isPropertySignature(_.valueDeclaration) && ts.isComputedPropertyName(_.valueDeclaration.name)
2378
2374
  );
2379
2375
  propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
2380
2376
  for (const propertySymbol of propertiesSymbols) {
@@ -2406,6 +2402,25 @@ function make3(ts, typeChecker) {
2406
2402
  "TypeParser.pipeCall",
2407
2403
  (node) => node
2408
2404
  );
2405
+ const scopeType = cachedBy(
2406
+ fn("TypeParser.scopeType")(function* (type, atLocation) {
2407
+ yield* pipeableType(type, atLocation);
2408
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2409
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration && ts.isPropertySignature(_.valueDeclaration) && ts.isComputedPropertyName(_.valueDeclaration.name)
2410
+ );
2411
+ propertiesSymbols.sort((a, b) => b.name.indexOf("ScopeTypeId") - a.name.indexOf("ScopeTypeId"));
2412
+ for (const propertySymbol of propertiesSymbols) {
2413
+ const computedPropertyExpression = propertySymbol.valueDeclaration.name;
2414
+ const symbol3 = typeChecker.getSymbolAtLocation(computedPropertyExpression.expression);
2415
+ if (symbol3 && symbol3.name === "ScopeTypeId") {
2416
+ return type;
2417
+ }
2418
+ }
2419
+ return yield* typeParserIssue("Type has no scope type id", type, atLocation);
2420
+ }),
2421
+ "TypeParser.scopeType",
2422
+ (type) => type
2423
+ );
2409
2424
  return {
2410
2425
  effectType,
2411
2426
  strictEffectType,
@@ -2419,7 +2434,8 @@ function make3(ts, typeChecker) {
2419
2434
  unnecessaryEffectGen: unnecessaryEffectGen2,
2420
2435
  effectSchemaType,
2421
2436
  contextTag,
2422
- pipeCall
2437
+ pipeCall,
2438
+ scopeType
2423
2439
  };
2424
2440
  }
2425
2441
 
@@ -2860,18 +2876,39 @@ var missingEffectError = createDiagnostic({
2860
2876
  code: 1,
2861
2877
  severity: "error",
2862
2878
  apply: fn("missingEffectError.apply")(function* (sourceFile, report) {
2879
+ const ts = yield* service(TypeScriptApi);
2863
2880
  const typeChecker = yield* service(TypeCheckerApi);
2864
2881
  const typeParser = yield* service(TypeParser);
2865
2882
  const typeOrder = yield* deterministicTypeOrder;
2883
+ const effectModuleIdentifier = yield* pipe(
2884
+ findImportedModuleIdentifierByPackageAndNameOrBarrel(
2885
+ sourceFile,
2886
+ "effect",
2887
+ "Effect"
2888
+ ),
2889
+ map3((_) => _.text),
2890
+ orElse2(() => succeed("Effect"))
2891
+ );
2892
+ const createDieMessage = (message) => ts.factory.createCallExpression(
2893
+ ts.factory.createPropertyAccessExpression(
2894
+ ts.factory.createIdentifier(effectModuleIdentifier),
2895
+ "dieMessage"
2896
+ ),
2897
+ void 0,
2898
+ [ts.factory.createStringLiteral(message)]
2899
+ );
2866
2900
  const checkForMissingErrorTypes = (node, expectedType, valueNode, realType) => pipe(
2867
2901
  all(
2868
2902
  typeParser.effectType(expectedType, node),
2869
2903
  typeParser.effectType(realType, valueNode)
2870
2904
  ),
2871
2905
  flatMap2(
2872
- ([expectedEffect, realEffect]) => getMissingTypeEntriesInTargetType(
2873
- realEffect.E,
2874
- expectedEffect.E
2906
+ ([expectedEffect, realEffect]) => pipe(
2907
+ getMissingTypeEntriesInTargetType(
2908
+ realEffect.E,
2909
+ expectedEffect.E
2910
+ ),
2911
+ map3((missingErrorTypes) => ({ missingErrorTypes, expectedErrorType: expectedEffect.E }))
2875
2912
  )
2876
2913
  )
2877
2914
  );
@@ -2886,15 +2923,79 @@ var missingEffectError = createDiagnostic({
2886
2923
  valueNode,
2887
2924
  realType
2888
2925
  ),
2889
- map3(
2890
- (missingTypes) => missingTypes.length > 0 ? report(
2926
+ map3((result) => {
2927
+ if (result.missingErrorTypes.length === 0) return;
2928
+ const fixes = [];
2929
+ if (ts.isExpression(valueNode) && result.expectedErrorType.flags & ts.TypeFlags.Never) {
2930
+ fixes.push({
2931
+ fixName: "missingEffectError_catchAll",
2932
+ description: "Catch all errors with Effect.catchAll",
2933
+ apply: gen(function* () {
2934
+ const changeTracker = yield* service(ChangeTracker);
2935
+ changeTracker.insertText(sourceFile, valueNode.getStart(), effectModuleIdentifier + ".catchAll(");
2936
+ changeTracker.insertText(sourceFile, valueNode.getEnd(), ", () => ");
2937
+ changeTracker.insertNodeAt(
2938
+ sourceFile,
2939
+ valueNode.getEnd(),
2940
+ createDieMessage("TODO: catchAll not implemented")
2941
+ );
2942
+ changeTracker.insertText(sourceFile, valueNode.getEnd(), ")");
2943
+ })
2944
+ });
2945
+ }
2946
+ if (ts.isExpression(valueNode)) {
2947
+ const propertyAssignments = pipe(
2948
+ result.missingErrorTypes,
2949
+ map2((_) => typeChecker.getPropertyOfType(_, "_tag")),
2950
+ filter((_) => !!_),
2951
+ map2((_) => typeChecker.getTypeOfSymbolAtLocation(_, valueNode)),
2952
+ filter((_) => !!(_.flags & ts.TypeFlags.Literal)),
2953
+ map2((_) => typeChecker.typeToTypeNode(_, void 0, ts.NodeBuilderFlags.NoTruncation)),
2954
+ filter((_) => !!_ && ts.isLiteralTypeNode(_)),
2955
+ map2((_) => _.literal),
2956
+ filter((_) => ts.isLiteralExpression(_)),
2957
+ map2((_) => _.text),
2958
+ sort(string2),
2959
+ map2(
2960
+ (_) => ts.factory.createPropertyAssignment(
2961
+ ts.factory.createIdentifier(_),
2962
+ ts.factory.createArrowFunction(
2963
+ void 0,
2964
+ void 0,
2965
+ [],
2966
+ void 0,
2967
+ void 0,
2968
+ createDieMessage(`TODO: catchTags() not implemented for ${_}`)
2969
+ )
2970
+ )
2971
+ )
2972
+ );
2973
+ if (propertyAssignments.length === result.missingErrorTypes.length) {
2974
+ fixes.push({
2975
+ fixName: "missingEffectError_tagged",
2976
+ description: "Catch unexpected errors with Effect.catchTag",
2977
+ apply: gen(function* () {
2978
+ const changeTracker = yield* service(ChangeTracker);
2979
+ changeTracker.insertText(sourceFile, valueNode.getStart(), effectModuleIdentifier + ".catchTags(");
2980
+ changeTracker.insertText(sourceFile, valueNode.getEnd(), ", ");
2981
+ changeTracker.insertNodeAt(
2982
+ sourceFile,
2983
+ valueNode.getEnd(),
2984
+ ts.factory.createObjectLiteralExpression(propertyAssignments)
2985
+ );
2986
+ changeTracker.insertText(sourceFile, valueNode.getEnd(), ")");
2987
+ })
2988
+ });
2989
+ }
2990
+ }
2991
+ report(
2891
2992
  {
2892
2993
  node,
2893
- messageText: `Missing '${sortTypes(missingTypes).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect errors.`,
2894
- fixes: []
2994
+ messageText: `Missing '${sortTypes(result.missingErrorTypes).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect errors.`,
2995
+ fixes
2895
2996
  }
2896
- ) : void 0
2897
- ),
2997
+ );
2998
+ }),
2898
2999
  ignore
2899
3000
  );
2900
3001
  }
@@ -3106,6 +3207,108 @@ Nested Effect-able types may be intended if you plan to later manually flatten o
3106
3207
  })
3107
3208
  });
3108
3209
 
3210
+ // src/diagnostics/scopeInLayerEffect.ts
3211
+ var scopeInLayerEffect = createDiagnostic({
3212
+ name: "scopeInLayerEffect",
3213
+ code: 13,
3214
+ severity: "warning",
3215
+ apply: fn("scopeInLayerEffect.apply")(function* (sourceFile, report) {
3216
+ const ts = yield* service(TypeScriptApi);
3217
+ const typeChecker = yield* service(TypeCheckerApi);
3218
+ const typeParser = yield* service(TypeParser);
3219
+ const layerModuleIdentifier = yield* pipe(
3220
+ findImportedModuleIdentifierByPackageAndNameOrBarrel(
3221
+ sourceFile,
3222
+ "effect",
3223
+ "Layer"
3224
+ ),
3225
+ map3((_) => _.text),
3226
+ orElse2(() => succeed("Layer"))
3227
+ );
3228
+ function parseLayerEffectApiCall(node) {
3229
+ if (!ts.isCallExpression(node)) return;
3230
+ const expression = node.expression;
3231
+ if (!ts.isPropertyAccessExpression(expression)) return;
3232
+ const calledModule = expression.expression;
3233
+ if (!(ts.isIdentifier(calledModule) && calledModule.text === layerModuleIdentifier)) return;
3234
+ const methodIdentifier = expression.name;
3235
+ if (!(ts.isIdentifier(methodIdentifier) && methodIdentifier.text.toLowerCase().startsWith("effect"))) return;
3236
+ return { methodIdentifier };
3237
+ }
3238
+ const reportIfLayerRequireScope = (type, node, methodIdentifier) => {
3239
+ let toCheck = [type];
3240
+ const entries = [];
3241
+ while (toCheck.length > 0) {
3242
+ const type2 = toCheck.pop();
3243
+ if (type2.isUnion()) {
3244
+ toCheck = toCheck.concat(type2.types);
3245
+ } else {
3246
+ entries.push(type2);
3247
+ }
3248
+ }
3249
+ return pipe(
3250
+ firstSuccessOf(entries.map((type2) => typeParser.scopeType(type2, node))),
3251
+ map3(
3252
+ () => report({
3253
+ node,
3254
+ messageText: `Seems like you are constructing a layer with a scope in the requirements.
3255
+ Consider using "scoped" instead to get ride of the scope in the requirements.`,
3256
+ fixes: methodIdentifier ? [{
3257
+ fixName: "scopeInLayerEffect_scoped",
3258
+ description: "Use scoped for Layer creation",
3259
+ apply: gen(function* () {
3260
+ const changeTracker = yield* service(ChangeTracker);
3261
+ changeTracker.replaceNode(
3262
+ sourceFile,
3263
+ methodIdentifier,
3264
+ ts.factory.createIdentifier("scoped")
3265
+ );
3266
+ })
3267
+ }] : []
3268
+ })
3269
+ ),
3270
+ ignore
3271
+ );
3272
+ };
3273
+ const nodeToVisit = [];
3274
+ const appendNodeToVisit = (node) => {
3275
+ nodeToVisit.push(node);
3276
+ return void 0;
3277
+ };
3278
+ ts.forEachChild(sourceFile, appendNodeToVisit);
3279
+ while (nodeToVisit.length > 0) {
3280
+ const node = nodeToVisit.shift();
3281
+ const layerEffectApiCall = parseLayerEffectApiCall(node);
3282
+ if (layerEffectApiCall) {
3283
+ const type = typeChecker.getTypeAtLocation(node);
3284
+ yield* pipe(
3285
+ typeParser.layerType(type, node),
3286
+ flatMap2(({ RIn }) => reportIfLayerRequireScope(RIn, node, layerEffectApiCall.methodIdentifier)),
3287
+ ignore
3288
+ );
3289
+ continue;
3290
+ }
3291
+ if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
3292
+ const classSym = typeChecker.getSymbolAtLocation(node.name);
3293
+ if (classSym) {
3294
+ const classType = typeChecker.getTypeOfSymbol(classSym);
3295
+ const defaultLayer = typeChecker.getPropertyOfType(classType, "Default");
3296
+ if (defaultLayer) {
3297
+ const type = typeChecker.getTypeOfSymbolAtLocation(defaultLayer, node);
3298
+ yield* pipe(
3299
+ typeParser.layerType(type, node),
3300
+ flatMap2(({ RIn }) => reportIfLayerRequireScope(RIn, node, void 0)),
3301
+ ignore
3302
+ );
3303
+ continue;
3304
+ }
3305
+ }
3306
+ }
3307
+ ts.forEachChild(node, appendNodeToVisit);
3308
+ }
3309
+ })
3310
+ });
3311
+
3109
3312
  // src/diagnostics/unnecessaryEffectGen.ts
3110
3313
  var unnecessaryEffectGen = createDiagnostic({
3111
3314
  name: "unnecessaryEffectGen",
@@ -3207,7 +3410,8 @@ var diagnostics = [
3207
3410
  unnecessaryPipe,
3208
3411
  genericEffectServices,
3209
3412
  returnEffectInGen,
3210
- importFromBarrel
3413
+ importFromBarrel,
3414
+ scopeInLayerEffect
3211
3415
  ];
3212
3416
 
3213
3417
  // src/transform.ts