@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.
- package/index.js +1238 -851
- package/index.js.map +1 -1
- 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) =>
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
);
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
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 (
|
|
2708
|
-
|
|
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 (
|
|
2714
|
-
|
|
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 (
|
|
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: () =>
|
|
2727
|
-
onSome: (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 (
|
|
2753
|
+
if (result._tag !== "Right") {
|
|
2740
2754
|
return result;
|
|
2741
2755
|
}
|
|
2742
|
-
|
|
2743
|
-
|
|
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(
|
|
2769
|
+
state = iterator.next(result.right);
|
|
2747
2770
|
}
|
|
2748
|
-
return
|
|
2771
|
+
return { _tag: "Right", right: state.value };
|
|
2749
2772
|
});
|
|
2750
2773
|
var option = (fa) => new Nano((ctx) => {
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
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
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
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
|
-
|
|
2790
|
-
|
|
2791
|
-
}
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
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:
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
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
|
-
|
|
2820
|
-
|
|
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/
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
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
|
|
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
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
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
|
|
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
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
function
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
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
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
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
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
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
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
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
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
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
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
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.
|
|
2956
|
-
const
|
|
2957
|
-
if (
|
|
2958
|
-
|
|
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.
|
|
2964
|
-
const
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3465
|
+
result.push([node.expression, expectedType, node.expression, realType]);
|
|
3466
|
+
continue;
|
|
2973
3467
|
}
|
|
2974
|
-
|
|
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
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
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
|
-
|
|
3018
|
-
return
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
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
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
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(
|
|
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(
|
|
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 !== "
|
|
3110
|
-
return yield* typeParserIssue(
|
|
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
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
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
|
|
3664
|
+
"Node is not a function expression",
|
|
3230
3665
|
void 0,
|
|
3231
|
-
|
|
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: (
|
|
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: (
|
|
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
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
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
|
|
3309
|
-
const
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
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: (
|
|
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
|
-
|
|
3352
|
-
|
|
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
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
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
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
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
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
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
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
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
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
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
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
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
|
-
|
|
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(
|
|
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 };
|