@effect/language-service 0.18.0 → 0.20.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/index.js CHANGED
@@ -5,7 +5,7 @@ var __export = (target, all3) => {
5
5
  __defProp(target, name, { get: all3[name], enumerable: true });
6
6
  };
7
7
 
8
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Function.js
8
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Function.js
9
9
  var isFunction = (input) => typeof input === "function";
10
10
  var dual = function(arity, body) {
11
11
  if (typeof arity === "function") {
@@ -102,7 +102,7 @@ function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
102
102
  }
103
103
  }
104
104
 
105
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Either.js
105
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Either.js
106
106
  var Either_exports = {};
107
107
  __export(Either_exports, {
108
108
  Do: () => Do,
@@ -146,7 +146,7 @@ __export(Either_exports, {
146
146
  zipWith: () => zipWith
147
147
  });
148
148
 
149
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Equivalence.js
149
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Equivalence.js
150
150
  var make = (isEquivalent) => (self, that) => self === that || isEquivalent(self, that);
151
151
  var array = (item) => make((self, that) => {
152
152
  if (self.length !== that.length) {
@@ -161,7 +161,7 @@ var array = (item) => make((self, that) => {
161
161
  return true;
162
162
  });
163
163
 
164
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/doNotation.js
164
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/doNotation.js
165
165
  var let_ = (map5) => dual(3, (self, name, f) => map5(self, (a) => Object.assign({}, a, {
166
166
  [name]: f(a)
167
167
  })));
@@ -172,11 +172,11 @@ var bind = (map5, flatMap4) => dual(3, (self, name, f) => flatMap4(self, (a) =>
172
172
  [name]: b
173
173
  }))));
174
174
 
175
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/version.js
176
- var moduleVersion = "3.16.3";
175
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/version.js
176
+ var moduleVersion = "3.16.5";
177
177
  var getCurrentVersion = () => moduleVersion;
178
178
 
179
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/GlobalValue.js
179
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/GlobalValue.js
180
180
  var globalStoreId = `effect/GlobalValue/globalStoreId/${/* @__PURE__ */ getCurrentVersion()}`;
181
181
  var globalStore;
182
182
  var globalValue = (id, compute) => {
@@ -190,7 +190,7 @@ var globalValue = (id, compute) => {
190
190
  return globalStore.get(id);
191
191
  };
192
192
 
193
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Predicate.js
193
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Predicate.js
194
194
  var isString = (input) => typeof input === "string";
195
195
  var isNumber = (input) => typeof input === "number";
196
196
  var isBoolean = (input) => typeof input === "boolean";
@@ -199,10 +199,10 @@ var isRecordOrArray = (input) => typeof input === "object" && input !== null;
199
199
  var isObject = (input) => isRecordOrArray(input) || isFunction2(input);
200
200
  var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObject(self) && property in self);
201
201
 
202
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/errors.js
202
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/errors.js
203
203
  var getBugErrorMessage = (message) => `BUG: ${message} - please report an issue at https://github.com/Effect-TS/effect/issues`;
204
204
 
205
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Utils.js
205
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Utils.js
206
206
  var GenKindTypeId = /* @__PURE__ */ Symbol.for("effect/Gen/GenKind");
207
207
  var isGenKind = (u) => isObject(u) && GenKindTypeId in u;
208
208
  var GenKindImpl = class {
@@ -338,7 +338,7 @@ var internalCall = isNotOptimizedAway ? standard.effect_internal_function : forc
338
338
  var genConstructor = function* () {
339
339
  }.constructor;
340
340
 
341
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Hash.js
341
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Hash.js
342
342
  var randomHashCache = /* @__PURE__ */ globalValue(/* @__PURE__ */ Symbol.for("effect/Hash/randomHashCache"), () => /* @__PURE__ */ new WeakMap());
343
343
  var symbol = /* @__PURE__ */ Symbol.for("effect/Hash");
344
344
  var hash = (self) => {
@@ -437,7 +437,7 @@ var cached = function() {
437
437
  return hash2;
438
438
  };
439
439
 
440
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Equal.js
440
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Equal.js
441
441
  var symbol2 = /* @__PURE__ */ Symbol.for("effect/Equal");
442
442
  function equals() {
443
443
  if (arguments.length === 1) {
@@ -490,7 +490,7 @@ function compareBoth(self, that) {
490
490
  }
491
491
  var isEqual = (u) => hasProperty(u, symbol2);
492
492
 
493
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Inspectable.js
493
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Inspectable.js
494
494
  var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
495
495
  var toJSON = (x) => {
496
496
  try {
@@ -542,7 +542,7 @@ var redact = (u) => {
542
542
  return u;
543
543
  };
544
544
 
545
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Pipeable.js
545
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Pipeable.js
546
546
  var pipeArguments = (self, args) => {
547
547
  switch (args.length) {
548
548
  case 0:
@@ -575,10 +575,10 @@ var pipeArguments = (self, args) => {
575
575
  }
576
576
  };
577
577
 
578
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/opCodes/effect.js
578
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/opCodes/effect.js
579
579
  var OP_COMMIT = "Commit";
580
580
 
581
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/effectable.js
581
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/effectable.js
582
582
  var EffectTypeId = /* @__PURE__ */ Symbol.for("effect/Effect");
583
583
  var StreamTypeId = /* @__PURE__ */ Symbol.for("effect/Stream");
584
584
  var SinkTypeId = /* @__PURE__ */ Symbol.for("effect/Sink");
@@ -665,7 +665,7 @@ var StructuralCommitPrototype = {
665
665
  ...StructuralPrototype
666
666
  };
667
667
 
668
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/option.js
668
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/option.js
669
669
  var TypeId = /* @__PURE__ */ Symbol.for("effect/Option");
670
670
  var CommonProto = {
671
671
  ...EffectPrototype,
@@ -723,7 +723,7 @@ var some = (value) => {
723
723
  return a;
724
724
  };
725
725
 
726
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/either.js
726
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/either.js
727
727
  var TypeId2 = /* @__PURE__ */ Symbol.for("effect/Either");
728
728
  var CommonProto2 = {
729
729
  ...EffectPrototype,
@@ -788,7 +788,7 @@ var getLeft = (self) => isRight(self) ? none : some(self.left);
788
788
  var getRight = (self) => isLeft(self) ? none : some(self.right);
789
789
  var fromOption = /* @__PURE__ */ dual(2, (self, onNone) => isNone(self) ? left(onNone()) : right(self.value));
790
790
 
791
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Either.js
791
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Either.js
792
792
  var TypeId3 = TypeId2;
793
793
  var right2 = right;
794
794
  var void_ = /* @__PURE__ */ right2(void 0);
@@ -898,13 +898,13 @@ var transposeOption = (self) => {
898
898
  };
899
899
  var transposeMapOption = /* @__PURE__ */ dual(2, (self, f) => isNone(self) ? right2(none) : map(f(self.value), some));
900
900
 
901
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/array.js
901
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/array.js
902
902
  var isNonEmptyArray = (self) => self.length > 0;
903
903
 
904
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Order.js
904
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Order.js
905
905
  var make2 = (compare) => (self, that) => self === that ? 0 : compare(self, that);
906
906
 
907
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Option.js
907
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Option.js
908
908
  var none2 = () => none;
909
909
  var some2 = some;
910
910
  var isNone2 = isNone;
@@ -919,9 +919,10 @@ var fromNullable2 = (nullableValue) => nullableValue == null ? none2() : some2(n
919
919
  var getOrUndefined2 = /* @__PURE__ */ getOrElse2(constUndefined);
920
920
  var map2 = /* @__PURE__ */ dual(2, (self, f) => isNone2(self) ? none2() : some2(f(self.value)));
921
921
 
922
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Array.js
922
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Array.js
923
923
  var fromIterable = (collection) => Array.isArray(collection) ? collection : Array.from(collection);
924
924
  var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
925
+ var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable(self).concat(fromIterable(that)));
925
926
  var isArray = Array.isArray;
926
927
  var isEmptyArray = (self) => self.length === 0;
927
928
  var isEmptyReadonlyArray = isEmptyArray;
@@ -1136,6 +1137,27 @@ var all2 = (...args) => gen2(function* () {
1136
1137
  var TypeScriptApi = Tag("TypeScriptApi");
1137
1138
  var TypeScriptProgram = Tag("TypeScriptProgram");
1138
1139
  var ChangeTracker = Tag("ChangeTracker");
1140
+ function parsePackageContentNameAndVersionFromScope(v) {
1141
+ if (!isObject(v)) return;
1142
+ if (!hasProperty(v, "packageJsonScope")) return;
1143
+ if (!v.packageJsonScope) return;
1144
+ const packageJsonScope = v.packageJsonScope;
1145
+ if (!hasProperty(packageJsonScope, "contents")) return;
1146
+ if (!hasProperty(packageJsonScope.contents, "packageJsonContent")) return;
1147
+ const packageJsonContent = packageJsonScope.contents.packageJsonContent;
1148
+ if (!hasProperty(packageJsonContent, "name")) return;
1149
+ if (!hasProperty(packageJsonContent, "version")) return;
1150
+ const { name, version } = packageJsonContent;
1151
+ if (!isString(name)) return;
1152
+ if (!isString(version)) return;
1153
+ const hasEffectInPeerDependencies = hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) && hasProperty(packageJsonContent.peerDependencies, "effect");
1154
+ return {
1155
+ name: name.toLowerCase(),
1156
+ version: version.toLowerCase(),
1157
+ hasEffectInPeerDependencies,
1158
+ contents: packageJsonContent
1159
+ };
1160
+ }
1139
1161
 
1140
1162
  // src/core/AST.ts
1141
1163
  function collectSelfAndAncestorNodesInRange(node, textRange) {
@@ -1484,6 +1506,19 @@ var createReturnYieldStarStatement = fn("AST.createReturnYieldStarStatement")(
1484
1506
  );
1485
1507
  }
1486
1508
  );
1509
+ var parsePipeCall = fn("AST.parsePipeCall")(
1510
+ function* (node) {
1511
+ const ts = yield* service(TypeScriptApi);
1512
+ if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && node.expression.name.text === "pipe") {
1513
+ return { node, subject: node.expression.expression, args: node.arguments };
1514
+ }
1515
+ if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "pipe" && node.arguments.length > 0) {
1516
+ const [subject, ...args] = node.arguments;
1517
+ return { node, subject, args };
1518
+ }
1519
+ return yield* fail(new NodeNotFoundError());
1520
+ }
1521
+ );
1487
1522
 
1488
1523
  // src/core/LSP.ts
1489
1524
  var RefactorNotApplicableError = class {
@@ -2094,6 +2129,51 @@ var expectedAndRealType = fn("TypeCheckerApi.expectedAndRealType")(function* (so
2094
2129
  cache.expectedAndRealType.set(sourceFile, result);
2095
2130
  return result;
2096
2131
  });
2132
+ var appendToUniqueTypesMap = fn(
2133
+ "TypeCheckerApi.appendToUniqueTypesMap"
2134
+ )(
2135
+ function* (memory, initialType, excludeNever) {
2136
+ const ts = yield* service(TypeScriptApi);
2137
+ const typeChecker = yield* service(TypeCheckerApi);
2138
+ const newIndexes = /* @__PURE__ */ new Set();
2139
+ const knownIndexes = /* @__PURE__ */ new Set();
2140
+ let toTest = [initialType];
2141
+ while (toTest.length > 0) {
2142
+ const type = toTest.pop();
2143
+ if (!type) break;
2144
+ if (excludeNever && type.flags & ts.TypeFlags.Never) {
2145
+ continue;
2146
+ }
2147
+ if (type.isUnion()) {
2148
+ toTest = toTest.concat(type.types);
2149
+ } else {
2150
+ const foundMatch = [];
2151
+ for (const [typeId, knownType] of memory.entries()) {
2152
+ const areSame = typeChecker.isTypeAssignableTo(knownType, type) && typeChecker.isTypeAssignableTo(type, knownType);
2153
+ if (areSame) {
2154
+ foundMatch.push(typeId);
2155
+ break;
2156
+ }
2157
+ }
2158
+ if (foundMatch.length === 0) {
2159
+ const newId = "t" + (memory.size + 1);
2160
+ memory.set(newId, type);
2161
+ newIndexes.add(newId);
2162
+ } else {
2163
+ knownIndexes.add(foundMatch[0]);
2164
+ }
2165
+ }
2166
+ }
2167
+ return {
2168
+ newIndexes,
2169
+ knownIndexes,
2170
+ allIndexes: pipe(
2171
+ fromIterable(newIndexes),
2172
+ appendAll(fromIterable(knownIndexes))
2173
+ )
2174
+ };
2175
+ }
2176
+ );
2097
2177
 
2098
2178
  // src/utils/TypeParser.ts
2099
2179
  var TypeParserIssue = class {
@@ -2114,6 +2194,13 @@ function covariantTypeArgument(type) {
2114
2194
  }
2115
2195
  return succeed(signatures[0].getReturnType());
2116
2196
  }
2197
+ function contravariantTypeArgument(type) {
2198
+ const signatures = type.getCallSignatures();
2199
+ if (signatures.length !== 1) {
2200
+ return typeParserIssue("Contravariant type has no call signature", type);
2201
+ }
2202
+ return succeed(signatures[0].getTypeParameterAtPosition(0));
2203
+ }
2117
2204
  function invariantTypeArgument(type) {
2118
2205
  const signatures = type.getCallSignatures();
2119
2206
  if (signatures.length !== 1) {
@@ -2145,6 +2232,19 @@ var varianceStructCovariantType = fn("TypeParser.varianceStructCovariantType")(
2145
2232
  return yield* covariantTypeArgument(propertyType);
2146
2233
  }
2147
2234
  );
2235
+ var varianceStructContravariantType = fn(
2236
+ "TypeParser.varianceStructContravariantType"
2237
+ )(
2238
+ function* (type, atLocation, propertyName) {
2239
+ const typeChecker = yield* service(TypeCheckerApi);
2240
+ const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
2241
+ if (!propertySymbol) {
2242
+ return yield* typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
2243
+ }
2244
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2245
+ return yield* contravariantTypeArgument(propertyType);
2246
+ }
2247
+ );
2148
2248
  var varianceStructInvariantType = fn("TypeParser.varianceStructInvariantType")(
2149
2249
  function* (type, atLocation, propertyName) {
2150
2250
  const typeChecker = yield* service(TypeCheckerApi);
@@ -2163,6 +2263,13 @@ var effectVarianceStruct = fn("TypeParser.effectVarianceStruct")(function* (type
2163
2263
  R: yield* varianceStructCovariantType(type, atLocation, "_R")
2164
2264
  };
2165
2265
  });
2266
+ var layerVarianceStruct = fn("TypeParser.layerVarianceStruct")(function* (type, atLocation) {
2267
+ return {
2268
+ ROut: yield* varianceStructContravariantType(type, atLocation, "_ROut"),
2269
+ E: yield* varianceStructCovariantType(type, atLocation, "_E"),
2270
+ RIn: yield* varianceStructCovariantType(type, atLocation, "_RIn")
2271
+ };
2272
+ });
2166
2273
  var effectType = fn("TypeParser.effectType")(function* (type, atLocation) {
2167
2274
  const ts = yield* service(TypeScriptApi);
2168
2275
  const typeChecker = yield* service(TypeCheckerApi);
@@ -2183,6 +2290,26 @@ var effectType = fn("TypeParser.effectType")(function* (type, atLocation) {
2183
2290
  }
2184
2291
  return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
2185
2292
  });
2293
+ var layerType = fn("TypeParser.layerType")(function* (type, atLocation) {
2294
+ const ts = yield* service(TypeScriptApi);
2295
+ const typeChecker = yield* service(TypeCheckerApi);
2296
+ yield* pipeableType(type, atLocation);
2297
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2298
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
2299
+ );
2300
+ propertiesSymbols.sort((a, b) => b.name.indexOf("LayerTypeId") - a.name.indexOf("LayerTypeId"));
2301
+ for (const propertySymbol of propertiesSymbols) {
2302
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2303
+ const varianceArgs = yield* option(layerVarianceStruct(
2304
+ propertyType,
2305
+ atLocation
2306
+ ));
2307
+ if (isSome2(varianceArgs)) {
2308
+ return varianceArgs.value;
2309
+ }
2310
+ }
2311
+ return yield* typeParserIssue("Type has no layer variance struct", type, atLocation);
2312
+ });
2186
2313
  var fiberType = fn("TypeParser.fiberType")(function* (type, atLocation) {
2187
2314
  const typeChecker = yield* service(TypeCheckerApi);
2188
2315
  const awaitSymbol = typeChecker.getPropertyOfType(type, "await");
@@ -2348,19 +2475,68 @@ var effectFnGen = fn("TypeParser.effectFnGen")(function* (node) {
2348
2475
  functionStar: generatorFunction.getFirstToken()
2349
2476
  };
2350
2477
  });
2351
- var returnYieldEffectBlock = fn("TypeParser.returnYieldEffectBlock")(function* (body) {
2478
+ var unnecessaryEffectGen = fn("TypeParser.unnecessaryEffectGen")(function* (node) {
2352
2479
  const ts = yield* service(TypeScriptApi);
2353
2480
  const typeChecker = yield* service(TypeCheckerApi);
2354
- if (ts.isBlock(body) && body.statements.length === 1 && ts.isReturnStatement(body.statements[0]) && body.statements[0].expression && ts.isYieldExpression(body.statements[0].expression) && body.statements[0].expression.expression) {
2355
- const nodeToCheck = body.statements[0].expression.expression;
2356
- const type = typeChecker.getTypeAtLocation(nodeToCheck);
2357
- yield* effectType(type, nodeToCheck);
2358
- return nodeToCheck;
2481
+ const { body } = yield* effectGen(node);
2482
+ if (body.statements.length !== 1) {
2483
+ return yield* typeParserIssue(
2484
+ "Generator body should have a single statement",
2485
+ void 0,
2486
+ node
2487
+ );
2488
+ }
2489
+ let explicitReturn = false;
2490
+ let nodeToCheck = body.statements[0];
2491
+ while (nodeToCheck) {
2492
+ if (ts.isReturnStatement(nodeToCheck) && nodeToCheck.expression) {
2493
+ nodeToCheck = nodeToCheck.expression;
2494
+ explicitReturn = true;
2495
+ continue;
2496
+ }
2497
+ if (ts.isExpressionStatement(nodeToCheck)) {
2498
+ nodeToCheck = nodeToCheck.expression;
2499
+ continue;
2500
+ }
2501
+ if (ts.isYieldExpression(nodeToCheck) && nodeToCheck.asteriskToken && nodeToCheck.expression) {
2502
+ const yieldedExpression = nodeToCheck.expression;
2503
+ const type = typeChecker.getTypeAtLocation(yieldedExpression);
2504
+ const { A: successType } = yield* effectType(type, yieldedExpression);
2505
+ let replacementNode = succeed(yieldedExpression);
2506
+ if (!explicitReturn && !(successType.flags & ts.TypeFlags.VoidLike)) {
2507
+ replacementNode = pipe(
2508
+ gen2(function* () {
2509
+ const effectIdentifier = pipe(
2510
+ yield* option(
2511
+ findImportedModuleIdentifierByPackageAndNameOrBarrel(node.getSourceFile(), "effect", "Effect")
2512
+ ),
2513
+ match2({
2514
+ onNone: () => "Effect",
2515
+ onSome: (_) => _.text
2516
+ })
2517
+ );
2518
+ return ts.factory.createCallExpression(
2519
+ ts.factory.createPropertyAccessExpression(
2520
+ ts.factory.createIdentifier(effectIdentifier),
2521
+ "asVoid"
2522
+ ),
2523
+ void 0,
2524
+ [
2525
+ yieldedExpression
2526
+ ]
2527
+ );
2528
+ }),
2529
+ provideService(TypeScriptApi, ts)
2530
+ );
2531
+ }
2532
+ return { node, body, yieldedExpression, replacementNode };
2533
+ }
2534
+ break;
2359
2535
  }
2360
2536
  return yield* typeParserIssue(
2361
- "Node is not a return statement with a yield expression",
2537
+ "Not an handled node",
2362
2538
  void 0,
2363
- body
2539
+ node
2364
2540
  );
2365
2541
  });
2366
2542
  var effectSchemaVarianceStruct = fn("TypeParser.effectSchemaVarianceStruct")(
@@ -2474,11 +2650,45 @@ var genFunctionStar = createCompletion({
2474
2650
  })
2475
2651
  });
2476
2652
 
2653
+ // src/completions/rpcMakeClasses.ts
2654
+ var rpcMakeClasses = createCompletion({
2655
+ name: "rpcMakeClasses",
2656
+ apply: fn("rpcMakeClasses")(function* (sourceFile, position) {
2657
+ const ts = yield* service(TypeScriptApi);
2658
+ const maybeInfos = yield* option(
2659
+ parseDataForExtendsClassCompletion(sourceFile, position)
2660
+ );
2661
+ if (isNone2(maybeInfos)) return [];
2662
+ const { accessedObject, className, replacementSpan } = maybeInfos.value;
2663
+ const rpcName = yield* option(
2664
+ findImportedModuleIdentifierByPackageAndNameOrBarrel(
2665
+ sourceFile,
2666
+ "@effect/rpc",
2667
+ "Rpc"
2668
+ )
2669
+ );
2670
+ const rpcIdentifier = match2(rpcName, {
2671
+ onNone: () => "Rpc",
2672
+ onSome: (_) => _.text
2673
+ });
2674
+ if (rpcIdentifier !== accessedObject.text) return [];
2675
+ const name = className.text;
2676
+ return [{
2677
+ name: `make("${name}")`,
2678
+ kind: ts.ScriptElementKind.constElement,
2679
+ insertText: `${rpcIdentifier}.make("${name}", {${"${0}"}}) {}`,
2680
+ replacementSpan,
2681
+ isSnippet: true
2682
+ }];
2683
+ })
2684
+ });
2685
+
2477
2686
  // src/completions.ts
2478
2687
  var completions = [
2479
2688
  effectSchemaSelfInClasses,
2480
2689
  effectSelfInClasses,
2481
2690
  contextSelfInClasses,
2691
+ rpcMakeClasses,
2482
2692
  genFunctionStar,
2483
2693
  fnFunctionStar,
2484
2694
  effectDataClasses
@@ -2498,27 +2708,6 @@ function parse(config) {
2498
2708
  // src/diagnostics/duplicatePackage.ts
2499
2709
  var checkedPackagesCache = /* @__PURE__ */ new Map();
2500
2710
  var programResolvedCacheSize = /* @__PURE__ */ new Map();
2501
- function parsePackageContentNameAndVersion(v) {
2502
- if (!isObject(v)) return;
2503
- if (!hasProperty(v, "packageJsonScope")) return;
2504
- if (!v.packageJsonScope) return;
2505
- const packageJsonScope = v.packageJsonScope;
2506
- if (!hasProperty(packageJsonScope, "contents")) return;
2507
- if (!hasProperty(packageJsonScope.contents, "packageJsonContent")) return;
2508
- const packageJsonContent = packageJsonScope.contents.packageJsonContent;
2509
- if (!hasProperty(packageJsonContent, "name")) return;
2510
- if (!hasProperty(packageJsonContent, "version")) return;
2511
- const { name, version } = packageJsonContent;
2512
- if (!isString(name)) return;
2513
- if (!isString(version)) return;
2514
- const hasEffectInPeerDependencies = hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) && hasProperty(packageJsonContent.peerDependencies, "effect");
2515
- return {
2516
- name: name.toLowerCase(),
2517
- version: version.toLowerCase(),
2518
- hasEffectInPeerDependencies,
2519
- contents: packageJsonContent
2520
- };
2521
- }
2522
2711
  var duplicatePackage = createDiagnostic({
2523
2712
  name: "duplicatePackage",
2524
2713
  code: 6,
@@ -2535,7 +2724,7 @@ var duplicatePackage = createDiagnostic({
2535
2724
  const seenPackages = /* @__PURE__ */ new Set();
2536
2725
  resolvedPackages = {};
2537
2726
  program.getSourceFiles().map((_) => {
2538
- const packageInfo = parsePackageContentNameAndVersion(_);
2727
+ const packageInfo = parsePackageContentNameAndVersionFromScope(_);
2539
2728
  if (!packageInfo) return;
2540
2729
  const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
2541
2730
  if (seenPackages.has(packageNameAndVersion)) return;
@@ -2716,6 +2905,75 @@ var missingEffectError = createDiagnostic({
2716
2905
  })
2717
2906
  });
2718
2907
 
2908
+ // src/diagnostics/missingReturnYieldStar.ts
2909
+ var missingReturnYieldStar = createDiagnostic({
2910
+ name: "missingReturnYieldStar",
2911
+ code: 7,
2912
+ apply: fn("missingReturnYieldStar.apply")(function* (sourceFile) {
2913
+ const ts = yield* service(TypeScriptApi);
2914
+ const typeChecker = yield* service(TypeCheckerApi);
2915
+ const effectDiagnostics = [];
2916
+ const brokenYields = /* @__PURE__ */ new Set();
2917
+ const nodeToVisit = [];
2918
+ const appendNodeToVisit = (node) => {
2919
+ nodeToVisit.push(node);
2920
+ return void 0;
2921
+ };
2922
+ ts.forEachChild(sourceFile, appendNodeToVisit);
2923
+ while (nodeToVisit.length > 0) {
2924
+ const node = nodeToVisit.shift();
2925
+ ts.forEachChild(node, appendNodeToVisit);
2926
+ if (ts.isYieldExpression(node) && node.expression && node.asteriskToken) {
2927
+ const type = typeChecker.getTypeAtLocation(node.expression);
2928
+ const maybeEffect = yield* option(effectType(type, node.expression));
2929
+ if (isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never) {
2930
+ const generatorFunctionOrReturnStatement = ts.findAncestor(
2931
+ node,
2932
+ (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isReturnStatement(_)
2933
+ );
2934
+ if (generatorFunctionOrReturnStatement && !ts.isReturnStatement(generatorFunctionOrReturnStatement)) {
2935
+ if (generatorFunctionOrReturnStatement && generatorFunctionOrReturnStatement.parent) {
2936
+ const effectGenNode = generatorFunctionOrReturnStatement.parent;
2937
+ const effectGenLike = yield* pipe(
2938
+ effectGen(effectGenNode),
2939
+ orElse3(() => effectFnUntracedGen(effectGenNode)),
2940
+ orElse3(() => effectFnGen(effectGenNode)),
2941
+ option
2942
+ );
2943
+ if (isSome2(effectGenLike)) {
2944
+ brokenYields.add(node);
2945
+ }
2946
+ }
2947
+ }
2948
+ }
2949
+ }
2950
+ }
2951
+ brokenYields.forEach((node) => {
2952
+ const fix = node.expression ? [{
2953
+ fixName: "missingReturnYieldStar_fix",
2954
+ description: "Add return statement",
2955
+ apply: gen2(function* () {
2956
+ const changeTracker = yield* service(ChangeTracker);
2957
+ changeTracker.replaceNode(
2958
+ sourceFile,
2959
+ node,
2960
+ ts.factory.createReturnStatement(
2961
+ node
2962
+ )
2963
+ );
2964
+ })
2965
+ }] : [];
2966
+ effectDiagnostics.push({
2967
+ node,
2968
+ category: ts.DiagnosticCategory.Error,
2969
+ messageText: `Yielded Effect never completes, so it is best to use a 'return yield*' instead.`,
2970
+ fixes: fix
2971
+ });
2972
+ });
2973
+ return effectDiagnostics;
2974
+ })
2975
+ });
2976
+
2719
2977
  // src/diagnostics/missingStarInYieldEffectGen.ts
2720
2978
  var missingStarInYieldEffectGen = createDiagnostic({
2721
2979
  name: "missingStarInYieldEffectGen",
@@ -2792,7 +3050,7 @@ var missingStarInYieldEffectGen = createDiagnostic({
2792
3050
  });
2793
3051
 
2794
3052
  // src/diagnostics/unnecessaryEffectGen.ts
2795
- var unnecessaryEffectGen = createDiagnostic({
3053
+ var unnecessaryEffectGen2 = createDiagnostic({
2796
3054
  name: "unnecessaryEffectGen",
2797
3055
  code: 5,
2798
3056
  apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile) {
@@ -2808,13 +3066,9 @@ var unnecessaryEffectGen = createDiagnostic({
2808
3066
  while (nodeToVisit.length > 0) {
2809
3067
  const node = nodeToVisit.shift();
2810
3068
  ts.forEachChild(node, appendNodeToVisit);
2811
- const maybeNode = yield* pipe(
2812
- effectGen(node),
2813
- flatMap3(({ body }) => returnYieldEffectBlock(body)),
2814
- option
2815
- );
3069
+ const maybeNode = yield* option(unnecessaryEffectGen(node));
2816
3070
  if (isSome2(maybeNode)) {
2817
- unnecessaryGenerators.set(node, maybeNode.value);
3071
+ unnecessaryGenerators.set(node, maybeNode.value.replacementNode);
2818
3072
  }
2819
3073
  }
2820
3074
  unnecessaryGenerators.forEach(
@@ -2829,7 +3083,7 @@ var unnecessaryEffectGen = createDiagnostic({
2829
3083
  const textChanges = yield* service(
2830
3084
  ChangeTracker
2831
3085
  );
2832
- textChanges.replaceNode(sourceFile, effectGenCall, yieldedResult);
3086
+ textChanges.replaceNode(sourceFile, effectGenCall, yield* yieldedResult);
2833
3087
  })
2834
3088
  }]
2835
3089
  })
@@ -2845,24 +3099,132 @@ var diagnostics = [
2845
3099
  missingEffectError,
2846
3100
  floatingEffect,
2847
3101
  missingStarInYieldEffectGen,
2848
- unnecessaryEffectGen
3102
+ unnecessaryEffectGen2,
3103
+ missingReturnYieldStar
2849
3104
  ];
2850
3105
 
2851
- // src/quickinfo.ts
3106
+ // src/goto/effectRpcDefinition.ts
3107
+ function effectRpcDefinition(applicableGotoDefinition, sourceFile, position) {
3108
+ return gen2(function* () {
3109
+ const program = yield* service(TypeScriptProgram);
3110
+ const ts = yield* service(TypeScriptApi);
3111
+ const typeChecker = yield* service(TypeCheckerApi);
3112
+ const textRange = toTextRange(position);
3113
+ function isSymbolFromEffectRpcModule(symbol3) {
3114
+ if (symbol3.valueDeclaration) {
3115
+ const sourceFile2 = symbol3.valueDeclaration.getSourceFile();
3116
+ const packageInfo = parsePackageContentNameAndVersionFromScope(sourceFile2);
3117
+ if (packageInfo && packageInfo.name === "@effect/rpc") {
3118
+ const fileSymbol = typeChecker.getSymbolAtLocation(sourceFile2);
3119
+ return fileSymbol && fileSymbol.exports && fileSymbol.exports.has("isRpc") && fileSymbol.exports.has("make") && fileSymbol.exports.has("fromTaggedRequest");
3120
+ }
3121
+ }
3122
+ return false;
3123
+ }
3124
+ function isSymbolFromEffectRpcClientModule(symbol3) {
3125
+ if (symbol3.valueDeclaration) {
3126
+ const sourceFile2 = symbol3.valueDeclaration.getSourceFile();
3127
+ const packageInfo = parsePackageContentNameAndVersionFromScope(sourceFile2);
3128
+ if (packageInfo && packageInfo.name === "@effect/rpc") {
3129
+ const fileSymbol = typeChecker.getSymbolAtLocation(sourceFile2);
3130
+ return fileSymbol && fileSymbol.exports && fileSymbol.exports.has("RpcClient") && fileSymbol.exports.has("make");
3131
+ }
3132
+ }
3133
+ return false;
3134
+ }
3135
+ let rpcName = null;
3136
+ let callNode = null;
3137
+ for (const node of yield* getAncestorNodesInRange(sourceFile, textRange)) {
3138
+ if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && isNodeInRange(textRange)(node.name)) {
3139
+ const type = typeChecker.getTypeAtLocation(node);
3140
+ for (const callSig of type.getCallSignatures()) {
3141
+ if (callSig.parameters.length >= 2 && isSymbolFromEffectRpcClientModule(callSig.parameters[1])) {
3142
+ rpcName = node.name.text;
3143
+ callNode = node.name;
3144
+ }
3145
+ }
3146
+ }
3147
+ }
3148
+ if (rpcName === null || callNode === null) return applicableGotoDefinition;
3149
+ const result = [];
3150
+ const nodeToVisit = [];
3151
+ const appendNodeToVisit = (node) => {
3152
+ nodeToVisit.push(node);
3153
+ return void 0;
3154
+ };
3155
+ const filesToTest = [];
3156
+ for (const programFile of program.getSourceFiles()) {
3157
+ if (programFile.isDeclarationFile) continue;
3158
+ if (programFile.text.indexOf("make") === -1 && programFile.text.indexOf("fromTaggedRequest") === -1) continue;
3159
+ if (programFile.text.indexOf(rpcName) > -1) {
3160
+ filesToTest.unshift(programFile);
3161
+ } else {
3162
+ filesToTest.push(programFile);
3163
+ }
3164
+ }
3165
+ for (const fileToTest of filesToTest) {
3166
+ if (result.length > 0) break;
3167
+ ts.forEachChild(fileToTest, appendNodeToVisit);
3168
+ while (result.length === 0 && nodeToVisit.length > 0) {
3169
+ const node = nodeToVisit.shift();
3170
+ if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && (node.expression.name.text === "make" || node.expression.name.text === "fromTaggedRequest")) {
3171
+ const symbol3 = typeChecker.getSymbolAtLocation(node.expression.name);
3172
+ if (symbol3 && isSymbolFromEffectRpcModule(symbol3)) {
3173
+ const type = typeChecker.getTypeAtLocation(node);
3174
+ const _tag = type.getProperty("_tag");
3175
+ if (_tag) {
3176
+ const tagValue = typeChecker.getTypeOfSymbolAtLocation(_tag, node);
3177
+ if ("value" in tagValue && tagValue.value === rpcName) result.push([node, symbol3]);
3178
+ }
3179
+ }
3180
+ }
3181
+ ts.forEachChild(node, appendNodeToVisit);
3182
+ }
3183
+ }
3184
+ if (result.length === 0) return applicableGotoDefinition;
3185
+ const effectRpcResult = result.map(([node]) => ({
3186
+ fileName: node.getSourceFile().fileName,
3187
+ textSpan: ts.createTextSpan(node.getStart(), node.getEnd() - node.getStart()),
3188
+ kind: ts.ScriptElementKind.constElement,
3189
+ name: rpcName,
3190
+ containerKind: ts.ScriptElementKind.constElement,
3191
+ containerName: rpcName
3192
+ }));
3193
+ if (applicableGotoDefinition) {
3194
+ return {
3195
+ ...applicableGotoDefinition,
3196
+ definitions: (applicableGotoDefinition.definitions || []).concat(effectRpcResult)
3197
+ };
3198
+ }
3199
+ return {
3200
+ textSpan: ts.createTextSpan(callNode.getStart(), callNode.getEnd() - callNode.getStart()),
3201
+ definitions: effectRpcResult
3202
+ };
3203
+ });
3204
+ }
3205
+
3206
+ // src/goto.ts
3207
+ function goto(applicableGotoDefinition, sourceFile, position) {
3208
+ return effectRpcDefinition(applicableGotoDefinition, sourceFile, position);
3209
+ }
3210
+
3211
+ // src/quickinfo/dedupeJsDocs.ts
2852
3212
  var SymbolDisplayPartEq = make((fa, fb) => fa.kind === fb.kind && fa.text === fb.text);
2853
3213
  var JSDocTagInfoEq = make(
2854
3214
  (fa, fb) => fa.name === fb.name && typeof fa.text === typeof fb.text && (typeof fa.text !== "undefined" ? array(SymbolDisplayPartEq)(fa.text, fb.text) : true)
2855
3215
  );
2856
- function dedupeJsDocTags(quickInfo) {
2857
- if (!quickInfo) return quickInfo;
2858
- if (quickInfo.tags) {
2859
- return {
2860
- ...quickInfo,
2861
- tags: dedupeWith(quickInfo.tags, JSDocTagInfoEq)
2862
- };
3216
+ function dedupeJsDocs(quickInfo2) {
3217
+ if (!quickInfo2) return succeed(quickInfo2);
3218
+ if (quickInfo2.tags) {
3219
+ return succeed({
3220
+ ...quickInfo2,
3221
+ tags: dedupeWith(quickInfo2.tags, JSDocTagInfoEq)
3222
+ });
2863
3223
  }
2864
- return quickInfo;
3224
+ return succeed(quickInfo2);
2865
3225
  }
3226
+
3227
+ // src/quickinfo/effectTypeArgs.ts
2866
3228
  function formatTypeForQuickInfo(channelType, channelName) {
2867
3229
  return gen2(function* () {
2868
3230
  const ts = yield* service(TypeScriptApi);
@@ -2875,7 +3237,7 @@ function formatTypeForQuickInfo(channelType, channelName) {
2875
3237
  return `type ${channelName} = ${stringRepresentation}`;
2876
3238
  });
2877
3239
  }
2878
- function prependEffectTypeArguments(sourceFile, position, quickInfo) {
3240
+ function effectTypeArgs(sourceFile, position, quickInfo2) {
2879
3241
  return pipe(
2880
3242
  gen2(function* () {
2881
3243
  const ts = yield* service(TypeScriptApi);
@@ -2884,11 +3246,11 @@ function prependEffectTypeArguments(sourceFile, position, quickInfo) {
2884
3246
  yield* getAncestorNodesInRange(sourceFile, toTextRange(position)),
2885
3247
  head
2886
3248
  );
2887
- if (isNone2(maybeNode)) return quickInfo;
3249
+ if (isNone2(maybeNode)) return quickInfo2;
2888
3250
  const node = maybeNode.value;
2889
- const hasTruncationHappened = quickInfo && ts.displayPartsToString(quickInfo.displayParts).indexOf("...") > -1;
2890
- const nodeForType = !quickInfo && ts.isYieldExpression(node) && node.asteriskToken && node.expression ? node.expression : hasTruncationHappened ? node : void 0;
2891
- if (!nodeForType) return quickInfo;
3251
+ const hasTruncationHappened = quickInfo2 && ts.displayPartsToString(quickInfo2.displayParts).indexOf("...") > -1;
3252
+ const nodeForType = !quickInfo2 && ts.isYieldExpression(node) && node.asteriskToken && node.expression ? node.expression : hasTruncationHappened ? node : void 0;
3253
+ if (!nodeForType) return quickInfo2;
2892
3254
  const effectType2 = yield* effectType(
2893
3255
  typeChecker.getTypeAtLocation(nodeForType),
2894
3256
  nodeForType
@@ -2897,7 +3259,7 @@ function prependEffectTypeArguments(sourceFile, position, quickInfo) {
2897
3259
  kind: "text",
2898
3260
  text: "```ts\n/* Effect Type Parameters */\n" + (yield* formatTypeForQuickInfo(effectType2.A, "Success")) + "\n" + (yield* formatTypeForQuickInfo(effectType2.E, "Failure")) + "\n" + (yield* formatTypeForQuickInfo(effectType2.R, "Requirements")) + "\n```\n"
2899
3261
  }];
2900
- if (!quickInfo) {
3262
+ if (!quickInfo2) {
2901
3263
  const start = node.getStart();
2902
3264
  const end = node.getEnd();
2903
3265
  return {
@@ -2907,21 +3269,392 @@ function prependEffectTypeArguments(sourceFile, position, quickInfo) {
2907
3269
  documentation: effectTypeArgsDocumentation
2908
3270
  };
2909
3271
  }
2910
- if (quickInfo.documentation) {
3272
+ if (quickInfo2.documentation) {
2911
3273
  return {
2912
- ...quickInfo,
2913
- documentation: effectTypeArgsDocumentation.concat(quickInfo.documentation)
3274
+ ...quickInfo2,
3275
+ documentation: effectTypeArgsDocumentation.concat(quickInfo2.documentation)
2914
3276
  };
2915
3277
  }
2916
3278
  return {
2917
- ...quickInfo,
3279
+ ...quickInfo2,
2918
3280
  documentation: effectTypeArgsDocumentation
2919
3281
  };
2920
3282
  }),
2921
- orElse3(() => succeed(quickInfo))
3283
+ orElse3(() => succeed(quickInfo2))
2922
3284
  );
2923
3285
  }
2924
3286
 
3287
+ // src/quickinfo/layerInfo.ts
3288
+ var UnableToProduceLayerGraphError = class {
3289
+ constructor(message, node) {
3290
+ this.message = message;
3291
+ this.node = node;
3292
+ }
3293
+ _tag = "@effect/language-service/UnableToProduceLayerGraphError";
3294
+ };
3295
+ var GraphNodeLeaf = class {
3296
+ constructor(id, node, rout, rin) {
3297
+ this.id = id;
3298
+ this.node = node;
3299
+ this.rout = rout;
3300
+ this.rin = rin;
3301
+ }
3302
+ _tag = "GraphNodeLeaf";
3303
+ };
3304
+ var GraphNodeCompoundTransform = class {
3305
+ constructor(id, node, args, rout, rin) {
3306
+ this.id = id;
3307
+ this.node = node;
3308
+ this.args = args;
3309
+ this.rout = rout;
3310
+ this.rin = rin;
3311
+ }
3312
+ _tag = "GraphNodeCompoundTransform";
3313
+ };
3314
+ function processLayerGraphNode(ctx, node, pipedInGraphNode) {
3315
+ return gen2(function* () {
3316
+ const ts = yield* service(TypeScriptApi);
3317
+ const typeChecker = yield* service(TypeCheckerApi);
3318
+ const maybePipe = yield* option(parsePipeCall(node));
3319
+ if (isSome2(maybePipe)) {
3320
+ let graphNode = yield* processLayerGraphNode(ctx, maybePipe.value.subject, void 0);
3321
+ for (const entry of maybePipe.value.args) {
3322
+ graphNode = yield* processLayerGraphNode(ctx, entry, graphNode);
3323
+ }
3324
+ return graphNode;
3325
+ }
3326
+ if (ts.isCallExpression(node)) {
3327
+ const type = typeChecker.getTypeAtLocation(node);
3328
+ const maybeLayer = yield* option(layerType(type, node));
3329
+ if (isSome2(maybeLayer)) {
3330
+ const argNodes = yield* option(
3331
+ all2(...node.arguments.map((_) => processLayerGraphNode(ctx, _, void 0)))
3332
+ );
3333
+ if (isSome2(argNodes) && argNodes.value.length === node.arguments.length) {
3334
+ const { allIndexes: outTypes } = yield* appendToUniqueTypesMap(
3335
+ ctx.services,
3336
+ maybeLayer.value.ROut,
3337
+ true
3338
+ );
3339
+ const { allIndexes: inTypes } = yield* appendToUniqueTypesMap(
3340
+ ctx.services,
3341
+ maybeLayer.value.RIn,
3342
+ true
3343
+ );
3344
+ return new GraphNodeCompoundTransform(
3345
+ ctx.nextId(),
3346
+ node,
3347
+ argNodes.value,
3348
+ outTypes,
3349
+ inTypes
3350
+ );
3351
+ }
3352
+ }
3353
+ }
3354
+ if (pipedInGraphNode && ts.isExpression(node)) {
3355
+ const type = typeChecker.getContextualType(node);
3356
+ if (type) {
3357
+ const callSignatures = type.getCallSignatures();
3358
+ if (callSignatures.length === 1) {
3359
+ const [signature] = callSignatures;
3360
+ const returnType = signature.getReturnType();
3361
+ const maybeLayer = yield* option(layerType(returnType, node));
3362
+ if (isSome2(maybeLayer)) {
3363
+ const { allIndexes: outTypes } = yield* appendToUniqueTypesMap(
3364
+ ctx.services,
3365
+ maybeLayer.value.ROut,
3366
+ true
3367
+ );
3368
+ const { allIndexes: inTypes } = yield* appendToUniqueTypesMap(
3369
+ ctx.services,
3370
+ maybeLayer.value.RIn,
3371
+ true
3372
+ );
3373
+ if (ts.isCallExpression(node)) {
3374
+ const argNodes = yield* option(
3375
+ all2(...node.arguments.map((_) => processLayerGraphNode(ctx, _, void 0)))
3376
+ );
3377
+ if (isSome2(argNodes) && argNodes.value.length === node.arguments.length) {
3378
+ return new GraphNodeCompoundTransform(
3379
+ ctx.nextId(),
3380
+ node,
3381
+ [pipedInGraphNode, ...argNodes.value],
3382
+ outTypes,
3383
+ inTypes
3384
+ );
3385
+ }
3386
+ }
3387
+ const argNode = yield* option(processLayerGraphNode(ctx, node, void 0));
3388
+ if (isSome2(argNode)) {
3389
+ return new GraphNodeCompoundTransform(
3390
+ ctx.nextId(),
3391
+ node,
3392
+ [pipedInGraphNode, argNode.value],
3393
+ outTypes,
3394
+ inTypes
3395
+ );
3396
+ } else {
3397
+ return new GraphNodeCompoundTransform(
3398
+ ctx.nextId(),
3399
+ node,
3400
+ [pipedInGraphNode],
3401
+ outTypes,
3402
+ inTypes
3403
+ );
3404
+ }
3405
+ }
3406
+ }
3407
+ }
3408
+ }
3409
+ if (ts.isExpression(node)) {
3410
+ const type = typeChecker.getTypeAtLocation(node);
3411
+ const maybeLayer = yield* option(layerType(type, node));
3412
+ if (isSome2(maybeLayer)) {
3413
+ const { allIndexes: outTypes } = yield* appendToUniqueTypesMap(
3414
+ ctx.services,
3415
+ maybeLayer.value.ROut,
3416
+ true
3417
+ );
3418
+ const { allIndexes: inTypes } = yield* appendToUniqueTypesMap(
3419
+ ctx.services,
3420
+ maybeLayer.value.RIn,
3421
+ true
3422
+ );
3423
+ return new GraphNodeLeaf(ctx.nextId(), node, outTypes, inTypes);
3424
+ }
3425
+ }
3426
+ return yield* fail(new UnableToProduceLayerGraphError(node.getText()));
3427
+ });
3428
+ }
3429
+ function findInnermostGraphEdge(graph, kind, key) {
3430
+ switch (graph._tag) {
3431
+ case "GraphNodeLeaf":
3432
+ return graph[kind].indexOf(key) > -1 ? [graph] : [];
3433
+ case "GraphNodeCompoundTransform": {
3434
+ if (graph[kind].indexOf(key) > -1) {
3435
+ let result = [];
3436
+ for (const child of graph.args) {
3437
+ result = result.concat(findInnermostGraphEdge(child, kind, key));
3438
+ }
3439
+ if (result.length > 0) return result;
3440
+ return [graph];
3441
+ }
3442
+ return [];
3443
+ }
3444
+ }
3445
+ }
3446
+ function escapeMermaid(text) {
3447
+ return text.replace(/"/mg, "#quot;").replace(/\n/mg, " ");
3448
+ }
3449
+ function processNodeMermaid(graph, ctx, ctxL) {
3450
+ return gen2(function* () {
3451
+ const ts = yield* service(TypeScriptApi);
3452
+ const typeChecker = yield* service(TypeCheckerApi);
3453
+ let subgraphDefs = [];
3454
+ if (!ctx.seenIds.has(graph.id)) {
3455
+ const subgraphsIn = [];
3456
+ for (const serviceId of graph.rin) {
3457
+ const type = ctxL.services.get(serviceId);
3458
+ const typeString = typeChecker.typeToString(type, void 0, ts.TypeFormatFlags.NoTruncation);
3459
+ subgraphsIn.push("subgraph " + graph.id + "_rin_" + serviceId + ' ["`' + escapeMermaid(typeString) + '`"]');
3460
+ subgraphsIn.push("end");
3461
+ }
3462
+ const subgraphsOut = [];
3463
+ for (const serviceId of graph.rout) {
3464
+ const type = ctxL.services.get(serviceId);
3465
+ const typeString = typeChecker.typeToString(type, void 0, ts.TypeFormatFlags.NoTruncation);
3466
+ subgraphsOut.push("subgraph " + graph.id + "_rout_" + serviceId + ' ["`' + escapeMermaid(typeString) + '`"]');
3467
+ subgraphsOut.push("end");
3468
+ }
3469
+ const sourceFile = graph.node.getSourceFile();
3470
+ const nodePosition = graph.node.getStart(sourceFile, false);
3471
+ const { character, line } = ts.getLineAndCharacterOfPosition(sourceFile, nodePosition);
3472
+ if (subgraphsIn.length > 0) {
3473
+ subgraphDefs = [
3474
+ ...subgraphDefs,
3475
+ "subgraph " + graph.id + "_rin [Requires]",
3476
+ ...subgraphsIn,
3477
+ "end",
3478
+ "style " + graph.id + "_rin stroke:none"
3479
+ ];
3480
+ }
3481
+ if (subgraphsOut.length > 0) {
3482
+ subgraphDefs = [
3483
+ ...subgraphDefs,
3484
+ "subgraph " + graph.id + "_rout [Provides]",
3485
+ ...subgraphsOut,
3486
+ "end",
3487
+ "style " + graph.id + "_rout stroke:none"
3488
+ ];
3489
+ }
3490
+ subgraphDefs = [
3491
+ "subgraph " + graph.id + ' ["`' + escapeMermaid(graph.node.getText()) + " _at ln " + (line + 1) + " col " + character + '_`"]',
3492
+ ...subgraphDefs,
3493
+ "end",
3494
+ "style " + graph.id + " fill:transparent"
3495
+ ];
3496
+ ctx.seenIds.add(graph.id);
3497
+ }
3498
+ switch (graph._tag) {
3499
+ case "GraphNodeLeaf": {
3500
+ return subgraphDefs;
3501
+ }
3502
+ case "GraphNodeCompoundTransform": {
3503
+ const childs = flatten(yield* all2(...graph.args.map((_) => processNodeMermaid(_, ctx, ctxL))));
3504
+ let currentEdges = [];
3505
+ const connectedNodes = /* @__PURE__ */ new Set();
3506
+ for (const requiredServiceKey of graph.rin) {
3507
+ for (const childNode of graph.args.filter((childNode2) => childNode2.rin.indexOf(requiredServiceKey) > -1)) {
3508
+ currentEdges = [
3509
+ ...currentEdges,
3510
+ graph.id + "_rin_" + requiredServiceKey + " -.-> " + childNode.id + "_rin_" + requiredServiceKey
3511
+ ];
3512
+ connectedNodes.add(childNode.id);
3513
+ }
3514
+ }
3515
+ for (const providedServiceKey of graph.rout) {
3516
+ for (const childNode of graph.args.filter((childNode2) => childNode2.rout.indexOf(providedServiceKey) > -1)) {
3517
+ currentEdges = [
3518
+ ...currentEdges,
3519
+ graph.id + "_rout_" + providedServiceKey + " -.-> " + childNode.id + "_rout_" + providedServiceKey
3520
+ ];
3521
+ connectedNodes.add(childNode.id);
3522
+ }
3523
+ }
3524
+ for (const childNode of graph.args) {
3525
+ if (!connectedNodes.has(childNode.id)) {
3526
+ currentEdges = [...currentEdges, graph.id + " -.-x " + childNode.id];
3527
+ }
3528
+ }
3529
+ return [...subgraphDefs, ...childs, ...currentEdges];
3530
+ }
3531
+ }
3532
+ });
3533
+ }
3534
+ function generateMarmaidUri(graph, ctxL) {
3535
+ return gen2(function* () {
3536
+ const ctx = {
3537
+ seenIds: /* @__PURE__ */ new Set()
3538
+ };
3539
+ const lines = yield* processNodeMermaid(graph, ctx, ctxL);
3540
+ const code = "flowchart TB\n" + lines.join("\n");
3541
+ const state = btoa(JSON.stringify({ code }));
3542
+ return "https://www.mermaidchart.com/play#" + state;
3543
+ });
3544
+ }
3545
+ function layerInfo(sourceFile, position, quickInfo2) {
3546
+ return pipe(
3547
+ gen2(function* () {
3548
+ const ts = yield* service(TypeScriptApi);
3549
+ const typeChecker = yield* service(TypeCheckerApi);
3550
+ const range = toTextRange(position);
3551
+ const maybeNode = pipe(
3552
+ yield* getAncestorNodesInRange(sourceFile, range),
3553
+ filter((_) => ts.isVariableDeclaration(_) || ts.isPropertyDeclaration(_)),
3554
+ filter((_) => isNodeInRange(range)(_.name)),
3555
+ head
3556
+ );
3557
+ if (isNone2(maybeNode)) return quickInfo2;
3558
+ const node = maybeNode.value;
3559
+ const layerNode = node.initializer ? node.initializer : node;
3560
+ const layerType2 = typeChecker.getTypeAtLocation(layerNode);
3561
+ const maybeLayer = yield* option(layerType(layerType2, layerNode));
3562
+ if (isNone2(maybeLayer)) return quickInfo2;
3563
+ let lastId = 0;
3564
+ const graphCtx = {
3565
+ services: /* @__PURE__ */ new Map(),
3566
+ serviceTypeToString: /* @__PURE__ */ new Map(),
3567
+ nextId: () => "id" + lastId++
3568
+ };
3569
+ const layerInfoDisplayParts = yield* pipe(
3570
+ processLayerGraphNode(graphCtx, layerNode, void 0),
3571
+ flatMap3(
3572
+ (rootNode) => gen2(function* () {
3573
+ yield* succeed(void 0);
3574
+ const lines = [];
3575
+ const appendInfo = (providesNode, type, kindText) => {
3576
+ const typeString = typeChecker.typeToString(
3577
+ type,
3578
+ void 0,
3579
+ ts.TypeFormatFlags.NoTruncation
3580
+ );
3581
+ const positions = providesNode.map((_) => {
3582
+ const nodePosition = _.node.getStart(sourceFile, false);
3583
+ const { character, line } = ts.getLineAndCharacterOfPosition(sourceFile, nodePosition);
3584
+ const nodeText = _.node.getText().trim().substr(0, 100);
3585
+ return "ln " + (line + 1) + " col " + character + " by `" + nodeText + "`";
3586
+ });
3587
+ lines.push("- " + typeString + " " + kindText + " at " + positions.join(", "));
3588
+ };
3589
+ for (const providesKey of rootNode.rout) {
3590
+ const providesNode = findInnermostGraphEdge(rootNode, "rout", providesKey);
3591
+ appendInfo(providesNode, graphCtx.services.get(providesKey), "provided");
3592
+ }
3593
+ lines.push("");
3594
+ for (const requiresKey of rootNode.rin) {
3595
+ const requiresNode = findInnermostGraphEdge(rootNode, "rin", requiresKey);
3596
+ appendInfo(requiresNode, graphCtx.services.get(requiresKey), "required");
3597
+ }
3598
+ const mermaidUri = yield* option(generateMarmaidUri(rootNode, graphCtx));
3599
+ const linkParts = [];
3600
+ if (isSome2(mermaidUri)) {
3601
+ linkParts.push({ kind: "space", text: "\n" });
3602
+ linkParts.push({ kind: "link", text: "{@link " });
3603
+ linkParts.push({ kind: "linkText", text: mermaidUri.value + " Show full Layer graph" });
3604
+ linkParts.push({ kind: "link", text: "}" });
3605
+ linkParts.push({ kind: "space", text: "\n" });
3606
+ }
3607
+ return [
3608
+ {
3609
+ kind: "text",
3610
+ text: "```\n/**\n" + lines.map((l) => " * " + l).join("\n") + "\n */\n```\n"
3611
+ },
3612
+ ...linkParts
3613
+ ];
3614
+ })
3615
+ ),
3616
+ orElse3(
3617
+ (e) => succeed([{
3618
+ kind: "text",
3619
+ text: "```\n/** layer graph not created: " + e.message + " */\n```\n"
3620
+ }])
3621
+ )
3622
+ );
3623
+ if (!quickInfo2) {
3624
+ const start = node.getStart();
3625
+ const end = node.getEnd();
3626
+ return {
3627
+ kind: ts.ScriptElementKind.callSignatureElement,
3628
+ kindModifiers: "",
3629
+ textSpan: { start, length: end - start },
3630
+ documentation: layerInfoDisplayParts
3631
+ };
3632
+ }
3633
+ if (quickInfo2.documentation) {
3634
+ return {
3635
+ ...quickInfo2,
3636
+ documentation: quickInfo2.documentation.concat([{ kind: "space", text: "\n" }]).concat(layerInfoDisplayParts)
3637
+ };
3638
+ }
3639
+ return {
3640
+ ...quickInfo2,
3641
+ documentation: layerInfoDisplayParts
3642
+ };
3643
+ }),
3644
+ orElse3(() => succeed(quickInfo2))
3645
+ );
3646
+ }
3647
+
3648
+ // src/quickinfo.ts
3649
+ function quickInfo(sourceFile, position, quickInfo2) {
3650
+ return gen2(function* () {
3651
+ const deduped = yield* dedupeJsDocs(quickInfo2);
3652
+ const withEffectTypeArgs = yield* effectTypeArgs(sourceFile, position, deduped);
3653
+ const withLayerInfo = yield* layerInfo(sourceFile, position, withEffectTypeArgs);
3654
+ return withLayerInfo;
3655
+ });
3656
+ }
3657
+
2925
3658
  // src/refactors/asyncAwaitToGen.ts
2926
3659
  var asyncAwaitToGen = createRefactor({
2927
3660
  name: "asyncAwaitToGen",
@@ -3118,14 +3851,14 @@ var effectGenToFn = createRefactor({
3118
3851
  nodeToReplace2 = parent;
3119
3852
  continue;
3120
3853
  }
3121
- if (ts.isPropertyAccessExpression(parent) && parent.expression === nodeToReplace2 && parent.name.text === "pipe" && ts.isCallExpression(parent.parent)) {
3122
- pipeArgs2 = ts.factory.createNodeArray(pipeArgs2.concat(parent.parent.arguments));
3123
- nodeToReplace2 = parent.parent;
3124
- continue;
3125
- }
3126
- if (ts.isCallExpression(parent) && ts.isIdentifier(parent.expression) && parent.expression.text === "pipe" && parent.arguments.length > 0 && parent.arguments[0] === nodeToReplace2) {
3127
- pipeArgs2 = ts.factory.createNodeArray(pipeArgs2.concat(parent.arguments.slice(1)));
3128
- nodeToReplace2 = parent;
3854
+ const maybePipe = yield* pipe(
3855
+ parsePipeCall(parent),
3856
+ orElse3((e) => parent.parent ? parsePipeCall(parent.parent) : fail(e)),
3857
+ option
3858
+ );
3859
+ if (isSome2(maybePipe) && maybePipe.value.subject === nodeToReplace2) {
3860
+ pipeArgs2 = ts.factory.createNodeArray(pipeArgs2.concat(maybePipe.value.args));
3861
+ nodeToReplace2 = maybePipe.value.node;
3129
3862
  continue;
3130
3863
  }
3131
3864
  break;
@@ -3611,19 +4344,15 @@ var removeUnnecessaryEffectGen = createRefactor({
3611
4344
  description: "Remove unnecessary Effect.gen",
3612
4345
  apply: fn("removeUnnecessaryEffectGen.apply")(function* (sourceFile, textRange) {
3613
4346
  for (const nodeToReplace of yield* getAncestorNodesInRange(sourceFile, textRange)) {
3614
- const maybeNode = yield* pipe(
3615
- effectGen(nodeToReplace),
3616
- flatMap3(({ body }) => returnYieldEffectBlock(body)),
3617
- option
3618
- );
4347
+ const maybeNode = yield* option(unnecessaryEffectGen(nodeToReplace));
3619
4348
  if (isNone2(maybeNode)) continue;
3620
- const returnedYieldedEffect = maybeNode.value;
4349
+ const replacementNode = maybeNode.value.replacementNode;
3621
4350
  return {
3622
4351
  kind: "refactor.rewrite.effect.removeUnnecessaryEffectGen",
3623
4352
  description: "Remove unnecessary Effect.gen",
3624
4353
  apply: gen2(function* () {
3625
4354
  const changeTracker = yield* service(ChangeTracker);
3626
- changeTracker.replaceNode(sourceFile, nodeToReplace, returnedYieldedEffect);
4355
+ changeTracker.replaceNode(sourceFile, nodeToReplace, yield* replacementNode);
3627
4356
  })
3628
4357
  };
3629
4358
  }
@@ -4558,27 +5287,25 @@ var init = (modules) => {
4558
5287
  );
4559
5288
  };
4560
5289
  proxy.getQuickInfoAtPosition = (fileName, position, ...args) => {
4561
- const quickInfo = languageService.getQuickInfoAtPosition(fileName, position, ...args);
5290
+ const applicableQuickInfo = languageService.getQuickInfoAtPosition(fileName, position, ...args);
4562
5291
  if (languageServicePluginOptions.quickinfo) {
4563
- const dedupedTagsQuickInfo = dedupeJsDocTags(quickInfo);
4564
5292
  const program = languageService.getProgram();
4565
5293
  if (program) {
4566
5294
  const sourceFile = program.getSourceFile(fileName);
4567
5295
  if (sourceFile) {
4568
5296
  return pipe(
4569
- prependEffectTypeArguments(
5297
+ quickInfo(
4570
5298
  sourceFile,
4571
5299
  position,
4572
- dedupedTagsQuickInfo
5300
+ applicableQuickInfo
4573
5301
  ),
4574
5302
  runNano(program),
4575
- Either_exports.getOrElse(() => dedupedTagsQuickInfo)
5303
+ Either_exports.getOrElse(() => applicableQuickInfo)
4576
5304
  );
4577
5305
  }
4578
5306
  }
4579
- return dedupedTagsQuickInfo;
4580
5307
  }
4581
- return quickInfo;
5308
+ return applicableQuickInfo;
4582
5309
  };
4583
5310
  proxy.getCompletionsAtPosition = (fileName, position, options, formattingSettings, ...args) => {
4584
5311
  const applicableCompletions = languageService.getCompletionsAtPosition(
@@ -4620,6 +5347,21 @@ var init = (modules) => {
4620
5347
  }
4621
5348
  return applicableCompletions;
4622
5349
  };
5350
+ proxy.getDefinitionAndBoundSpan = (fileName, position, ...args) => {
5351
+ const applicableDefinition = languageService.getDefinitionAndBoundSpan(fileName, position, ...args);
5352
+ const program = languageService.getProgram();
5353
+ if (program) {
5354
+ const sourceFile = program.getSourceFile(fileName);
5355
+ if (sourceFile) {
5356
+ return pipe(
5357
+ goto(applicableDefinition, sourceFile, position),
5358
+ runNano(program),
5359
+ Either_exports.getOrElse(() => applicableDefinition)
5360
+ );
5361
+ }
5362
+ }
5363
+ return applicableDefinition;
5364
+ };
4623
5365
  return proxy;
4624
5366
  }
4625
5367
  return { create };