@effect/language-service 0.25.0 → 0.26.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/README.md +5 -2
- package/cli.js +1954 -277
- package/cli.js.map +1 -1
- package/index.js +196 -18
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +127 -11
- package/transform.js.map +1 -1
package/index.js
CHANGED
|
@@ -903,6 +903,7 @@ var NanoFiber = class {
|
|
|
903
903
|
_stack = [];
|
|
904
904
|
_yielded = void 0;
|
|
905
905
|
_services = {};
|
|
906
|
+
_cache = {};
|
|
906
907
|
runLoop(nano) {
|
|
907
908
|
let current = nano;
|
|
908
909
|
while (true) {
|
|
@@ -1053,8 +1054,32 @@ var service = (tag) => {
|
|
|
1053
1054
|
nano[args] = tag;
|
|
1054
1055
|
return nano;
|
|
1055
1056
|
};
|
|
1056
|
-
|
|
1057
|
-
|
|
1057
|
+
var CachedProto = {
|
|
1058
|
+
...PrimitiveProto,
|
|
1059
|
+
[evaluate](fiber) {
|
|
1060
|
+
const [fa, type, key] = this[args];
|
|
1061
|
+
const cache = fiber._cache[type] || /* @__PURE__ */ new WeakMap();
|
|
1062
|
+
fiber._cache[type] = cache;
|
|
1063
|
+
const cached2 = cache.get(key);
|
|
1064
|
+
if (cached2) return cached2;
|
|
1065
|
+
return match2(fa, {
|
|
1066
|
+
onSuccess: (_) => {
|
|
1067
|
+
cache.set(key, succeed(_));
|
|
1068
|
+
return succeed(_);
|
|
1069
|
+
},
|
|
1070
|
+
onFailure: (_) => {
|
|
1071
|
+
cache.set(key, fail(_));
|
|
1072
|
+
return fail(_);
|
|
1073
|
+
}
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
function cachedBy(fa, type, lookupKey) {
|
|
1078
|
+
return (...p) => {
|
|
1079
|
+
const nano = Object.create(CachedProto);
|
|
1080
|
+
nano[args] = [fa(...p), type, lookupKey(...p)];
|
|
1081
|
+
return nano;
|
|
1082
|
+
};
|
|
1058
1083
|
}
|
|
1059
1084
|
var option = (fa) => {
|
|
1060
1085
|
const nano = Object.create(MatchProto);
|
|
@@ -2018,8 +2043,7 @@ var unrollUnionMembers = (type) => {
|
|
|
2018
2043
|
var appendToUniqueTypesMap = fn(
|
|
2019
2044
|
"TypeCheckerApi.appendToUniqueTypesMap"
|
|
2020
2045
|
)(
|
|
2021
|
-
function* (memory, initialType,
|
|
2022
|
-
const ts = yield* service(TypeScriptApi);
|
|
2046
|
+
function* (memory, initialType, shouldExclude) {
|
|
2023
2047
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2024
2048
|
const newIndexes = /* @__PURE__ */ new Set();
|
|
2025
2049
|
const knownIndexes = /* @__PURE__ */ new Set();
|
|
@@ -2027,7 +2051,7 @@ var appendToUniqueTypesMap = fn(
|
|
|
2027
2051
|
while (toTest.length > 0) {
|
|
2028
2052
|
const type = toTest.pop();
|
|
2029
2053
|
if (!type) break;
|
|
2030
|
-
if (
|
|
2054
|
+
if (yield* shouldExclude(type)) {
|
|
2031
2055
|
continue;
|
|
2032
2056
|
}
|
|
2033
2057
|
if (type.isUnion()) {
|
|
@@ -2650,11 +2674,16 @@ function make3(ts, typeChecker) {
|
|
|
2650
2674
|
const pipeCall = cachedBy(
|
|
2651
2675
|
function(node) {
|
|
2652
2676
|
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && node.expression.name.text === "pipe") {
|
|
2653
|
-
return succeed({
|
|
2677
|
+
return succeed({
|
|
2678
|
+
node,
|
|
2679
|
+
subject: node.expression.expression,
|
|
2680
|
+
args: Array.from(node.arguments),
|
|
2681
|
+
kind: "pipeable"
|
|
2682
|
+
});
|
|
2654
2683
|
}
|
|
2655
2684
|
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "pipe" && node.arguments.length > 0) {
|
|
2656
2685
|
const [subject, ...args2] = node.arguments;
|
|
2657
|
-
return succeed({ node, subject, args: args2 });
|
|
2686
|
+
return succeed({ node, subject, args: args2, kind: "pipe" });
|
|
2658
2687
|
}
|
|
2659
2688
|
return typeParserIssue("Node is not a pipe call", void 0, node);
|
|
2660
2689
|
},
|
|
@@ -2693,6 +2722,7 @@ function make3(ts, typeChecker) {
|
|
|
2693
2722
|
unnecessaryEffectGen: unnecessaryEffectGen2,
|
|
2694
2723
|
effectSchemaType,
|
|
2695
2724
|
contextTag,
|
|
2725
|
+
pipeableType,
|
|
2696
2726
|
pipeCall,
|
|
2697
2727
|
scopeType
|
|
2698
2728
|
};
|
|
@@ -3014,7 +3044,18 @@ var leakingRequirements = createDiagnostic({
|
|
|
3014
3044
|
);
|
|
3015
3045
|
if (effectContextType) {
|
|
3016
3046
|
effectMembers++;
|
|
3017
|
-
const { allIndexes } = yield* appendToUniqueTypesMap(
|
|
3047
|
+
const { allIndexes } = yield* appendToUniqueTypesMap(
|
|
3048
|
+
memory,
|
|
3049
|
+
effectContextType,
|
|
3050
|
+
(type) => {
|
|
3051
|
+
if (type.flags & ts.TypeFlags.Never) return succeed(true);
|
|
3052
|
+
return pipe(
|
|
3053
|
+
typeParser.scopeType(type, atLocation),
|
|
3054
|
+
map4(() => true),
|
|
3055
|
+
orElse2(() => succeed(false))
|
|
3056
|
+
);
|
|
3057
|
+
}
|
|
3058
|
+
);
|
|
3018
3059
|
if (!sharedRequirementsKeys) {
|
|
3019
3060
|
sharedRequirementsKeys = allIndexes;
|
|
3020
3061
|
} else {
|
|
@@ -3570,8 +3611,8 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
|
|
|
3570
3611
|
// src/diagnostics/tryCatchInEffectGen.ts
|
|
3571
3612
|
var tryCatchInEffectGen = createDiagnostic({
|
|
3572
3613
|
name: "tryCatchInEffectGen",
|
|
3573
|
-
code:
|
|
3574
|
-
severity: "
|
|
3614
|
+
code: 15,
|
|
3615
|
+
severity: "suggestion",
|
|
3575
3616
|
apply: fn("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
|
|
3576
3617
|
const ts = yield* service(TypeScriptApi);
|
|
3577
3618
|
const typeParser = yield* service(TypeParser);
|
|
@@ -3700,6 +3741,80 @@ var unnecessaryPipe = createDiagnostic({
|
|
|
3700
3741
|
})
|
|
3701
3742
|
});
|
|
3702
3743
|
|
|
3744
|
+
// src/diagnostics/unnecessaryPipeChain.ts
|
|
3745
|
+
var unnecessaryPipeChain = createDiagnostic({
|
|
3746
|
+
name: "unnecessaryPipeChain",
|
|
3747
|
+
code: 16,
|
|
3748
|
+
severity: "suggestion",
|
|
3749
|
+
apply: fn("unnecessaryPipeChain.apply")(function* (sourceFile, report) {
|
|
3750
|
+
const ts = yield* service(TypeScriptApi);
|
|
3751
|
+
const typeParser = yield* service(TypeParser);
|
|
3752
|
+
const nodeToVisit = [];
|
|
3753
|
+
const appendNodeToVisit = (node) => {
|
|
3754
|
+
nodeToVisit.push(node);
|
|
3755
|
+
return void 0;
|
|
3756
|
+
};
|
|
3757
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
3758
|
+
while (nodeToVisit.length > 0) {
|
|
3759
|
+
const node = nodeToVisit.shift();
|
|
3760
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
3761
|
+
if (ts.isCallExpression(node)) {
|
|
3762
|
+
yield* pipe(
|
|
3763
|
+
typeParser.pipeCall(node),
|
|
3764
|
+
flatMap2(
|
|
3765
|
+
(pipeCall) => map4(typeParser.pipeCall(pipeCall.subject), (innerCall) => ({ pipeCall, innerCall }))
|
|
3766
|
+
),
|
|
3767
|
+
map4(({ innerCall, pipeCall }) => {
|
|
3768
|
+
report({
|
|
3769
|
+
node,
|
|
3770
|
+
messageText: `Chained pipe calls can be simplified to a single pipe call`,
|
|
3771
|
+
fixes: [{
|
|
3772
|
+
fixName: "unnecessaryPipeChain_fix",
|
|
3773
|
+
description: "Rewrite as single pipe call",
|
|
3774
|
+
apply: gen(function* () {
|
|
3775
|
+
const changeTracker = yield* service(
|
|
3776
|
+
ChangeTracker
|
|
3777
|
+
);
|
|
3778
|
+
switch (innerCall.kind) {
|
|
3779
|
+
case "pipe": {
|
|
3780
|
+
changeTracker.replaceNode(
|
|
3781
|
+
sourceFile,
|
|
3782
|
+
node,
|
|
3783
|
+
ts.factory.createCallExpression(
|
|
3784
|
+
ts.factory.createIdentifier("pipe"),
|
|
3785
|
+
void 0,
|
|
3786
|
+
[innerCall.subject, ...innerCall.args, ...pipeCall.args]
|
|
3787
|
+
)
|
|
3788
|
+
);
|
|
3789
|
+
break;
|
|
3790
|
+
}
|
|
3791
|
+
case "pipeable": {
|
|
3792
|
+
changeTracker.replaceNode(
|
|
3793
|
+
sourceFile,
|
|
3794
|
+
node,
|
|
3795
|
+
ts.factory.createCallExpression(
|
|
3796
|
+
ts.factory.createPropertyAccessExpression(
|
|
3797
|
+
innerCall.subject,
|
|
3798
|
+
"pipe"
|
|
3799
|
+
),
|
|
3800
|
+
void 0,
|
|
3801
|
+
[...innerCall.args, ...pipeCall.args]
|
|
3802
|
+
)
|
|
3803
|
+
);
|
|
3804
|
+
break;
|
|
3805
|
+
}
|
|
3806
|
+
}
|
|
3807
|
+
})
|
|
3808
|
+
}]
|
|
3809
|
+
});
|
|
3810
|
+
}),
|
|
3811
|
+
ignore
|
|
3812
|
+
);
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
3815
|
+
})
|
|
3816
|
+
});
|
|
3817
|
+
|
|
3703
3818
|
// src/diagnostics.ts
|
|
3704
3819
|
var diagnostics = [
|
|
3705
3820
|
duplicatePackage,
|
|
@@ -3716,7 +3831,8 @@ var diagnostics = [
|
|
|
3716
3831
|
tryCatchInEffectGen,
|
|
3717
3832
|
importFromBarrel,
|
|
3718
3833
|
scopeInLayerEffect,
|
|
3719
|
-
effectInVoidSuccess
|
|
3834
|
+
effectInVoidSuccess,
|
|
3835
|
+
unnecessaryPipeChain
|
|
3720
3836
|
];
|
|
3721
3837
|
|
|
3722
3838
|
// src/completions/effectDiagnosticsComment.ts
|
|
@@ -8796,6 +8912,7 @@ function processLayerGraphNode(ctx, node, pipedInGraphNode) {
|
|
|
8796
8912
|
const ts = yield* service(TypeScriptApi);
|
|
8797
8913
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
8798
8914
|
const typeParser = yield* service(TypeParser);
|
|
8915
|
+
const excludeNever = (type) => succeed((type.flags & ts.TypeFlags.Never) !== 0);
|
|
8799
8916
|
const maybePipe = yield* option(typeParser.pipeCall(node));
|
|
8800
8917
|
if (isSome2(maybePipe)) {
|
|
8801
8918
|
let graphNode = yield* processLayerGraphNode(ctx, maybePipe.value.subject, void 0);
|
|
@@ -8815,12 +8932,12 @@ function processLayerGraphNode(ctx, node, pipedInGraphNode) {
|
|
|
8815
8932
|
const { allIndexes: outTypes } = yield* appendToUniqueTypesMap(
|
|
8816
8933
|
ctx.services,
|
|
8817
8934
|
maybeLayer.value.ROut,
|
|
8818
|
-
|
|
8935
|
+
excludeNever
|
|
8819
8936
|
);
|
|
8820
8937
|
const { allIndexes: inTypes } = yield* appendToUniqueTypesMap(
|
|
8821
8938
|
ctx.services,
|
|
8822
8939
|
maybeLayer.value.RIn,
|
|
8823
|
-
|
|
8940
|
+
excludeNever
|
|
8824
8941
|
);
|
|
8825
8942
|
return new GraphNodeCompoundTransform(
|
|
8826
8943
|
ctx.nextId(),
|
|
@@ -8844,12 +8961,12 @@ function processLayerGraphNode(ctx, node, pipedInGraphNode) {
|
|
|
8844
8961
|
const { allIndexes: outTypes } = yield* appendToUniqueTypesMap(
|
|
8845
8962
|
ctx.services,
|
|
8846
8963
|
maybeLayer.value.ROut,
|
|
8847
|
-
|
|
8964
|
+
excludeNever
|
|
8848
8965
|
);
|
|
8849
8966
|
const { allIndexes: inTypes } = yield* appendToUniqueTypesMap(
|
|
8850
8967
|
ctx.services,
|
|
8851
8968
|
maybeLayer.value.RIn,
|
|
8852
|
-
|
|
8969
|
+
excludeNever
|
|
8853
8970
|
);
|
|
8854
8971
|
if (ts.isCallExpression(node)) {
|
|
8855
8972
|
const argNodes = yield* option(
|
|
@@ -8894,12 +9011,12 @@ function processLayerGraphNode(ctx, node, pipedInGraphNode) {
|
|
|
8894
9011
|
const { allIndexes: outTypes } = yield* appendToUniqueTypesMap(
|
|
8895
9012
|
ctx.services,
|
|
8896
9013
|
maybeLayer.value.ROut,
|
|
8897
|
-
|
|
9014
|
+
excludeNever
|
|
8898
9015
|
);
|
|
8899
9016
|
const { allIndexes: inTypes } = yield* appendToUniqueTypesMap(
|
|
8900
9017
|
ctx.services,
|
|
8901
9018
|
maybeLayer.value.RIn,
|
|
8902
|
-
|
|
9019
|
+
excludeNever
|
|
8903
9020
|
);
|
|
8904
9021
|
return new GraphNodeLeaf(ctx.nextId(), node, outTypes, inTypes);
|
|
8905
9022
|
}
|
|
@@ -9892,6 +10009,66 @@ var toggleLazyConst = createRefactor({
|
|
|
9892
10009
|
})
|
|
9893
10010
|
});
|
|
9894
10011
|
|
|
10012
|
+
// src/refactors/togglePipeStyle.ts
|
|
10013
|
+
var togglePipeStyle = createRefactor({
|
|
10014
|
+
name: "togglePipeStyle",
|
|
10015
|
+
description: "Toggle pipe style",
|
|
10016
|
+
apply: fn("togglePipeStyle.apply")(function* (sourceFile, textRange) {
|
|
10017
|
+
const ts = yield* service(TypeScriptApi);
|
|
10018
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
10019
|
+
const typeParser = yield* service(TypeParser);
|
|
10020
|
+
const togglePipeStyle2 = (node) => gen(function* () {
|
|
10021
|
+
const pipeCall = yield* typeParser.pipeCall(node);
|
|
10022
|
+
switch (pipeCall.kind) {
|
|
10023
|
+
case "pipe": {
|
|
10024
|
+
yield* typeParser.pipeableType(typeChecker.getTypeAtLocation(pipeCall.subject), pipeCall.subject);
|
|
10025
|
+
return {
|
|
10026
|
+
kind: "refactor.rewrite.effect.togglePipeStyle",
|
|
10027
|
+
description: "Rewrite as X.pipe(Y, Z, ...)",
|
|
10028
|
+
apply: gen(function* () {
|
|
10029
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
10030
|
+
changeTracker.replaceNode(
|
|
10031
|
+
sourceFile,
|
|
10032
|
+
node,
|
|
10033
|
+
ts.factory.createCallExpression(
|
|
10034
|
+
ts.factory.createPropertyAccessExpression(
|
|
10035
|
+
pipeCall.subject,
|
|
10036
|
+
"pipe"
|
|
10037
|
+
),
|
|
10038
|
+
void 0,
|
|
10039
|
+
pipeCall.args
|
|
10040
|
+
)
|
|
10041
|
+
);
|
|
10042
|
+
})
|
|
10043
|
+
};
|
|
10044
|
+
}
|
|
10045
|
+
case "pipeable":
|
|
10046
|
+
return {
|
|
10047
|
+
kind: "refactor.rewrite.effect.togglePipeStyle",
|
|
10048
|
+
description: "Rewrite as pipe(X, Y, Z, ...)",
|
|
10049
|
+
apply: gen(function* () {
|
|
10050
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
10051
|
+
changeTracker.replaceNode(
|
|
10052
|
+
sourceFile,
|
|
10053
|
+
node,
|
|
10054
|
+
ts.factory.createCallExpression(
|
|
10055
|
+
ts.factory.createIdentifier("pipe"),
|
|
10056
|
+
void 0,
|
|
10057
|
+
[pipeCall.subject].concat(pipeCall.args)
|
|
10058
|
+
)
|
|
10059
|
+
);
|
|
10060
|
+
})
|
|
10061
|
+
};
|
|
10062
|
+
}
|
|
10063
|
+
});
|
|
10064
|
+
const ancestorNodes = yield* getAncestorNodesInRange(sourceFile, textRange);
|
|
10065
|
+
return yield* pipe(
|
|
10066
|
+
firstSuccessOf(ancestorNodes.map(togglePipeStyle2)),
|
|
10067
|
+
orElse2(() => fail(new RefactorNotApplicableError()))
|
|
10068
|
+
);
|
|
10069
|
+
})
|
|
10070
|
+
});
|
|
10071
|
+
|
|
9895
10072
|
// src/refactors/toggleReturnTypeAnnotation.ts
|
|
9896
10073
|
var toggleReturnTypeAnnotation = createRefactor({
|
|
9897
10074
|
name: "toggleReturnTypeAnnotation",
|
|
@@ -10608,7 +10785,8 @@ var refactors = [
|
|
|
10608
10785
|
toggleTypeAnnotation,
|
|
10609
10786
|
wrapWithEffectGen,
|
|
10610
10787
|
wrapWithPipe,
|
|
10611
|
-
effectGenToFn
|
|
10788
|
+
effectGenToFn,
|
|
10789
|
+
togglePipeStyle
|
|
10612
10790
|
];
|
|
10613
10791
|
|
|
10614
10792
|
// src/index.ts
|