@effect/language-service 0.74.0 → 0.75.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -3102,6 +3102,7 @@ var externals = (graph, config = {}) => {
3102
3102
  };
3103
3103
 
3104
3104
  // src/core/Nano.ts
3105
+ var debugPerformance = false;
3105
3106
  var NanoTag = class {
3106
3107
  constructor(key) {
3107
3108
  this.key = key;
@@ -3199,7 +3200,6 @@ var NanoFiber = class {
3199
3200
  _yielded = void 0;
3200
3201
  _services = {};
3201
3202
  _cache = {};
3202
- _perf = false;
3203
3203
  _lastSpan = "";
3204
3204
  runLoop(nano) {
3205
3205
  let current = nano;
@@ -3230,7 +3230,7 @@ var WithSpanProto = {
3230
3230
  ...PrimitiveProto,
3231
3231
  [evaluate](fiber) {
3232
3232
  const [fa, name] = this[args];
3233
- if (!fiber._perf) return fa;
3233
+ if (!debugPerformance) return fa;
3234
3234
  const previousSpan = fiber._lastSpan;
3235
3235
  fiber._lastSpan = name;
3236
3236
  const start = performance.now();
@@ -3438,6 +3438,21 @@ var all = fn("all")(
3438
3438
  return results;
3439
3439
  }
3440
3440
  );
3441
+ var getTimings = () => {
3442
+ if (!debugPerformance) return [];
3443
+ const result = [];
3444
+ for (const key in timings) {
3445
+ result.push([key, timings[key] / (timingsCount[key] || 1), timingsCount[key], timings[key]]);
3446
+ }
3447
+ result.sort((a, b) => b[3] - a[3]);
3448
+ const lines = [];
3449
+ for (const [name, avg, hits, total] of result) {
3450
+ lines.push(
3451
+ `${name.padEnd(75)} tot ${total.toFixed(2).padStart(10)}ms avg ${avg.toFixed(2).padStart(10)}ms ${hits.toString().padStart(10)} hits`
3452
+ );
3453
+ }
3454
+ return lines;
3455
+ };
3441
3456
 
3442
3457
  // src/core/LanguageServicePluginOptions.ts
3443
3458
  var LanguageServicePluginOptions = Tag("PluginOptions");
@@ -4200,6 +4215,26 @@ var getApplicableRefactors = fn("LSP.getApplicableRefactors")(function* (refacto
4200
4215
  }
4201
4216
  return effectRefactors;
4202
4217
  });
4218
+ function codeFixNameToFullyQualifiedName(name) {
4219
+ return `@effect/language-service/codefixes/${name}`;
4220
+ }
4221
+ var codeFixesToApplicableRefactor = fn("LSP.codeFixesToApplicableRefactor")(function* (codeFixes, sourceFile, positionOrRange) {
4222
+ const effectRefactors = [];
4223
+ const range = typeof positionOrRange === "number" ? { pos: positionOrRange, end: positionOrRange } : positionOrRange;
4224
+ const inRangeCodeFixes = codeFixes.filter((_) => _.start <= range.pos && _.end >= range.end);
4225
+ for (const codeFix of inRangeCodeFixes) {
4226
+ effectRefactors.push({
4227
+ name: codeFixNameToFullyQualifiedName(codeFix.fixName),
4228
+ description: "Quick Fix: " + codeFix.description,
4229
+ actions: [{
4230
+ name: codeFixNameToFullyQualifiedName(codeFix.fixName),
4231
+ description: "Quick Fix: " + codeFix.description,
4232
+ kind: "refactor.rewrite.codeFixEffect." + codeFix.fixName
4233
+ }]
4234
+ });
4235
+ }
4236
+ return effectRefactors;
4237
+ });
4203
4238
  var getEditsForRefactor = fn("LSP.getEditsForRefactor")(function* (refactors2, sourceFile, positionOrRange, refactorName) {
4204
4239
  const refactor = refactors2.find((refactor2) => refactorNameToFullyQualifiedName(refactor2.name) === refactorName);
4205
4240
  if (!refactor) {
@@ -4208,6 +4243,16 @@ var getEditsForRefactor = fn("LSP.getEditsForRefactor")(function* (refactors2, s
4208
4243
  const textRange = typeof positionOrRange === "number" ? { pos: positionOrRange, end: positionOrRange } : positionOrRange;
4209
4244
  return yield* refactor.apply(sourceFile, textRange);
4210
4245
  });
4246
+ var getEditsForCodeFixes = fn("LSP.getEditsForCodeFixes")(function* (codeFixes, positionOrRange, refactorName) {
4247
+ const textRange = typeof positionOrRange === "number" ? { pos: positionOrRange, end: positionOrRange } : positionOrRange;
4248
+ const fixToRun = codeFixes.find(
4249
+ (_) => codeFixNameToFullyQualifiedName(_.fixName) === refactorName && _.start <= textRange.pos && _.end >= textRange.end
4250
+ );
4251
+ if (!fixToRun) {
4252
+ return yield* fail3(new RefactorNotApplicableError());
4253
+ }
4254
+ return fixToRun;
4255
+ });
4211
4256
  var getCompletionsAtPosition = fn("LSP.getCompletionsAtPosition")(function* (completions2, sourceFile, position, options, formatCodeSettings) {
4212
4257
  let effectCompletions = [];
4213
4258
  for (const completion of completions2) {
@@ -4291,7 +4336,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
4291
4336
  message: ts.DiagnosticCategory.Message,
4292
4337
  suggestion: ts.DiagnosticCategory.Suggestion
4293
4338
  };
4294
- const execute = (rule) => gen(function* () {
4339
+ const execute = fn("LSP.execute")(function* (rule) {
4295
4340
  const diagnostics2 = [];
4296
4341
  const codeFixes = [];
4297
4342
  const ruleNameLowered = rule.name.toLowerCase();
@@ -5138,6 +5183,9 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5138
5183
  if (signatures.length !== 1) {
5139
5184
  return typeParserIssue("Covariant type has no call signature", type);
5140
5185
  }
5186
+ if (signatures[0].typeParameters && signatures[0].typeParameters.length > 0) {
5187
+ return typeParserIssue("Invariant type should not have type parameters", type);
5188
+ }
5141
5189
  return succeed(typeChecker.getReturnTypeOfSignature(signatures[0]));
5142
5190
  }
5143
5191
  function contravariantTypeArgument(type) {
@@ -5145,6 +5193,9 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5145
5193
  if (signatures.length !== 1) {
5146
5194
  return typeParserIssue("Contravariant type has no call signature", type);
5147
5195
  }
5196
+ if (signatures[0].typeParameters && signatures[0].typeParameters.length > 0) {
5197
+ return typeParserIssue("Invariant type should not have type parameters", type);
5198
+ }
5148
5199
  return succeed(typeCheckerUtils.getTypeParameterAtPosition(signatures[0], 0));
5149
5200
  }
5150
5201
  function invariantTypeArgument(type) {
@@ -5152,6 +5203,9 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5152
5203
  if (signatures.length !== 1) {
5153
5204
  return typeParserIssue("Invariant type has no call signature", type);
5154
5205
  }
5206
+ if (signatures[0].typeParameters && signatures[0].typeParameters.length > 0) {
5207
+ return typeParserIssue("Invariant type should not have type parameters", type);
5208
+ }
5155
5209
  return succeed(typeChecker.getReturnTypeOfSignature(signatures[0]));
5156
5210
  }
5157
5211
  const pipeableType = cachedBy(
@@ -7145,25 +7199,27 @@ var generate = fn("writeTagClassAccessors.generate")(function* (sourceFile, serv
7145
7199
  return succeed(typeNode);
7146
7200
  })
7147
7201
  );
7148
- const proxySignature = (signature, atLocation2, className2) => gen(function* () {
7149
- const signatureDeclaration = typeChecker.signatureToSignatureDeclaration(
7150
- signature,
7151
- ts.SyntaxKind.FunctionType,
7152
- atLocation2,
7153
- ts.NodeBuilderFlags.NoTruncation
7154
- );
7155
- if (!signatureDeclaration) return yield* fail3("error generating signature");
7156
- const returnType = yield* generateReturnType(
7157
- typeChecker.getReturnTypeOfSignature(signature),
7158
- atLocation2,
7159
- className2
7160
- );
7161
- return ts.factory.createFunctionTypeNode(
7162
- signatureDeclaration.typeParameters,
7163
- signatureDeclaration.parameters,
7164
- returnType
7165
- );
7166
- });
7202
+ const proxySignature = fn("writeTagClassAccessors.proxySignature")(
7203
+ function* (signature, atLocation2, className2) {
7204
+ const signatureDeclaration = typeChecker.signatureToSignatureDeclaration(
7205
+ signature,
7206
+ ts.SyntaxKind.FunctionType,
7207
+ atLocation2,
7208
+ ts.NodeBuilderFlags.NoTruncation
7209
+ );
7210
+ if (!signatureDeclaration) return yield* fail3("error generating signature");
7211
+ const returnType = yield* generateReturnType(
7212
+ typeChecker.getReturnTypeOfSignature(signature),
7213
+ atLocation2,
7214
+ className2
7215
+ );
7216
+ return ts.factory.createFunctionTypeNode(
7217
+ signatureDeclaration.typeParameters,
7218
+ signatureDeclaration.parameters,
7219
+ returnType
7220
+ );
7221
+ }
7222
+ );
7167
7223
  for (const { property, propertyType } of involvedMembers) {
7168
7224
  const callSignatures = [];
7169
7225
  let propertyDeclaration = void 0;
@@ -7300,7 +7356,7 @@ var annotate = createCodegen({
7300
7356
  const tsUtils = yield* service(TypeScriptUtils);
7301
7357
  const typeChecker = yield* service(TypeCheckerApi);
7302
7358
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
7303
- const parse3 = (node) => gen(function* () {
7359
+ const parse3 = fn("annotate.parse")(function* (node) {
7304
7360
  let variableDeclarations = [];
7305
7361
  const result = [];
7306
7362
  if (ts.isVariableStatement(node)) {
@@ -7980,7 +8036,7 @@ var typeToSchema = createCodegen({
7980
8036
  new CodegenNotApplicableError("the typeToSchema codegen can be used only once per file")
7981
8037
  );
7982
8038
  }
7983
- const parse3 = (node) => gen(function* () {
8039
+ const parse3 = fn("typeToSchema.parse")(function* (node) {
7984
8040
  if (!ts.isTypeAliasDeclaration(node)) {
7985
8041
  return yield* fail3(
7986
8042
  new CodegenNotApplicableError(
@@ -8268,32 +8324,38 @@ var catchAllToMapError = createDiagnostic({
8268
8324
  return void 0;
8269
8325
  };
8270
8326
  const getEffectFailCallInfo = (body) => {
8271
- return gen(function* () {
8272
- if (ts.isCallExpression(body)) {
8273
- const isFailCall = yield* pipe(
8274
- typeParser.isNodeReferenceToEffectModuleApi("fail")(body.expression),
8275
- orUndefined
8276
- );
8277
- if (isFailCall && body.arguments.length >= 1) {
8278
- return { failCall: body, failArg: body.arguments[0] };
8279
- }
8280
- }
8281
- if (ts.isBlock(body)) {
8282
- const statements = body.statements;
8283
- if (statements.length === 1) {
8284
- const stmt = statements[0];
8285
- if (ts.isReturnStatement(stmt) && stmt.expression && ts.isCallExpression(stmt.expression)) {
8286
- const isFailCall = yield* pipe(
8287
- typeParser.isNodeReferenceToEffectModuleApi("fail")(stmt.expression.expression),
8288
- orUndefined
8289
- );
8290
- if (isFailCall && stmt.expression.arguments.length >= 1) {
8291
- return { failCall: stmt.expression, failArg: stmt.expression.arguments[0] };
8292
- }
8327
+ if (ts.isCallExpression(body)) {
8328
+ return pipe(
8329
+ typeParser.isNodeReferenceToEffectModuleApi("fail")(body.expression),
8330
+ orUndefined,
8331
+ map8((isFailCall) => {
8332
+ if (isFailCall && body.arguments.length >= 1) {
8333
+ return { failCall: body, failArg: body.arguments[0] };
8293
8334
  }
8335
+ return void 0;
8336
+ })
8337
+ );
8338
+ }
8339
+ if (ts.isBlock(body)) {
8340
+ const statements = body.statements;
8341
+ if (statements.length === 1) {
8342
+ const stmt = statements[0];
8343
+ if (ts.isReturnStatement(stmt) && stmt.expression && ts.isCallExpression(stmt.expression)) {
8344
+ const callExpr = stmt.expression;
8345
+ return pipe(
8346
+ typeParser.isNodeReferenceToEffectModuleApi("fail")(callExpr.expression),
8347
+ orUndefined,
8348
+ map8((isFailCall) => {
8349
+ if (isFailCall && callExpr.arguments.length >= 1) {
8350
+ return { failCall: callExpr, failArg: callExpr.arguments[0] };
8351
+ }
8352
+ return void 0;
8353
+ })
8354
+ );
8294
8355
  }
8295
8356
  }
8296
- });
8357
+ }
8358
+ return void_;
8297
8359
  };
8298
8360
  const flows = yield* typeParser.pipingFlows(true)(sourceFile);
8299
8361
  for (const flow2 of flows) {
@@ -8472,20 +8534,21 @@ var deterministicKeys = createDiagnostic({
8472
8534
  const typeScriptUtils = yield* service(TypeScriptUtils);
8473
8535
  const options = yield* service(LanguageServicePluginOptions);
8474
8536
  const parseExtendsCustom = cachedBy(
8475
- fn("parseExtendsCustom")(function* (classDeclaration) {
8537
+ (classDeclaration) => {
8476
8538
  if (!options.extendedKeyDetection) {
8477
- return yield* typeParserIssue("Extended key detection is disabled", void 0, classDeclaration);
8539
+ return TypeParserIssue.issue;
8478
8540
  }
8479
8541
  if (!classDeclaration.name) {
8480
- return yield* typeParserIssue("Class has no name", void 0, classDeclaration);
8542
+ return TypeParserIssue.issue;
8481
8543
  }
8482
8544
  if (!ts.isIdentifier(classDeclaration.name)) {
8483
- return yield* typeParserIssue("Class name is not an identifier", void 0, classDeclaration);
8545
+ return TypeParserIssue.issue;
8484
8546
  }
8485
8547
  const heritageClauses = classDeclaration.heritageClauses;
8486
8548
  if (!heritageClauses) {
8487
- return yield* typeParserIssue("Class has no heritage clauses", void 0, classDeclaration);
8549
+ return TypeParserIssue.issue;
8488
8550
  }
8551
+ const className = classDeclaration.name;
8489
8552
  const nodeToVisit2 = [...classDeclaration.heritageClauses];
8490
8553
  const appendNodeToVisit2 = (node) => {
8491
8554
  nodeToVisit2.push(node);
@@ -8506,7 +8569,7 @@ var deterministicKeys = createDiagnostic({
8506
8569
  const parameterSourceFile = typeScriptUtils.getSourceFileOfNode(declaration);
8507
8570
  const paramText = parameterSourceFile.text.substring(declaration.pos, declaration.end);
8508
8571
  if (paramText.toLowerCase().includes("@effect-identifier")) {
8509
- return { className: classDeclaration.name, keyStringLiteral: arg, target: "custom" };
8572
+ return succeed({ className, keyStringLiteral: arg, target: "custom" });
8510
8573
  }
8511
8574
  }
8512
8575
  }
@@ -8515,12 +8578,8 @@ var deterministicKeys = createDiagnostic({
8515
8578
  }
8516
8579
  ts.forEachChild(node, appendNodeToVisit2);
8517
8580
  }
8518
- return yield* typeParserIssue(
8519
- "Class does not extend any custom pattern",
8520
- void 0,
8521
- classDeclaration
8522
- );
8523
- }),
8581
+ return TypeParserIssue.issue;
8582
+ },
8524
8583
  "deterministicKeys.parseExtendsCustom",
8525
8584
  (classDeclaration) => classDeclaration
8526
8585
  );
@@ -8799,7 +8858,7 @@ var effectFnOpportunity = createDiagnostic({
8799
8858
  }
8800
8859
  return false;
8801
8860
  };
8802
- const tryExtractWithSpanExpression = (expr) => gen(function* () {
8861
+ const tryExtractWithSpanExpression = fn("effectFnOpportunity.tryExtractWithSpanExpression")(function* (expr) {
8803
8862
  if (!ts.isCallExpression(expr)) return void 0;
8804
8863
  const callee = expr.expression;
8805
8864
  const isWithSpan = yield* pipe(
@@ -8811,7 +8870,9 @@ var effectFnOpportunity = createDiagnostic({
8811
8870
  if (expr.arguments.length === 0) return void 0;
8812
8871
  return expr.arguments[0];
8813
8872
  });
8814
- const tryParseGenOpportunity = (fnNode) => gen(function* () {
8873
+ const tryParseGenOpportunity = fn(
8874
+ "effectFnOpportunity.tryParseGenOpportunity"
8875
+ )(function* (fnNode) {
8815
8876
  const bodyExpression = getBodyExpression(fnNode);
8816
8877
  if (!bodyExpression) return yield* TypeParserIssue.issue;
8817
8878
  const { pipeArguments: pipeArguments2, subject } = yield* pipe(
@@ -8847,62 +8908,67 @@ var effectFnOpportunity = createDiagnostic({
8847
8908
  orElse2(() => succeed(false))
8848
8909
  );
8849
8910
  };
8850
- const parseEffectFnOpportunityTarget = (node) => gen(function* () {
8911
+ const parseEffectFnOpportunityTargetGen = fn("effectFnOpportunity.parseEffectFnOpportunityTarget")(
8912
+ function* (node, returnType, traceName, nameIdentifier) {
8913
+ if (yield* isInsideEffectFn(node)) {
8914
+ return yield* TypeParserIssue.issue;
8915
+ }
8916
+ const unionMembers = typeCheckerUtils.unrollUnionMembers(returnType);
8917
+ yield* all(...unionMembers.map((member) => typeParser.strictEffectType(member, node)));
8918
+ const opportunity = yield* pipe(
8919
+ tryParseGenOpportunity(node),
8920
+ orElse2(() => {
8921
+ if (ts.isArrowFunction(node) && !ts.isBlock(node.body)) {
8922
+ return TypeParserIssue.issue;
8923
+ }
8924
+ const body = ts.isArrowFunction(node) ? node.body : node.body;
8925
+ if (!body || !ts.isBlock(body) || body.statements.length <= 5) {
8926
+ return TypeParserIssue.issue;
8927
+ }
8928
+ return succeed({
8929
+ effectModuleName: sourceEffectModuleName,
8930
+ pipeArguments: [],
8931
+ generatorFunction: void 0,
8932
+ explicitTraceExpression: void 0
8933
+ });
8934
+ })
8935
+ );
8936
+ return {
8937
+ node,
8938
+ nameIdentifier,
8939
+ effectModuleName: opportunity.effectModuleName,
8940
+ inferredTraceName: traceName,
8941
+ explicitTraceExpression: opportunity.explicitTraceExpression,
8942
+ pipeArguments: opportunity.pipeArguments,
8943
+ generatorFunction: opportunity.generatorFunction,
8944
+ hasParamsInPipeArgs: areParametersReferencedIn(node, opportunity.pipeArguments)
8945
+ };
8946
+ }
8947
+ );
8948
+ const parseEffectFnOpportunityTarget = (node) => {
8851
8949
  if (!ts.isFunctionExpression(node) && !ts.isArrowFunction(node) && !ts.isFunctionDeclaration(node)) {
8852
- return yield* TypeParserIssue.issue;
8950
+ return TypeParserIssue.issue;
8853
8951
  }
8854
8952
  if ((ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node)) && node.asteriskToken) {
8855
- return yield* TypeParserIssue.issue;
8953
+ return TypeParserIssue.issue;
8856
8954
  }
8857
8955
  if (ts.isFunctionExpression(node) && node.name) {
8858
- return yield* TypeParserIssue.issue;
8956
+ return TypeParserIssue.issue;
8859
8957
  }
8860
8958
  if (node.type) {
8861
- return yield* TypeParserIssue.issue;
8862
- }
8863
- if (yield* isInsideEffectFn(node)) {
8864
- return yield* TypeParserIssue.issue;
8959
+ return TypeParserIssue.issue;
8865
8960
  }
8866
8961
  const functionType = typeChecker.getTypeAtLocation(node);
8867
- if (!functionType) return yield* TypeParserIssue.issue;
8962
+ if (!functionType) return TypeParserIssue.issue;
8868
8963
  const callSignatures = typeChecker.getSignaturesOfType(functionType, ts.SignatureKind.Call);
8869
- if (callSignatures.length !== 1) return yield* TypeParserIssue.issue;
8964
+ if (callSignatures.length !== 1) return TypeParserIssue.issue;
8870
8965
  const signature = callSignatures[0];
8871
8966
  const returnType = typeChecker.getReturnTypeOfSignature(signature);
8872
- const unionMembers = typeCheckerUtils.unrollUnionMembers(returnType);
8873
- yield* all(...unionMembers.map((member) => typeParser.strictEffectType(member, node)));
8874
8967
  const nameIdentifier = getNameIdentifier(node);
8875
8968
  const traceName = nameIdentifier ? ts.isIdentifier(nameIdentifier) ? ts.idText(nameIdentifier) : nameIdentifier.text : void 0;
8876
- if (!traceName) return yield* TypeParserIssue.issue;
8877
- const opportunity = yield* pipe(
8878
- tryParseGenOpportunity(node),
8879
- orElse2(() => {
8880
- if (ts.isArrowFunction(node) && !ts.isBlock(node.body)) {
8881
- return TypeParserIssue.issue;
8882
- }
8883
- const body = ts.isArrowFunction(node) ? node.body : node.body;
8884
- if (!body || !ts.isBlock(body) || body.statements.length <= 5) {
8885
- return TypeParserIssue.issue;
8886
- }
8887
- return succeed({
8888
- effectModuleName: sourceEffectModuleName,
8889
- pipeArguments: [],
8890
- generatorFunction: void 0,
8891
- explicitTraceExpression: void 0
8892
- });
8893
- })
8894
- );
8895
- return {
8896
- node,
8897
- nameIdentifier,
8898
- effectModuleName: opportunity.effectModuleName,
8899
- inferredTraceName: traceName,
8900
- explicitTraceExpression: opportunity.explicitTraceExpression,
8901
- pipeArguments: opportunity.pipeArguments,
8902
- generatorFunction: opportunity.generatorFunction,
8903
- hasParamsInPipeArgs: areParametersReferencedIn(node, opportunity.pipeArguments)
8904
- };
8905
- });
8969
+ if (!traceName) return TypeParserIssue.issue;
8970
+ return parseEffectFnOpportunityTargetGen(node, returnType, traceName, nameIdentifier);
8971
+ };
8906
8972
  const getFunctionBodyBlock = (node) => {
8907
8973
  if (ts.isArrowFunction(node)) {
8908
8974
  if (ts.isBlock(node.body)) {
@@ -9143,7 +9209,7 @@ var effectInVoidSuccess = createDiagnostic({
9143
9209
  );
9144
9210
  return { voidedEffect };
9145
9211
  }
9146
- return yield* fail3(typeParserIssue("expectedEffect success is not void"));
9212
+ return yield* TypeParserIssue.issue;
9147
9213
  });
9148
9214
  const entries2 = typeCheckerUtils.expectedAndRealType(sourceFile);
9149
9215
  for (const [node, expectedType, valueNode, realType] of entries2) {
@@ -11000,73 +11066,99 @@ var preferSchemaOverJson = createDiagnostic({
11000
11066
  apply: fn("preferSchemaOverJson.apply")(function* (sourceFile, report) {
11001
11067
  const ts = yield* service(TypeScriptApi);
11002
11068
  const typeParser = yield* service(TypeParser);
11003
- const parseJsonMethod = (node) => gen(function* () {
11004
- if (!ts.isCallExpression(node)) return yield* fail3("node is not a call expression");
11005
- const expression = node.expression;
11006
- if (!ts.isPropertyAccessExpression(expression)) return yield* fail3("expression is not a property access");
11007
- const objectExpr = expression.expression;
11008
- const methodName = ts.idText(expression.name);
11009
- if (!ts.isIdentifier(objectExpr) || ts.idText(objectExpr) !== "JSON") {
11010
- return yield* fail3("object is not JSON");
11069
+ const isJsonCall = (node) => ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.expression) && ts.idText(node.expression.expression) === "JSON" && (ts.idText(node.expression.name) === "parse" || ts.idText(node.expression.name) === "stringify");
11070
+ const findEnclosingEffectTry = (jsonCall) => {
11071
+ const parent = jsonCall.parent;
11072
+ let lazy;
11073
+ if (ts.isArrowFunction(parent) && parent.body === jsonCall && parent.parameters.length === 0 && (!parent.typeParameters || parent.typeParameters.length === 0)) {
11074
+ lazy = parent;
11075
+ }
11076
+ if (!lazy && ts.isReturnStatement(parent) && parent.expression === jsonCall) {
11077
+ const block = parent.parent;
11078
+ if (ts.isBlock(block) && block.statements.length === 1) {
11079
+ const fn2 = block.parent;
11080
+ if ((ts.isArrowFunction(fn2) || ts.isFunctionExpression(fn2)) && fn2.parameters.length === 0 && (!fn2.typeParameters || fn2.typeParameters.length === 0)) {
11081
+ lazy = fn2;
11082
+ }
11083
+ }
11011
11084
  }
11012
- if (methodName !== "parse" && methodName !== "stringify") {
11013
- return yield* fail3("method is not parse or stringify");
11085
+ if (!lazy) return void 0;
11086
+ const lazyParent = lazy.parent;
11087
+ if (ts.isCallExpression(lazyParent) && lazyParent.arguments.length > 0 && lazyParent.arguments[0] === lazy) {
11088
+ return lazyParent;
11089
+ }
11090
+ if (ts.isPropertyAssignment(lazyParent) && ts.isIdentifier(lazyParent.name) && ts.idText(lazyParent.name) === "try") {
11091
+ const objLiteral = lazyParent.parent;
11092
+ if (ts.isObjectLiteralExpression(objLiteral)) {
11093
+ const callExpr = objLiteral.parent;
11094
+ if (ts.isCallExpression(callExpr) && callExpr.arguments.length > 0 && callExpr.arguments[0] === objLiteral) {
11095
+ return callExpr;
11096
+ }
11097
+ }
11014
11098
  }
11015
- return { node, methodName };
11016
- });
11017
- const effectTrySimple = (node) => gen(function* () {
11018
- if (!ts.isCallExpression(node)) return yield* fail3("node is not a call expression");
11099
+ return void 0;
11100
+ };
11101
+ const jsonCalls = [];
11102
+ const collectJsonCalls = (node) => {
11103
+ if (isJsonCall(node)) {
11104
+ jsonCalls.push(node);
11105
+ }
11106
+ ts.forEachChild(node, collectJsonCalls);
11107
+ };
11108
+ ts.forEachChild(sourceFile, collectJsonCalls);
11109
+ if (jsonCalls.length === 0) return;
11110
+ const effectTrySimple = fn("preferSchemaOverJson.effectTrySimple")(function* (node) {
11019
11111
  yield* typeParser.isNodeReferenceToEffectModuleApi("try")(node.expression);
11020
- if (node.arguments.length === 0) return yield* fail3("Effect.try has no arguments");
11112
+ if (node.arguments.length === 0) return yield* TypeParserIssue.issue;
11021
11113
  const lazyFn = yield* typeParser.lazyExpression(node.arguments[0]);
11022
- const jsonMethod = yield* parseJsonMethod(lazyFn.expression);
11023
- return { node: jsonMethod.node, methodName: jsonMethod.methodName };
11114
+ if (!isJsonCall(lazyFn.expression)) return yield* TypeParserIssue.issue;
11115
+ return lazyFn.expression;
11024
11116
  });
11025
- const effectTryObject = (node) => gen(function* () {
11026
- if (!ts.isCallExpression(node)) return yield* fail3("node is not a call expression");
11117
+ const effectTryObject = fn("preferSchemaOverJson.effectTryObject")(function* (node) {
11027
11118
  yield* typeParser.isNodeReferenceToEffectModuleApi("try")(node.expression);
11028
- if (node.arguments.length === 0) return yield* fail3("Effect.try has no arguments");
11119
+ if (node.arguments.length === 0) return yield* TypeParserIssue.issue;
11029
11120
  const arg = node.arguments[0];
11030
- if (!ts.isObjectLiteralExpression(arg)) return yield* fail3("argument is not an object literal");
11121
+ if (!ts.isObjectLiteralExpression(arg)) return yield* TypeParserIssue.issue;
11031
11122
  const tryProp = arg.properties.find(
11032
11123
  (p) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && ts.idText(p.name) === "try"
11033
11124
  );
11034
- if (!tryProp) return yield* fail3("object has no 'try' property");
11125
+ if (!tryProp) return yield* TypeParserIssue.issue;
11035
11126
  const lazyFn = yield* typeParser.lazyExpression(tryProp.initializer);
11036
- const jsonMethod = yield* parseJsonMethod(lazyFn.expression);
11037
- return { node: jsonMethod.node, methodName: jsonMethod.methodName };
11127
+ if (!isJsonCall(lazyFn.expression)) return yield* TypeParserIssue.issue;
11128
+ return lazyFn.expression;
11038
11129
  });
11039
- const jsonMethodInEffectGen = (node) => gen(function* () {
11040
- const jsonMethod = yield* parseJsonMethod(node);
11041
- const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(node);
11042
- if (!effectGen || effectGen.body.statements.length === 0) {
11043
- return yield* fail3("not inside an Effect generator");
11130
+ const jsonMethodInEffectGen = fn("preferSchemaOverJson.jsonMethodInEffectGen")(
11131
+ function* (jsonCall) {
11132
+ const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(jsonCall);
11133
+ if (!effectGen || effectGen.body.statements.length === 0) {
11134
+ return yield* TypeParserIssue.issue;
11135
+ }
11136
+ if (scopeNode && scopeNode !== effectGen.generatorFunction) {
11137
+ return yield* TypeParserIssue.issue;
11138
+ }
11139
+ return jsonCall;
11044
11140
  }
11045
- if (scopeNode && scopeNode !== effectGen.generatorFunction) {
11046
- return yield* fail3("inside a nested function scope");
11141
+ );
11142
+ for (const jsonCall of jsonCalls) {
11143
+ const effectTryCall = findEnclosingEffectTry(jsonCall);
11144
+ let match3;
11145
+ if (effectTryCall) {
11146
+ match3 = yield* pipe(
11147
+ firstSuccessOf([
11148
+ effectTrySimple(effectTryCall),
11149
+ effectTryObject(effectTryCall)
11150
+ ]),
11151
+ option
11152
+ );
11153
+ } else {
11154
+ match3 = yield* pipe(
11155
+ jsonMethodInEffectGen(jsonCall),
11156
+ option
11157
+ );
11047
11158
  }
11048
- return { node: jsonMethod.node, methodName: jsonMethod.methodName };
11049
- });
11050
- const nodeToVisit = [];
11051
- const appendNodeToVisit = (node) => {
11052
- nodeToVisit.push(node);
11053
- return void 0;
11054
- };
11055
- ts.forEachChild(sourceFile, appendNodeToVisit);
11056
- while (nodeToVisit.length > 0) {
11057
- const node = nodeToVisit.shift();
11058
- ts.forEachChild(node, appendNodeToVisit);
11059
- const match3 = yield* pipe(
11060
- firstSuccessOf([
11061
- effectTrySimple(node),
11062
- effectTryObject(node),
11063
- jsonMethodInEffectGen(node)
11064
- ]),
11065
- option
11066
- );
11067
11159
  if (isSome2(match3)) {
11068
11160
  report({
11069
- location: match3.value.node,
11161
+ location: match3.value,
11070
11162
  messageText: "Consider using Effect Schema for JSON operations instead of JSON.parse/JSON.stringify",
11071
11163
  fixes: []
11072
11164
  });
@@ -11710,19 +11802,24 @@ var strictEffectProvide = createDiagnostic({
11710
11802
  const ts = yield* service(TypeScriptApi);
11711
11803
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
11712
11804
  const typeParser = yield* service(TypeParser);
11713
- const parseEffectProvideWithLayer = (node) => gen(function* () {
11805
+ const parseEffectProvideWithLayerGen = fn("strictEffectProvide.parseEffectProvideWithLayer")(
11806
+ function* (node) {
11807
+ yield* typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression);
11808
+ return yield* firstSuccessOf(
11809
+ node.arguments.map((arg) => {
11810
+ const argType = typeCheckerUtils.getTypeAtLocation(arg);
11811
+ if (!argType) return typeParserIssue("Could not get argument type");
11812
+ return typeParser.layerType(argType, arg);
11813
+ })
11814
+ );
11815
+ }
11816
+ );
11817
+ const parseEffectProvideWithLayer = (node) => {
11714
11818
  if (!ts.isCallExpression(node) || node.arguments.length === 0) {
11715
- return yield* typeParserIssue("Not an Effect.provide call");
11716
- }
11717
- yield* typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression);
11718
- return yield* firstSuccessOf(
11719
- node.arguments.map((arg) => {
11720
- const argType = typeCheckerUtils.getTypeAtLocation(arg);
11721
- if (!argType) return typeParserIssue("Could not get argument type");
11722
- return typeParser.layerType(argType, arg);
11723
- })
11724
- );
11725
- });
11819
+ return TypeParserIssue.issue;
11820
+ }
11821
+ return parseEffectProvideWithLayerGen(node);
11822
+ };
11726
11823
  const nodeToVisit = [];
11727
11824
  const appendNodeToVisit = (node) => {
11728
11825
  nodeToVisit.push(node);
@@ -12306,23 +12403,38 @@ var effectSchemaSelfInClasses = createCompletion({
12306
12403
  });
12307
12404
  }
12308
12405
  }
12309
- if (typeParser.supportedEffect() === "v3") {
12310
- const hasTaggedClassCompletion = isFullyQualified || isSome2(
12406
+ if (typeParser.supportedEffect() === "v4") {
12407
+ const hasTaggedErrorCompletion = isFullyQualified || isSome2(
12311
12408
  yield* pipe(
12312
- typeParser.isNodeReferenceToEffectSchemaModuleApi("TaggedClass")(accessedObject),
12409
+ typeParser.isNodeReferenceToEffectSchemaModuleApi("TaggedErrorClass")(accessedObject),
12313
12410
  option
12314
12411
  )
12315
12412
  );
12316
- if (hasTaggedClassCompletion) {
12413
+ if (hasTaggedErrorCompletion) {
12317
12414
  completions2.push({
12318
- name: `TaggedClass<${name}>`,
12415
+ name: `TaggedError<${name}>`,
12319
12416
  kind: ts.ScriptElementKind.constElement,
12320
- insertText: isFullyQualified ? `${schemaIdentifier}.TaggedClass<${name}>()("${name}", {${"${0}"}}){}` : `TaggedClass<${name}>()("${name}", {${"${0}"}}){}`,
12417
+ insertText: isFullyQualified ? `${schemaIdentifier}.TaggedErrorClass<${name}>()("${errorTagKey}", {${"${0}"}}){}` : `TaggedErrorClass<${name}>()("${errorTagKey}", {${"${0}"}}){}`,
12321
12418
  replacementSpan,
12322
12419
  isSnippet: true
12323
12420
  });
12324
12421
  }
12325
12422
  }
12423
+ const hasTaggedClassCompletion = isFullyQualified || isSome2(
12424
+ yield* pipe(
12425
+ typeParser.isNodeReferenceToEffectSchemaModuleApi("TaggedClass")(accessedObject),
12426
+ option
12427
+ )
12428
+ );
12429
+ if (hasTaggedClassCompletion) {
12430
+ completions2.push({
12431
+ name: `TaggedClass<${name}>`,
12432
+ kind: ts.ScriptElementKind.constElement,
12433
+ insertText: isFullyQualified ? `${schemaIdentifier}.TaggedClass<${name}>()("${name}", {${"${0}"}}){}` : `TaggedClass<${name}>()("${name}", {${"${0}"}}){}`,
12434
+ replacementSpan,
12435
+ isSnippet: true
12436
+ });
12437
+ }
12326
12438
  if (typeParser.supportedEffect() === "v3") {
12327
12439
  const hasTaggedRequestCompletion = isFullyQualified || isSome2(
12328
12440
  yield* pipe(
@@ -12351,24 +12463,7 @@ var effectSchemaSelfInClasses = createCompletion({
12351
12463
  completions2.push({
12352
12464
  name: `ErrorClass<${name}>`,
12353
12465
  kind: ts.ScriptElementKind.constElement,
12354
- insertText: isFullyQualified ? `${schemaIdentifier}.ErrorClass<${name}>()({${"${0}"}}){}` : `ErrorClass<${name}>()({${"${0}"}}){}`,
12355
- replacementSpan,
12356
- isSnippet: true
12357
- });
12358
- }
12359
- }
12360
- if (typeParser.supportedEffect() === "v4") {
12361
- const hasRequestClassCompletion = isFullyQualified || isSome2(
12362
- yield* pipe(
12363
- typeParser.isNodeReferenceToEffectSchemaModuleApi("RequestClass")(accessedObject),
12364
- option
12365
- )
12366
- );
12367
- if (hasRequestClassCompletion) {
12368
- completions2.push({
12369
- name: `RequestClass<${name}>`,
12370
- kind: ts.ScriptElementKind.constElement,
12371
- insertText: isFullyQualified ? `${schemaIdentifier}.RequestClass<${name}>("${name}")({${"${0}"}}){}` : `RequestClass<${name}>("${name}")({${"${0}"}}){}`,
12466
+ insertText: isFullyQualified ? `${schemaIdentifier}.ErrorClass<${name}>("${name}")({${"${0}"}}){}` : `ErrorClass<${name}>()({${"${0}"}}){}`,
12372
12467
  replacementSpan,
12373
12468
  isSnippet: true
12374
12469
  });
@@ -12623,8 +12718,55 @@ var schemaBrand = createCompletion({
12623
12718
  })
12624
12719
  });
12625
12720
 
12721
+ // src/completions/serviceMapSelfInClasses.ts
12722
+ var serviceMapSelfInClasses = createCompletion({
12723
+ name: "serviceMapSelfInClasses",
12724
+ apply: fn("serviceMapSelfInClasses")(function* (sourceFile, position) {
12725
+ const ts = yield* service(TypeScriptApi);
12726
+ const tsUtils = yield* service(TypeScriptUtils);
12727
+ const typeParser = yield* service(TypeParser);
12728
+ if (typeParser.supportedEffect() === "v3") return [];
12729
+ const maybeInfos = tsUtils.parseDataForExtendsClassCompletion(sourceFile, position);
12730
+ if (!maybeInfos) return [];
12731
+ const { accessedObject, className, replacementSpan } = maybeInfos;
12732
+ const serviceMapIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
12733
+ sourceFile,
12734
+ "effect",
12735
+ "ServiceMap"
12736
+ ) || "ServiceMap";
12737
+ const isFullyQualified = serviceMapIdentifier === ts.idText(accessedObject);
12738
+ const name = ts.idText(className);
12739
+ const tagKey = (yield* createString(sourceFile, name, "service")) || name;
12740
+ const completions2 = [];
12741
+ const hasServiceCompletion = isFullyQualified || isSome2(
12742
+ yield* pipe(
12743
+ typeParser.isNodeReferenceToServiceMapModuleApi("Service")(accessedObject),
12744
+ option
12745
+ )
12746
+ );
12747
+ if (hasServiceCompletion) {
12748
+ completions2.push({
12749
+ name: `Service<${name}, {}>`,
12750
+ kind: ts.ScriptElementKind.constElement,
12751
+ insertText: isFullyQualified ? `${serviceMapIdentifier}.Service<${name}, {${"${0}"}}>()("${tagKey}"){}` : `Service<${name}, {${"${0}"}}>()("${tagKey}"){}`,
12752
+ replacementSpan,
12753
+ isSnippet: true
12754
+ });
12755
+ completions2.push({
12756
+ name: `Service<${name}>({ make })`,
12757
+ kind: ts.ScriptElementKind.constElement,
12758
+ insertText: isFullyQualified ? `${serviceMapIdentifier}.Service<${name}>()("${tagKey}", { make: ${"${0}"} }){}` : `Service<${name}>()("${tagKey}", { make: ${"${0}"} }){}`,
12759
+ replacementSpan,
12760
+ isSnippet: true
12761
+ });
12762
+ }
12763
+ return completions2;
12764
+ })
12765
+ });
12766
+
12626
12767
  // src/completions.ts
12627
12768
  var completions = [
12769
+ serviceMapSelfInClasses,
12628
12770
  effectSqlModelSelfInClasses,
12629
12771
  effectSchemaSelfInClasses,
12630
12772
  effectSelfInClasses,
@@ -13192,36 +13334,38 @@ var middlewareAutoImportQuickfixes = fn("middlewareAutoImportQuickfixes")(functi
13192
13334
  const program = yield* service(TypeScriptProgram);
13193
13335
  const autoImportProvider = yield* getOrMakeAutoImportProvider(sourceFile);
13194
13336
  const changedCodeFixes = [];
13195
- const createImportAllChanges = (imports) => gen(function* () {
13196
- const newImports = [];
13197
- for (const importToAdd of imports) {
13198
- if (!importToAdd.exportName) return;
13199
- const fileName = ts.resolveModuleName(
13200
- importToAdd.moduleName,
13201
- sourceFile.fileName,
13202
- program.getCompilerOptions(),
13203
- program
13337
+ const createImportAllChanges = fn("middlewareAutoImportQuickfixes.createImportAllChanges")(
13338
+ function* (imports) {
13339
+ const newImports = [];
13340
+ for (const importToAdd of imports) {
13341
+ if (!importToAdd.exportName) return;
13342
+ const fileName = ts.resolveModuleName(
13343
+ importToAdd.moduleName,
13344
+ sourceFile.fileName,
13345
+ program.getCompilerOptions(),
13346
+ program
13347
+ );
13348
+ if (!fileName.resolvedModule) return;
13349
+ const importKind = autoImportProvider.resolve(fileName.resolvedModule.resolvedFileName, importToAdd.exportName);
13350
+ if (!importKind) return;
13351
+ if (importKind.introducedPrefix) return;
13352
+ newImports.push(importKind);
13353
+ }
13354
+ const formatContext = ts.formatting.getFormatContext(
13355
+ formatOptions,
13356
+ languageServiceHost
13357
+ );
13358
+ const edits = ts.textChanges.ChangeTracker.with(
13359
+ {
13360
+ formatContext,
13361
+ host: languageServiceHost,
13362
+ preferences: preferences || {}
13363
+ },
13364
+ (changeTracker) => newImports.forEach((_) => addImport(ts, sourceFile, changeTracker, preferences, _))
13204
13365
  );
13205
- if (!fileName.resolvedModule) return;
13206
- const importKind = autoImportProvider.resolve(fileName.resolvedModule.resolvedFileName, importToAdd.exportName);
13207
- if (!importKind) return;
13208
- if (importKind.introducedPrefix) return;
13209
- newImports.push(importKind);
13366
+ return edits;
13210
13367
  }
13211
- const formatContext = ts.formatting.getFormatContext(
13212
- formatOptions,
13213
- languageServiceHost
13214
- );
13215
- const edits = ts.textChanges.ChangeTracker.with(
13216
- {
13217
- formatContext,
13218
- host: languageServiceHost,
13219
- preferences: preferences || {}
13220
- },
13221
- (changeTracker) => newImports.forEach((_) => addImport(ts, sourceFile, changeTracker, preferences, _))
13222
- );
13223
- return edits;
13224
- });
13368
+ );
13225
13369
  for (const codeFix of codeFixes) {
13226
13370
  const textFileChanges = codeFix.changes;
13227
13371
  if (textFileChanges.length !== 1) {
@@ -18848,6 +18992,30 @@ var asyncAwaitToGenTryPromise = createRefactor({
18848
18992
  })
18849
18993
  });
18850
18994
 
18995
+ // src/refactors/debugPerformance.ts
18996
+ var debugPerformance2 = createRefactor({
18997
+ name: "debugPerformance",
18998
+ description: "Debug: LSP Performance",
18999
+ apply: fn("debugPerformance.apply")(function* (sourceFile) {
19000
+ const ts = yield* service(TypeScriptApi);
19001
+ return {
19002
+ kind: "refactor.rewrite.effect.debugPerformance",
19003
+ description: "Debug: LSP Performance",
19004
+ apply: pipe(
19005
+ gen(function* () {
19006
+ const changeTracker = yield* service(ChangeTracker);
19007
+ changeTracker.insertText(
19008
+ sourceFile,
19009
+ 0,
19010
+ "/** \n" + getTimings().join("\n") + "\n */"
19011
+ );
19012
+ }),
19013
+ provideService(TypeScriptApi, ts)
19014
+ )
19015
+ };
19016
+ })
19017
+ });
19018
+
18851
19019
  // src/refactors/effectGenToFn.ts
18852
19020
  var effectGenToFn = createRefactor({
18853
19021
  name: "effectGenToFn",
@@ -19720,7 +19888,7 @@ var togglePipeStyle = createRefactor({
19720
19888
  const typeChecker = yield* service(TypeCheckerApi);
19721
19889
  const typeParser = yield* service(TypeParser);
19722
19890
  const tsUtils = yield* service(TypeScriptUtils);
19723
- const togglePipeStyle2 = (node) => gen(function* () {
19891
+ const togglePipeStyleForNode = fn("togglePipeStyle.togglePipeStyleForNode")(function* (node) {
19724
19892
  const pipeCall = yield* typeParser.pipeCall(node);
19725
19893
  switch (pipeCall.kind) {
19726
19894
  case "pipe": {
@@ -19766,7 +19934,7 @@ var togglePipeStyle = createRefactor({
19766
19934
  });
19767
19935
  const ancestorNodes = tsUtils.getAncestorNodesInRange(sourceFile, textRange);
19768
19936
  return yield* pipe(
19769
- firstSuccessOf(ancestorNodes.map(togglePipeStyle2)),
19937
+ firstSuccessOf(ancestorNodes.map(togglePipeStyleForNode)),
19770
19938
  orElse2(() => fail3(new RefactorNotApplicableError()))
19771
19939
  );
19772
19940
  })
@@ -20038,7 +20206,7 @@ var createUnsupportedNodeComment = (ts, sourceFile, node) => ts.addSyntheticTrai
20038
20206
  ts.SyntaxKind.MultiLineCommentTrivia,
20039
20207
  " Not supported conversion: " + node.getText(sourceFile) + " "
20040
20208
  );
20041
- var processNode = (node, isVirtualTypeNode) => gen(function* () {
20209
+ var processNode = fn("SchemaGen.processNode")(function* (node, isVirtualTypeNode) {
20042
20210
  const { createApiCall, createApiPropertyAccess, entityNameToDataTypeName, sourceFile, supportedEffect, ts } = yield* service(
20043
20211
  SchemaGenContext
20044
20212
  );
@@ -20531,10 +20699,10 @@ var refactors = [
20531
20699
  effectGenToFn,
20532
20700
  togglePipeStyle,
20533
20701
  writeTagClassAccessors
20534
- ];
20702
+ ].concat(debugPerformance ? [debugPerformance2] : []);
20535
20703
 
20536
20704
  // src/renames/keyStrings.ts
20537
- var renameKeyStrings = (sourceFile, position, _findInStrings, _findInComments, _preferences, renameLocations) => gen(function* () {
20705
+ var renameKeyStrings = fn("renameKeyStrings")(function* (sourceFile, position, _findInStrings, _findInComments, _preferences, renameLocations) {
20538
20706
  const ts = yield* service(TypeScriptApi);
20539
20707
  const tsUtils = yield* service(TypeScriptUtils);
20540
20708
  const typeParser = yield* service(TypeParser);
@@ -20732,10 +20900,23 @@ var init = (modules) => {
20732
20900
  if (program) {
20733
20901
  const sourceFile = program.getSourceFile(fileName);
20734
20902
  if (sourceFile) {
20903
+ if (!effectCodeFixesForFile.has(fileName)) {
20904
+ runDiagnosticsAndCacheCodeFixes(fileName);
20905
+ }
20735
20906
  return pipe(
20736
20907
  getApplicableRefactors(refactors, sourceFile, positionOrRange),
20908
+ flatMap4(
20909
+ (effectRefactors) => map8(
20910
+ codeFixesToApplicableRefactor(
20911
+ effectCodeFixesForFile.get(fileName) || [],
20912
+ sourceFile,
20913
+ positionOrRange
20914
+ ),
20915
+ (effectCodefixes) => effectCodefixes.concat(effectRefactors)
20916
+ )
20917
+ ),
20737
20918
  runNano(program),
20738
- map((effectRefactors) => applicableRefactors.concat(effectRefactors)),
20919
+ map((effectCodeActions) => applicableRefactors.concat(effectCodeActions)),
20739
20920
  getOrElse(() => applicableRefactors)
20740
20921
  );
20741
20922
  }
@@ -20749,11 +20930,16 @@ var init = (modules) => {
20749
20930
  if (sourceFile) {
20750
20931
  const result = pipe(
20751
20932
  gen(function* () {
20752
- const applicableRefactor = yield* getEditsForRefactor(
20753
- refactors,
20754
- sourceFile,
20755
- positionOrRange,
20756
- refactorName
20933
+ const applicableRefactor = yield* pipe(
20934
+ getEditsForRefactor(
20935
+ refactors,
20936
+ sourceFile,
20937
+ positionOrRange,
20938
+ refactorName
20939
+ ),
20940
+ orElse2(
20941
+ () => getEditsForCodeFixes(effectCodeFixesForFile.get(fileName) || [], positionOrRange, refactorName)
20942
+ )
20757
20943
  );
20758
20944
  const formatContext = modules.typescript.formatting.getFormatContext(
20759
20945
  formatOptions,