@effect/language-service 0.8.0 → 0.9.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.
Files changed (3) hide show
  1. package/index.js +1238 -851
  2. package/index.js.map +1 -1
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -954,6 +954,18 @@ var sort = /* @__PURE__ */ dual(2, (self, O) => {
954
954
  });
955
955
  var empty = () => [];
956
956
  var map2 = /* @__PURE__ */ dual(2, (self, f) => self.map(f));
957
+ var filterMap = /* @__PURE__ */ dual(2, (self, f) => {
958
+ const as = fromIterable(self);
959
+ const out = [];
960
+ for (let i = 0; i < as.length; i++) {
961
+ const o = f(as[i], i);
962
+ if (isSome2(o)) {
963
+ out.push(o.value);
964
+ }
965
+ }
966
+ return out;
967
+ });
968
+ var getSomes = /* @__PURE__ */ filterMap(identity);
957
969
  var filter = /* @__PURE__ */ dual(2, (self, predicate) => {
958
970
  const as = fromIterable(self);
959
971
  const out = [];
@@ -2659,8 +2671,6 @@ var TaggedError = (tag) => {
2659
2671
  };
2660
2672
 
2661
2673
  // src/core/Nano.ts
2662
- var NanoInterruptedException = class extends TaggedError("NanoInterruptedException") {
2663
- };
2664
2674
  var NanoDefectException = class extends TaggedError("NanoDefectException") {
2665
2675
  };
2666
2676
  var NanoTag = class {
@@ -2691,40 +2701,44 @@ var Nano = class {
2691
2701
  return new SingleShotGen(new YieldWrap(this));
2692
2702
  }
2693
2703
  };
2694
- var run = (fa) => pipe(
2695
- try_({
2696
- try: () => fa.run(contextEmpty),
2697
- catch: (error) => new NanoDefectException({ value: error })
2698
- }),
2699
- flatMap((_) => _),
2700
- flatMap((_) => _)
2701
- );
2702
- var succeed = (value) => new Nano(() => right2(right2(value)));
2703
- var fail3 = (value) => new Nano(() => right2(left2(value)));
2704
- var sync = (value) => new Nano(() => right2(right2(value())));
2704
+ var run = (fa) => {
2705
+ try {
2706
+ const result = fa.run(contextEmpty);
2707
+ switch (result._tag) {
2708
+ case "Left":
2709
+ return left2(result.left);
2710
+ case "Defect":
2711
+ return left2(new NanoDefectException({ message: result.defect }));
2712
+ case "Right":
2713
+ return right2(result.right);
2714
+ }
2715
+ } catch (e) {
2716
+ return left2(new NanoDefectException({ message: e }));
2717
+ }
2718
+ };
2719
+ var succeed = (value) => new Nano(() => ({ _tag: "Right", right: value }));
2720
+ var fail3 = (value) => new Nano(() => ({ _tag: "Left", left: value }));
2721
+ var sync = (value) => new Nano(() => ({ _tag: "Right", right: value() }));
2705
2722
  var flatMap4 = dual(2, (fa, f) => new Nano((ctx) => {
2706
2723
  const result = fa.run(ctx);
2707
- if (isLeft2(result)) return result;
2708
- if (isLeft2(result.right)) return result;
2709
- return f(result.right.right).run(ctx);
2724
+ if (result._tag !== "Right") return result;
2725
+ return f(result.right).run(ctx);
2710
2726
  }));
2711
2727
  var map7 = dual(2, (fa, f) => new Nano((ctx) => {
2712
2728
  const result = fa.run(ctx);
2713
- if (isLeft2(result)) return result;
2714
- if (isLeft2(result.right)) return result;
2715
- return right2(right2(f(result.right.right)));
2729
+ if (result._tag !== "Right") return result;
2730
+ return { _tag: "Right", right: f(result.right) };
2716
2731
  }));
2717
2732
  var orElse3 = (f) => (fa) => new Nano((ctx) => {
2718
2733
  const result = fa.run(ctx);
2719
- if (isLeft2(result)) return result;
2720
- if (isLeft2(result.right)) return f().run(ctx);
2734
+ if (result._tag === "Left") return f().run(ctx);
2721
2735
  return result;
2722
2736
  });
2723
2737
  var firstSuccessOf = (arr) => reduce(arr.slice(1), arr[0], (arr2, fa) => orElse3(() => fa)(arr2));
2724
2738
  var service = (tag) => new Nano(
2725
2739
  (ctx) => contextGet(ctx, tag).pipe(match2({
2726
- onNone: () => left2(new NanoDefectException({ value: `Cannot find service ${tag.key}` })),
2727
- onSome: (value) => right2(right2(value))
2740
+ onNone: () => ({ _tag: "Defect", defect: `Cannot find service ${tag.key}` }),
2741
+ onSome: (value) => ({ _tag: "Right", right: value })
2728
2742
  }))
2729
2743
  );
2730
2744
  var provideService = (tag, value) => (fa) => new Nano((ctx) => {
@@ -2736,25 +2750,36 @@ var gen2 = (...args) => new Nano((ctx) => {
2736
2750
  while (!state.done) {
2737
2751
  const current = isGenKind(state.value) ? state.value.value : yieldWrapGet(state.value);
2738
2752
  const result = current.run(ctx);
2739
- if (isLeft2(result)) {
2753
+ if (result._tag !== "Right") {
2740
2754
  return result;
2741
2755
  }
2742
- const inner = result.right;
2743
- if (isLeft2(inner)) {
2756
+ state = iterator.next(result.right);
2757
+ }
2758
+ return { _tag: "Right", right: state.value };
2759
+ });
2760
+ var fn = (_) => (body) => (...args) => new Nano((ctx) => {
2761
+ const iterator = body(...args);
2762
+ let state = iterator.next();
2763
+ while (!state.done) {
2764
+ const current = isGenKind(state.value) ? state.value.value : yieldWrapGet(state.value);
2765
+ const result = current.run(ctx);
2766
+ if (result._tag !== "Right") {
2744
2767
  return result;
2745
2768
  }
2746
- state = iterator.next(inner.right);
2769
+ state = iterator.next(result.right);
2747
2770
  }
2748
- return right2(right2(state.value));
2771
+ return { _tag: "Right", right: state.value };
2749
2772
  });
2750
2773
  var option = (fa) => new Nano((ctx) => {
2751
- return match(fa.run(ctx), {
2752
- onLeft: (cause) => left2(cause),
2753
- onRight: match({
2754
- onLeft: () => right2(right2(none2())),
2755
- onRight: (value) => right2(right2(some2(value)))
2756
- })
2757
- });
2774
+ const result = fa.run(ctx);
2775
+ switch (result._tag) {
2776
+ case "Right":
2777
+ return { _tag: "Right", right: some2(result.right) };
2778
+ case "Left":
2779
+ return { _tag: "Right", right: none2() };
2780
+ case "Defect":
2781
+ return result;
2782
+ }
2758
2783
  });
2759
2784
 
2760
2785
  // src/core/LSP.ts
@@ -2766,214 +2791,684 @@ function createRefactor(definition) {
2766
2791
  function createDiagnostic(definition) {
2767
2792
  return definition;
2768
2793
  }
2794
+ function createCompletion(definition) {
2795
+ return definition;
2796
+ }
2769
2797
  var PluginOptions = Tag("PluginOptions");
2770
2798
  var SourceFileNotFoundError = class extends TaggedError("SourceFileNotFoundError") {
2771
2799
  };
2772
- function getSemanticDiagnostics(diagnostics2, sourceFile) {
2773
- return gen2(function* () {
2774
- const effectDiagnostics = [];
2775
- for (const diagnostic of diagnostics2) {
2776
- const result = yield* option(diagnostic.apply(sourceFile));
2777
- if (isSome2(result)) {
2778
- effectDiagnostics.push(...result.value.map((_) => ({
2779
- file: sourceFile,
2780
- start: _.node.getStart(sourceFile),
2781
- length: _.node.getEnd() - _.node.getStart(sourceFile),
2782
- messageText: _.messageText,
2783
- category: _.category,
2784
- code: diagnostic.code,
2785
- source: "effect"
2786
- })));
2787
- }
2800
+ var getSemanticDiagnostics = fn("LSP.getSemanticDiagnostics")(function* (diagnostics2, sourceFile) {
2801
+ const effectDiagnostics = [];
2802
+ for (const diagnostic of diagnostics2) {
2803
+ const result = yield* option(diagnostic.apply(sourceFile));
2804
+ if (isSome2(result)) {
2805
+ effectDiagnostics.push(...result.value.map((_) => ({
2806
+ file: sourceFile,
2807
+ start: _.node.getStart(sourceFile),
2808
+ length: _.node.getEnd() - _.node.getStart(sourceFile),
2809
+ messageText: _.messageText,
2810
+ category: _.category,
2811
+ code: diagnostic.code,
2812
+ source: "effect"
2813
+ })));
2814
+ }
2815
+ }
2816
+ return effectDiagnostics;
2817
+ });
2818
+ var getCodeFixesAtPosition = fn("LSP.getCodeFixesAtPosition")(function* (diagnostics2, sourceFile, start, end, errorCodes) {
2819
+ const runnableDiagnostics = diagnostics2.filter((_) => errorCodes.indexOf(_.code) > -1);
2820
+ const applicableFixes = [];
2821
+ for (const diagnostic of runnableDiagnostics) {
2822
+ const result = yield* option(diagnostic.apply(sourceFile));
2823
+ if (isSome2(result)) {
2824
+ applicableFixes.push(
2825
+ ...pipe(
2826
+ result.value,
2827
+ filter(
2828
+ (_) => _.node.getStart(sourceFile) === start && _.node.getEnd() === end
2829
+ ),
2830
+ map2((_) => _.fix),
2831
+ getSomes
2832
+ )
2833
+ );
2788
2834
  }
2789
- return effectDiagnostics;
2790
- });
2791
- }
2792
- function getApplicableRefactors(refactors2, sourceFile, positionOrRange) {
2793
- return gen2(function* () {
2794
- const textRange = typeof positionOrRange === "number" ? { pos: positionOrRange, end: positionOrRange } : positionOrRange;
2795
- const effectRefactors = [];
2796
- for (const refactor of refactors2) {
2797
- const result = yield* option(refactor.apply(sourceFile, textRange));
2798
- if (isSome2(result)) {
2799
- effectRefactors.push({
2835
+ }
2836
+ return applicableFixes;
2837
+ });
2838
+ var getApplicableRefactors = fn("LSP.getApplicableRefactors")(function* (refactors2, sourceFile, positionOrRange) {
2839
+ const textRange = typeof positionOrRange === "number" ? { pos: positionOrRange, end: positionOrRange } : positionOrRange;
2840
+ const effectRefactors = [];
2841
+ for (const refactor of refactors2) {
2842
+ const result = yield* option(refactor.apply(sourceFile, textRange));
2843
+ if (isSome2(result)) {
2844
+ effectRefactors.push({
2845
+ name: refactor.name,
2846
+ description: refactor.description,
2847
+ actions: [{
2800
2848
  name: refactor.name,
2801
- description: refactor.description,
2802
- actions: [{
2803
- name: refactor.name,
2804
- description: result.value.description,
2805
- kind: result.value.kind
2806
- }]
2807
- });
2808
- }
2809
- }
2810
- return effectRefactors;
2811
- });
2812
- }
2813
- function getEditsForRefactor(refactors2, sourceFile, positionOrRange, refactorName) {
2814
- return gen2(function* () {
2815
- const refactor = refactors2.find((refactor2) => refactor2.name === refactorName);
2816
- if (!refactor) {
2817
- return yield* fail3(new RefactorNotApplicableError());
2849
+ description: result.value.description,
2850
+ kind: result.value.kind
2851
+ }]
2852
+ });
2818
2853
  }
2819
- const textRange = typeof positionOrRange === "number" ? { pos: positionOrRange, end: positionOrRange } : positionOrRange;
2820
- return yield* refactor.apply(sourceFile, textRange);
2821
- });
2822
- }
2854
+ }
2855
+ return effectRefactors;
2856
+ });
2857
+ var getEditsForRefactor = fn("LSP.getEditsForRefactor")(function* (refactors2, sourceFile, positionOrRange, refactorName) {
2858
+ const refactor = refactors2.find((refactor2) => refactor2.name === refactorName);
2859
+ if (!refactor) {
2860
+ return yield* fail3(new RefactorNotApplicableError());
2861
+ }
2862
+ const textRange = typeof positionOrRange === "number" ? { pos: positionOrRange, end: positionOrRange } : positionOrRange;
2863
+ return yield* refactor.apply(sourceFile, textRange);
2864
+ });
2865
+ var getCompletionsAtPosition = fn("LSP.getCompletionsAtPosition")(function* (completions2, sourceFile, position, options, formatCodeSettings) {
2866
+ const effectCompletions = [];
2867
+ for (const completion of completions2) {
2868
+ const result = yield* completion.apply(sourceFile, position, options, formatCodeSettings);
2869
+ effectCompletions.push(
2870
+ ...result.map((_) => ({ sortText: "11", ..._ }))
2871
+ );
2872
+ }
2873
+ return effectCompletions;
2874
+ });
2823
2875
 
2824
2876
  // src/utils/TypeScriptApi.ts
2825
2877
  var TypeScriptApi = Tag("TypeScriptApi");
2826
2878
  var ChangeTracker = Tag("ChangeTracker");
2827
2879
 
2828
- // src/utils/TypeCheckerApi.ts
2829
- var TypeCheckerApi = Tag("TypeChecker");
2830
- var deterministicTypeOrder = gen2(function* () {
2831
- const typeChecker = yield* service(TypeCheckerApi);
2832
- return make2((a, b) => {
2833
- const aName = typeChecker.typeToString(a);
2834
- const bName = typeChecker.typeToString(b);
2835
- if (aName < bName) return -1;
2836
- if (aName > bName) return 1;
2837
- return 0;
2838
- });
2839
- });
2840
- function getMissingTypeEntriesInTargetType(realType, expectedType) {
2841
- return gen2(function* () {
2842
- const typeChecker = yield* service(TypeCheckerApi);
2843
- const result = [];
2844
- const toTest = [realType];
2845
- while (toTest.length > 0) {
2846
- const type = toTest.pop();
2847
- if (!type) return result;
2848
- if (type.isUnion()) {
2849
- toTest.push(...type.types);
2850
- } else {
2851
- const assignable = typeChecker.isTypeAssignableTo(type, expectedType);
2852
- if (!assignable) {
2853
- result.push(type);
2854
- }
2880
+ // src/utils/AST.ts
2881
+ function collectSelfAndAncestorNodesInRange(node, textRange) {
2882
+ return sync(() => {
2883
+ let result = empty();
2884
+ let parent = node;
2885
+ while (parent) {
2886
+ if (parent.end >= textRange.end) {
2887
+ result = pipe(result, append(parent));
2855
2888
  }
2889
+ parent = parent.parent;
2856
2890
  }
2857
2891
  return result;
2858
2892
  });
2859
2893
  }
2860
- var CannotFindAncestorConvertibleDeclarationError = class extends TaggedError("CannotFindAncestorConvertibleDeclarationError") {
2894
+ var getAncestorNodesInRange = fn("AST.getAncestorNodesInRange")(function* (sourceFile, textRange) {
2895
+ const ts = yield* service(TypeScriptApi);
2896
+ const precedingToken = ts.findPrecedingToken(textRange.pos, sourceFile);
2897
+ if (!precedingToken) return empty();
2898
+ return yield* collectSelfAndAncestorNodesInRange(precedingToken, textRange);
2899
+ });
2900
+ var NodeNotFoundError = class extends TaggedError("@effect/language-service/NodeNotFoundError") {
2861
2901
  };
2862
- function getAncestorConvertibleDeclaration(node) {
2863
- return gen2(function* () {
2864
- const ts = yield* service(TypeScriptApi);
2865
- let current = node;
2866
- while (current) {
2867
- if (ts.isFunctionDeclaration(current) || ts.isFunctionExpression(current) || ts.isArrowFunction(current) || ts.isMethodDeclaration(current)) {
2868
- return current;
2869
- }
2870
- current = current.parent;
2902
+ var findNodeAtPosition = fn("AST.findNodeAtPosition")(function* (sourceFile, position) {
2903
+ const ts = yield* service(TypeScriptApi);
2904
+ function find(node) {
2905
+ if (position >= node.getStart() && position < node.getEnd()) {
2906
+ return ts.forEachChild(node, find) || node;
2871
2907
  }
2872
- return yield* fail3(new CannotFindAncestorConvertibleDeclarationError({ node }));
2873
- });
2908
+ return void 0;
2909
+ }
2910
+ const result = find(sourceFile);
2911
+ if (!result) return yield* fail3(new NodeNotFoundError());
2912
+ return result;
2913
+ });
2914
+ var collectDescendantsAndAncestorsInRange = fn(
2915
+ "AST.collectDescendantsAndAncestorsInRange"
2916
+ )(function* (sourceFile, textRange) {
2917
+ const nodeAtPosition = yield* option(findNodeAtPosition(sourceFile, textRange.pos));
2918
+ if (isNone2(nodeAtPosition)) return empty();
2919
+ return yield* collectSelfAndAncestorNodesInRange(nodeAtPosition.value, textRange);
2920
+ });
2921
+ function toTextRange(positionOrRange) {
2922
+ return typeof positionOrRange === "number" ? { end: positionOrRange, pos: positionOrRange } : positionOrRange;
2874
2923
  }
2875
- var CannotInferReturnTypeFromEmptyBody = class extends TaggedError("CannotInferReturnTypeFromEmptyBody") {
2876
- };
2877
- var CannotInferReturnType = class extends TaggedError("CannotInferReturnType") {
2878
- };
2879
- function getInferredReturnType(declaration) {
2880
- return gen2(function* () {
2881
- const typeChecker = yield* service(TypeCheckerApi);
2882
- if (!declaration.body) {
2883
- return yield* fail3(
2884
- new CannotInferReturnTypeFromEmptyBody({ declaration })
2885
- );
2886
- }
2887
- let returnType;
2888
- if (typeChecker.isImplementationOfOverload(declaration)) {
2889
- const signatures = typeChecker.getTypeAtLocation(declaration).getCallSignatures();
2890
- if (signatures.length > 1) {
2891
- returnType = typeChecker.getUnionType(
2892
- signatures.map((s) => s.getReturnType()).filter((_) => !!_)
2924
+ function isNodeInRange(textRange) {
2925
+ return (node) => node.pos <= textRange.pos && node.end >= textRange.end;
2926
+ }
2927
+ var transformAsyncAwaitToEffectGen = fn("AST.transformAsyncAwaitToEffectGen")(
2928
+ function* (node, effectModuleName, onAwait) {
2929
+ const ts = yield* service(TypeScriptApi);
2930
+ function visitor(_) {
2931
+ if (ts.isAwaitExpression(_)) {
2932
+ const expression = ts.visitEachChild(_.expression, visitor, ts.nullTransformationContext);
2933
+ return ts.factory.createYieldExpression(
2934
+ ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
2935
+ onAwait(expression)
2893
2936
  );
2894
2937
  }
2938
+ return ts.visitEachChild(_, visitor, ts.nullTransformationContext);
2895
2939
  }
2896
- if (!returnType) {
2897
- const signature = typeChecker.getSignatureFromDeclaration(declaration);
2898
- if (signature) {
2899
- const typePredicate = typeChecker.getTypePredicateOfSignature(signature);
2900
- if (typePredicate && typePredicate.type) {
2901
- return typePredicate.type;
2902
- } else {
2903
- returnType = typeChecker.getReturnTypeOfSignature(signature);
2904
- }
2905
- }
2906
- }
2907
- if (!returnType) {
2908
- return yield* fail3(
2909
- new CannotInferReturnType({ declaration })
2940
+ const generatorBody = visitor(node.body);
2941
+ const generator = ts.factory.createFunctionExpression(
2942
+ void 0,
2943
+ ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
2944
+ void 0,
2945
+ [],
2946
+ [],
2947
+ void 0,
2948
+ generatorBody
2949
+ // NOTE(mattia): intended, to use same routine for both ConciseBody and Body
2950
+ );
2951
+ const effectGenCallExp = ts.factory.createCallExpression(
2952
+ ts.factory.createPropertyAccessExpression(
2953
+ ts.factory.createIdentifier(effectModuleName),
2954
+ "gen"
2955
+ ),
2956
+ void 0,
2957
+ [generator]
2958
+ );
2959
+ let currentFlags = ts.getCombinedModifierFlags(node);
2960
+ currentFlags &= ~ts.ModifierFlags.Async;
2961
+ const newModifiers = ts.factory.createModifiersFromModifierFlags(currentFlags);
2962
+ if (ts.isArrowFunction(node)) {
2963
+ return ts.factory.createArrowFunction(
2964
+ newModifiers,
2965
+ node.typeParameters,
2966
+ node.parameters,
2967
+ void 0,
2968
+ node.equalsGreaterThanToken,
2969
+ effectGenCallExp
2910
2970
  );
2911
2971
  }
2912
- return returnType;
2913
- });
2914
- }
2915
- function expectedAndRealType(node) {
2916
- return gen2(function* () {
2917
- const typeChecker = yield* service(TypeCheckerApi);
2918
- const ts = yield* service(TypeScriptApi);
2919
- if (ts.isVariableDeclaration(node) && node.initializer) {
2920
- const expectedType = typeChecker.getTypeAtLocation(node.name);
2921
- const realType = typeChecker.getTypeAtLocation(node.initializer);
2922
- return [[node.name, expectedType, node.initializer, realType]];
2972
+ const newBody = ts.factory.createBlock([
2973
+ ts.factory.createReturnStatement(effectGenCallExp)
2974
+ ]);
2975
+ if (ts.isFunctionDeclaration(node)) {
2976
+ return ts.factory.createFunctionDeclaration(
2977
+ newModifiers,
2978
+ node.asteriskToken,
2979
+ node.name,
2980
+ node.typeParameters,
2981
+ node.parameters,
2982
+ void 0,
2983
+ newBody
2984
+ );
2923
2985
  }
2924
- if (ts.isCallExpression(node)) {
2925
- const resolvedSignature = typeChecker.getResolvedSignature(node);
2926
- if (resolvedSignature) {
2927
- return resolvedSignature.getParameters().map((parameter, index) => {
2928
- const expectedType = typeChecker.getTypeOfSymbolAtLocation(parameter, node);
2929
- const realType = typeChecker.getTypeAtLocation(node.arguments[index]);
2930
- return [node.arguments[index], expectedType, node.arguments[index], realType];
2931
- });
2932
- }
2986
+ return ts.factory.createFunctionExpression(
2987
+ newModifiers,
2988
+ node.asteriskToken,
2989
+ node.name,
2990
+ node.typeParameters,
2991
+ node.parameters,
2992
+ void 0,
2993
+ newBody
2994
+ );
2995
+ }
2996
+ );
2997
+ var addReturnTypeAnnotation = fn("AST.addReturnTypeAnnotation")(function* (sourceFile, declaration, typeNode) {
2998
+ const ts = yield* service(TypeScriptApi);
2999
+ const changes = yield* service(ChangeTracker);
3000
+ const closeParen = ts.findChildOfKind(declaration, ts.SyntaxKind.CloseParenToken, sourceFile);
3001
+ const needParens = ts.isArrowFunction(declaration) && closeParen === void 0;
3002
+ const endNode = needParens ? declaration.parameters[0] : closeParen;
3003
+ if (endNode) {
3004
+ if (needParens) {
3005
+ changes.insertNodeBefore(
3006
+ sourceFile,
3007
+ endNode,
3008
+ ts.factory.createToken(ts.SyntaxKind.OpenParenToken)
3009
+ );
3010
+ changes.insertNodeAfter(
3011
+ sourceFile,
3012
+ endNode,
3013
+ ts.factory.createToken(ts.SyntaxKind.CloseParenToken)
3014
+ );
2933
3015
  }
2934
- if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
2935
- const parent = node.parent;
2936
- if (ts.isObjectLiteralElement(parent)) {
2937
- if (ts.isObjectLiteralExpression(parent.parent) && parent.name === node) {
2938
- const type = typeChecker.getContextualType(parent.parent);
2939
- if (type) {
2940
- const symbol3 = typeChecker.getPropertyOfType(type, node.text);
2941
- if (symbol3) {
2942
- const expectedType = typeChecker.getTypeOfSymbolAtLocation(symbol3, node);
2943
- const realType = typeChecker.getTypeAtLocation(node);
2944
- return [[node, expectedType, node, realType]];
2945
- }
3016
+ changes.insertNodeAt(sourceFile, endNode.end, typeNode, { prefix: ": " });
3017
+ }
3018
+ });
3019
+ var removeReturnTypeAnnotation = fn("AST.removeReturnTypeAnnotation")(function* (sourceFile, declaration) {
3020
+ const ts = yield* service(TypeScriptApi);
3021
+ const changes = yield* service(ChangeTracker);
3022
+ const closeParen = ts.findChildOfKind(declaration, ts.SyntaxKind.CloseParenToken, sourceFile);
3023
+ const needParens = ts.isArrowFunction(declaration) && closeParen === void 0;
3024
+ const endNode = needParens ? declaration.parameters[0] : closeParen;
3025
+ if (endNode && declaration.type) {
3026
+ changes.deleteRange(sourceFile, { pos: endNode.end, end: declaration.type.end });
3027
+ }
3028
+ });
3029
+ var ImportModuleIdentifierNotFoundError = class extends TaggedError("@effect/language-service/ImportModuleIdentifierNotFoundError") {
3030
+ };
3031
+ var findImportedModuleIdentifier = fn("AST.findImportedModuleIdentifier")(
3032
+ function* (sourceFile, test) {
3033
+ const ts = yield* service(TypeScriptApi);
3034
+ for (const statement of sourceFile.statements) {
3035
+ if (!ts.isImportDeclaration(statement)) continue;
3036
+ const importClause = statement.importClause;
3037
+ if (!importClause) continue;
3038
+ const namedBindings = importClause.namedBindings;
3039
+ if (!namedBindings) continue;
3040
+ if (ts.isNamespaceImport(namedBindings)) {
3041
+ if (yield* test(namedBindings.name, statement.moduleSpecifier, none2())) {
3042
+ return namedBindings.name;
3043
+ }
3044
+ } else if (ts.isNamedImports(namedBindings)) {
3045
+ for (const importSpecifier of namedBindings.elements) {
3046
+ const importProperty = fromNullable2(importSpecifier.propertyName).pipe(
3047
+ orElse2(() => some2(importSpecifier.name))
3048
+ );
3049
+ if (yield* test(importSpecifier.name, statement.moduleSpecifier, importProperty)) {
3050
+ return importSpecifier.name;
2946
3051
  }
2947
3052
  }
2948
3053
  }
2949
3054
  }
2950
- if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
2951
- const expectedType = typeChecker.getTypeAtLocation(node.left);
2952
- const realType = typeChecker.getTypeAtLocation(node.right);
2953
- return [[node.left, expectedType, node.right, realType]];
3055
+ return yield* fail3(new ImportModuleIdentifierNotFoundError());
3056
+ }
3057
+ );
3058
+ function findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, packageName, moduleName) {
3059
+ return findImportedModuleIdentifier(
3060
+ sourceFile,
3061
+ fn(
3062
+ "AST.findImportedModuleIdentifierByPackageAndNameOrBarrel.findImportedModuleIdentifier"
3063
+ )(function* (_, fromModule, importProperty) {
3064
+ const ts = yield* service(TypeScriptApi);
3065
+ if (isNone2(importProperty) && ts.isStringLiteral(fromModule) && fromModule.text === packageName + "/" + moduleName) {
3066
+ return true;
3067
+ }
3068
+ if (isSome2(importProperty) && ts.isIdentifier(importProperty.value) && importProperty.value.text === moduleName && ts.isStringLiteral(fromModule) && fromModule.text === packageName) {
3069
+ return true;
3070
+ }
3071
+ return false;
3072
+ })
3073
+ );
3074
+ }
3075
+ var simplifyTypeNode = fn("AST.simplifyTypeNode")(function* (typeNode) {
3076
+ const ts = yield* service(TypeScriptApi);
3077
+ function collectCallable(typeNode2) {
3078
+ if (ts.isParenthesizedTypeNode(typeNode2)) return collectCallable(typeNode2.type);
3079
+ if (ts.isFunctionTypeNode(typeNode2)) {
3080
+ return some2([
3081
+ ts.factory.createCallSignature(typeNode2.typeParameters, typeNode2.parameters, typeNode2.type)
3082
+ ]);
2954
3083
  }
2955
- if (ts.isReturnStatement(node) && node.expression) {
2956
- const parentDeclaration = yield* option(getAncestorConvertibleDeclaration(node));
2957
- if (isSome2(parentDeclaration)) {
2958
- const expectedType = yield* option(getInferredReturnType(parentDeclaration.value));
2959
- const realType = typeChecker.getTypeAtLocation(node.expression);
2960
- if (isSome2(expectedType)) return [[node, expectedType.value, node, realType]];
3084
+ if (ts.isTypeLiteralNode(typeNode2)) {
3085
+ const allCallSignatures = typeNode2.members.every(ts.isCallSignatureDeclaration);
3086
+ if (allCallSignatures) {
3087
+ return some2(typeNode2.members);
2961
3088
  }
2962
3089
  }
2963
- if (ts.isArrowFunction(node) && ts.isExpression(node.body)) {
2964
- const body = node.body;
2965
- const expectedType = typeChecker.getContextualType(body);
2966
- const realType = typeChecker.getTypeAtLocation(body);
2967
- if (expectedType) return [[body, expectedType, body, realType]];
3090
+ if (ts.isIntersectionTypeNode(typeNode2)) {
3091
+ const members = typeNode2.types.map((node) => collectCallable(node));
3092
+ if (members.every(isSome2)) {
3093
+ return some2(members.map((_) => isSome2(_) ? _.value : []).flat());
3094
+ }
2968
3095
  }
2969
- if (ts.isSatisfiesExpression(node)) {
3096
+ return none2();
3097
+ }
3098
+ const callSignatures = collectCallable(typeNode);
3099
+ if (isSome2(callSignatures) && callSignatures.value.length > 1) {
3100
+ return ts.factory.createTypeLiteralNode(callSignatures.value);
3101
+ }
3102
+ return typeNode;
3103
+ });
3104
+ var tryPreserveDeclarationSemantics = fn("AST.tryPreserveDeclarationSemantics")(
3105
+ function* (nodeToReplace, node) {
3106
+ const ts = yield* service(TypeScriptApi);
3107
+ if (!ts.isExpression(node)) return node;
3108
+ if (ts.isFunctionDeclaration(nodeToReplace)) {
3109
+ if (!nodeToReplace.name) return node;
3110
+ return ts.factory.createVariableStatement(
3111
+ nodeToReplace.modifiers,
3112
+ ts.factory.createVariableDeclarationList(
3113
+ [ts.factory.createVariableDeclaration(
3114
+ nodeToReplace.name,
3115
+ void 0,
3116
+ void 0,
3117
+ node
3118
+ )],
3119
+ ts.NodeFlags.Const
3120
+ )
3121
+ );
3122
+ } else if (ts.isMethodDeclaration(nodeToReplace)) {
3123
+ return ts.factory.createPropertyDeclaration(
3124
+ nodeToReplace.modifiers,
3125
+ nodeToReplace.name,
3126
+ void 0,
3127
+ void 0,
3128
+ node
3129
+ );
3130
+ }
3131
+ return node;
3132
+ }
3133
+ );
3134
+ var parseDataForExtendsClassCompletion = fn(
3135
+ "AST.parseDataForExtendsClassCompletion"
3136
+ )(function* (sourceFile, position) {
3137
+ const ts = yield* service(TypeScriptApi);
3138
+ const precedingToken = ts.findPrecedingToken(position, sourceFile, void 0, true);
3139
+ if (!precedingToken) return none2();
3140
+ let accessedObject = precedingToken;
3141
+ let replacementSpan = ts.createTextSpan(position, 0);
3142
+ let outerNode = precedingToken;
3143
+ if (ts.isIdentifier(precedingToken) && precedingToken.parent && ts.isPropertyAccessExpression(precedingToken.parent)) {
3144
+ replacementSpan = ts.createTextSpan(
3145
+ precedingToken.parent.getStart(sourceFile),
3146
+ precedingToken.end - precedingToken.parent.getStart(sourceFile)
3147
+ );
3148
+ accessedObject = precedingToken.parent.expression;
3149
+ outerNode = precedingToken.parent;
3150
+ } else if (ts.isToken(precedingToken) && precedingToken.kind === ts.SyntaxKind.DotToken && ts.isPropertyAccessExpression(precedingToken.parent)) {
3151
+ replacementSpan = ts.createTextSpan(
3152
+ precedingToken.parent.getStart(sourceFile),
3153
+ precedingToken.end - precedingToken.parent.getStart(sourceFile)
3154
+ );
3155
+ accessedObject = precedingToken.parent.expression;
3156
+ outerNode = precedingToken.parent;
3157
+ } else if (ts.isIdentifier(precedingToken) && precedingToken.parent) {
3158
+ replacementSpan = ts.createTextSpan(
3159
+ precedingToken.getStart(sourceFile),
3160
+ precedingToken.end - precedingToken.getStart(sourceFile)
3161
+ );
3162
+ accessedObject = precedingToken;
3163
+ outerNode = precedingToken;
3164
+ } else {
3165
+ return none2();
3166
+ }
3167
+ if (!ts.isIdentifier(accessedObject)) return none2();
3168
+ let classDeclaration = outerNode.parent;
3169
+ while (ts.isExpressionWithTypeArguments(classDeclaration) || ts.isHeritageClause(classDeclaration)) {
3170
+ if (!classDeclaration.parent) break;
3171
+ classDeclaration = classDeclaration.parent;
3172
+ }
3173
+ if (!ts.isClassDeclaration(classDeclaration)) return none2();
3174
+ if (!classDeclaration.name) return none2();
3175
+ return some2(
3176
+ { accessedObject, classDeclaration, className: classDeclaration.name, replacementSpan }
3177
+ );
3178
+ });
3179
+
3180
+ // src/completions/contextSelfInClasses.ts
3181
+ var contextSelfInClasses = createCompletion({
3182
+ name: "effect/contextSelfInClasses",
3183
+ apply: fn("contextSelfInClasses")(function* (sourceFile, position) {
3184
+ const ts = yield* service(TypeScriptApi);
3185
+ const maybeInfos = yield* parseDataForExtendsClassCompletion(sourceFile, position);
3186
+ if (isNone2(maybeInfos)) return [];
3187
+ const { accessedObject, className, replacementSpan } = maybeInfos.value;
3188
+ const contextName = yield* option(
3189
+ findImportedModuleIdentifierByPackageAndNameOrBarrel(
3190
+ sourceFile,
3191
+ "effect",
3192
+ "Context"
3193
+ )
3194
+ );
3195
+ const contextIdentifier = match2(contextName, {
3196
+ onNone: () => "Context",
3197
+ onSome: (_) => _.text
3198
+ });
3199
+ if (contextIdentifier !== accessedObject.text) return [];
3200
+ const name = className.text;
3201
+ return [{
3202
+ name: `Tag("${name}")`,
3203
+ kind: ts.ScriptElementKind.constElement,
3204
+ insertText: `${contextIdentifier}.Tag("${name}")<${name}, ${"${0}"}>(){}`,
3205
+ replacementSpan,
3206
+ isSnippet: true
3207
+ }];
3208
+ })
3209
+ });
3210
+
3211
+ // src/completions/effectSchemaSelfInClasses.ts
3212
+ var effectSchemaSelfInClasses = createCompletion({
3213
+ name: "effect/effectSchemaSelfInClasses",
3214
+ apply: fn("effectSchemaSelfInClasses")(function* (sourceFile, position) {
3215
+ const ts = yield* service(TypeScriptApi);
3216
+ const maybeInfos = yield* parseDataForExtendsClassCompletion(sourceFile, position);
3217
+ if (isNone2(maybeInfos)) return [];
3218
+ const { accessedObject, className, replacementSpan } = maybeInfos.value;
3219
+ const effectSchemaName = yield* option(
3220
+ findImportedModuleIdentifierByPackageAndNameOrBarrel(
3221
+ sourceFile,
3222
+ "effect",
3223
+ "Schema"
3224
+ )
3225
+ );
3226
+ const schemaIdentifier = match2(effectSchemaName, {
3227
+ onNone: () => "Schema",
3228
+ onSome: (_) => _.text
3229
+ });
3230
+ if (schemaIdentifier !== accessedObject.text) return [];
3231
+ const name = className.text;
3232
+ return [{
3233
+ name: `Class<${name}>`,
3234
+ kind: ts.ScriptElementKind.constElement,
3235
+ insertText: `${schemaIdentifier}.Class<${name}>("${name}")({${"${0}"}}){}`,
3236
+ replacementSpan,
3237
+ isSnippet: true
3238
+ }, {
3239
+ name: `TaggedError<${name}>`,
3240
+ kind: ts.ScriptElementKind.constElement,
3241
+ insertText: `${schemaIdentifier}.TaggedError<${name}>("${name}")("${name}", {${"${0}"}}){}`,
3242
+ replacementSpan,
3243
+ isSnippet: true
3244
+ }, {
3245
+ name: `TaggedClass<${name}>`,
3246
+ kind: ts.ScriptElementKind.constElement,
3247
+ insertText: `${schemaIdentifier}.TaggedClass<${name}>("${name}")("${name}", {${"${0}"}}){}`,
3248
+ replacementSpan,
3249
+ isSnippet: true
3250
+ }, {
3251
+ name: `TaggedRequest<${name}>`,
3252
+ kind: ts.ScriptElementKind.constElement,
3253
+ insertText: `${schemaIdentifier}.TaggedRequest<${name}>("${name}")("${name}", {${"${0}"}}){}`,
3254
+ replacementSpan,
3255
+ isSnippet: true
3256
+ }];
3257
+ })
3258
+ });
3259
+
3260
+ // src/completions/effectSelfInClasses.ts
3261
+ var effectSelfInClasses = createCompletion({
3262
+ name: "effect/effectSelfInClasses",
3263
+ apply: fn("effectSelfInClasses")(function* (sourceFile, position) {
3264
+ const ts = yield* service(TypeScriptApi);
3265
+ const maybeInfos = yield* parseDataForExtendsClassCompletion(sourceFile, position);
3266
+ if (isNone2(maybeInfos)) return [];
3267
+ const { accessedObject, className, replacementSpan } = maybeInfos.value;
3268
+ const effectName = yield* option(
3269
+ findImportedModuleIdentifierByPackageAndNameOrBarrel(
3270
+ sourceFile,
3271
+ "effect",
3272
+ "Effect"
3273
+ )
3274
+ );
3275
+ const effectIdentifier = match2(effectName, {
3276
+ onNone: () => "Effect",
3277
+ onSome: (_) => _.text
3278
+ });
3279
+ if (effectIdentifier !== accessedObject.text) return [];
3280
+ const name = className.text;
3281
+ return [{
3282
+ name: `Service<${name}>`,
3283
+ kind: ts.ScriptElementKind.constElement,
3284
+ insertText: `${effectIdentifier}.Service<${name}>()("${name}", {${"${0}"}}){}`,
3285
+ replacementSpan,
3286
+ isSnippet: true
3287
+ }];
3288
+ })
3289
+ });
3290
+
3291
+ // src/completions.ts
3292
+ var completions = [effectSchemaSelfInClasses, effectSelfInClasses, contextSelfInClasses];
3293
+
3294
+ // src/utils/TypeCheckerApi.ts
3295
+ var TypeCheckerApi = Tag("TypeChecker");
3296
+ var TypeCheckerApiCache = Tag("TypeCheckerApiCache");
3297
+ function makeTypeCheckerApiCache() {
3298
+ return {
3299
+ expectedAndRealType: /* @__PURE__ */ new WeakMap()
3300
+ };
3301
+ }
3302
+ var deterministicTypeOrder = gen2(function* () {
3303
+ const typeChecker = yield* service(TypeCheckerApi);
3304
+ return make2((a, b) => {
3305
+ const aName = typeChecker.typeToString(a);
3306
+ const bName = typeChecker.typeToString(b);
3307
+ if (aName < bName) return -1;
3308
+ if (aName > bName) return 1;
3309
+ return 0;
3310
+ });
3311
+ });
3312
+ var getMissingTypeEntriesInTargetType = fn(
3313
+ "TypeCheckerApi.getMissingTypeEntriesInTargetType"
3314
+ )(
3315
+ function* (realType, expectedType) {
3316
+ const typeChecker = yield* service(TypeCheckerApi);
3317
+ const result = [];
3318
+ const toTest = [realType];
3319
+ while (toTest.length > 0) {
3320
+ const type = toTest.pop();
3321
+ if (!type) return result;
3322
+ if (type.isUnion()) {
3323
+ toTest.push(...type.types);
3324
+ } else {
3325
+ const assignable = typeChecker.isTypeAssignableTo(type, expectedType);
3326
+ if (!assignable) {
3327
+ result.push(type);
3328
+ }
3329
+ }
3330
+ }
3331
+ return result;
3332
+ }
3333
+ );
3334
+ var CannotFindAncestorConvertibleDeclarationError = class extends TaggedError("CannotFindAncestorConvertibleDeclarationError") {
3335
+ };
3336
+ var getAncestorConvertibleDeclaration = fn(
3337
+ "TypeCheckerApi.getAncestorConvertibleDeclaration"
3338
+ )(function* (node) {
3339
+ const ts = yield* service(TypeScriptApi);
3340
+ let current = node;
3341
+ while (current) {
3342
+ if (ts.isFunctionDeclaration(current) || ts.isFunctionExpression(current) || ts.isArrowFunction(current) || ts.isMethodDeclaration(current)) {
3343
+ return current;
3344
+ }
3345
+ current = current.parent;
3346
+ }
3347
+ return yield* fail3(new CannotFindAncestorConvertibleDeclarationError({ node }));
3348
+ });
3349
+ var CannotInferReturnTypeFromEmptyBody = class extends TaggedError("CannotInferReturnTypeFromEmptyBody") {
3350
+ };
3351
+ var CannotInferReturnType = class extends TaggedError("CannotInferReturnType") {
3352
+ };
3353
+ var getInferredReturnType = fn("TypeCheckerApi.getInferredReturnType")(function* (declaration) {
3354
+ const typeChecker = yield* service(TypeCheckerApi);
3355
+ if (!declaration.body) {
3356
+ return yield* fail3(
3357
+ new CannotInferReturnTypeFromEmptyBody({ declaration })
3358
+ );
3359
+ }
3360
+ let returnType;
3361
+ if (typeChecker.isImplementationOfOverload(declaration)) {
3362
+ const signatures = typeChecker.getTypeAtLocation(declaration).getCallSignatures();
3363
+ if (signatures.length > 1) {
3364
+ returnType = typeChecker.getUnionType(
3365
+ signatures.map((s) => s.getReturnType()).filter((_) => !!_)
3366
+ );
3367
+ }
3368
+ }
3369
+ if (!returnType) {
3370
+ const signature = typeChecker.getSignatureFromDeclaration(declaration);
3371
+ if (signature) {
3372
+ const typePredicate = typeChecker.getTypePredicateOfSignature(signature);
3373
+ if (typePredicate && typePredicate.type) {
3374
+ return typePredicate.type;
3375
+ } else {
3376
+ returnType = typeChecker.getReturnTypeOfSignature(signature);
3377
+ }
3378
+ }
3379
+ }
3380
+ if (!returnType) {
3381
+ return yield* fail3(
3382
+ new CannotInferReturnType({ declaration })
3383
+ );
3384
+ }
3385
+ return returnType;
3386
+ });
3387
+ var expectedAndRealType = fn("TypeCheckerApi.expectedAndRealType")(function* (sourceFile) {
3388
+ const cache = yield* service(TypeCheckerApiCache);
3389
+ const resultCached = cache.expectedAndRealType.get(sourceFile);
3390
+ if (resultCached) return resultCached;
3391
+ const typeChecker = yield* service(TypeCheckerApi);
3392
+ const ts = yield* service(TypeScriptApi);
3393
+ const result = [];
3394
+ const nodeToVisit = [];
3395
+ const appendNodeToVisit = (node) => {
3396
+ nodeToVisit.push(node);
3397
+ return void 0;
3398
+ };
3399
+ ts.forEachChild(sourceFile, appendNodeToVisit);
3400
+ while (nodeToVisit.length > 0) {
3401
+ const node = nodeToVisit.shift();
3402
+ ts.forEachChild(node, appendNodeToVisit);
3403
+ if (ts.isVariableDeclaration(node) && node.initializer) {
3404
+ const expectedType = typeChecker.getTypeAtLocation(node.name);
3405
+ const realType = typeChecker.getTypeAtLocation(node.initializer);
3406
+ result.push([node.name, expectedType, node.initializer, realType]);
3407
+ continue;
3408
+ } else if (ts.isCallExpression(node)) {
3409
+ const resolvedSignature = typeChecker.getResolvedSignature(node);
3410
+ if (resolvedSignature) {
3411
+ resolvedSignature.getParameters().map((parameter, index) => {
3412
+ const expectedType = typeChecker.getTypeOfSymbolAtLocation(parameter, node);
3413
+ const realType = typeChecker.getTypeAtLocation(node.arguments[index]);
3414
+ result.push([
3415
+ node.arguments[index],
3416
+ expectedType,
3417
+ node.arguments[index],
3418
+ realType
3419
+ ]);
3420
+ });
3421
+ continue;
3422
+ }
3423
+ } else if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
3424
+ const parent = node.parent;
3425
+ if (ts.isObjectLiteralElement(parent)) {
3426
+ if (ts.isObjectLiteralExpression(parent.parent) && parent.name === node) {
3427
+ const type = typeChecker.getContextualType(parent.parent);
3428
+ if (type) {
3429
+ const symbol3 = typeChecker.getPropertyOfType(type, node.text);
3430
+ if (symbol3) {
3431
+ const expectedType = typeChecker.getTypeOfSymbolAtLocation(symbol3, node);
3432
+ const realType = typeChecker.getTypeAtLocation(node);
3433
+ result.push([node, expectedType, node, realType]);
3434
+ continue;
3435
+ }
3436
+ }
3437
+ }
3438
+ }
3439
+ } else if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
3440
+ const expectedType = typeChecker.getTypeAtLocation(node.left);
3441
+ const realType = typeChecker.getTypeAtLocation(node.right);
3442
+ result.push([node.left, expectedType, node.right, realType]);
3443
+ continue;
3444
+ } else if (ts.isReturnStatement(node) && node.expression) {
3445
+ const parentDeclaration = yield* option(getAncestorConvertibleDeclaration(node));
3446
+ if (isSome2(parentDeclaration)) {
3447
+ const expectedType = yield* option(getInferredReturnType(parentDeclaration.value));
3448
+ const realType = typeChecker.getTypeAtLocation(node.expression);
3449
+ if (isSome2(expectedType)) {
3450
+ result.push([node, expectedType.value, node, realType]);
3451
+ continue;
3452
+ }
3453
+ }
3454
+ } else if (ts.isArrowFunction(node) && ts.isExpression(node.body)) {
3455
+ const body = node.body;
3456
+ const expectedType = typeChecker.getContextualType(body);
3457
+ const realType = typeChecker.getTypeAtLocation(body);
3458
+ if (expectedType) {
3459
+ result.push([body, expectedType, body, realType]);
3460
+ continue;
3461
+ }
3462
+ } else if (ts.isSatisfiesExpression(node)) {
2970
3463
  const expectedType = typeChecker.getTypeAtLocation(node.type);
2971
3464
  const realType = typeChecker.getTypeAtLocation(node.expression);
2972
- return [[node.expression, expectedType, node.expression, realType]];
3465
+ result.push([node.expression, expectedType, node.expression, realType]);
3466
+ continue;
2973
3467
  }
2974
- return [];
2975
- });
2976
- }
3468
+ }
3469
+ cache.expectedAndRealType.set(sourceFile, result);
3470
+ return result;
3471
+ });
2977
3472
 
2978
3473
  // src/utils/TypeParser.ts
2979
3474
  var TypeParserIssue = class extends TaggedError("@effect/language-service/TypeParserIssue") {
@@ -2988,23 +3483,21 @@ function covariantTypeArgument(type) {
2988
3483
  }
2989
3484
  return succeed(signatures[0].getReturnType());
2990
3485
  }
2991
- function pipeableType(type, atLocation) {
2992
- return gen2(function* () {
2993
- const typeChecker = yield* service(TypeCheckerApi);
2994
- const pipeSymbol = typeChecker.getPropertyOfType(type, "pipe");
2995
- if (!pipeSymbol) {
2996
- return yield* typeParserIssue("Type has no 'pipe' property", type, atLocation);
2997
- }
2998
- const pipeType = typeChecker.getTypeOfSymbolAtLocation(pipeSymbol, atLocation);
2999
- const signatures = pipeType.getCallSignatures();
3000
- if (signatures.length === 0) {
3001
- return yield* typeParserIssue("'pipe' property is not callable", type, atLocation);
3002
- }
3003
- return type;
3004
- });
3005
- }
3006
- function varianceStructCovariantType(type, atLocation, propertyName) {
3007
- return gen2(function* () {
3486
+ var pipeableType = fn("TypeParser.pipeableType")(function* (type, atLocation) {
3487
+ const typeChecker = yield* service(TypeCheckerApi);
3488
+ const pipeSymbol = typeChecker.getPropertyOfType(type, "pipe");
3489
+ if (!pipeSymbol) {
3490
+ return yield* typeParserIssue("Type has no 'pipe' property", type, atLocation);
3491
+ }
3492
+ const pipeType = typeChecker.getTypeOfSymbolAtLocation(pipeSymbol, atLocation);
3493
+ const signatures = pipeType.getCallSignatures();
3494
+ if (signatures.length === 0) {
3495
+ return yield* typeParserIssue("'pipe' property is not callable", type, atLocation);
3496
+ }
3497
+ return type;
3498
+ });
3499
+ var varianceStructCovariantType = fn("TypeParser.varianceStructCovariantType")(
3500
+ function* (type, atLocation, propertyName) {
3008
3501
  const typeChecker = yield* service(TypeCheckerApi);
3009
3502
  const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
3010
3503
  if (!propertySymbol) {
@@ -3012,82 +3505,108 @@ function varianceStructCovariantType(type, atLocation, propertyName) {
3012
3505
  }
3013
3506
  const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
3014
3507
  return yield* covariantTypeArgument(propertyType);
3015
- });
3016
- }
3017
- function effectVarianceStruct(type, atLocation) {
3018
- return gen2(function* () {
3019
- return {
3020
- A: yield* varianceStructCovariantType(type, atLocation, "_A"),
3021
- E: yield* varianceStructCovariantType(type, atLocation, "_E"),
3022
- R: yield* varianceStructCovariantType(type, atLocation, "_R")
3023
- };
3024
- });
3025
- }
3026
- function effectType(type, atLocation) {
3027
- return gen2(function* () {
3028
- const typeChecker = yield* service(TypeCheckerApi);
3029
- yield* pipeableType(type, atLocation);
3030
- for (const propertySymbol of typeChecker.getPropertiesOfType(type)) {
3031
- const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
3032
- const varianceArgs = yield* option(effectVarianceStruct(
3033
- propertyType,
3034
- atLocation
3035
- ));
3036
- if (isSome2(varianceArgs)) {
3037
- return varianceArgs.value;
3038
- }
3039
- }
3040
- return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
3041
- });
3042
- }
3043
- function fiberType(type, atLocation) {
3044
- return gen2(function* () {
3045
- const typeChecker = yield* service(TypeCheckerApi);
3046
- const awaitSymbol = typeChecker.getPropertyOfType(type, "await");
3047
- const pollSymbol = typeChecker.getPropertyOfType(type, "poll");
3048
- if (!awaitSymbol || !pollSymbol) {
3049
- return yield* typeParserIssue(
3050
- "Type is not a fiber because it does not have 'await' or 'poll' property",
3051
- type,
3052
- atLocation
3053
- );
3054
- }
3055
- return yield* effectType(type, atLocation);
3056
- });
3057
- }
3058
- function effectSubtype(type, atLocation) {
3059
- return gen2(function* () {
3060
- const typeChecker = yield* service(TypeCheckerApi);
3061
- const tagSymbol = typeChecker.getPropertyOfType(type, "_tag");
3062
- if (!tagSymbol) {
3063
- return yield* typeParserIssue(
3064
- "Type is not a subtype of effect because it does not have '_tag' property",
3065
- type,
3066
- atLocation
3067
- );
3068
- }
3069
- return yield* effectType(type, atLocation);
3070
- });
3071
- }
3072
- function importedEffectModule(node) {
3073
- return gen2(function* () {
3074
- const ts = yield* service(TypeScriptApi);
3075
- const typeChecker = yield* service(TypeCheckerApi);
3076
- const type = typeChecker.getTypeAtLocation(node);
3077
- const propertySymbol = typeChecker.getPropertyOfType(type, "never");
3078
- if (!propertySymbol) {
3079
- return yield* typeParserIssue("Type has no 'never' property", type, node);
3080
- }
3081
- if (!ts.isExpression(node)) {
3082
- return yield* typeParserIssue("Node is not an expression", type, node);
3508
+ }
3509
+ );
3510
+ var effectVarianceStruct = fn("TypeParser.effectVarianceStruct")(function* (type, atLocation) {
3511
+ return {
3512
+ A: yield* varianceStructCovariantType(type, atLocation, "_A"),
3513
+ E: yield* varianceStructCovariantType(type, atLocation, "_E"),
3514
+ R: yield* varianceStructCovariantType(type, atLocation, "_R")
3515
+ };
3516
+ });
3517
+ var effectType = fn("TypeParser.effectType")(function* (type, atLocation) {
3518
+ const ts = yield* service(TypeScriptApi);
3519
+ const typeChecker = yield* service(TypeCheckerApi);
3520
+ yield* pipeableType(type, atLocation);
3521
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
3522
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
3523
+ );
3524
+ propertiesSymbols.sort((a, b) => b.name.indexOf("EffectTypeId") - a.name.indexOf("EffectTypeId"));
3525
+ for (const propertySymbol of propertiesSymbols) {
3526
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
3527
+ const varianceArgs = yield* option(effectVarianceStruct(
3528
+ propertyType,
3529
+ atLocation
3530
+ ));
3531
+ if (isSome2(varianceArgs)) {
3532
+ return varianceArgs.value;
3083
3533
  }
3084
- const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, node);
3085
- yield* effectType(propertyType, node);
3086
- return node;
3087
- });
3088
- }
3089
- function effectGen(node) {
3090
- return gen2(function* () {
3534
+ }
3535
+ return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
3536
+ });
3537
+ var fiberType = fn("TypeParser.fiberType")(function* (type, atLocation) {
3538
+ const typeChecker = yield* service(TypeCheckerApi);
3539
+ const awaitSymbol = typeChecker.getPropertyOfType(type, "await");
3540
+ const pollSymbol = typeChecker.getPropertyOfType(type, "poll");
3541
+ if (!awaitSymbol || !pollSymbol) {
3542
+ return yield* typeParserIssue(
3543
+ "Type is not a fiber because it does not have 'await' or 'poll' property",
3544
+ type,
3545
+ atLocation
3546
+ );
3547
+ }
3548
+ return yield* effectType(type, atLocation);
3549
+ });
3550
+ var effectSubtype = fn("TypeParser.effectSubtype")(function* (type, atLocation) {
3551
+ const typeChecker = yield* service(TypeCheckerApi);
3552
+ const tagSymbol = typeChecker.getPropertyOfType(type, "_tag");
3553
+ if (!tagSymbol) {
3554
+ return yield* typeParserIssue(
3555
+ "Type is not a subtype of effect because it does not have '_tag' property",
3556
+ type,
3557
+ atLocation
3558
+ );
3559
+ }
3560
+ return yield* effectType(type, atLocation);
3561
+ });
3562
+ var importedEffectModule = fn("TypeParser.importedEffectModule")(function* (node) {
3563
+ const ts = yield* service(TypeScriptApi);
3564
+ const typeChecker = yield* service(TypeCheckerApi);
3565
+ const type = typeChecker.getTypeAtLocation(node);
3566
+ const propertySymbol = typeChecker.getPropertyOfType(type, "never");
3567
+ if (!propertySymbol) {
3568
+ return yield* typeParserIssue("Type has no 'never' property", type, node);
3569
+ }
3570
+ if (!ts.isExpression(node)) {
3571
+ return yield* typeParserIssue("Node is not an expression", type, node);
3572
+ }
3573
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, node);
3574
+ yield* effectType(propertyType, node);
3575
+ return node;
3576
+ });
3577
+ var effectGen = fn("TypeParser.effectGen")(function* (node) {
3578
+ const ts = yield* service(TypeScriptApi);
3579
+ if (!ts.isCallExpression(node)) {
3580
+ return yield* typeParserIssue("Node is not a call expression", void 0, node);
3581
+ }
3582
+ if (node.arguments.length === 0) {
3583
+ return yield* typeParserIssue("Node has no arguments", void 0, node);
3584
+ }
3585
+ const generatorFunction = node.arguments[0];
3586
+ if (!ts.isFunctionExpression(generatorFunction)) {
3587
+ return yield* typeParserIssue("Node is not a function expression", void 0, node);
3588
+ }
3589
+ if (generatorFunction.asteriskToken === void 0) {
3590
+ return yield* typeParserIssue("Node is not a generator function", void 0, node);
3591
+ }
3592
+ if (!ts.isPropertyAccessExpression(node.expression)) {
3593
+ return yield* typeParserIssue("Node is not a property access expression", void 0, node);
3594
+ }
3595
+ const propertyAccess = node.expression;
3596
+ if (propertyAccess.name.text !== "gen") {
3597
+ return yield* typeParserIssue("Call expression name is not 'gen'", void 0, node);
3598
+ }
3599
+ const effectModule = yield* importedEffectModule(propertyAccess.expression);
3600
+ return {
3601
+ node,
3602
+ effectModule,
3603
+ generatorFunction,
3604
+ body: generatorFunction.body,
3605
+ functionStar: generatorFunction.getFirstToken()
3606
+ };
3607
+ });
3608
+ var effectFnUntracedGen = fn("TypeParser.effectFnUntracedGen")(
3609
+ function* (node) {
3091
3610
  const ts = yield* service(TypeScriptApi);
3092
3611
  if (!ts.isCallExpression(node)) {
3093
3612
  return yield* typeParserIssue("Node is not a call expression", void 0, node);
@@ -3100,14 +3619,26 @@ function effectGen(node) {
3100
3619
  return yield* typeParserIssue("Node is not a function expression", void 0, node);
3101
3620
  }
3102
3621
  if (generatorFunction.asteriskToken === void 0) {
3103
- return yield* typeParserIssue("Node is not a generator function", void 0, node);
3622
+ return yield* typeParserIssue(
3623
+ "Node is not a generator function",
3624
+ void 0,
3625
+ node
3626
+ );
3104
3627
  }
3105
3628
  if (!ts.isPropertyAccessExpression(node.expression)) {
3106
- return yield* typeParserIssue("Node is not a property access expression", void 0, node);
3629
+ return yield* typeParserIssue(
3630
+ "Node is not a property access expression",
3631
+ void 0,
3632
+ node
3633
+ );
3107
3634
  }
3108
3635
  const propertyAccess = node.expression;
3109
- if (propertyAccess.name.text !== "gen") {
3110
- return yield* typeParserIssue("Call expression name is not 'gen'", void 0, node);
3636
+ if (propertyAccess.name.text !== "fnUntraced") {
3637
+ return yield* typeParserIssue(
3638
+ "Call expression name is not 'fnUntraced'",
3639
+ void 0,
3640
+ node
3641
+ );
3111
3642
  }
3112
3643
  const effectModule = yield* importedEffectModule(propertyAccess.expression);
3113
3644
  return {
@@ -3117,127 +3648,77 @@ function effectGen(node) {
3117
3648
  body: generatorFunction.body,
3118
3649
  functionStar: generatorFunction.getFirstToken()
3119
3650
  };
3120
- });
3121
- }
3122
- function effectFnUntracedGen(node) {
3123
- return gen2(function* () {
3124
- const ts = yield* service(TypeScriptApi);
3125
- if (!ts.isCallExpression(node)) {
3126
- return yield* typeParserIssue("Node is not a call expression", void 0, node);
3127
- }
3128
- if (node.arguments.length === 0) {
3129
- return yield* typeParserIssue("Node has no arguments", void 0, node);
3130
- }
3131
- const generatorFunction = node.arguments[0];
3132
- if (!ts.isFunctionExpression(generatorFunction)) {
3133
- return yield* typeParserIssue("Node is not a function expression", void 0, node);
3134
- }
3135
- if (generatorFunction.asteriskToken === void 0) {
3136
- return yield* typeParserIssue(
3137
- "Node is not a generator function",
3138
- void 0,
3139
- node
3140
- );
3141
- }
3142
- if (!ts.isPropertyAccessExpression(node.expression)) {
3143
- return yield* typeParserIssue(
3144
- "Node is not a property access expression",
3145
- void 0,
3146
- node
3147
- );
3148
- }
3149
- const propertyAccess = node.expression;
3150
- if (propertyAccess.name.text !== "fnUntraced") {
3151
- return yield* typeParserIssue(
3152
- "Call expression name is not 'fnUntraced'",
3153
- void 0,
3154
- node
3155
- );
3156
- }
3157
- const effectModule = yield* importedEffectModule(propertyAccess.expression);
3158
- return {
3159
- node,
3160
- effectModule,
3161
- generatorFunction,
3162
- body: generatorFunction.body,
3163
- functionStar: generatorFunction.getFirstToken()
3164
- };
3165
- });
3166
- }
3167
- function effectFnGen(node) {
3168
- return gen2(function* () {
3169
- const ts = yield* service(TypeScriptApi);
3170
- if (!ts.isCallExpression(node)) {
3171
- return yield* typeParserIssue("Node is not a call expression", void 0, node);
3172
- }
3173
- if (node.arguments.length === 0) {
3174
- return yield* typeParserIssue("Node has no arguments", void 0, node);
3175
- }
3176
- const generatorFunction = node.arguments[0];
3177
- if (!ts.isFunctionExpression(generatorFunction)) {
3178
- return yield* typeParserIssue(
3179
- "Node is not a function expression",
3180
- void 0,
3181
- node
3182
- );
3183
- }
3184
- if (generatorFunction.asteriskToken === void 0) {
3185
- return yield* typeParserIssue(
3186
- "Node is not a generator function",
3187
- void 0,
3188
- node
3189
- );
3190
- }
3191
- const expressionToTest = ts.isCallExpression(node.expression) ? node.expression.expression : node.expression;
3192
- if (!ts.isPropertyAccessExpression(expressionToTest)) {
3193
- return yield* typeParserIssue(
3194
- "Node is not a property access expression",
3195
- void 0,
3196
- node
3197
- );
3198
- }
3199
- const propertyAccess = expressionToTest;
3200
- if (propertyAccess.name.text !== "fn") {
3201
- return yield* typeParserIssue(
3202
- "Call expression name is not 'fn'",
3203
- void 0,
3204
- node
3205
- );
3206
- }
3207
- const effectModule = yield* importedEffectModule(propertyAccess.expression);
3208
- return {
3209
- node,
3210
- generatorFunction,
3211
- effectModule,
3212
- body: generatorFunction.body,
3213
- functionStar: generatorFunction.getFirstToken()
3214
- };
3215
- });
3216
- }
3217
- function returnYieldEffectBlock(body) {
3218
- return gen2(function* () {
3219
- const ts = yield* service(TypeScriptApi);
3220
- const typeChecker = yield* service(TypeCheckerApi);
3221
- if (!ts.isBlock(body)) return yield* typeParserIssue("Node is not a block", void 0, body);
3222
- if (body.statements.length === 1 && ts.isReturnStatement(body.statements[0]) && body.statements[0].expression && ts.isYieldExpression(body.statements[0].expression) && body.statements[0].expression.expression) {
3223
- const nodeToCheck = body.statements[0].expression.expression;
3224
- const type = typeChecker.getTypeAtLocation(nodeToCheck);
3225
- yield* effectType(type, nodeToCheck);
3226
- return nodeToCheck;
3227
- }
3651
+ }
3652
+ );
3653
+ var effectFnGen = fn("TypeParser.effectFnGen")(function* (node) {
3654
+ const ts = yield* service(TypeScriptApi);
3655
+ if (!ts.isCallExpression(node)) {
3656
+ return yield* typeParserIssue("Node is not a call expression", void 0, node);
3657
+ }
3658
+ if (node.arguments.length === 0) {
3659
+ return yield* typeParserIssue("Node has no arguments", void 0, node);
3660
+ }
3661
+ const generatorFunction = node.arguments[0];
3662
+ if (!ts.isFunctionExpression(generatorFunction)) {
3228
3663
  return yield* typeParserIssue(
3229
- "Node is not a return statement with a yield expression",
3664
+ "Node is not a function expression",
3230
3665
  void 0,
3231
- body
3666
+ node
3232
3667
  );
3233
- });
3234
- }
3668
+ }
3669
+ if (generatorFunction.asteriskToken === void 0) {
3670
+ return yield* typeParserIssue(
3671
+ "Node is not a generator function",
3672
+ void 0,
3673
+ node
3674
+ );
3675
+ }
3676
+ const expressionToTest = ts.isCallExpression(node.expression) ? node.expression.expression : node.expression;
3677
+ if (!ts.isPropertyAccessExpression(expressionToTest)) {
3678
+ return yield* typeParserIssue(
3679
+ "Node is not a property access expression",
3680
+ void 0,
3681
+ node
3682
+ );
3683
+ }
3684
+ const propertyAccess = expressionToTest;
3685
+ if (propertyAccess.name.text !== "fn") {
3686
+ return yield* typeParserIssue(
3687
+ "Call expression name is not 'fn'",
3688
+ void 0,
3689
+ node
3690
+ );
3691
+ }
3692
+ const effectModule = yield* importedEffectModule(propertyAccess.expression);
3693
+ return {
3694
+ node,
3695
+ generatorFunction,
3696
+ effectModule,
3697
+ body: generatorFunction.body,
3698
+ functionStar: generatorFunction.getFirstToken()
3699
+ };
3700
+ });
3701
+ var returnYieldEffectBlock = fn("TypeParser.returnYieldEffectBlock")(function* (body) {
3702
+ const ts = yield* service(TypeScriptApi);
3703
+ const typeChecker = yield* service(TypeCheckerApi);
3704
+ if (ts.isBlock(body) && body.statements.length === 1 && ts.isReturnStatement(body.statements[0]) && body.statements[0].expression && ts.isYieldExpression(body.statements[0].expression) && body.statements[0].expression.expression) {
3705
+ const nodeToCheck = body.statements[0].expression.expression;
3706
+ const type = typeChecker.getTypeAtLocation(nodeToCheck);
3707
+ yield* effectType(type, nodeToCheck);
3708
+ return nodeToCheck;
3709
+ }
3710
+ return yield* typeParserIssue(
3711
+ "Node is not a return statement with a yield expression",
3712
+ void 0,
3713
+ body
3714
+ );
3715
+ });
3235
3716
 
3236
3717
  // src/diagnostics/floatingEffect.ts
3237
3718
  var floatingEffect = createDiagnostic({
3238
3719
  name: "effect/floatingEffect",
3239
3720
  code: 3,
3240
- apply: (sourceFile) => gen2(function* () {
3721
+ apply: fn("floatingEffect.apply")(function* (sourceFile) {
3241
3722
  const ts = yield* service(TypeScriptApi);
3242
3723
  const typeChecker = yield* service(TypeCheckerApi);
3243
3724
  function isFloatingExpression(node) {
@@ -3270,7 +3751,8 @@ var floatingEffect = createDiagnostic({
3270
3751
  effectDiagnostics.push({
3271
3752
  node,
3272
3753
  category: ts.DiagnosticCategory.Error,
3273
- messageText: `Effect must be yielded or assigned to a variable.`
3754
+ messageText: `Effect must be yielded or assigned to a variable.`,
3755
+ fix: none2()
3274
3756
  });
3275
3757
  }
3276
3758
  }
@@ -3283,57 +3765,48 @@ var floatingEffect = createDiagnostic({
3283
3765
  var missingEffectContext = createDiagnostic({
3284
3766
  name: "effect/missingEffectContext",
3285
3767
  code: 1,
3286
- apply: (sourceFile) => gen2(function* () {
3768
+ apply: fn("missingEffectContext.apply")(function* (sourceFile) {
3287
3769
  const ts = yield* service(TypeScriptApi);
3288
3770
  const typeChecker = yield* service(TypeCheckerApi);
3289
3771
  const typeOrder = yield* deterministicTypeOrder;
3290
- function checkForMissingContextTypes(node, expectedType, valueNode, realType) {
3291
- return gen2(function* () {
3292
- const expectedEffect = yield* effectType(
3293
- expectedType,
3294
- node
3295
- );
3296
- const realEffect = yield* effectType(
3297
- realType,
3298
- valueNode
3299
- );
3300
- return yield* getMissingTypeEntriesInTargetType(
3301
- realEffect.R,
3302
- expectedEffect.R
3303
- );
3304
- });
3305
- }
3772
+ const checkForMissingContextTypes = fn(
3773
+ "missingEffectContext.apply.checkForMissingContextTypes"
3774
+ )(function* (node, expectedType, valueNode, realType) {
3775
+ const expectedEffect = yield* effectType(
3776
+ expectedType,
3777
+ node
3778
+ );
3779
+ const realEffect = yield* effectType(
3780
+ realType,
3781
+ valueNode
3782
+ );
3783
+ return yield* getMissingTypeEntriesInTargetType(
3784
+ realEffect.R,
3785
+ expectedEffect.R
3786
+ );
3787
+ });
3306
3788
  const effectDiagnostics = [];
3307
3789
  const sortTypes = sort(typeOrder);
3308
- const nodeToVisit = [];
3309
- const appendNodeToVisit = (node) => {
3310
- nodeToVisit.push(node);
3311
- return void 0;
3312
- };
3313
- ts.forEachChild(sourceFile, appendNodeToVisit);
3314
- while (nodeToVisit.length > 0) {
3315
- const node = nodeToVisit.shift();
3316
- ts.forEachChild(node, appendNodeToVisit);
3317
- const entries = yield* expectedAndRealType(node);
3318
- for (const [node2, expectedType, valueNode, realType] of entries) {
3319
- const missingContext = yield* pipe(
3320
- checkForMissingContextTypes(
3321
- node2,
3322
- expectedType,
3323
- valueNode,
3324
- realType
3325
- ),
3326
- orElse3(() => succeed([]))
3790
+ const entries = yield* expectedAndRealType(sourceFile);
3791
+ for (const [node, expectedType, valueNode, realType] of entries) {
3792
+ const missingContext = yield* pipe(
3793
+ checkForMissingContextTypes(
3794
+ node,
3795
+ expectedType,
3796
+ valueNode,
3797
+ realType
3798
+ ),
3799
+ orElse3(() => succeed([]))
3800
+ );
3801
+ if (missingContext.length > 0) {
3802
+ effectDiagnostics.push(
3803
+ {
3804
+ node,
3805
+ category: ts.DiagnosticCategory.Error,
3806
+ messageText: `Missing '${sortTypes(missingContext).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect context.`,
3807
+ fix: none2()
3808
+ }
3327
3809
  );
3328
- if (missingContext.length > 0) {
3329
- effectDiagnostics.push(
3330
- {
3331
- node: node2,
3332
- category: ts.DiagnosticCategory.Error,
3333
- messageText: `Missing '${sortTypes(missingContext).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect context.`
3334
- }
3335
- );
3336
- }
3337
3810
  }
3338
3811
  }
3339
3812
  return effectDiagnostics;
@@ -3344,410 +3817,187 @@ var missingEffectContext = createDiagnostic({
3344
3817
  var missingEffectError = createDiagnostic({
3345
3818
  name: "effect/missingEffectError",
3346
3819
  code: 1,
3347
- apply: (sourceFile) => gen2(function* () {
3820
+ apply: fn("missingEffectError.apply")(function* (sourceFile) {
3348
3821
  const ts = yield* service(TypeScriptApi);
3349
3822
  const typeChecker = yield* service(TypeCheckerApi);
3350
3823
  const typeOrder = yield* deterministicTypeOrder;
3351
- function checkForMissingErrorTypes(node, expectedType, valueNode, realType) {
3352
- return gen2(function* () {
3824
+ const checkForMissingErrorTypes = fn("missingEffectError.apply.checkForMissingErrorTypes")(
3825
+ function* (node, expectedType, valueNode, realType) {
3353
3826
  const expectedEffect = yield* effectType(
3354
3827
  expectedType,
3355
3828
  node
3356
3829
  );
3357
3830
  const realEffect = yield* effectType(
3358
- realType,
3359
- valueNode
3360
- );
3361
- return yield* getMissingTypeEntriesInTargetType(
3362
- realEffect.E,
3363
- expectedEffect.E
3364
- );
3365
- });
3366
- }
3367
- const effectDiagnostics = [];
3368
- const sortTypes = sort(typeOrder);
3369
- const nodeToVisit = [];
3370
- const appendNodeToVisit = (node) => {
3371
- nodeToVisit.push(node);
3372
- return void 0;
3373
- };
3374
- ts.forEachChild(sourceFile, appendNodeToVisit);
3375
- while (nodeToVisit.length > 0) {
3376
- const node = nodeToVisit.shift();
3377
- ts.forEachChild(node, appendNodeToVisit);
3378
- const entries = yield* expectedAndRealType(node);
3379
- for (const [node2, expectedType, valueNode, realType] of entries) {
3380
- const missingContext = yield* pipe(
3381
- checkForMissingErrorTypes(
3382
- node2,
3383
- expectedType,
3384
- valueNode,
3385
- realType
3386
- ),
3387
- orElse3(() => succeed([]))
3388
- );
3389
- if (missingContext.length > 0) {
3390
- effectDiagnostics.push(
3391
- {
3392
- node: node2,
3393
- category: ts.DiagnosticCategory.Error,
3394
- messageText: `Missing '${sortTypes(missingContext).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect errors.`
3395
- }
3396
- );
3397
- }
3398
- }
3399
- }
3400
- return effectDiagnostics;
3401
- })
3402
- });
3403
-
3404
- // src/diagnostics/missingStarInYieldEffectGen.ts
3405
- var missingStarInYieldEffectGen = createDiagnostic({
3406
- name: "effect/missingStarInYieldEffectGen",
3407
- code: 4,
3408
- apply: (sourceFile) => gen2(function* () {
3409
- const ts = yield* service(TypeScriptApi);
3410
- const typeChecker = yield* service(TypeCheckerApi);
3411
- const effectDiagnostics = [];
3412
- const brokenGenerators = /* @__PURE__ */ new Set();
3413
- const brokenYields = /* @__PURE__ */ new Set();
3414
- const nodeToVisit = [];
3415
- const appendNodeToVisit = (functionStarNode) => (node) => {
3416
- nodeToVisit.push([node, functionStarNode]);
3417
- return void 0;
3418
- };
3419
- ts.forEachChild(sourceFile, appendNodeToVisit(void 0));
3420
- while (nodeToVisit.length > 0) {
3421
- const [node, functionStarNode] = nodeToVisit.shift();
3422
- if (functionStarNode && ts.isYieldExpression(node) && node.expression && node.asteriskToken === void 0) {
3423
- const type = typeChecker.getTypeAtLocation(node.expression);
3424
- const effect = yield* option(effectType(type, node.expression));
3425
- if (isSome2(effect)) {
3426
- brokenGenerators.add(functionStarNode);
3427
- brokenYields.add(node);
3428
- }
3429
- }
3430
- const effectGenLike = yield* pipe(
3431
- effectGen(node),
3432
- orElse3(() => effectFnUntracedGen(node)),
3433
- orElse3(() => effectFnGen(node)),
3434
- option
3435
- );
3436
- if (isSome2(effectGenLike)) {
3437
- ts.forEachChild(
3438
- effectGenLike.value.body,
3439
- appendNodeToVisit(effectGenLike.value.functionStar)
3440
- );
3441
- } else if ((ts.isFunctionExpression(node) || ts.isMethodDeclaration(node)) && node.asteriskToken !== void 0) {
3442
- ts.forEachChild(node, appendNodeToVisit(void 0));
3443
- } else {
3444
- ts.forEachChild(node, appendNodeToVisit(functionStarNode));
3445
- }
3446
- }
3447
- brokenGenerators.forEach(
3448
- (node) => effectDiagnostics.push({
3449
- node,
3450
- category: ts.DiagnosticCategory.Error,
3451
- messageText: `Seems like you used yield instead of yield* inside this Effect.gen.`
3452
- })
3453
- );
3454
- brokenYields.forEach(
3455
- (node) => effectDiagnostics.push({
3456
- node,
3457
- category: ts.DiagnosticCategory.Error,
3458
- messageText: `When yielding Effects inside Effect.gen, you should use yield* instead of yield.`
3459
- })
3460
- );
3461
- return effectDiagnostics;
3462
- })
3463
- });
3464
-
3465
- // src/diagnostics/unnecessaryEffectGen.ts
3466
- var unnecessaryEffectGen = createDiagnostic({
3467
- name: "effect/unnecessaryEffectGen",
3468
- code: 5,
3469
- apply: (sourceFile) => gen2(function* () {
3470
- const ts = yield* service(TypeScriptApi);
3471
- const effectDiagnostics = [];
3472
- const brokenGenerators = /* @__PURE__ */ new Set();
3473
- const nodeToVisit = [];
3474
- const appendNodeToVisit = (node) => {
3475
- nodeToVisit.push(node);
3476
- return void 0;
3477
- };
3478
- ts.forEachChild(sourceFile, appendNodeToVisit);
3479
- while (nodeToVisit.length > 0) {
3480
- const node = nodeToVisit.shift();
3481
- ts.forEachChild(node, appendNodeToVisit);
3482
- const maybeUnnecessaryGen = yield* pipe(
3483
- effectGen(node),
3484
- flatMap4(({ body }) => returnYieldEffectBlock(body)),
3485
- option
3486
- );
3487
- if (isSome2(maybeUnnecessaryGen)) {
3488
- brokenGenerators.add(node);
3489
- }
3490
- }
3491
- brokenGenerators.forEach(
3492
- (node) => effectDiagnostics.push({
3493
- node,
3494
- category: ts.DiagnosticCategory.Suggestion,
3495
- messageText: `This Effect.gen is useless here because it only contains a single return statement.`
3496
- })
3497
- );
3498
- return effectDiagnostics;
3499
- })
3500
- });
3501
-
3502
- // src/diagnostics.ts
3503
- var diagnostics = [
3504
- missingEffectContext,
3505
- missingEffectError,
3506
- floatingEffect,
3507
- missingStarInYieldEffectGen,
3508
- unnecessaryEffectGen
3509
- ];
3510
-
3511
- // src/utils/AST.ts
3512
- function collectSelfAndAncestorNodesInRange(node, textRange) {
3513
- return sync(() => {
3514
- let result = empty();
3515
- let parent = node;
3516
- while (parent) {
3517
- if (parent.end >= textRange.end) {
3518
- result = pipe(result, append(parent));
3519
- }
3520
- parent = parent.parent;
3521
- }
3522
- return result;
3523
- });
3524
- }
3525
- function getAncestorNodesInRange(sourceFile, textRange) {
3526
- return gen2(function* () {
3527
- const ts = yield* service(TypeScriptApi);
3528
- const precedingToken = ts.findPrecedingToken(textRange.pos, sourceFile);
3529
- if (!precedingToken) return empty();
3530
- return yield* collectSelfAndAncestorNodesInRange(precedingToken, textRange);
3531
- });
3532
- }
3533
- var NodeNotFoundError = class extends TaggedError("@effect/language-service/NodeNotFoundError") {
3534
- };
3535
- function findNodeAtPosition(sourceFile, position) {
3536
- return gen2(function* () {
3537
- const ts = yield* service(TypeScriptApi);
3538
- function find(node) {
3539
- if (position >= node.getStart() && position < node.getEnd()) {
3540
- return ts.forEachChild(node, find) || node;
3541
- }
3542
- return void 0;
3543
- }
3544
- const result = find(sourceFile);
3545
- if (!result) return yield* fail3(new NodeNotFoundError());
3546
- return result;
3547
- });
3548
- }
3549
- function collectDescendantsAndAncestorsInRange(sourceFile, textRange) {
3550
- return gen2(function* () {
3551
- const nodeAtPosition = yield* option(findNodeAtPosition(sourceFile, textRange.pos));
3552
- if (isNone2(nodeAtPosition)) return empty();
3553
- return yield* collectSelfAndAncestorNodesInRange(nodeAtPosition.value, textRange);
3554
- });
3555
- }
3556
- function toTextRange(positionOrRange) {
3557
- return typeof positionOrRange === "number" ? { end: positionOrRange, pos: positionOrRange } : positionOrRange;
3558
- }
3559
- function isNodeInRange(textRange) {
3560
- return (node) => node.pos <= textRange.pos && node.end >= textRange.end;
3561
- }
3562
- function transformAsyncAwaitToEffectGen(node, effectModuleName, onAwait) {
3563
- return gen2(function* () {
3564
- const ts = yield* service(TypeScriptApi);
3565
- function visitor(_) {
3566
- if (ts.isAwaitExpression(_)) {
3567
- const expression = ts.visitEachChild(_.expression, visitor, ts.nullTransformationContext);
3568
- return ts.factory.createYieldExpression(
3569
- ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
3570
- onAwait(expression)
3571
- );
3572
- }
3573
- return ts.visitEachChild(_, visitor, ts.nullTransformationContext);
3574
- }
3575
- const generatorBody = visitor(node.body);
3576
- const generator = ts.factory.createFunctionExpression(
3577
- void 0,
3578
- ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
3579
- void 0,
3580
- [],
3581
- [],
3582
- void 0,
3583
- generatorBody
3584
- // NOTE(mattia): intended, to use same routine for both ConciseBody and Body
3585
- );
3586
- const effectGenCallExp = ts.factory.createCallExpression(
3587
- ts.factory.createPropertyAccessExpression(
3588
- ts.factory.createIdentifier(effectModuleName),
3589
- "gen"
3590
- ),
3591
- void 0,
3592
- [generator]
3593
- );
3594
- let currentFlags = ts.getCombinedModifierFlags(node);
3595
- currentFlags &= ~ts.ModifierFlags.Async;
3596
- const newModifiers = ts.factory.createModifiersFromModifierFlags(currentFlags);
3597
- if (ts.isArrowFunction(node)) {
3598
- return ts.factory.createArrowFunction(
3599
- newModifiers,
3600
- node.typeParameters,
3601
- node.parameters,
3602
- void 0,
3603
- node.equalsGreaterThanToken,
3604
- effectGenCallExp
3605
- );
3606
- }
3607
- const newBody = ts.factory.createBlock([
3608
- ts.factory.createReturnStatement(effectGenCallExp)
3609
- ]);
3610
- if (ts.isFunctionDeclaration(node)) {
3611
- return ts.factory.createFunctionDeclaration(
3612
- newModifiers,
3613
- node.asteriskToken,
3614
- node.name,
3615
- node.typeParameters,
3616
- node.parameters,
3617
- void 0,
3618
- newBody
3619
- );
3620
- }
3621
- return ts.factory.createFunctionExpression(
3622
- newModifiers,
3623
- node.asteriskToken,
3624
- node.name,
3625
- node.typeParameters,
3626
- node.parameters,
3627
- void 0,
3628
- newBody
3629
- );
3630
- });
3631
- }
3632
- function addReturnTypeAnnotation(sourceFile, declaration, typeNode) {
3633
- return gen2(function* () {
3634
- const ts = yield* service(TypeScriptApi);
3635
- const changes = yield* service(ChangeTracker);
3636
- const closeParen = ts.findChildOfKind(declaration, ts.SyntaxKind.CloseParenToken, sourceFile);
3637
- const needParens = ts.isArrowFunction(declaration) && closeParen === void 0;
3638
- const endNode = needParens ? declaration.parameters[0] : closeParen;
3639
- if (endNode) {
3640
- if (needParens) {
3641
- changes.insertNodeBefore(
3642
- sourceFile,
3643
- endNode,
3644
- ts.factory.createToken(ts.SyntaxKind.OpenParenToken)
3831
+ realType,
3832
+ valueNode
3645
3833
  );
3646
- changes.insertNodeAfter(
3647
- sourceFile,
3648
- endNode,
3649
- ts.factory.createToken(ts.SyntaxKind.CloseParenToken)
3834
+ return yield* getMissingTypeEntriesInTargetType(
3835
+ realEffect.E,
3836
+ expectedEffect.E
3837
+ );
3838
+ }
3839
+ );
3840
+ const effectDiagnostics = [];
3841
+ const sortTypes = sort(typeOrder);
3842
+ const entries = yield* expectedAndRealType(sourceFile);
3843
+ for (const [node, expectedType, valueNode, realType] of entries) {
3844
+ const missingContext = yield* pipe(
3845
+ checkForMissingErrorTypes(
3846
+ node,
3847
+ expectedType,
3848
+ valueNode,
3849
+ realType
3850
+ ),
3851
+ orElse3(() => succeed([]))
3852
+ );
3853
+ if (missingContext.length > 0) {
3854
+ effectDiagnostics.push(
3855
+ {
3856
+ node,
3857
+ category: ts.DiagnosticCategory.Error,
3858
+ messageText: `Missing '${sortTypes(missingContext).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect errors.`,
3859
+ fix: none2()
3860
+ }
3650
3861
  );
3651
3862
  }
3652
- changes.insertNodeAt(sourceFile, endNode.end, typeNode, { prefix: ": " });
3653
- }
3654
- });
3655
- }
3656
- function removeReturnTypeAnnotation(sourceFile, declaration) {
3657
- return gen2(function* () {
3658
- const ts = yield* service(TypeScriptApi);
3659
- const changes = yield* service(ChangeTracker);
3660
- const closeParen = ts.findChildOfKind(declaration, ts.SyntaxKind.CloseParenToken, sourceFile);
3661
- const needParens = ts.isArrowFunction(declaration) && closeParen === void 0;
3662
- const endNode = needParens ? declaration.parameters[0] : closeParen;
3663
- if (endNode && declaration.type) {
3664
- changes.deleteRange(sourceFile, { pos: endNode.end, end: declaration.type.end });
3665
3863
  }
3666
- });
3667
- }
3668
- var ImportModuleIdentifierNotFoundError = class extends TaggedError("@effect/language-service/ImportModuleIdentifierNotFoundError") {
3669
- };
3670
- function findImportedModuleIdentifier(sourceFile, test) {
3671
- return gen2(function* () {
3864
+ return effectDiagnostics;
3865
+ })
3866
+ });
3867
+
3868
+ // src/diagnostics/missingStarInYieldEffectGen.ts
3869
+ var missingStarInYieldEffectGen = createDiagnostic({
3870
+ name: "effect/missingStarInYieldEffectGen",
3871
+ code: 4,
3872
+ apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile) {
3672
3873
  const ts = yield* service(TypeScriptApi);
3673
- for (const statement of sourceFile.statements) {
3674
- if (!ts.isImportDeclaration(statement)) continue;
3675
- const importClause = statement.importClause;
3676
- if (!importClause) continue;
3677
- const namedBindings = importClause.namedBindings;
3678
- if (!namedBindings) continue;
3679
- if (ts.isNamespaceImport(namedBindings)) {
3680
- if (yield* test(namedBindings.name)) return namedBindings.name;
3681
- } else if (ts.isNamedImports(namedBindings)) {
3682
- for (const importSpecifier of namedBindings.elements) {
3683
- if (yield* test(importSpecifier.name)) return importSpecifier.name;
3874
+ const typeChecker = yield* service(TypeCheckerApi);
3875
+ const effectDiagnostics = [];
3876
+ const brokenGenerators = /* @__PURE__ */ new Set();
3877
+ const brokenYields = /* @__PURE__ */ new Set();
3878
+ const nodeToVisit = [];
3879
+ const appendNodeToVisit = (functionStarNode) => (node) => {
3880
+ nodeToVisit.push([node, functionStarNode]);
3881
+ return void 0;
3882
+ };
3883
+ ts.forEachChild(sourceFile, appendNodeToVisit(void 0));
3884
+ while (nodeToVisit.length > 0) {
3885
+ const [node, functionStarNode] = nodeToVisit.shift();
3886
+ if (functionStarNode && ts.isYieldExpression(node) && node.expression && node.asteriskToken === void 0) {
3887
+ const type = typeChecker.getTypeAtLocation(node.expression);
3888
+ const effect = yield* option(effectType(type, node.expression));
3889
+ if (isSome2(effect)) {
3890
+ brokenGenerators.add(functionStarNode);
3891
+ brokenYields.add(node);
3684
3892
  }
3685
3893
  }
3686
- }
3687
- return yield* fail3(new ImportModuleIdentifierNotFoundError());
3688
- });
3689
- }
3690
- function simplifyTypeNode(typeNode) {
3691
- function collectCallable(ts, typeNode2) {
3692
- if (ts.isParenthesizedTypeNode(typeNode2)) return collectCallable(ts, typeNode2.type);
3693
- if (ts.isFunctionTypeNode(typeNode2)) {
3694
- return some2([
3695
- ts.factory.createCallSignature(typeNode2.typeParameters, typeNode2.parameters, typeNode2.type)
3696
- ]);
3697
- }
3698
- if (ts.isTypeLiteralNode(typeNode2)) {
3699
- const allCallSignatures = typeNode2.members.every(ts.isCallSignatureDeclaration);
3700
- if (allCallSignatures) {
3701
- return some2(typeNode2.members);
3702
- }
3703
- }
3704
- if (ts.isIntersectionTypeNode(typeNode2)) {
3705
- const members = typeNode2.types.map((node) => collectCallable(ts, node));
3706
- if (members.every(isSome2)) {
3707
- return some2(members.map((_) => isSome2(_) ? _.value : []).flat());
3894
+ const effectGenLike = yield* pipe(
3895
+ effectGen(node),
3896
+ orElse3(() => effectFnUntracedGen(node)),
3897
+ orElse3(() => effectFnGen(node)),
3898
+ option
3899
+ );
3900
+ if (isSome2(effectGenLike)) {
3901
+ ts.forEachChild(
3902
+ effectGenLike.value.body,
3903
+ appendNodeToVisit(effectGenLike.value.functionStar)
3904
+ );
3905
+ } else if ((ts.isFunctionExpression(node) || ts.isMethodDeclaration(node)) && node.asteriskToken !== void 0) {
3906
+ ts.forEachChild(node, appendNodeToVisit(void 0));
3907
+ } else {
3908
+ ts.forEachChild(node, appendNodeToVisit(functionStarNode));
3708
3909
  }
3709
3910
  }
3710
- return none2();
3711
- }
3712
- return gen2(function* () {
3713
- const ts = yield* service(TypeScriptApi);
3714
- const callSignatures = collectCallable(ts, typeNode);
3715
- if (isSome2(callSignatures) && callSignatures.value.length > 1) {
3716
- return ts.factory.createTypeLiteralNode(callSignatures.value);
3717
- }
3718
- return typeNode;
3719
- });
3720
- }
3721
- function tryPreserveDeclarationSemantics(nodeToReplace, node) {
3722
- return gen2(function* () {
3911
+ brokenGenerators.forEach(
3912
+ (node) => effectDiagnostics.push({
3913
+ node,
3914
+ category: ts.DiagnosticCategory.Error,
3915
+ messageText: `Seems like you used yield instead of yield* inside this Effect.gen.`,
3916
+ fix: none2()
3917
+ })
3918
+ );
3919
+ brokenYields.forEach((node) => {
3920
+ const fix = node.expression ? some2({
3921
+ fixName: "missingStarInYieldEffectGen_fix",
3922
+ description: "Replace yield with yield*",
3923
+ apply: gen2(function* () {
3924
+ const changeTracker = yield* service(ChangeTracker);
3925
+ changeTracker.replaceNode(
3926
+ sourceFile,
3927
+ node,
3928
+ ts.factory.createYieldExpression(
3929
+ ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
3930
+ node.expression
3931
+ )
3932
+ );
3933
+ })
3934
+ }) : none2();
3935
+ effectDiagnostics.push({
3936
+ node,
3937
+ category: ts.DiagnosticCategory.Error,
3938
+ messageText: `When yielding Effects inside Effect.gen, you should use yield* instead of yield.`,
3939
+ fix
3940
+ });
3941
+ });
3942
+ return effectDiagnostics;
3943
+ })
3944
+ });
3945
+
3946
+ // src/diagnostics/unnecessaryEffectGen.ts
3947
+ var unnecessaryEffectGen = createDiagnostic({
3948
+ name: "effect/unnecessaryEffectGen",
3949
+ code: 5,
3950
+ apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile) {
3723
3951
  const ts = yield* service(TypeScriptApi);
3724
- if (!ts.isExpression(node)) return node;
3725
- if (ts.isFunctionDeclaration(nodeToReplace)) {
3726
- if (!nodeToReplace.name) return node;
3727
- return ts.factory.createVariableStatement(
3728
- nodeToReplace.modifiers,
3729
- ts.factory.createVariableDeclarationList(
3730
- [ts.factory.createVariableDeclaration(
3731
- nodeToReplace.name,
3732
- void 0,
3733
- void 0,
3734
- node
3735
- )],
3736
- ts.NodeFlags.Const
3737
- )
3738
- );
3739
- } else if (ts.isMethodDeclaration(nodeToReplace)) {
3740
- return ts.factory.createPropertyDeclaration(
3741
- nodeToReplace.modifiers,
3742
- nodeToReplace.name,
3743
- void 0,
3744
- void 0,
3745
- node
3952
+ const effectDiagnostics = [];
3953
+ const unnecessaryGenerators = /* @__PURE__ */ new Map();
3954
+ const nodeToVisit = [];
3955
+ const appendNodeToVisit = (node) => {
3956
+ nodeToVisit.push(node);
3957
+ return void 0;
3958
+ };
3959
+ ts.forEachChild(sourceFile, appendNodeToVisit);
3960
+ while (nodeToVisit.length > 0) {
3961
+ const node = nodeToVisit.shift();
3962
+ ts.forEachChild(node, appendNodeToVisit);
3963
+ const maybeUnnecessaryGen = yield* pipe(
3964
+ effectGen(node),
3965
+ flatMap4(({ body }) => returnYieldEffectBlock(body)),
3966
+ option
3746
3967
  );
3968
+ if (isSome2(maybeUnnecessaryGen)) {
3969
+ unnecessaryGenerators.set(node, maybeUnnecessaryGen.value);
3970
+ }
3747
3971
  }
3748
- return node;
3749
- });
3750
- }
3972
+ unnecessaryGenerators.forEach(
3973
+ (body, node) => effectDiagnostics.push({
3974
+ node,
3975
+ category: ts.DiagnosticCategory.Suggestion,
3976
+ messageText: `This Effect.gen is useless here because it only contains a single return statement.`,
3977
+ fix: some2({
3978
+ fixName: "unnecessaryEffectGen_fix",
3979
+ description: "Remove the Effect.gen, and keep the body",
3980
+ apply: gen2(function* () {
3981
+ const textChanges = yield* service(
3982
+ ChangeTracker
3983
+ );
3984
+ textChanges.replaceNode(sourceFile, node, body);
3985
+ })
3986
+ })
3987
+ })
3988
+ );
3989
+ return effectDiagnostics;
3990
+ })
3991
+ });
3992
+
3993
+ // src/diagnostics.ts
3994
+ var diagnostics = [
3995
+ missingEffectContext,
3996
+ missingEffectError,
3997
+ floatingEffect,
3998
+ missingStarInYieldEffectGen,
3999
+ unnecessaryEffectGen
4000
+ ];
3751
4001
 
3752
4002
  // src/quickinfo.ts
3753
4003
  var SymbolDisplayPartEq = make(
@@ -4427,12 +4677,89 @@ var init = (modules) => {
4427
4677
  const languageService = info.languageService;
4428
4678
  const pluginOptions = {
4429
4679
  diagnostics: info.config && "diagnostics" in info.config && typeof info.config.diagnostics === "boolean" ? info.config.diagnostics : true,
4430
- quickinfo: info.config && "quickinfo" in info.config && typeof info.config.quickinfo === "boolean" ? info.config.quickinfo : true
4680
+ quickinfo: info.config && "quickinfo" in info.config && typeof info.config.quickinfo === "boolean" ? info.config.quickinfo : true,
4681
+ completions: info.config && "completions" in info.config && typeof info.config.completions === "boolean" ? info.config.completions : true
4431
4682
  };
4432
4683
  const proxy = /* @__PURE__ */ Object.create(null);
4433
- for (const k of Object.keys(info.languageService)) {
4684
+ for (const k of Object.keys(languageService)) {
4434
4685
  proxy[k] = (...args) => languageService[k].apply(languageService, args);
4435
4686
  }
4687
+ const diagnosticsErrorCodes = diagnostics.map((diagnostic) => diagnostic.code);
4688
+ try {
4689
+ ;
4690
+ modules.typescript.codefix.registerCodeFix({
4691
+ errorCodes: diagnosticsErrorCodes,
4692
+ getCodeActions: () => void 0
4693
+ });
4694
+ } catch (_) {
4695
+ }
4696
+ proxy.getSupportedCodeFixes = (...args) => languageService.getSupportedCodeFixes(...args).concat(
4697
+ diagnosticsErrorCodes.map((_) => "" + _)
4698
+ );
4699
+ proxy.getCodeFixesAtPosition = (fileName, start, end, errorCodes, formatOptions, preferences, ...args) => {
4700
+ const applicableCodeFixes = languageService.getCodeFixesAtPosition(
4701
+ fileName,
4702
+ start,
4703
+ end,
4704
+ errorCodes,
4705
+ formatOptions,
4706
+ preferences,
4707
+ ...args
4708
+ );
4709
+ const program = languageService.getProgram();
4710
+ if (program) {
4711
+ const sourceFile = program.getSourceFile(fileName);
4712
+ if (sourceFile) {
4713
+ return pipe(
4714
+ gen2(function* () {
4715
+ const effectCodeFixes = [];
4716
+ const applicableFixes = yield* getCodeFixesAtPosition(
4717
+ diagnostics,
4718
+ sourceFile,
4719
+ start,
4720
+ end,
4721
+ errorCodes
4722
+ );
4723
+ const formatContext = modules.typescript.formatting.getFormatContext(
4724
+ formatOptions,
4725
+ info.languageServiceHost
4726
+ );
4727
+ for (const applicableFix of applicableFixes) {
4728
+ const changes = modules.typescript.textChanges.ChangeTracker.with(
4729
+ {
4730
+ formatContext,
4731
+ host: info.languageServiceHost,
4732
+ preferences: preferences || {}
4733
+ },
4734
+ (changeTracker) => pipe(
4735
+ applicableFix.apply,
4736
+ provideService(ChangeTracker, changeTracker),
4737
+ run
4738
+ )
4739
+ );
4740
+ effectCodeFixes.push({
4741
+ fixName: applicableFix.fixName,
4742
+ description: applicableFix.description,
4743
+ changes
4744
+ });
4745
+ }
4746
+ return effectCodeFixes;
4747
+ }),
4748
+ provideService(TypeCheckerApi, program.getTypeChecker()),
4749
+ provideService(
4750
+ TypeCheckerApiCache,
4751
+ makeTypeCheckerApiCache()
4752
+ ),
4753
+ provideService(TypeScriptApi, modules.typescript),
4754
+ provideService(PluginOptions, pluginOptions),
4755
+ run,
4756
+ Either_exports.map((effectCodeFixes) => applicableCodeFixes.concat(effectCodeFixes)),
4757
+ Either_exports.getOrElse(() => applicableCodeFixes)
4758
+ );
4759
+ }
4760
+ }
4761
+ return applicableCodeFixes;
4762
+ };
4436
4763
  proxy.getSemanticDiagnostics = (fileName, ...args) => {
4437
4764
  const applicableDiagnostics = languageService.getSemanticDiagnostics(fileName, ...args);
4438
4765
  const program = languageService.getProgram();
@@ -4441,8 +4768,12 @@ var init = (modules) => {
4441
4768
  if (sourceFile) {
4442
4769
  return pipe(
4443
4770
  getSemanticDiagnostics(diagnostics, sourceFile),
4444
- provideService(TypeScriptApi, modules.typescript),
4445
4771
  provideService(TypeCheckerApi, program.getTypeChecker()),
4772
+ provideService(
4773
+ TypeCheckerApiCache,
4774
+ makeTypeCheckerApiCache()
4775
+ ),
4776
+ provideService(TypeScriptApi, modules.typescript),
4446
4777
  provideService(PluginOptions, pluginOptions),
4447
4778
  run,
4448
4779
  Either_exports.map((effectDiagnostics) => effectDiagnostics.concat(applicableDiagnostics)),
@@ -4461,8 +4792,12 @@ var init = (modules) => {
4461
4792
  if (sourceFile) {
4462
4793
  return pipe(
4463
4794
  getApplicableRefactors(refactors, sourceFile, positionOrRange),
4464
- provideService(TypeScriptApi, modules.typescript),
4465
4795
  provideService(TypeCheckerApi, program.getTypeChecker()),
4796
+ provideService(
4797
+ TypeCheckerApiCache,
4798
+ makeTypeCheckerApiCache()
4799
+ ),
4800
+ provideService(TypeScriptApi, modules.typescript),
4466
4801
  provideService(PluginOptions, pluginOptions),
4467
4802
  run,
4468
4803
  Either_exports.map((effectRefactors) => applicableRefactors.concat(effectRefactors)),
@@ -4503,8 +4838,12 @@ var init = (modules) => {
4503
4838
  );
4504
4839
  return { edits };
4505
4840
  }),
4506
- provideService(TypeScriptApi, modules.typescript),
4507
4841
  provideService(TypeCheckerApi, program.getTypeChecker()),
4842
+ provideService(
4843
+ TypeCheckerApiCache,
4844
+ makeTypeCheckerApiCache()
4845
+ ),
4846
+ provideService(TypeScriptApi, modules.typescript),
4508
4847
  provideService(PluginOptions, pluginOptions),
4509
4848
  run
4510
4849
  );
@@ -4535,8 +4874,9 @@ var init = (modules) => {
4535
4874
  position,
4536
4875
  dedupedTagsQuickInfo
4537
4876
  ),
4538
- provideService(TypeScriptApi, modules.typescript),
4539
4877
  provideService(TypeCheckerApi, program.getTypeChecker()),
4878
+ provideService(TypeScriptApi, modules.typescript),
4879
+ provideService(PluginOptions, pluginOptions),
4540
4880
  run,
4541
4881
  Either_exports.getOrElse(() => dedupedTagsQuickInfo)
4542
4882
  );
@@ -4546,6 +4886,53 @@ var init = (modules) => {
4546
4886
  }
4547
4887
  return quickInfo;
4548
4888
  };
4889
+ proxy.getCompletionsAtPosition = (fileName, position, options, formattingSettings, ...args) => {
4890
+ const applicableCompletions = languageService.getCompletionsAtPosition(
4891
+ fileName,
4892
+ position,
4893
+ options,
4894
+ formattingSettings,
4895
+ ...args
4896
+ );
4897
+ if (pluginOptions.completions) {
4898
+ const program = languageService.getProgram();
4899
+ if (program) {
4900
+ const sourceFile = program.getSourceFile(fileName);
4901
+ if (sourceFile) {
4902
+ return pipe(
4903
+ getCompletionsAtPosition(
4904
+ completions,
4905
+ sourceFile,
4906
+ position,
4907
+ options,
4908
+ formattingSettings
4909
+ ),
4910
+ provideService(TypeCheckerApi, program.getTypeChecker()),
4911
+ provideService(
4912
+ TypeCheckerApiCache,
4913
+ makeTypeCheckerApiCache()
4914
+ ),
4915
+ provideService(TypeScriptApi, modules.typescript),
4916
+ provideService(PluginOptions, pluginOptions),
4917
+ run,
4918
+ Either_exports.map(
4919
+ (effectCompletions) => applicableCompletions ? {
4920
+ ...applicableCompletions,
4921
+ entries: effectCompletions.concat(applicableCompletions.entries)
4922
+ } : effectCompletions.length > 0 ? {
4923
+ entries: effectCompletions,
4924
+ isGlobalCompletion: false,
4925
+ isMemberCompletion: false,
4926
+ isNewIdentifierLocation: false
4927
+ } : void 0
4928
+ ),
4929
+ Either_exports.getOrElse(() => applicableCompletions)
4930
+ );
4931
+ }
4932
+ }
4933
+ }
4934
+ return applicableCompletions;
4935
+ };
4549
4936
  return proxy;
4550
4937
  }
4551
4938
  return { create };