@effect/language-service 0.20.0 → 0.21.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
@@ -489,6 +489,7 @@ function compareBoth(self, that) {
489
489
  return structuralRegionState.enabled && structuralRegionState.tester ? structuralRegionState.tester(self, that) : false;
490
490
  }
491
491
  var isEqual = (u) => hasProperty(u, symbol2);
492
+ var equivalence = () => equals;
492
493
 
493
494
  // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Inspectable.js
494
495
  var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
@@ -947,6 +948,20 @@ var sort = /* @__PURE__ */ dual(2, (self, O) => {
947
948
  out.sort(O);
948
949
  return out;
949
950
  });
951
+ var containsWith = (isEquivalent) => dual(2, (self, a) => {
952
+ for (const i of self) {
953
+ if (isEquivalent(a, i)) {
954
+ return true;
955
+ }
956
+ }
957
+ return false;
958
+ });
959
+ var _equivalence = /* @__PURE__ */ equivalence();
960
+ var intersectionWith = (isEquivalent) => {
961
+ const has = containsWith(isEquivalent);
962
+ return dual(2, (self, that) => fromIterable(self).filter((a) => has(that, a)));
963
+ };
964
+ var intersection = /* @__PURE__ */ intersectionWith(_equivalence);
950
965
  var empty = () => [];
951
966
  var map3 = /* @__PURE__ */ dual(2, (self, f) => self.map(f));
952
967
  var flatMap2 = /* @__PURE__ */ dual(2, (self, f) => {
@@ -1039,7 +1054,8 @@ function make3(run2) {
1039
1054
  return result;
1040
1055
  }
1041
1056
  var unsafeRun = (fa) => {
1042
- const result = fa.run(contextEmpty);
1057
+ const program = provideService(internalNanoCache, {})(fa);
1058
+ const result = program.run(contextEmpty);
1043
1059
  switch (result._tag) {
1044
1060
  case "Left":
1045
1061
  return left2(result.value);
@@ -1076,14 +1092,14 @@ var orElse3 = (f) => (fa) => make3((ctx) => {
1076
1092
  });
1077
1093
  var firstSuccessOf = (arr) => arr.slice(1).reduce((arr2, fa) => orElse3(() => fa)(arr2), arr[0]);
1078
1094
  var service = (tag) => make3(
1079
- (ctx) => tag.key in ctx.value ? makeInternalSuccess(ctx.value[tag.key]) : makeInternalDefect(`Cannot find service ${tag.key}`)
1095
+ (ctx) => tag.key in ctx.value ? ctx.value[tag.key] : makeInternalDefect(`Cannot find service ${tag.key}`)
1080
1096
  );
1081
1097
  var provideService = (tag, value) => (fa) => make3((ctx) => {
1082
1098
  return fa.run({
1083
1099
  ...ctx,
1084
1100
  value: {
1085
1101
  ...ctx.value,
1086
- [tag.key]: value
1102
+ [tag.key]: makeInternalSuccess(value)
1087
1103
  }
1088
1104
  });
1089
1105
  });
@@ -1124,14 +1140,41 @@ var option = (fa) => make3((ctx) => {
1124
1140
  return result;
1125
1141
  }
1126
1142
  });
1127
- var all2 = (...args) => gen2(function* () {
1143
+ var successUndefined = makeInternalSuccess(void 0);
1144
+ var void_2 = make3(() => successUndefined);
1145
+ var ignore = (fa) => make3((ctx) => {
1146
+ fa.run(ctx);
1147
+ return successUndefined;
1148
+ });
1149
+ var all2 = (...args) => make3((ctx) => {
1128
1150
  const results = [];
1129
1151
  for (const arg of args) {
1130
- const result = yield* arg;
1131
- results.push(result);
1152
+ const result = arg.run(ctx);
1153
+ if (result._tag !== "Right") return result;
1154
+ results.push(result.value);
1132
1155
  }
1133
- return results;
1156
+ return makeInternalSuccess(results);
1134
1157
  });
1158
+ var internalNanoCache = Tag(
1159
+ "@effect/language-service/internalNanoCache"
1160
+ );
1161
+ function cachedBy(fa, key, lookupKey) {
1162
+ return (...args) => make3((ctx) => {
1163
+ const cacheObj = ctx.value[internalNanoCache.key];
1164
+ let cache = cacheObj[key];
1165
+ if (!cache) {
1166
+ cache = /* @__PURE__ */ new Map();
1167
+ cacheObj[key] = cache;
1168
+ }
1169
+ const lookup = lookupKey(...args);
1170
+ if (cache.has(lookup)) {
1171
+ return cache.get(lookup);
1172
+ }
1173
+ const result = fa(...args).run(ctx);
1174
+ cache.set(lookup, result);
1175
+ return result;
1176
+ });
1177
+ }
1135
1178
 
1136
1179
  // src/core/TypeScriptApi.ts
1137
1180
  var TypeScriptApi = Tag("TypeScriptApi");
@@ -1924,6 +1967,511 @@ var effectSelfInClasses = createCompletion({
1924
1967
  })
1925
1968
  });
1926
1969
 
1970
+ // src/core/TypeParser.ts
1971
+ var TypeParser = Tag("@effect/language-service/TypeParser");
1972
+ var TypeParserIssue = class _TypeParserIssue {
1973
+ _tag = "@effect/language-service/TypeParserIssue";
1974
+ static issue = fail(new _TypeParserIssue());
1975
+ };
1976
+ function make4(ts, typeChecker) {
1977
+ function typeParserIssue(_message, _type, _node) {
1978
+ return TypeParserIssue.issue;
1979
+ }
1980
+ function covariantTypeArgument(type) {
1981
+ const signatures = type.getCallSignatures();
1982
+ if (signatures.length !== 1) {
1983
+ return typeParserIssue("Covariant type has no call signature", type);
1984
+ }
1985
+ return succeed(signatures[0].getReturnType());
1986
+ }
1987
+ function contravariantTypeArgument(type) {
1988
+ const signatures = type.getCallSignatures();
1989
+ if (signatures.length !== 1) {
1990
+ return typeParserIssue("Contravariant type has no call signature", type);
1991
+ }
1992
+ return succeed(signatures[0].getTypeParameterAtPosition(0));
1993
+ }
1994
+ function invariantTypeArgument(type) {
1995
+ const signatures = type.getCallSignatures();
1996
+ if (signatures.length !== 1) {
1997
+ return typeParserIssue("Invariant type has no call signature", type);
1998
+ }
1999
+ return succeed(signatures[0].getReturnType());
2000
+ }
2001
+ const pipeableType = cachedBy(
2002
+ fn("TypeParser.pipeableType")(function* (type, atLocation) {
2003
+ const pipeSymbol = typeChecker.getPropertyOfType(type, "pipe");
2004
+ if (!pipeSymbol) {
2005
+ return yield* typeParserIssue("Type has no 'pipe' property", type, atLocation);
2006
+ }
2007
+ const pipeType = typeChecker.getTypeOfSymbolAtLocation(pipeSymbol, atLocation);
2008
+ const signatures = pipeType.getCallSignatures();
2009
+ if (signatures.length === 0) {
2010
+ return yield* typeParserIssue("'pipe' property is not callable", type, atLocation);
2011
+ }
2012
+ return type;
2013
+ }),
2014
+ "TypeParser.pipeableType",
2015
+ (type) => type
2016
+ );
2017
+ const varianceStructCovariantType = (type, atLocation, propertyName) => {
2018
+ const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
2019
+ if (!propertySymbol) {
2020
+ return typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
2021
+ }
2022
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2023
+ return covariantTypeArgument(propertyType);
2024
+ };
2025
+ const varianceStructContravariantType = (type, atLocation, propertyName) => {
2026
+ const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
2027
+ if (!propertySymbol) {
2028
+ return typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
2029
+ }
2030
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2031
+ return contravariantTypeArgument(propertyType);
2032
+ };
2033
+ const varianceStructInvariantType = (type, atLocation, propertyName) => {
2034
+ const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
2035
+ if (!propertySymbol) {
2036
+ return typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
2037
+ }
2038
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2039
+ return invariantTypeArgument(propertyType);
2040
+ };
2041
+ const effectVarianceStruct = (type, atLocation) => map4(
2042
+ all2(
2043
+ varianceStructCovariantType(type, atLocation, "_A"),
2044
+ varianceStructCovariantType(type, atLocation, "_E"),
2045
+ varianceStructCovariantType(type, atLocation, "_R")
2046
+ ),
2047
+ ([A, E, R]) => ({ A, E, R })
2048
+ );
2049
+ const layerVarianceStruct = (type, atLocation) => map4(
2050
+ all2(
2051
+ varianceStructContravariantType(type, atLocation, "_ROut"),
2052
+ varianceStructCovariantType(type, atLocation, "_E"),
2053
+ varianceStructCovariantType(type, atLocation, "_RIn")
2054
+ ),
2055
+ ([ROut, E, RIn]) => ({ ROut, E, RIn })
2056
+ );
2057
+ const effectType = cachedBy(
2058
+ fn("TypeParser.effectType")(function* (type, atLocation) {
2059
+ yield* pipeableType(type, atLocation);
2060
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2061
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
2062
+ );
2063
+ propertiesSymbols.sort((a, b) => b.name.indexOf("EffectTypeId") - a.name.indexOf("EffectTypeId"));
2064
+ for (const propertySymbol of propertiesSymbols) {
2065
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2066
+ const varianceArgs = yield* option(effectVarianceStruct(
2067
+ propertyType,
2068
+ atLocation
2069
+ ));
2070
+ if (isSome2(varianceArgs)) {
2071
+ return varianceArgs.value;
2072
+ }
2073
+ }
2074
+ return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
2075
+ }),
2076
+ "TypeParser.effectType",
2077
+ (type) => type
2078
+ );
2079
+ const layerType = cachedBy(
2080
+ fn("TypeParser.layerType")(function* (type, atLocation) {
2081
+ yield* pipeableType(type, atLocation);
2082
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2083
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
2084
+ );
2085
+ propertiesSymbols.sort((a, b) => b.name.indexOf("LayerTypeId") - a.name.indexOf("LayerTypeId"));
2086
+ for (const propertySymbol of propertiesSymbols) {
2087
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2088
+ const varianceArgs = yield* option(layerVarianceStruct(
2089
+ propertyType,
2090
+ atLocation
2091
+ ));
2092
+ if (isSome2(varianceArgs)) {
2093
+ return varianceArgs.value;
2094
+ }
2095
+ }
2096
+ return yield* typeParserIssue("Type has no layer variance struct", type, atLocation);
2097
+ }),
2098
+ "TypeParser.layerType",
2099
+ (type) => type
2100
+ );
2101
+ const fiberType = cachedBy(
2102
+ fn("TypeParser.fiberType")(function* (type, atLocation) {
2103
+ const awaitSymbol = typeChecker.getPropertyOfType(type, "await");
2104
+ const pollSymbol = typeChecker.getPropertyOfType(type, "poll");
2105
+ if (!awaitSymbol || !pollSymbol) {
2106
+ return yield* typeParserIssue(
2107
+ "Type is not a fiber because it does not have 'await' or 'poll' property",
2108
+ type,
2109
+ atLocation
2110
+ );
2111
+ }
2112
+ return yield* effectType(type, atLocation);
2113
+ }),
2114
+ "TypeParser.fiberType",
2115
+ (type) => type
2116
+ );
2117
+ const effectSubtype = cachedBy(
2118
+ fn("TypeParser.effectSubtype")(function* (type, atLocation) {
2119
+ const tagSymbol = typeChecker.getPropertyOfType(type, "_tag");
2120
+ const getSymbol = typeChecker.getPropertyOfType(type, "get");
2121
+ if (!(tagSymbol || getSymbol)) {
2122
+ return yield* typeParserIssue(
2123
+ "Type is not a subtype of effect because it does not have '_tag' or 'get' property",
2124
+ type,
2125
+ atLocation
2126
+ );
2127
+ }
2128
+ return yield* effectType(type, atLocation);
2129
+ }),
2130
+ "TypeParser.effectSubtype",
2131
+ (type) => type
2132
+ );
2133
+ const importedEffectModule = cachedBy(
2134
+ fn("TypeParser.importedEffectModule")(function* (node) {
2135
+ const type = typeChecker.getTypeAtLocation(node);
2136
+ const propertySymbol = typeChecker.getPropertyOfType(type, "never");
2137
+ if (!propertySymbol) {
2138
+ return yield* typeParserIssue("Type has no 'never' property", type, node);
2139
+ }
2140
+ if (!ts.isExpression(node)) {
2141
+ return yield* typeParserIssue("Node is not an expression", type, node);
2142
+ }
2143
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, node);
2144
+ yield* effectType(propertyType, node);
2145
+ return node;
2146
+ }),
2147
+ "TypeParser.importedEffectModule",
2148
+ (node) => node
2149
+ );
2150
+ const effectGen = cachedBy(
2151
+ fn("TypeParser.effectGen")(function* (node) {
2152
+ if (!ts.isCallExpression(node)) {
2153
+ return yield* typeParserIssue("Node is not a call expression", void 0, node);
2154
+ }
2155
+ if (node.arguments.length === 0) {
2156
+ return yield* typeParserIssue("Node has no arguments", void 0, node);
2157
+ }
2158
+ const generatorFunction = node.arguments[0];
2159
+ if (!ts.isFunctionExpression(generatorFunction)) {
2160
+ return yield* typeParserIssue("Node is not a function expression", void 0, node);
2161
+ }
2162
+ if (generatorFunction.asteriskToken === void 0) {
2163
+ return yield* typeParserIssue("Node is not a generator function", void 0, node);
2164
+ }
2165
+ if (!ts.isPropertyAccessExpression(node.expression)) {
2166
+ return yield* typeParserIssue("Node is not a property access expression", void 0, node);
2167
+ }
2168
+ const propertyAccess = node.expression;
2169
+ if (propertyAccess.name.text !== "gen") {
2170
+ return yield* typeParserIssue("Call expression name is not 'gen'", void 0, node);
2171
+ }
2172
+ const effectModule = yield* importedEffectModule(propertyAccess.expression);
2173
+ return {
2174
+ node,
2175
+ effectModule,
2176
+ generatorFunction,
2177
+ body: generatorFunction.body,
2178
+ functionStar: generatorFunction.getFirstToken()
2179
+ };
2180
+ }),
2181
+ "TypeParser.effectGen",
2182
+ (node) => node
2183
+ );
2184
+ const effectFnUntracedGen = cachedBy(
2185
+ fn("TypeParser.effectFnUntracedGen")(
2186
+ function* (node) {
2187
+ if (!ts.isCallExpression(node)) {
2188
+ return yield* typeParserIssue("Node is not a call expression", void 0, node);
2189
+ }
2190
+ if (node.arguments.length === 0) {
2191
+ return yield* typeParserIssue("Node has no arguments", void 0, node);
2192
+ }
2193
+ const generatorFunction = node.arguments[0];
2194
+ if (!ts.isFunctionExpression(generatorFunction)) {
2195
+ return yield* typeParserIssue("Node is not a function expression", void 0, node);
2196
+ }
2197
+ if (generatorFunction.asteriskToken === void 0) {
2198
+ return yield* typeParserIssue(
2199
+ "Node is not a generator function",
2200
+ void 0,
2201
+ node
2202
+ );
2203
+ }
2204
+ if (!ts.isPropertyAccessExpression(node.expression)) {
2205
+ return yield* typeParserIssue(
2206
+ "Node is not a property access expression",
2207
+ void 0,
2208
+ node
2209
+ );
2210
+ }
2211
+ const propertyAccess = node.expression;
2212
+ if (propertyAccess.name.text !== "fnUntraced") {
2213
+ return yield* typeParserIssue(
2214
+ "Call expression name is not 'fnUntraced'",
2215
+ void 0,
2216
+ node
2217
+ );
2218
+ }
2219
+ const effectModule = yield* importedEffectModule(propertyAccess.expression);
2220
+ return {
2221
+ node,
2222
+ effectModule,
2223
+ generatorFunction,
2224
+ body: generatorFunction.body,
2225
+ functionStar: generatorFunction.getFirstToken()
2226
+ };
2227
+ }
2228
+ ),
2229
+ "TypeParser.effectFnUntracedGen",
2230
+ (node) => node
2231
+ );
2232
+ const effectFnGen = cachedBy(
2233
+ fn("TypeParser.effectFnGen")(function* (node) {
2234
+ if (!ts.isCallExpression(node)) {
2235
+ return yield* typeParserIssue("Node is not a call expression", void 0, node);
2236
+ }
2237
+ if (node.arguments.length === 0) {
2238
+ return yield* typeParserIssue("Node has no arguments", void 0, node);
2239
+ }
2240
+ const generatorFunction = node.arguments[0];
2241
+ if (!ts.isFunctionExpression(generatorFunction)) {
2242
+ return yield* typeParserIssue(
2243
+ "Node is not a function expression",
2244
+ void 0,
2245
+ node
2246
+ );
2247
+ }
2248
+ if (generatorFunction.asteriskToken === void 0) {
2249
+ return yield* typeParserIssue(
2250
+ "Node is not a generator function",
2251
+ void 0,
2252
+ node
2253
+ );
2254
+ }
2255
+ const expressionToTest = ts.isCallExpression(node.expression) ? node.expression.expression : node.expression;
2256
+ if (!ts.isPropertyAccessExpression(expressionToTest)) {
2257
+ return yield* typeParserIssue(
2258
+ "Node is not a property access expression",
2259
+ void 0,
2260
+ node
2261
+ );
2262
+ }
2263
+ const propertyAccess = expressionToTest;
2264
+ if (propertyAccess.name.text !== "fn") {
2265
+ return yield* typeParserIssue(
2266
+ "Call expression name is not 'fn'",
2267
+ void 0,
2268
+ node
2269
+ );
2270
+ }
2271
+ const effectModule = yield* importedEffectModule(propertyAccess.expression);
2272
+ return {
2273
+ node,
2274
+ generatorFunction,
2275
+ effectModule,
2276
+ body: generatorFunction.body,
2277
+ functionStar: generatorFunction.getFirstToken()
2278
+ };
2279
+ }),
2280
+ "TypeParser.effectFnGen",
2281
+ (node) => node
2282
+ );
2283
+ const unnecessaryEffectGen2 = cachedBy(
2284
+ fn("TypeParser.unnecessaryEffectGen")(function* (node) {
2285
+ const { body } = yield* effectGen(node);
2286
+ if (body.statements.length !== 1) {
2287
+ return yield* typeParserIssue(
2288
+ "Generator body should have a single statement",
2289
+ void 0,
2290
+ node
2291
+ );
2292
+ }
2293
+ let explicitReturn = false;
2294
+ let nodeToCheck = body.statements[0];
2295
+ while (nodeToCheck) {
2296
+ if (ts.isReturnStatement(nodeToCheck) && nodeToCheck.expression) {
2297
+ nodeToCheck = nodeToCheck.expression;
2298
+ explicitReturn = true;
2299
+ continue;
2300
+ }
2301
+ if (ts.isExpressionStatement(nodeToCheck)) {
2302
+ nodeToCheck = nodeToCheck.expression;
2303
+ continue;
2304
+ }
2305
+ if (ts.isYieldExpression(nodeToCheck) && nodeToCheck.asteriskToken && nodeToCheck.expression) {
2306
+ const yieldedExpression = nodeToCheck.expression;
2307
+ const type = typeChecker.getTypeAtLocation(yieldedExpression);
2308
+ const { A: successType } = yield* effectType(type, yieldedExpression);
2309
+ let replacementNode = succeed(yieldedExpression);
2310
+ if (!explicitReturn && !(successType.flags & ts.TypeFlags.VoidLike)) {
2311
+ replacementNode = pipe(
2312
+ gen2(function* () {
2313
+ const effectIdentifier = pipe(
2314
+ yield* option(
2315
+ findImportedModuleIdentifierByPackageAndNameOrBarrel(node.getSourceFile(), "effect", "Effect")
2316
+ ),
2317
+ match2({
2318
+ onNone: () => "Effect",
2319
+ onSome: (_) => _.text
2320
+ })
2321
+ );
2322
+ return ts.factory.createCallExpression(
2323
+ ts.factory.createPropertyAccessExpression(
2324
+ ts.factory.createIdentifier(effectIdentifier),
2325
+ "asVoid"
2326
+ ),
2327
+ void 0,
2328
+ [
2329
+ yieldedExpression
2330
+ ]
2331
+ );
2332
+ }),
2333
+ provideService(TypeScriptApi, ts)
2334
+ );
2335
+ }
2336
+ return { node, body, yieldedExpression, replacementNode };
2337
+ }
2338
+ break;
2339
+ }
2340
+ return yield* typeParserIssue(
2341
+ "Not an handled node",
2342
+ void 0,
2343
+ node
2344
+ );
2345
+ }),
2346
+ "TypeParser.unnecessaryEffectGen",
2347
+ (node) => node
2348
+ );
2349
+ const effectSchemaVarianceStruct = (type, atLocation) => map4(
2350
+ all2(
2351
+ varianceStructInvariantType(type, atLocation, "_A"),
2352
+ varianceStructInvariantType(type, atLocation, "_I"),
2353
+ varianceStructCovariantType(type, atLocation, "_R")
2354
+ ),
2355
+ ([A, I, R]) => ({ A, I, R })
2356
+ );
2357
+ const effectSchemaType = cachedBy(
2358
+ fn("TypeParser.effectSchemaType")(function* (type, atLocation) {
2359
+ yield* pipeableType(type, atLocation);
2360
+ const ast = typeChecker.getPropertyOfType(type, "ast");
2361
+ if (!ast) return yield* typeParserIssue("Has no 'ast' property", type, atLocation);
2362
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2363
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
2364
+ );
2365
+ propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
2366
+ for (const propertySymbol of propertiesSymbols) {
2367
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2368
+ const varianceArgs = yield* option(effectSchemaVarianceStruct(
2369
+ propertyType,
2370
+ atLocation
2371
+ ));
2372
+ if (isSome2(varianceArgs)) {
2373
+ return varianceArgs.value;
2374
+ }
2375
+ }
2376
+ return yield* typeParserIssue("Type has no schema variance struct", type, atLocation);
2377
+ }),
2378
+ "TypeParser.effectSchemaType",
2379
+ (type) => type
2380
+ );
2381
+ const contextTagVarianceStruct = (type, atLocation) => map4(
2382
+ all2(
2383
+ varianceStructInvariantType(type, atLocation, "_Identifier"),
2384
+ varianceStructInvariantType(type, atLocation, "_Service")
2385
+ ),
2386
+ ([Identifier, Service]) => ({ Identifier, Service })
2387
+ );
2388
+ const contextTag = cachedBy(
2389
+ fn("TypeParser.contextTag")(function* (type, atLocation) {
2390
+ yield* pipeableType(type, atLocation);
2391
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2392
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
2393
+ );
2394
+ propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
2395
+ for (const propertySymbol of propertiesSymbols) {
2396
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2397
+ const varianceArgs = yield* option(contextTagVarianceStruct(
2398
+ propertyType,
2399
+ atLocation
2400
+ ));
2401
+ if (isSome2(varianceArgs)) {
2402
+ return varianceArgs.value;
2403
+ }
2404
+ }
2405
+ return yield* typeParserIssue("Type has no tag variance struct", type, atLocation);
2406
+ }),
2407
+ "TypeParser.contextTag",
2408
+ (type) => type
2409
+ );
2410
+ return {
2411
+ effectType,
2412
+ layerType,
2413
+ fiberType,
2414
+ effectSubtype,
2415
+ importedEffectModule,
2416
+ effectGen,
2417
+ effectFnUntracedGen,
2418
+ effectFnGen,
2419
+ unnecessaryEffectGen: unnecessaryEffectGen2,
2420
+ effectSchemaType,
2421
+ contextTag
2422
+ };
2423
+ }
2424
+
2425
+ // src/completions/fnFunctionStar.ts
2426
+ var fnFunctionStar = createCompletion({
2427
+ name: "fnFunctionStar",
2428
+ apply: fn("fnFunctionStar")(function* (sourceFile, position) {
2429
+ const ts = yield* service(TypeScriptApi);
2430
+ const typeParser = yield* service(TypeParser);
2431
+ const maybeInfos = yield* option(
2432
+ parseAccessedExpressionForCompletion(sourceFile, position)
2433
+ );
2434
+ if (isNone2(maybeInfos)) return [];
2435
+ const { accessedObject } = maybeInfos.value;
2436
+ const isEffectModule = yield* option(typeParser.importedEffectModule(accessedObject));
2437
+ if (isNone2(isEffectModule)) return [];
2438
+ const span = ts.createTextSpan(
2439
+ accessedObject.end + 1,
2440
+ Math.max(0, position - accessedObject.end - 1)
2441
+ );
2442
+ const maybeFnName = pipe(
2443
+ yield* getAncestorNodesInRange(sourceFile, toTextRange(accessedObject.pos)),
2444
+ filter(ts.isVariableDeclaration),
2445
+ map3((_) => _.name && ts.isIdentifier(_.name) ? _.name.text : ""),
2446
+ filter((_) => _.length > 0),
2447
+ head,
2448
+ map2((name) => [
2449
+ {
2450
+ name: `fn("${name}")`,
2451
+ kind: ts.ScriptElementKind.constElement,
2452
+ insertText: `fn("${name}")(function*(${"${1}"}){${"${0}"}})`,
2453
+ replacementSpan: span,
2454
+ isSnippet: true
2455
+ }
2456
+ ]),
2457
+ getOrElse2(() => [])
2458
+ );
2459
+ return maybeFnName.concat([{
2460
+ name: `fn(function*(){})`,
2461
+ kind: ts.ScriptElementKind.constElement,
2462
+ insertText: `fn(function*(${"${1}"}){${"${0}"}})`,
2463
+ replacementSpan: span,
2464
+ isSnippet: true
2465
+ }, {
2466
+ name: `fnUntraced(function*(){})`,
2467
+ kind: ts.ScriptElementKind.constElement,
2468
+ insertText: `fnUntraced(function*(${"${1}"}){${"${0}"}})`,
2469
+ replacementSpan: span,
2470
+ isSnippet: true
2471
+ }]);
2472
+ })
2473
+ });
2474
+
1927
2475
  // src/core/TypeCheckerApi.ts
1928
2476
  var TypeCheckerApi = Tag("TypeChecker");
1929
2477
  var TypeCheckerApiCache = Tag("TypeCheckerApiCache");
@@ -2076,549 +2624,104 @@ var expectedAndRealType = fn("TypeCheckerApi.expectedAndRealType")(function* (so
2076
2624
  const expectedType = typeChecker.getTypeOfSymbolAtLocation(symbol3, node);
2077
2625
  const realType = typeChecker.getTypeAtLocation(node);
2078
2626
  result.push([node, expectedType, node, realType]);
2079
- }
2080
- }
2081
- }
2082
- }
2083
- ts.forEachChild(node, appendNodeToVisit);
2084
- continue;
2085
- } else if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
2086
- const expectedType = typeChecker.getTypeAtLocation(node.left);
2087
- const realType = typeChecker.getTypeAtLocation(node.right);
2088
- result.push([node.left, expectedType, node.right, realType]);
2089
- appendNodeToVisit(node.right);
2090
- continue;
2091
- } else if (ts.isReturnStatement(node) && node.expression) {
2092
- const parentDeclaration = yield* option(getAncestorConvertibleDeclaration(node));
2093
- if (isSome2(parentDeclaration)) {
2094
- const expectedType = yield* option(getInferredReturnType(parentDeclaration.value));
2095
- const realType = typeChecker.getTypeAtLocation(node.expression);
2096
- if (isSome2(expectedType)) {
2097
- result.push([node, expectedType.value, node, realType]);
2098
- }
2099
- }
2100
- ts.forEachChild(node, appendNodeToVisit);
2101
- continue;
2102
- } else if (ts.isArrowFunction(node) && (node.typeParameters || []).length === 0 && ts.isExpression(node.body)) {
2103
- const body = node.body;
2104
- const expectedType = typeChecker.getContextualType(body);
2105
- const realType = typeChecker.getTypeAtLocation(body);
2106
- if (expectedType) {
2107
- result.push([body, expectedType, body, realType]);
2108
- }
2109
- ts.forEachChild(body, appendNodeToVisit);
2110
- continue;
2111
- } else if (ts.isArrowFunction(node) && (node.typeParameters || []).length > 0 && ts.isExpression(node.body)) {
2112
- const body = node.body;
2113
- const expectedType = yield* option(getInferredReturnType(node));
2114
- const realType = typeChecker.getTypeAtLocation(body);
2115
- if (isSome2(expectedType)) {
2116
- result.push([body, expectedType.value, body, realType]);
2117
- }
2118
- ts.forEachChild(body, appendNodeToVisit);
2119
- continue;
2120
- } else if (ts.isSatisfiesExpression(node)) {
2121
- const expectedType = typeChecker.getTypeAtLocation(node.type);
2122
- const realType = typeChecker.getTypeAtLocation(node.expression);
2123
- result.push([node.expression, expectedType, node.expression, realType]);
2124
- appendNodeToVisit(node.expression);
2125
- continue;
2126
- }
2127
- ts.forEachChild(node, appendNodeToVisit);
2128
- }
2129
- cache.expectedAndRealType.set(sourceFile, result);
2130
- return result;
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
- );
2177
-
2178
- // src/utils/TypeParser.ts
2179
- var TypeParserIssue = class {
2180
- constructor(type, node, message) {
2181
- this.type = type;
2182
- this.node = node;
2183
- this.message = message;
2184
- }
2185
- _tag = "@effect/language-service/TypeParserIssue";
2186
- };
2187
- function typeParserIssue(message, type, node) {
2188
- return fail(new TypeParserIssue(type, node, message));
2189
- }
2190
- function covariantTypeArgument(type) {
2191
- const signatures = type.getCallSignatures();
2192
- if (signatures.length !== 1) {
2193
- return typeParserIssue("Covariant type has no call signature", type);
2194
- }
2195
- return succeed(signatures[0].getReturnType());
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
- }
2204
- function invariantTypeArgument(type) {
2205
- const signatures = type.getCallSignatures();
2206
- if (signatures.length !== 1) {
2207
- return typeParserIssue("Invariant type has no call signature", type);
2208
- }
2209
- return succeed(signatures[0].getReturnType());
2210
- }
2211
- var pipeableType = fn("TypeParser.pipeableType")(function* (type, atLocation) {
2212
- const typeChecker = yield* service(TypeCheckerApi);
2213
- const pipeSymbol = typeChecker.getPropertyOfType(type, "pipe");
2214
- if (!pipeSymbol) {
2215
- return yield* typeParserIssue("Type has no 'pipe' property", type, atLocation);
2216
- }
2217
- const pipeType = typeChecker.getTypeOfSymbolAtLocation(pipeSymbol, atLocation);
2218
- const signatures = pipeType.getCallSignatures();
2219
- if (signatures.length === 0) {
2220
- return yield* typeParserIssue("'pipe' property is not callable", type, atLocation);
2221
- }
2222
- return type;
2223
- });
2224
- var varianceStructCovariantType = fn("TypeParser.varianceStructCovariantType")(
2225
- function* (type, atLocation, propertyName) {
2226
- const typeChecker = yield* service(TypeCheckerApi);
2227
- const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
2228
- if (!propertySymbol) {
2229
- return yield* typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
2230
- }
2231
- const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2232
- return yield* covariantTypeArgument(propertyType);
2233
- }
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
- );
2248
- var varianceStructInvariantType = fn("TypeParser.varianceStructInvariantType")(
2249
- function* (type, atLocation, propertyName) {
2250
- const typeChecker = yield* service(TypeCheckerApi);
2251
- const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
2252
- if (!propertySymbol) {
2253
- return yield* typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
2254
- }
2255
- const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2256
- return yield* invariantTypeArgument(propertyType);
2257
- }
2258
- );
2259
- var effectVarianceStruct = fn("TypeParser.effectVarianceStruct")(function* (type, atLocation) {
2260
- return {
2261
- A: yield* varianceStructCovariantType(type, atLocation, "_A"),
2262
- E: yield* varianceStructCovariantType(type, atLocation, "_E"),
2263
- R: yield* varianceStructCovariantType(type, atLocation, "_R")
2264
- };
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
- });
2273
- var effectType = fn("TypeParser.effectType")(function* (type, atLocation) {
2274
- const ts = yield* service(TypeScriptApi);
2275
- const typeChecker = yield* service(TypeCheckerApi);
2276
- yield* pipeableType(type, atLocation);
2277
- const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2278
- (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
2279
- );
2280
- propertiesSymbols.sort((a, b) => b.name.indexOf("EffectTypeId") - a.name.indexOf("EffectTypeId"));
2281
- for (const propertySymbol of propertiesSymbols) {
2282
- const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2283
- const varianceArgs = yield* option(effectVarianceStruct(
2284
- propertyType,
2285
- atLocation
2286
- ));
2287
- if (isSome2(varianceArgs)) {
2288
- return varianceArgs.value;
2289
- }
2290
- }
2291
- return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
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
- });
2313
- var fiberType = fn("TypeParser.fiberType")(function* (type, atLocation) {
2314
- const typeChecker = yield* service(TypeCheckerApi);
2315
- const awaitSymbol = typeChecker.getPropertyOfType(type, "await");
2316
- const pollSymbol = typeChecker.getPropertyOfType(type, "poll");
2317
- if (!awaitSymbol || !pollSymbol) {
2318
- return yield* typeParserIssue(
2319
- "Type is not a fiber because it does not have 'await' or 'poll' property",
2320
- type,
2321
- atLocation
2322
- );
2323
- }
2324
- return yield* effectType(type, atLocation);
2325
- });
2326
- var effectSubtype = fn("TypeParser.effectSubtype")(function* (type, atLocation) {
2327
- const typeChecker = yield* service(TypeCheckerApi);
2328
- const tagSymbol = typeChecker.getPropertyOfType(type, "_tag");
2329
- const getSymbol = typeChecker.getPropertyOfType(type, "get");
2330
- if (!(tagSymbol || getSymbol)) {
2331
- return yield* typeParserIssue(
2332
- "Type is not a subtype of effect because it does not have '_tag' or 'get' property",
2333
- type,
2334
- atLocation
2335
- );
2336
- }
2337
- return yield* effectType(type, atLocation);
2338
- });
2339
- var importedEffectModule = fn("TypeParser.importedEffectModule")(function* (node) {
2340
- const ts = yield* service(TypeScriptApi);
2341
- const typeChecker = yield* service(TypeCheckerApi);
2342
- const type = typeChecker.getTypeAtLocation(node);
2343
- const propertySymbol = typeChecker.getPropertyOfType(type, "never");
2344
- if (!propertySymbol) {
2345
- return yield* typeParserIssue("Type has no 'never' property", type, node);
2346
- }
2347
- if (!ts.isExpression(node)) {
2348
- return yield* typeParserIssue("Node is not an expression", type, node);
2349
- }
2350
- const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, node);
2351
- yield* effectType(propertyType, node);
2352
- return node;
2353
- });
2354
- var effectGen = fn("TypeParser.effectGen")(function* (node) {
2355
- const ts = yield* service(TypeScriptApi);
2356
- if (!ts.isCallExpression(node)) {
2357
- return yield* typeParserIssue("Node is not a call expression", void 0, node);
2358
- }
2359
- if (node.arguments.length === 0) {
2360
- return yield* typeParserIssue("Node has no arguments", void 0, node);
2361
- }
2362
- const generatorFunction = node.arguments[0];
2363
- if (!ts.isFunctionExpression(generatorFunction)) {
2364
- return yield* typeParserIssue("Node is not a function expression", void 0, node);
2365
- }
2366
- if (generatorFunction.asteriskToken === void 0) {
2367
- return yield* typeParserIssue("Node is not a generator function", void 0, node);
2368
- }
2369
- if (!ts.isPropertyAccessExpression(node.expression)) {
2370
- return yield* typeParserIssue("Node is not a property access expression", void 0, node);
2371
- }
2372
- const propertyAccess = node.expression;
2373
- if (propertyAccess.name.text !== "gen") {
2374
- return yield* typeParserIssue("Call expression name is not 'gen'", void 0, node);
2375
- }
2376
- const effectModule = yield* importedEffectModule(propertyAccess.expression);
2377
- return {
2378
- node,
2379
- effectModule,
2380
- generatorFunction,
2381
- body: generatorFunction.body,
2382
- functionStar: generatorFunction.getFirstToken()
2383
- };
2384
- });
2385
- var effectFnUntracedGen = fn("TypeParser.effectFnUntracedGen")(
2386
- function* (node) {
2387
- const ts = yield* service(TypeScriptApi);
2388
- if (!ts.isCallExpression(node)) {
2389
- return yield* typeParserIssue("Node is not a call expression", void 0, node);
2390
- }
2391
- if (node.arguments.length === 0) {
2392
- return yield* typeParserIssue("Node has no arguments", void 0, node);
2393
- }
2394
- const generatorFunction = node.arguments[0];
2395
- if (!ts.isFunctionExpression(generatorFunction)) {
2396
- return yield* typeParserIssue("Node is not a function expression", void 0, node);
2397
- }
2398
- if (generatorFunction.asteriskToken === void 0) {
2399
- return yield* typeParserIssue(
2400
- "Node is not a generator function",
2401
- void 0,
2402
- node
2403
- );
2404
- }
2405
- if (!ts.isPropertyAccessExpression(node.expression)) {
2406
- return yield* typeParserIssue(
2407
- "Node is not a property access expression",
2408
- void 0,
2409
- node
2410
- );
2411
- }
2412
- const propertyAccess = node.expression;
2413
- if (propertyAccess.name.text !== "fnUntraced") {
2414
- return yield* typeParserIssue(
2415
- "Call expression name is not 'fnUntraced'",
2416
- void 0,
2417
- node
2418
- );
2419
- }
2420
- const effectModule = yield* importedEffectModule(propertyAccess.expression);
2421
- return {
2422
- node,
2423
- effectModule,
2424
- generatorFunction,
2425
- body: generatorFunction.body,
2426
- functionStar: generatorFunction.getFirstToken()
2427
- };
2428
- }
2429
- );
2430
- var effectFnGen = fn("TypeParser.effectFnGen")(function* (node) {
2431
- const ts = yield* service(TypeScriptApi);
2432
- if (!ts.isCallExpression(node)) {
2433
- return yield* typeParserIssue("Node is not a call expression", void 0, node);
2434
- }
2435
- if (node.arguments.length === 0) {
2436
- return yield* typeParserIssue("Node has no arguments", void 0, node);
2437
- }
2438
- const generatorFunction = node.arguments[0];
2439
- if (!ts.isFunctionExpression(generatorFunction)) {
2440
- return yield* typeParserIssue(
2441
- "Node is not a function expression",
2442
- void 0,
2443
- node
2444
- );
2445
- }
2446
- if (generatorFunction.asteriskToken === void 0) {
2447
- return yield* typeParserIssue(
2448
- "Node is not a generator function",
2449
- void 0,
2450
- node
2451
- );
2452
- }
2453
- const expressionToTest = ts.isCallExpression(node.expression) ? node.expression.expression : node.expression;
2454
- if (!ts.isPropertyAccessExpression(expressionToTest)) {
2455
- return yield* typeParserIssue(
2456
- "Node is not a property access expression",
2457
- void 0,
2458
- node
2459
- );
2460
- }
2461
- const propertyAccess = expressionToTest;
2462
- if (propertyAccess.name.text !== "fn") {
2463
- return yield* typeParserIssue(
2464
- "Call expression name is not 'fn'",
2465
- void 0,
2466
- node
2467
- );
2468
- }
2469
- const effectModule = yield* importedEffectModule(propertyAccess.expression);
2470
- return {
2471
- node,
2472
- generatorFunction,
2473
- effectModule,
2474
- body: generatorFunction.body,
2475
- functionStar: generatorFunction.getFirstToken()
2476
- };
2477
- });
2478
- var unnecessaryEffectGen = fn("TypeParser.unnecessaryEffectGen")(function* (node) {
2479
- const ts = yield* service(TypeScriptApi);
2480
- const typeChecker = yield* service(TypeCheckerApi);
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;
2627
+ }
2628
+ }
2629
+ }
2630
+ }
2631
+ ts.forEachChild(node, appendNodeToVisit);
2495
2632
  continue;
2496
- }
2497
- if (ts.isExpressionStatement(nodeToCheck)) {
2498
- nodeToCheck = nodeToCheck.expression;
2633
+ } else if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
2634
+ const expectedType = typeChecker.getTypeAtLocation(node.left);
2635
+ const realType = typeChecker.getTypeAtLocation(node.right);
2636
+ result.push([node.left, expectedType, node.right, realType]);
2637
+ appendNodeToVisit(node.right);
2499
2638
  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
- );
2639
+ } else if (ts.isReturnStatement(node) && node.expression) {
2640
+ const parentDeclaration = yield* option(getAncestorConvertibleDeclaration(node));
2641
+ if (isSome2(parentDeclaration)) {
2642
+ const expectedType = yield* option(getInferredReturnType(parentDeclaration.value));
2643
+ const realType = typeChecker.getTypeAtLocation(node.expression);
2644
+ if (isSome2(expectedType)) {
2645
+ result.push([node, expectedType.value, node, realType]);
2646
+ }
2647
+ }
2648
+ ts.forEachChild(node, appendNodeToVisit);
2649
+ continue;
2650
+ } else if (ts.isArrowFunction(node) && (node.typeParameters || []).length === 0 && ts.isExpression(node.body)) {
2651
+ const body = node.body;
2652
+ const expectedType = typeChecker.getContextualType(body);
2653
+ const realType = typeChecker.getTypeAtLocation(body);
2654
+ if (expectedType) {
2655
+ result.push([body, expectedType, body, realType]);
2656
+ }
2657
+ ts.forEachChild(body, appendNodeToVisit);
2658
+ continue;
2659
+ } else if (ts.isArrowFunction(node) && (node.typeParameters || []).length > 0 && ts.isExpression(node.body)) {
2660
+ const body = node.body;
2661
+ const expectedType = yield* option(getInferredReturnType(node));
2662
+ const realType = typeChecker.getTypeAtLocation(body);
2663
+ if (isSome2(expectedType)) {
2664
+ result.push([body, expectedType.value, body, realType]);
2531
2665
  }
2532
- return { node, body, yieldedExpression, replacementNode };
2666
+ ts.forEachChild(body, appendNodeToVisit);
2667
+ continue;
2668
+ } else if (ts.isSatisfiesExpression(node)) {
2669
+ const expectedType = typeChecker.getTypeAtLocation(node.type);
2670
+ const realType = typeChecker.getTypeAtLocation(node.expression);
2671
+ result.push([node.expression, expectedType, node.expression, realType]);
2672
+ appendNodeToVisit(node.expression);
2673
+ continue;
2533
2674
  }
2534
- break;
2675
+ ts.forEachChild(node, appendNodeToVisit);
2535
2676
  }
2536
- return yield* typeParserIssue(
2537
- "Not an handled node",
2538
- void 0,
2539
- node
2540
- );
2677
+ cache.expectedAndRealType.set(sourceFile, result);
2678
+ return result;
2541
2679
  });
2542
- var effectSchemaVarianceStruct = fn("TypeParser.effectSchemaVarianceStruct")(
2543
- function* (type, atLocation) {
2680
+ var appendToUniqueTypesMap = fn(
2681
+ "TypeCheckerApi.appendToUniqueTypesMap"
2682
+ )(
2683
+ function* (memory, initialType, excludeNever) {
2684
+ const ts = yield* service(TypeScriptApi);
2685
+ const typeChecker = yield* service(TypeCheckerApi);
2686
+ const newIndexes = /* @__PURE__ */ new Set();
2687
+ const knownIndexes = /* @__PURE__ */ new Set();
2688
+ let toTest = [initialType];
2689
+ while (toTest.length > 0) {
2690
+ const type = toTest.pop();
2691
+ if (!type) break;
2692
+ if (excludeNever && type.flags & ts.TypeFlags.Never) {
2693
+ continue;
2694
+ }
2695
+ if (type.isUnion()) {
2696
+ toTest = toTest.concat(type.types);
2697
+ } else {
2698
+ const foundMatch = [];
2699
+ for (const [typeId, knownType] of memory.entries()) {
2700
+ const areSame = typeChecker.isTypeAssignableTo(knownType, type) && typeChecker.isTypeAssignableTo(type, knownType);
2701
+ if (areSame) {
2702
+ foundMatch.push(typeId);
2703
+ break;
2704
+ }
2705
+ }
2706
+ if (foundMatch.length === 0) {
2707
+ const newId = "t" + (memory.size + 1);
2708
+ memory.set(newId, type);
2709
+ newIndexes.add(newId);
2710
+ } else {
2711
+ knownIndexes.add(foundMatch[0]);
2712
+ }
2713
+ }
2714
+ }
2544
2715
  return {
2545
- A: yield* varianceStructInvariantType(type, atLocation, "_A"),
2546
- I: yield* varianceStructInvariantType(type, atLocation, "_I"),
2547
- R: yield* varianceStructCovariantType(type, atLocation, "_R")
2716
+ newIndexes,
2717
+ knownIndexes,
2718
+ allIndexes: pipe(
2719
+ fromIterable(newIndexes),
2720
+ appendAll(fromIterable(knownIndexes))
2721
+ )
2548
2722
  };
2549
2723
  }
2550
2724
  );
2551
- var effectSchemaType = fn("TypeParser.effectSchemaType")(function* (type, atLocation) {
2552
- const ts = yield* service(TypeScriptApi);
2553
- const typeChecker = yield* service(TypeCheckerApi);
2554
- yield* pipeableType(type, atLocation);
2555
- const ast = typeChecker.getPropertyOfType(type, "ast");
2556
- if (!ast) return yield* typeParserIssue("Has no 'ast' property", type, atLocation);
2557
- const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2558
- (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
2559
- );
2560
- propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
2561
- for (const propertySymbol of propertiesSymbols) {
2562
- const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2563
- const varianceArgs = yield* option(effectSchemaVarianceStruct(
2564
- propertyType,
2565
- atLocation
2566
- ));
2567
- if (isSome2(varianceArgs)) {
2568
- return varianceArgs.value;
2569
- }
2570
- }
2571
- return yield* typeParserIssue("Type has no schema variance struct", type, atLocation);
2572
- });
2573
-
2574
- // src/completions/fnFunctionStar.ts
2575
- var fnFunctionStar = createCompletion({
2576
- name: "fnFunctionStar",
2577
- apply: fn("fnFunctionStar")(function* (sourceFile, position) {
2578
- const ts = yield* service(TypeScriptApi);
2579
- const maybeInfos = yield* option(
2580
- parseAccessedExpressionForCompletion(sourceFile, position)
2581
- );
2582
- if (isNone2(maybeInfos)) return [];
2583
- const { accessedObject } = maybeInfos.value;
2584
- const isEffectModule = yield* option(importedEffectModule(accessedObject));
2585
- if (isNone2(isEffectModule)) return [];
2586
- const span = ts.createTextSpan(
2587
- accessedObject.end + 1,
2588
- Math.max(0, position - accessedObject.end - 1)
2589
- );
2590
- const maybeFnName = pipe(
2591
- yield* getAncestorNodesInRange(sourceFile, toTextRange(accessedObject.pos)),
2592
- filter(ts.isVariableDeclaration),
2593
- map3((_) => _.name && ts.isIdentifier(_.name) ? _.name.text : ""),
2594
- filter((_) => _.length > 0),
2595
- head,
2596
- map2((name) => [
2597
- {
2598
- name: `fn("${name}")`,
2599
- kind: ts.ScriptElementKind.constElement,
2600
- insertText: `fn("${name}")(function*(${"${1}"}){${"${0}"}})`,
2601
- replacementSpan: span,
2602
- isSnippet: true
2603
- }
2604
- ]),
2605
- getOrElse2(() => [])
2606
- );
2607
- return maybeFnName.concat([{
2608
- name: `fn(function*(){})`,
2609
- kind: ts.ScriptElementKind.constElement,
2610
- insertText: `fn(function*(${"${1}"}){${"${0}"}})`,
2611
- replacementSpan: span,
2612
- isSnippet: true
2613
- }, {
2614
- name: `fnUntraced(function*(){})`,
2615
- kind: ts.ScriptElementKind.constElement,
2616
- insertText: `fnUntraced(function*(${"${1}"}){${"${0}"}})`,
2617
- replacementSpan: span,
2618
- isSnippet: true
2619
- }]);
2620
- })
2621
- });
2622
2725
 
2623
2726
  // src/completions/genFunctionStar.ts
2624
2727
  var genFunctionStar = createCompletion({
@@ -2701,6 +2804,7 @@ function parse(config) {
2701
2804
  diagnostics: isObject(config) && hasProperty(config, "diagnostics") && isBoolean(config.diagnostics) ? config.diagnostics : true,
2702
2805
  quickinfo: isObject(config) && hasProperty(config, "quickinfo") && isBoolean(config.quickinfo) ? config.quickinfo : true,
2703
2806
  completions: isObject(config) && hasProperty(config, "completions") && isBoolean(config.completions) ? config.completions : true,
2807
+ goto: isObject(config) && hasProperty(config, "goto") && isBoolean(config.goto) ? config.goto : true,
2704
2808
  allowedDuplicatedPackages: isObject(config) && hasProperty(config, "allowedDuplicatedPackages") && isArray(config.allowedDuplicatedPackages) && config.allowedDuplicatedPackages.every(isString) ? config.allowedDuplicatedPackages.map((_) => _.toLowerCase()) : []
2705
2809
  };
2706
2810
  }
@@ -2761,6 +2865,7 @@ var floatingEffect = createDiagnostic({
2761
2865
  apply: fn("floatingEffect.apply")(function* (sourceFile) {
2762
2866
  const ts = yield* service(TypeScriptApi);
2763
2867
  const typeChecker = yield* service(TypeCheckerApi);
2868
+ const typeParser = yield* service(TypeParser);
2764
2869
  function isFloatingExpression(node) {
2765
2870
  if (!ts.isExpressionStatement(node)) return false;
2766
2871
  if (!(ts.isBlock(node.parent) || ts.isSourceFile(node.parent))) return false;
@@ -2780,11 +2885,11 @@ var floatingEffect = createDiagnostic({
2780
2885
  ts.forEachChild(node, appendNodeToVisit);
2781
2886
  if (!isFloatingExpression(node)) continue;
2782
2887
  const type = typeChecker.getTypeAtLocation(node.expression);
2783
- const effect = yield* option(effectType(type, node.expression));
2888
+ const effect = yield* option(typeParser.effectType(type, node.expression));
2784
2889
  if (isSome2(effect)) {
2785
2890
  const allowedFloatingEffects = yield* pipe(
2786
- fiberType(type, node.expression),
2787
- orElse3(() => effectSubtype(type, node.expression)),
2891
+ typeParser.fiberType(type, node.expression),
2892
+ orElse3(() => typeParser.effectSubtype(type, node.expression)),
2788
2893
  option
2789
2894
  );
2790
2895
  if (isNone2(allowedFloatingEffects)) {
@@ -2801,6 +2906,112 @@ var floatingEffect = createDiagnostic({
2801
2906
  })
2802
2907
  });
2803
2908
 
2909
+ // src/diagnostics/leakingRequirements.ts
2910
+ var leakingRequirements = createDiagnostic({
2911
+ name: "leakingRequirements",
2912
+ code: 8,
2913
+ apply: fn("leakingRequirements.apply")(function* (sourceFile) {
2914
+ const ts = yield* service(TypeScriptApi);
2915
+ const typeChecker = yield* service(TypeCheckerApi);
2916
+ const typeParser = yield* service(TypeParser);
2917
+ const typeOrder = yield* deterministicTypeOrder;
2918
+ const effectDiagnostics = [];
2919
+ const parseLeakedRequirements = cachedBy(
2920
+ fn("leakingServices.checkServiceLeaking")(
2921
+ function* (service2, atLocation) {
2922
+ const properties = typeChecker.getPropertiesOfType(service2);
2923
+ if (properties.length < 1) return [];
2924
+ const memory = /* @__PURE__ */ new Map();
2925
+ let sharedRequirementsKeys = void 0;
2926
+ let effectMembers = 0;
2927
+ for (const property of properties) {
2928
+ const servicePropertyType = typeChecker.getTypeOfSymbolAtLocation(property, atLocation);
2929
+ let effectContextType = void 0;
2930
+ yield* pipe(
2931
+ typeParser.effectType(servicePropertyType, atLocation),
2932
+ map4((_) => effectContextType = _.R),
2933
+ orElse3(() => {
2934
+ const servicePropertyCallSignatures = servicePropertyType.getCallSignatures();
2935
+ if (servicePropertyCallSignatures.length === 1) {
2936
+ return pipe(
2937
+ typeParser.effectType(servicePropertyCallSignatures[0].getReturnType(), atLocation),
2938
+ map4((_) => {
2939
+ effectContextType = _.R;
2940
+ })
2941
+ );
2942
+ }
2943
+ return void_2;
2944
+ }),
2945
+ ignore
2946
+ );
2947
+ if (effectContextType) {
2948
+ effectMembers++;
2949
+ const { allIndexes } = yield* appendToUniqueTypesMap(memory, effectContextType, true);
2950
+ if (!sharedRequirementsKeys) {
2951
+ sharedRequirementsKeys = allIndexes;
2952
+ } else {
2953
+ sharedRequirementsKeys = intersection(sharedRequirementsKeys, allIndexes);
2954
+ if (sharedRequirementsKeys.length === 0) return [];
2955
+ }
2956
+ }
2957
+ }
2958
+ if (sharedRequirementsKeys && sharedRequirementsKeys.length > 0 && effectMembers >= 2) {
2959
+ return sharedRequirementsKeys.map((key) => memory.get(key));
2960
+ }
2961
+ return [];
2962
+ }
2963
+ ),
2964
+ "leakingServices.checkServiceLeaking",
2965
+ (_, service2) => service2
2966
+ );
2967
+ function reportLeakingRequirements(node, requirements) {
2968
+ if (requirements.length === 0) return;
2969
+ effectDiagnostics.push({
2970
+ node,
2971
+ category: ts.DiagnosticCategory.Warning,
2972
+ messageText: `This Service is leaking the ${requirements.map((_) => typeChecker.typeToString(_)).join(" | ")} requirement`,
2973
+ fixes: []
2974
+ });
2975
+ }
2976
+ const nodeToVisit = [];
2977
+ const appendNodeToVisit = (node) => {
2978
+ nodeToVisit.push(node);
2979
+ return void 0;
2980
+ };
2981
+ ts.forEachChild(sourceFile, appendNodeToVisit);
2982
+ while (nodeToVisit.length > 0) {
2983
+ const node = nodeToVisit.shift();
2984
+ const typesToCheck = [];
2985
+ if (ts.isCallExpression(node)) {
2986
+ typesToCheck.push([typeChecker.getTypeAtLocation(node), node]);
2987
+ } else if (ts.isClassDeclaration(node) && node.name) {
2988
+ const classSym = typeChecker.getSymbolAtLocation(node.name);
2989
+ if (classSym) {
2990
+ const type = typeChecker.getTypeOfSymbol(classSym);
2991
+ typesToCheck.push([type, node.name]);
2992
+ }
2993
+ } else {
2994
+ ts.forEachChild(node, appendNodeToVisit);
2995
+ continue;
2996
+ }
2997
+ for (const [type, reportAt] of typesToCheck) {
2998
+ yield* pipe(
2999
+ typeParser.contextTag(type, node),
3000
+ flatMap3(
3001
+ ({ Service }) => pipe(
3002
+ parseLeakedRequirements(Service, node),
3003
+ map4((requirements) => reportLeakingRequirements(reportAt, sort(requirements, typeOrder)))
3004
+ )
3005
+ ),
3006
+ orElse3(() => sync(() => ts.forEachChild(node, appendNodeToVisit))),
3007
+ ignore
3008
+ );
3009
+ }
3010
+ }
3011
+ return effectDiagnostics;
3012
+ })
3013
+ });
3014
+
2804
3015
  // src/diagnostics/missingEffectContext.ts
2805
3016
  var missingEffectContext = createDiagnostic({
2806
3017
  name: "missingEffectContext",
@@ -2808,15 +3019,16 @@ var missingEffectContext = createDiagnostic({
2808
3019
  apply: fn("missingEffectContext.apply")(function* (sourceFile) {
2809
3020
  const ts = yield* service(TypeScriptApi);
2810
3021
  const typeChecker = yield* service(TypeCheckerApi);
3022
+ const typeParser = yield* service(TypeParser);
2811
3023
  const typeOrder = yield* deterministicTypeOrder;
2812
3024
  const checkForMissingContextTypes = fn(
2813
3025
  "missingEffectContext.apply.checkForMissingContextTypes"
2814
3026
  )(function* (node, expectedType, valueNode, realType) {
2815
- const expectedEffect = yield* effectType(
3027
+ const expectedEffect = yield* typeParser.effectType(
2816
3028
  expectedType,
2817
3029
  node
2818
3030
  );
2819
- const realEffect = yield* effectType(
3031
+ const realEffect = yield* typeParser.effectType(
2820
3032
  realType,
2821
3033
  valueNode
2822
3034
  );
@@ -2860,14 +3072,15 @@ var missingEffectError = createDiagnostic({
2860
3072
  apply: fn("missingEffectError.apply")(function* (sourceFile) {
2861
3073
  const ts = yield* service(TypeScriptApi);
2862
3074
  const typeChecker = yield* service(TypeCheckerApi);
3075
+ const typeParser = yield* service(TypeParser);
2863
3076
  const typeOrder = yield* deterministicTypeOrder;
2864
3077
  const checkForMissingErrorTypes = fn("missingEffectError.apply.checkForMissingErrorTypes")(
2865
3078
  function* (node, expectedType, valueNode, realType) {
2866
- const expectedEffect = yield* effectType(
3079
+ const expectedEffect = yield* typeParser.effectType(
2867
3080
  expectedType,
2868
3081
  node
2869
3082
  );
2870
- const realEffect = yield* effectType(
3083
+ const realEffect = yield* typeParser.effectType(
2871
3084
  realType,
2872
3085
  valueNode
2873
3086
  );
@@ -2912,6 +3125,7 @@ var missingReturnYieldStar = createDiagnostic({
2912
3125
  apply: fn("missingReturnYieldStar.apply")(function* (sourceFile) {
2913
3126
  const ts = yield* service(TypeScriptApi);
2914
3127
  const typeChecker = yield* service(TypeCheckerApi);
3128
+ const typeParser = yield* service(TypeParser);
2915
3129
  const effectDiagnostics = [];
2916
3130
  const brokenYields = /* @__PURE__ */ new Set();
2917
3131
  const nodeToVisit = [];
@@ -2925,7 +3139,7 @@ var missingReturnYieldStar = createDiagnostic({
2925
3139
  ts.forEachChild(node, appendNodeToVisit);
2926
3140
  if (ts.isYieldExpression(node) && node.expression && node.asteriskToken) {
2927
3141
  const type = typeChecker.getTypeAtLocation(node.expression);
2928
- const maybeEffect = yield* option(effectType(type, node.expression));
3142
+ const maybeEffect = yield* option(typeParser.effectType(type, node.expression));
2929
3143
  if (isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never) {
2930
3144
  const generatorFunctionOrReturnStatement = ts.findAncestor(
2931
3145
  node,
@@ -2935,9 +3149,9 @@ var missingReturnYieldStar = createDiagnostic({
2935
3149
  if (generatorFunctionOrReturnStatement && generatorFunctionOrReturnStatement.parent) {
2936
3150
  const effectGenNode = generatorFunctionOrReturnStatement.parent;
2937
3151
  const effectGenLike = yield* pipe(
2938
- effectGen(effectGenNode),
2939
- orElse3(() => effectFnUntracedGen(effectGenNode)),
2940
- orElse3(() => effectFnGen(effectGenNode)),
3152
+ typeParser.effectGen(effectGenNode),
3153
+ orElse3(() => typeParser.effectFnUntracedGen(effectGenNode)),
3154
+ orElse3(() => typeParser.effectFnGen(effectGenNode)),
2941
3155
  option
2942
3156
  );
2943
3157
  if (isSome2(effectGenLike)) {
@@ -2980,6 +3194,7 @@ var missingStarInYieldEffectGen = createDiagnostic({
2980
3194
  code: 4,
2981
3195
  apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile) {
2982
3196
  const ts = yield* service(TypeScriptApi);
3197
+ const typeParser = yield* service(TypeParser);
2983
3198
  const effectDiagnostics = [];
2984
3199
  const brokenGenerators = /* @__PURE__ */ new Set();
2985
3200
  const brokenYields = /* @__PURE__ */ new Set();
@@ -2999,18 +3214,18 @@ var missingStarInYieldEffectGen = createDiagnostic({
2999
3214
  );
3000
3215
  if (functionStarNode && functionStarNode.parent) {
3001
3216
  const effectGenNode = functionStarNode.parent;
3002
- const effectGenLike = yield* pipe(
3003
- effectGen(effectGenNode),
3004
- orElse3(() => effectFnUntracedGen(effectGenNode)),
3005
- orElse3(() => effectFnGen(effectGenNode)),
3006
- option
3217
+ yield* pipe(
3218
+ typeParser.effectGen(effectGenNode),
3219
+ orElse3(() => typeParser.effectFnUntracedGen(effectGenNode)),
3220
+ orElse3(() => typeParser.effectFnGen(effectGenNode)),
3221
+ map4(({ functionStar }) => {
3222
+ if (functionStar) {
3223
+ brokenGenerators.add(functionStar);
3224
+ }
3225
+ brokenYields.add(node);
3226
+ }),
3227
+ ignore
3007
3228
  );
3008
- if (isSome2(effectGenLike)) {
3009
- if (effectGenLike.value.functionStar) {
3010
- brokenGenerators.add(effectGenLike.value.functionStar);
3011
- }
3012
- brokenYields.add(node);
3013
- }
3014
3229
  }
3015
3230
  }
3016
3231
  }
@@ -3050,11 +3265,12 @@ var missingStarInYieldEffectGen = createDiagnostic({
3050
3265
  });
3051
3266
 
3052
3267
  // src/diagnostics/unnecessaryEffectGen.ts
3053
- var unnecessaryEffectGen2 = createDiagnostic({
3268
+ var unnecessaryEffectGen = createDiagnostic({
3054
3269
  name: "unnecessaryEffectGen",
3055
3270
  code: 5,
3056
3271
  apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile) {
3057
3272
  const ts = yield* service(TypeScriptApi);
3273
+ const typeParser = yield* service(TypeParser);
3058
3274
  const effectDiagnostics = [];
3059
3275
  const unnecessaryGenerators = /* @__PURE__ */ new Map();
3060
3276
  const nodeToVisit = [];
@@ -3066,9 +3282,12 @@ var unnecessaryEffectGen2 = createDiagnostic({
3066
3282
  while (nodeToVisit.length > 0) {
3067
3283
  const node = nodeToVisit.shift();
3068
3284
  ts.forEachChild(node, appendNodeToVisit);
3069
- const maybeNode = yield* option(unnecessaryEffectGen(node));
3070
- if (isSome2(maybeNode)) {
3071
- unnecessaryGenerators.set(node, maybeNode.value.replacementNode);
3285
+ if (ts.isCallExpression(node)) {
3286
+ yield* pipe(
3287
+ typeParser.unnecessaryEffectGen(node),
3288
+ map4(({ replacementNode }) => unnecessaryGenerators.set(node, replacementNode)),
3289
+ ignore
3290
+ );
3072
3291
  }
3073
3292
  }
3074
3293
  unnecessaryGenerators.forEach(
@@ -3099,8 +3318,9 @@ var diagnostics = [
3099
3318
  missingEffectError,
3100
3319
  floatingEffect,
3101
3320
  missingStarInYieldEffectGen,
3102
- unnecessaryEffectGen2,
3103
- missingReturnYieldStar
3321
+ unnecessaryEffectGen,
3322
+ missingReturnYieldStar,
3323
+ leakingRequirements
3104
3324
  ];
3105
3325
 
3106
3326
  // src/goto/effectRpcDefinition.ts
@@ -3242,6 +3462,7 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
3242
3462
  gen2(function* () {
3243
3463
  const ts = yield* service(TypeScriptApi);
3244
3464
  const typeChecker = yield* service(TypeCheckerApi);
3465
+ const typeParser = yield* service(TypeParser);
3245
3466
  const maybeNode = pipe(
3246
3467
  yield* getAncestorNodesInRange(sourceFile, toTextRange(position)),
3247
3468
  head
@@ -3251,13 +3472,13 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
3251
3472
  const hasTruncationHappened = quickInfo2 && ts.displayPartsToString(quickInfo2.displayParts).indexOf("...") > -1;
3252
3473
  const nodeForType = !quickInfo2 && ts.isYieldExpression(node) && node.asteriskToken && node.expression ? node.expression : hasTruncationHappened ? node : void 0;
3253
3474
  if (!nodeForType) return quickInfo2;
3254
- const effectType2 = yield* effectType(
3475
+ const effectType = yield* typeParser.effectType(
3255
3476
  typeChecker.getTypeAtLocation(nodeForType),
3256
3477
  nodeForType
3257
3478
  );
3258
3479
  const effectTypeArgsDocumentation = [{
3259
3480
  kind: "text",
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"
3481
+ text: "```ts\n/* Effect Type Parameters */\n" + (yield* formatTypeForQuickInfo(effectType.A, "Success")) + "\n" + (yield* formatTypeForQuickInfo(effectType.E, "Failure")) + "\n" + (yield* formatTypeForQuickInfo(effectType.R, "Requirements")) + "\n```\n"
3261
3482
  }];
3262
3483
  if (!quickInfo2) {
3263
3484
  const start = node.getStart();
@@ -3315,6 +3536,7 @@ function processLayerGraphNode(ctx, node, pipedInGraphNode) {
3315
3536
  return gen2(function* () {
3316
3537
  const ts = yield* service(TypeScriptApi);
3317
3538
  const typeChecker = yield* service(TypeCheckerApi);
3539
+ const typeParser = yield* service(TypeParser);
3318
3540
  const maybePipe = yield* option(parsePipeCall(node));
3319
3541
  if (isSome2(maybePipe)) {
3320
3542
  let graphNode = yield* processLayerGraphNode(ctx, maybePipe.value.subject, void 0);
@@ -3325,7 +3547,7 @@ function processLayerGraphNode(ctx, node, pipedInGraphNode) {
3325
3547
  }
3326
3548
  if (ts.isCallExpression(node)) {
3327
3549
  const type = typeChecker.getTypeAtLocation(node);
3328
- const maybeLayer = yield* option(layerType(type, node));
3550
+ const maybeLayer = yield* option(typeParser.layerType(type, node));
3329
3551
  if (isSome2(maybeLayer)) {
3330
3552
  const argNodes = yield* option(
3331
3553
  all2(...node.arguments.map((_) => processLayerGraphNode(ctx, _, void 0)))
@@ -3358,7 +3580,7 @@ function processLayerGraphNode(ctx, node, pipedInGraphNode) {
3358
3580
  if (callSignatures.length === 1) {
3359
3581
  const [signature] = callSignatures;
3360
3582
  const returnType = signature.getReturnType();
3361
- const maybeLayer = yield* option(layerType(returnType, node));
3583
+ const maybeLayer = yield* option(typeParser.layerType(returnType, node));
3362
3584
  if (isSome2(maybeLayer)) {
3363
3585
  const { allIndexes: outTypes } = yield* appendToUniqueTypesMap(
3364
3586
  ctx.services,
@@ -3408,7 +3630,7 @@ function processLayerGraphNode(ctx, node, pipedInGraphNode) {
3408
3630
  }
3409
3631
  if (ts.isExpression(node)) {
3410
3632
  const type = typeChecker.getTypeAtLocation(node);
3411
- const maybeLayer = yield* option(layerType(type, node));
3633
+ const maybeLayer = yield* option(typeParser.layerType(type, node));
3412
3634
  if (isSome2(maybeLayer)) {
3413
3635
  const { allIndexes: outTypes } = yield* appendToUniqueTypesMap(
3414
3636
  ctx.services,
@@ -3547,6 +3769,7 @@ function layerInfo(sourceFile, position, quickInfo2) {
3547
3769
  gen2(function* () {
3548
3770
  const ts = yield* service(TypeScriptApi);
3549
3771
  const typeChecker = yield* service(TypeCheckerApi);
3772
+ const typeParser = yield* service(TypeParser);
3550
3773
  const range = toTextRange(position);
3551
3774
  const maybeNode = pipe(
3552
3775
  yield* getAncestorNodesInRange(sourceFile, range),
@@ -3557,8 +3780,8 @@ function layerInfo(sourceFile, position, quickInfo2) {
3557
3780
  if (isNone2(maybeNode)) return quickInfo2;
3558
3781
  const node = maybeNode.value;
3559
3782
  const layerNode = node.initializer ? node.initializer : node;
3560
- const layerType2 = typeChecker.getTypeAtLocation(layerNode);
3561
- const maybeLayer = yield* option(layerType(layerType2, layerNode));
3783
+ const layerType = typeChecker.getTypeAtLocation(layerNode);
3784
+ const maybeLayer = yield* option(typeParser.layerType(layerType, layerNode));
3562
3785
  if (isNone2(maybeLayer)) return quickInfo2;
3563
3786
  let lastId = 0;
3564
3787
  const graphCtx = {
@@ -3662,6 +3885,7 @@ var asyncAwaitToGen = createRefactor({
3662
3885
  apply: fn("asyncAwaitToGen.apply")(function* (sourceFile, textRange) {
3663
3886
  const ts = yield* service(TypeScriptApi);
3664
3887
  const typeChecker = yield* service(TypeCheckerApi);
3888
+ const typeParser = yield* service(TypeParser);
3665
3889
  const maybeNode = pipe(
3666
3890
  yield* getAncestorNodesInRange(sourceFile, textRange),
3667
3891
  filter(
@@ -3684,7 +3908,7 @@ var asyncAwaitToGen = createRefactor({
3684
3908
  findImportedModuleIdentifier(
3685
3909
  sourceFile,
3686
3910
  (node2) => pipe(
3687
- importedEffectModule(node2),
3911
+ typeParser.importedEffectModule(node2),
3688
3912
  option,
3689
3913
  map4(isSome2)
3690
3914
  )
@@ -3732,6 +3956,7 @@ var asyncAwaitToGenTryPromise = createRefactor({
3732
3956
  apply: fn("asyncAwaitToGenTryPromise.apply")(function* (sourceFile, textRange) {
3733
3957
  const ts = yield* service(TypeScriptApi);
3734
3958
  const typeChecker = yield* service(TypeCheckerApi);
3959
+ const typeParser = yield* service(TypeParser);
3735
3960
  const maybeNode = pipe(
3736
3961
  yield* getAncestorNodesInRange(sourceFile, textRange),
3737
3962
  filter(
@@ -3754,7 +3979,7 @@ var asyncAwaitToGenTryPromise = createRefactor({
3754
3979
  findImportedModuleIdentifier(
3755
3980
  sourceFile,
3756
3981
  (node2) => pipe(
3757
- importedEffectModule(node2),
3982
+ typeParser.importedEffectModule(node2),
3758
3983
  option,
3759
3984
  map4(isSome2)
3760
3985
  )
@@ -3831,17 +4056,18 @@ var effectGenToFn = createRefactor({
3831
4056
  description: "Convert to Effect.fn",
3832
4057
  apply: fn("effectGenToFn.apply")(function* (sourceFile, textRange) {
3833
4058
  const ts = yield* service(TypeScriptApi);
4059
+ const typeParser = yield* service(TypeParser);
3834
4060
  const parseEffectGenNode = fn("asyncAwaitToGen.apply")(function* (node) {
3835
- const effectGen2 = yield* effectGen(node);
4061
+ const effectGen = yield* typeParser.effectGen(node);
3836
4062
  let pipeArgs2 = ts.factory.createNodeArray([]);
3837
4063
  let nodeToReplace2 = node;
3838
4064
  while (nodeToReplace2.parent) {
3839
4065
  const parent = nodeToReplace2.parent;
3840
4066
  if (ts.isConciseBody(nodeToReplace2) && ts.isArrowFunction(parent) && parent.body === nodeToReplace2) {
3841
- return { ...effectGen2, pipeArgs: pipeArgs2, nodeToReplace: parent };
4067
+ return { ...effectGen, pipeArgs: pipeArgs2, nodeToReplace: parent };
3842
4068
  }
3843
4069
  if ((ts.isFunctionDeclaration(parent) || ts.isMethodDeclaration(parent)) && parent.body === nodeToReplace2) {
3844
- return { ...effectGen2, pipeArgs: pipeArgs2, nodeToReplace: parent };
4070
+ return { ...effectGen, pipeArgs: pipeArgs2, nodeToReplace: parent };
3845
4071
  }
3846
4072
  if (ts.isBlock(parent) && parent.statements.length === 1 && parent.statements[0] === nodeToReplace2) {
3847
4073
  nodeToReplace2 = parent;
@@ -3978,6 +4204,7 @@ var _findSchemaVariableDeclaration = fn(
3978
4204
  function* (sourceFile, textRange) {
3979
4205
  const ts = yield* service(TypeScriptApi);
3980
4206
  const typeChecker = yield* service(TypeCheckerApi);
4207
+ const typeParser = yield* service(TypeParser);
3981
4208
  const findSchema = fn("makeSchemaOpaque.apply.findSchema")(
3982
4209
  function* (node) {
3983
4210
  if (!ts.isVariableDeclaration(node)) {
@@ -3996,7 +4223,7 @@ var _findSchemaVariableDeclaration = fn(
3996
4223
  return yield* fail("parent not variable declaration statement");
3997
4224
  }
3998
4225
  const type = typeChecker.getTypeAtLocation(initializer);
3999
- const types = yield* effectSchemaType(type, initializer);
4226
+ const types = yield* typeParser.effectSchemaType(type, initializer);
4000
4227
  return { identifier, variableStatement, variableDeclarationList, types };
4001
4228
  }
4002
4229
  );
@@ -4343,8 +4570,9 @@ var removeUnnecessaryEffectGen = createRefactor({
4343
4570
  name: "removeUnnecessaryEffectGen",
4344
4571
  description: "Remove unnecessary Effect.gen",
4345
4572
  apply: fn("removeUnnecessaryEffectGen.apply")(function* (sourceFile, textRange) {
4573
+ const typeParser = yield* service(TypeParser);
4346
4574
  for (const nodeToReplace of yield* getAncestorNodesInRange(sourceFile, textRange)) {
4347
- const maybeNode = yield* option(unnecessaryEffectGen(nodeToReplace));
4575
+ const maybeNode = yield* option(typeParser.unnecessaryEffectGen(nodeToReplace));
4348
4576
  if (isNone2(maybeNode)) continue;
4349
4577
  const replacementNode = maybeNode.value.replacementNode;
4350
4578
  return {
@@ -4717,12 +4945,21 @@ var processNode = (node, isVirtualTypeNode) => gen2(function* () {
4717
4945
  [ts.factory.createObjectLiteralExpression(properties, true)].concat(records)
4718
4946
  );
4719
4947
  }
4948
+ if (ts.isParenthesizedTypeNode(node)) {
4949
+ return yield* processNode(node.type, isVirtualTypeNode);
4950
+ }
4720
4951
  if (ts.isTypeQueryNode(node)) {
4721
4952
  const typeChecker = yield* service(TypeCheckerApi);
4722
4953
  const type = typeChecker.getTypeAtLocation(node.exprName);
4723
4954
  const typeNode = typeChecker.typeToTypeNode(type, void 0, ts.NodeBuilderFlags.NoTruncation);
4724
4955
  if (typeNode) return yield* processNode(typeNode, true);
4725
4956
  }
4957
+ if (!isVirtualTypeNode && ts.isIndexedAccessTypeNode(node) && ts.isParenthesizedTypeNode(node.objectType) && ts.isTypeQueryNode(node.objectType.type) && ts.isTypeOperatorNode(node.indexType) && node.indexType.operator === ts.SyntaxKind.KeyOfKeyword && ts.isTypeQueryNode(node.indexType.type) && node.indexType.type.exprName.getText().trim() === node.objectType.type.exprName.getText().trim()) {
4958
+ const typeChecker = yield* service(TypeCheckerApi);
4959
+ const type = typeChecker.getTypeAtLocation(node);
4960
+ const typeNode = typeChecker.typeToTypeNode(type, void 0, ts.NodeBuilderFlags.NoTruncation);
4961
+ if (typeNode) return yield* processNode(typeNode, true);
4962
+ }
4726
4963
  if (ts.isTypeReferenceNode(node)) {
4727
4964
  const parsedName = entityNameToDataTypeName(node.typeName);
4728
4965
  if (isSome2(parsedName)) {
@@ -5018,13 +5255,14 @@ var wrapWithEffectGen = createRefactor({
5018
5255
  apply: fn("wrapWithEffectGen.apply")(function* (sourceFile, textRange) {
5019
5256
  const ts = yield* service(TypeScriptApi);
5020
5257
  const typeChecker = yield* service(TypeCheckerApi);
5258
+ const typeParser = yield* service(TypeParser);
5021
5259
  const findEffectToWrap = fn("wrapWithEffectGen.apply.findEffectToWrap")(
5022
5260
  function* (node) {
5023
5261
  if (!ts.isExpression(node)) return yield* fail("is not an expression");
5024
5262
  const parent = node.parent;
5025
5263
  if (parent != null && ts.isVariableDeclaration(parent) && parent.initializer !== node) return yield* fail("is LHS of variable declaration");
5026
5264
  const type = typeChecker.getTypeAtLocation(node);
5027
- yield* effectType(type, node);
5265
+ yield* typeParser.effectType(type, node);
5028
5266
  return node;
5029
5267
  }
5030
5268
  );
@@ -5035,19 +5273,35 @@ var wrapWithEffectGen = createRefactor({
5035
5273
  option
5036
5274
  );
5037
5275
  if (isNone2(maybeNode)) return yield* fail(new RefactorNotApplicableError());
5276
+ const effectModuleIdentifier = match2(
5277
+ yield* option(
5278
+ findImportedModuleIdentifier(
5279
+ sourceFile,
5280
+ (node) => pipe(
5281
+ typeParser.importedEffectModule(node),
5282
+ option,
5283
+ map4(isSome2)
5284
+ )
5285
+ )
5286
+ ),
5287
+ {
5288
+ onNone: () => "Effect",
5289
+ onSome: (node) => node.text
5290
+ }
5291
+ );
5038
5292
  return {
5039
5293
  kind: "refactor.rewrite.effect.wrapWithEffectGen",
5040
5294
  description: `Wrap with Effect.gen`,
5041
5295
  apply: pipe(
5042
5296
  gen2(function* () {
5043
5297
  const changeTracker = yield* service(ChangeTracker);
5044
- const effectGen2 = yield* pipe(
5298
+ const effectGen = yield* pipe(
5045
5299
  createEffectGenCallExpressionWithBlock(
5046
- yield* getEffectModuleIdentifierName(sourceFile),
5300
+ effectModuleIdentifier,
5047
5301
  yield* createReturnYieldStarStatement(maybeNode.value)
5048
5302
  )
5049
5303
  );
5050
- changeTracker.replaceNode(sourceFile, maybeNode.value, effectGen2);
5304
+ changeTracker.replaceNode(sourceFile, maybeNode.value, effectGen);
5051
5305
  }),
5052
5306
  provideService(TypeScriptApi, ts),
5053
5307
  provideService(TypeCheckerApi, typeChecker)
@@ -5055,26 +5309,6 @@ var wrapWithEffectGen = createRefactor({
5055
5309
  };
5056
5310
  })
5057
5311
  });
5058
- var getEffectModuleIdentifierName = fn("getEffectModuleIdentifierName")(
5059
- function* (sourceFile) {
5060
- return match2(
5061
- yield* option(
5062
- findImportedModuleIdentifier(
5063
- sourceFile,
5064
- (node) => pipe(
5065
- importedEffectModule(node),
5066
- option,
5067
- map4(isSome2)
5068
- )
5069
- )
5070
- ),
5071
- {
5072
- onNone: () => "Effect",
5073
- onSome: (node) => node.text
5074
- }
5075
- );
5076
- }
5077
- );
5078
5312
 
5079
5313
  // src/refactors/wrapWithPipe.ts
5080
5314
  var wrapWithPipe = createRefactor({
@@ -5139,6 +5373,7 @@ var init = (modules) => {
5139
5373
  function runNano(program) {
5140
5374
  return (fa) => pipe(
5141
5375
  fa,
5376
+ provideService(TypeParser, make4(modules.typescript, program.getTypeChecker())),
5142
5377
  provideService(TypeScriptProgram, program),
5143
5378
  provideService(TypeCheckerApi, program.getTypeChecker()),
5144
5379
  provideService(
@@ -5349,15 +5584,17 @@ var init = (modules) => {
5349
5584
  };
5350
5585
  proxy.getDefinitionAndBoundSpan = (fileName, position, ...args) => {
5351
5586
  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
- );
5587
+ if (languageServicePluginOptions.goto) {
5588
+ const program = languageService.getProgram();
5589
+ if (program) {
5590
+ const sourceFile = program.getSourceFile(fileName);
5591
+ if (sourceFile) {
5592
+ return pipe(
5593
+ goto(applicableDefinition, sourceFile, position),
5594
+ runNano(program),
5595
+ Either_exports.getOrElse(() => applicableDefinition)
5596
+ );
5597
+ }
5361
5598
  }
5362
5599
  }
5363
5600
  return applicableDefinition;