@effect/language-service 0.10.2 → 0.12.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 +1 -0
- package/index.js +359 -52
- package/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,6 +71,7 @@ Few options can be provided alongside the initialization of the Language Service
|
|
|
71
71
|
- Pipe to datafirst: Transform a pipe() call into a series of datafirst function calls (where available).
|
|
72
72
|
- Toggle return type signature: With a single refactor, adds or removes type annotations from the definition.
|
|
73
73
|
- Remove unnecessary `Effect.gen` definitions that contains a single `yield` statement.
|
|
74
|
+
- Wrap an `Effect` expression with `Effect.gen`
|
|
74
75
|
|
|
75
76
|
## Configuring diagnostics
|
|
76
77
|
|
package/index.js
CHANGED
|
@@ -1166,24 +1166,7 @@ var transformAsyncAwaitToEffectGen = fn("AST.transformAsyncAwaitToEffectGen")(
|
|
|
1166
1166
|
return ts.visitEachChild(_, visitor, ts.nullTransformationContext);
|
|
1167
1167
|
}
|
|
1168
1168
|
const generatorBody = visitor(node.body);
|
|
1169
|
-
const
|
|
1170
|
-
void 0,
|
|
1171
|
-
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
1172
|
-
void 0,
|
|
1173
|
-
[],
|
|
1174
|
-
[],
|
|
1175
|
-
void 0,
|
|
1176
|
-
generatorBody
|
|
1177
|
-
// NOTE(mattia): intended, to use same routine for both ConciseBody and Body
|
|
1178
|
-
);
|
|
1179
|
-
const effectGenCallExp = ts.factory.createCallExpression(
|
|
1180
|
-
ts.factory.createPropertyAccessExpression(
|
|
1181
|
-
ts.factory.createIdentifier(effectModuleName),
|
|
1182
|
-
"gen"
|
|
1183
|
-
),
|
|
1184
|
-
void 0,
|
|
1185
|
-
[generator]
|
|
1186
|
-
);
|
|
1169
|
+
const effectGenCallExp = yield* createEffectGenCallExpression(effectModuleName, generatorBody);
|
|
1187
1170
|
let currentFlags = ts.getCombinedModifierFlags(node);
|
|
1188
1171
|
currentFlags &= ~ts.ModifierFlags.Async;
|
|
1189
1172
|
const newModifiers = ts.factory.createModifiersFromModifierFlags(currentFlags);
|
|
@@ -1405,6 +1388,47 @@ var parseDataForExtendsClassCompletion = fn(
|
|
|
1405
1388
|
{ accessedObject, classDeclaration, className: classDeclaration.name, replacementSpan }
|
|
1406
1389
|
);
|
|
1407
1390
|
});
|
|
1391
|
+
var createEffectGenCallExpression = fn("AST.createEffectGenCallExpression")(function* (effectModuleIdentifierName, node) {
|
|
1392
|
+
const ts = yield* service(TypeScriptApi);
|
|
1393
|
+
const generator = ts.factory.createFunctionExpression(
|
|
1394
|
+
void 0,
|
|
1395
|
+
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
1396
|
+
void 0,
|
|
1397
|
+
[],
|
|
1398
|
+
[],
|
|
1399
|
+
void 0,
|
|
1400
|
+
node
|
|
1401
|
+
// NOTE(mattia): intended, to use same routine for both ConciseBody and Body
|
|
1402
|
+
);
|
|
1403
|
+
return ts.factory.createCallExpression(
|
|
1404
|
+
ts.factory.createPropertyAccessExpression(
|
|
1405
|
+
ts.factory.createIdentifier(effectModuleIdentifierName),
|
|
1406
|
+
"gen"
|
|
1407
|
+
),
|
|
1408
|
+
void 0,
|
|
1409
|
+
[generator]
|
|
1410
|
+
);
|
|
1411
|
+
});
|
|
1412
|
+
var createEffectGenCallExpressionWithBlock = fn(
|
|
1413
|
+
"AST.createEffectGenCallExpressionWithBlock"
|
|
1414
|
+
)(function* (effectModuleIdentifierName, statement) {
|
|
1415
|
+
const ts = yield* service(TypeScriptApi);
|
|
1416
|
+
return yield* createEffectGenCallExpression(
|
|
1417
|
+
effectModuleIdentifierName,
|
|
1418
|
+
ts.factory.createBlock(Array.isArray(statement) ? statement : [statement], false)
|
|
1419
|
+
);
|
|
1420
|
+
});
|
|
1421
|
+
var createReturnYieldStarStatement = fn("AST.createReturnYieldStarStatement")(
|
|
1422
|
+
function* (expr) {
|
|
1423
|
+
const ts = yield* service(TypeScriptApi);
|
|
1424
|
+
return ts.factory.createReturnStatement(
|
|
1425
|
+
ts.factory.createYieldExpression(
|
|
1426
|
+
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
1427
|
+
expr
|
|
1428
|
+
)
|
|
1429
|
+
);
|
|
1430
|
+
}
|
|
1431
|
+
);
|
|
1408
1432
|
|
|
1409
1433
|
// src/core/LSP.ts
|
|
1410
1434
|
var RefactorNotApplicableError = class {
|
|
@@ -1945,6 +1969,13 @@ function covariantTypeArgument(type) {
|
|
|
1945
1969
|
}
|
|
1946
1970
|
return succeed(signatures[0].getReturnType());
|
|
1947
1971
|
}
|
|
1972
|
+
function invariantTypeArgument(type) {
|
|
1973
|
+
const signatures = type.getCallSignatures();
|
|
1974
|
+
if (signatures.length !== 1) {
|
|
1975
|
+
return typeParserIssue("Invariant type has no call signature", type);
|
|
1976
|
+
}
|
|
1977
|
+
return succeed(signatures[0].getReturnType());
|
|
1978
|
+
}
|
|
1948
1979
|
var pipeableType = fn("TypeParser.pipeableType")(function* (type, atLocation) {
|
|
1949
1980
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
1950
1981
|
const pipeSymbol = typeChecker.getPropertyOfType(type, "pipe");
|
|
@@ -1969,6 +2000,17 @@ var varianceStructCovariantType = fn("TypeParser.varianceStructCovariantType")(
|
|
|
1969
2000
|
return yield* covariantTypeArgument(propertyType);
|
|
1970
2001
|
}
|
|
1971
2002
|
);
|
|
2003
|
+
var varianceStructInvariantType = fn("TypeParser.varianceStructInvariantType")(
|
|
2004
|
+
function* (type, atLocation, propertyName) {
|
|
2005
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
2006
|
+
const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
|
|
2007
|
+
if (!propertySymbol) {
|
|
2008
|
+
return yield* typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
|
|
2009
|
+
}
|
|
2010
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2011
|
+
return yield* invariantTypeArgument(propertyType);
|
|
2012
|
+
}
|
|
2013
|
+
);
|
|
1972
2014
|
var effectVarianceStruct = fn("TypeParser.effectVarianceStruct")(function* (type, atLocation) {
|
|
1973
2015
|
return {
|
|
1974
2016
|
A: yield* varianceStructCovariantType(type, atLocation, "_A"),
|
|
@@ -2175,6 +2217,37 @@ var returnYieldEffectBlock = fn("TypeParser.returnYieldEffectBlock")(function* (
|
|
|
2175
2217
|
body
|
|
2176
2218
|
);
|
|
2177
2219
|
});
|
|
2220
|
+
var effectSchemaVarianceStruct = fn("TypeParser.effectSchemaVarianceStruct")(
|
|
2221
|
+
function* (type, atLocation) {
|
|
2222
|
+
return {
|
|
2223
|
+
A: yield* varianceStructInvariantType(type, atLocation, "_A"),
|
|
2224
|
+
I: yield* varianceStructInvariantType(type, atLocation, "_I"),
|
|
2225
|
+
R: yield* varianceStructCovariantType(type, atLocation, "_R")
|
|
2226
|
+
};
|
|
2227
|
+
}
|
|
2228
|
+
);
|
|
2229
|
+
var effectSchemaType = fn("TypeParser.effectSchemaType")(function* (type, atLocation) {
|
|
2230
|
+
const ts = yield* service(TypeScriptApi);
|
|
2231
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
2232
|
+
yield* pipeableType(type, atLocation);
|
|
2233
|
+
const ast = typeChecker.getPropertyOfType(type, "ast");
|
|
2234
|
+
if (!ast) return yield* typeParserIssue("Has no 'ast' property", type, atLocation);
|
|
2235
|
+
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2236
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2237
|
+
);
|
|
2238
|
+
propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
|
|
2239
|
+
for (const propertySymbol of propertiesSymbols) {
|
|
2240
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2241
|
+
const varianceArgs = yield* option(effectSchemaVarianceStruct(
|
|
2242
|
+
propertyType,
|
|
2243
|
+
atLocation
|
|
2244
|
+
));
|
|
2245
|
+
if (isSome2(varianceArgs)) {
|
|
2246
|
+
return varianceArgs.value;
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
return yield* typeParserIssue("Type has no schema variance struct", type, atLocation);
|
|
2250
|
+
});
|
|
2178
2251
|
|
|
2179
2252
|
// src/diagnostics/floatingEffect.ts
|
|
2180
2253
|
var floatingEffect = createDiagnostic({
|
|
@@ -2535,7 +2608,7 @@ function prependEffectTypeArguments(sourceFile, position, quickInfo) {
|
|
|
2535
2608
|
var asyncAwaitToGen = createRefactor({
|
|
2536
2609
|
name: "effect/asyncAwaitToGen",
|
|
2537
2610
|
description: "Convert to Effect.gen",
|
|
2538
|
-
apply: (
|
|
2611
|
+
apply: fn("asyncAwaitToGen.apply")(function* (sourceFile, textRange) {
|
|
2539
2612
|
const ts = yield* service(TypeScriptApi);
|
|
2540
2613
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2541
2614
|
const maybeNode = pipe(
|
|
@@ -2607,7 +2680,7 @@ var asyncAwaitToGen = createRefactor({
|
|
|
2607
2680
|
var asyncAwaitToGenTryPromise = createRefactor({
|
|
2608
2681
|
name: "effect/asyncAwaitToGenTryPromise",
|
|
2609
2682
|
description: "Convert to Effect.gen with failures",
|
|
2610
|
-
apply: (
|
|
2683
|
+
apply: fn("asyncAwaitToGenTryPromise.apply")(function* (sourceFile, textRange) {
|
|
2611
2684
|
const ts = yield* service(TypeScriptApi);
|
|
2612
2685
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2613
2686
|
const maybeNode = pipe(
|
|
@@ -2709,34 +2782,32 @@ var asyncAwaitToGenTryPromise = createRefactor({
|
|
|
2709
2782
|
var effectGenToFn = createRefactor({
|
|
2710
2783
|
name: "effect/effectGenToFn",
|
|
2711
2784
|
description: "Convert to Effect.fn",
|
|
2712
|
-
apply: (
|
|
2785
|
+
apply: fn("effectGenToFn.apply")(function* (sourceFile, textRange) {
|
|
2713
2786
|
const ts = yield* service(TypeScriptApi);
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2787
|
+
const parseEffectGenNode = fn("asyncAwaitToGen.apply")(function* (node) {
|
|
2788
|
+
const effectGen2 = yield* effectGen(node);
|
|
2789
|
+
let pipeArgs2 = ts.factory.createNodeArray([]);
|
|
2790
|
+
let nodeToReplace2 = node.parent;
|
|
2791
|
+
if (ts.isPropertyAccessExpression(node.parent) && node.parent.name.text === "pipe" && ts.isCallExpression(node.parent.parent)) {
|
|
2792
|
+
pipeArgs2 = node.parent.parent.arguments;
|
|
2793
|
+
nodeToReplace2 = node.parent.parent.parent;
|
|
2794
|
+
}
|
|
2795
|
+
while (nodeToReplace2) {
|
|
2796
|
+
if (ts.isArrowFunction(nodeToReplace2) || ts.isFunctionDeclaration(nodeToReplace2) || ts.isMethodDeclaration(nodeToReplace2)) {
|
|
2797
|
+
return { ...effectGen2, pipeArgs: pipeArgs2, nodeToReplace: nodeToReplace2 };
|
|
2722
2798
|
}
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
}
|
|
2727
|
-
if (ts.isConciseBody(nodeToReplace2) || ts.isReturnStatement(nodeToReplace2)) {
|
|
2728
|
-
nodeToReplace2 = nodeToReplace2.parent;
|
|
2729
|
-
continue;
|
|
2730
|
-
}
|
|
2731
|
-
if (ts.isBlock(nodeToReplace2) && nodeToReplace2.statements.length === 1) {
|
|
2732
|
-
nodeToReplace2 = nodeToReplace2.parent;
|
|
2733
|
-
continue;
|
|
2734
|
-
}
|
|
2735
|
-
break;
|
|
2799
|
+
if (ts.isConciseBody(nodeToReplace2) || ts.isReturnStatement(nodeToReplace2)) {
|
|
2800
|
+
nodeToReplace2 = nodeToReplace2.parent;
|
|
2801
|
+
continue;
|
|
2736
2802
|
}
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2803
|
+
if (ts.isBlock(nodeToReplace2) && nodeToReplace2.statements.length === 1) {
|
|
2804
|
+
nodeToReplace2 = nodeToReplace2.parent;
|
|
2805
|
+
continue;
|
|
2806
|
+
}
|
|
2807
|
+
break;
|
|
2808
|
+
}
|
|
2809
|
+
return yield* fail(new RefactorNotApplicableError());
|
|
2810
|
+
});
|
|
2740
2811
|
const maybeNode = yield* pipe(
|
|
2741
2812
|
yield* getAncestorNodesInRange(sourceFile, textRange),
|
|
2742
2813
|
map2(parseEffectGenNode),
|
|
@@ -2791,7 +2862,7 @@ var effectGenToFn = createRefactor({
|
|
|
2791
2862
|
var functionToArrow = createRefactor({
|
|
2792
2863
|
name: "effect/functionToArrow",
|
|
2793
2864
|
description: "Convert to arrow",
|
|
2794
|
-
apply: (
|
|
2865
|
+
apply: fn("functionToArrow.apply")(function* (sourceFile, textRange) {
|
|
2795
2866
|
const ts = yield* service(TypeScriptApi);
|
|
2796
2867
|
const maybeNode = pipe(
|
|
2797
2868
|
yield* getAncestorNodesInRange(sourceFile, textRange),
|
|
@@ -2843,11 +2914,180 @@ var functionToArrow = createRefactor({
|
|
|
2843
2914
|
})
|
|
2844
2915
|
});
|
|
2845
2916
|
|
|
2917
|
+
// src/refactors/makeSchemaOpaque.ts
|
|
2918
|
+
var makeSchemaOpaque = createRefactor({
|
|
2919
|
+
name: "effect/makeSchemaOpaque",
|
|
2920
|
+
description: "Make Schema opaque",
|
|
2921
|
+
apply: fn("makeSchemaOpaque.apply")(function* (sourceFile, textRange) {
|
|
2922
|
+
const ts = yield* service(TypeScriptApi);
|
|
2923
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
2924
|
+
const findSchema = fn("makeSchemaOpaque.apply.findSchema")(
|
|
2925
|
+
function* (node) {
|
|
2926
|
+
if (!ts.isVariableDeclaration(node)) {
|
|
2927
|
+
return yield* fail("parent should be variable declaration");
|
|
2928
|
+
}
|
|
2929
|
+
const identifier2 = node.name;
|
|
2930
|
+
if (!ts.isIdentifier(identifier2)) return yield* fail("name should be an identifier");
|
|
2931
|
+
const initializer = node.initializer;
|
|
2932
|
+
if (!initializer) return yield* fail("should have an initializer");
|
|
2933
|
+
const variableDeclarationList2 = node.parent;
|
|
2934
|
+
if (!variableDeclarationList2 || !ts.isVariableDeclarationList(variableDeclarationList2)) {
|
|
2935
|
+
return yield* fail("parent is not a variable declaration list");
|
|
2936
|
+
}
|
|
2937
|
+
const variableStatement2 = variableDeclarationList2.parent;
|
|
2938
|
+
if (!variableStatement2 || !ts.isVariableStatement(variableStatement2)) {
|
|
2939
|
+
return yield* fail("parent not variable declaration statement");
|
|
2940
|
+
}
|
|
2941
|
+
const type = typeChecker.getTypeAtLocation(initializer);
|
|
2942
|
+
const types2 = yield* effectSchemaType(type, initializer);
|
|
2943
|
+
return { identifier: identifier2, variableStatement: variableStatement2, variableDeclarationList: variableDeclarationList2, types: types2 };
|
|
2944
|
+
}
|
|
2945
|
+
);
|
|
2946
|
+
const maybeNode = yield* pipe(
|
|
2947
|
+
yield* getAncestorNodesInRange(sourceFile, textRange),
|
|
2948
|
+
map2(findSchema),
|
|
2949
|
+
firstSuccessOf,
|
|
2950
|
+
option
|
|
2951
|
+
);
|
|
2952
|
+
if (isNone2(maybeNode)) return yield* fail(new RefactorNotApplicableError());
|
|
2953
|
+
const { identifier, types, variableDeclarationList, variableStatement } = maybeNode.value;
|
|
2954
|
+
return {
|
|
2955
|
+
kind: "refactor.rewrite.effect.makeSchemaOpaque",
|
|
2956
|
+
description: `Make Schema opaque`,
|
|
2957
|
+
apply: pipe(
|
|
2958
|
+
gen2(function* () {
|
|
2959
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
2960
|
+
const effectSchemaName = match2(
|
|
2961
|
+
yield* option(
|
|
2962
|
+
findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
2963
|
+
sourceFile,
|
|
2964
|
+
"effect",
|
|
2965
|
+
"Schema"
|
|
2966
|
+
)
|
|
2967
|
+
),
|
|
2968
|
+
{
|
|
2969
|
+
onNone: () => "Schema",
|
|
2970
|
+
onSome: (_) => _.text
|
|
2971
|
+
}
|
|
2972
|
+
);
|
|
2973
|
+
const newIdentifier = ts.factory.createIdentifier(identifier.text + "_");
|
|
2974
|
+
const opaqueInferred = ts.factory.createExpressionWithTypeArguments(
|
|
2975
|
+
ts.factory.createPropertyAccessExpression(
|
|
2976
|
+
ts.factory.createPropertyAccessExpression(
|
|
2977
|
+
ts.factory.createIdentifier(effectSchemaName),
|
|
2978
|
+
ts.factory.createIdentifier("Schema")
|
|
2979
|
+
),
|
|
2980
|
+
ts.factory.createIdentifier("Type")
|
|
2981
|
+
),
|
|
2982
|
+
[ts.factory.createTypeQueryNode(
|
|
2983
|
+
ts.factory.createIdentifier(newIdentifier.text)
|
|
2984
|
+
)]
|
|
2985
|
+
);
|
|
2986
|
+
const opaqueType = types.A.isUnion() ? ts.factory.createTypeAliasDeclaration(
|
|
2987
|
+
variableStatement.modifiers,
|
|
2988
|
+
identifier.text,
|
|
2989
|
+
[],
|
|
2990
|
+
opaqueInferred
|
|
2991
|
+
) : ts.factory.createInterfaceDeclaration(
|
|
2992
|
+
variableStatement.modifiers,
|
|
2993
|
+
identifier.text,
|
|
2994
|
+
void 0,
|
|
2995
|
+
[ts.factory.createHeritageClause(
|
|
2996
|
+
ts.SyntaxKind.ExtendsKeyword,
|
|
2997
|
+
[opaqueInferred]
|
|
2998
|
+
)],
|
|
2999
|
+
[]
|
|
3000
|
+
);
|
|
3001
|
+
const encodedInferred = ts.factory.createExpressionWithTypeArguments(
|
|
3002
|
+
ts.factory.createPropertyAccessExpression(
|
|
3003
|
+
ts.factory.createPropertyAccessExpression(
|
|
3004
|
+
ts.factory.createIdentifier(effectSchemaName),
|
|
3005
|
+
ts.factory.createIdentifier("Schema")
|
|
3006
|
+
),
|
|
3007
|
+
ts.factory.createIdentifier("Encoded")
|
|
3008
|
+
),
|
|
3009
|
+
[ts.factory.createTypeQueryNode(
|
|
3010
|
+
ts.factory.createIdentifier(newIdentifier.text)
|
|
3011
|
+
)]
|
|
3012
|
+
);
|
|
3013
|
+
const encodedType = types.I.isUnion() ? ts.factory.createTypeAliasDeclaration(
|
|
3014
|
+
variableStatement.modifiers,
|
|
3015
|
+
identifier.text + "Encoded",
|
|
3016
|
+
[],
|
|
3017
|
+
encodedInferred
|
|
3018
|
+
) : ts.factory.createInterfaceDeclaration(
|
|
3019
|
+
variableStatement.modifiers,
|
|
3020
|
+
identifier.text + "Encoded",
|
|
3021
|
+
void 0,
|
|
3022
|
+
[ts.factory.createHeritageClause(
|
|
3023
|
+
ts.SyntaxKind.ExtendsKeyword,
|
|
3024
|
+
[encodedInferred]
|
|
3025
|
+
)],
|
|
3026
|
+
[]
|
|
3027
|
+
);
|
|
3028
|
+
const contextInferred = ts.factory.createExpressionWithTypeArguments(
|
|
3029
|
+
ts.factory.createPropertyAccessExpression(
|
|
3030
|
+
ts.factory.createPropertyAccessExpression(
|
|
3031
|
+
ts.factory.createIdentifier(effectSchemaName),
|
|
3032
|
+
ts.factory.createIdentifier("Schema")
|
|
3033
|
+
),
|
|
3034
|
+
ts.factory.createIdentifier("Context")
|
|
3035
|
+
),
|
|
3036
|
+
[ts.factory.createTypeQueryNode(
|
|
3037
|
+
ts.factory.createIdentifier(newIdentifier.text)
|
|
3038
|
+
)]
|
|
3039
|
+
);
|
|
3040
|
+
const contextType = ts.factory.createTypeAliasDeclaration(
|
|
3041
|
+
variableStatement.modifiers,
|
|
3042
|
+
identifier.text + "Context",
|
|
3043
|
+
[],
|
|
3044
|
+
contextInferred
|
|
3045
|
+
);
|
|
3046
|
+
changeTracker.replaceNode(
|
|
3047
|
+
sourceFile,
|
|
3048
|
+
identifier,
|
|
3049
|
+
newIdentifier
|
|
3050
|
+
);
|
|
3051
|
+
changeTracker.insertNodeAfter(sourceFile, variableStatement, opaqueType);
|
|
3052
|
+
changeTracker.insertNodeAfter(sourceFile, variableStatement, encodedType);
|
|
3053
|
+
changeTracker.insertNodeAfter(sourceFile, variableStatement, contextType);
|
|
3054
|
+
const newSchemaType = ts.factory.createTypeReferenceNode(
|
|
3055
|
+
ts.factory.createQualifiedName(
|
|
3056
|
+
ts.factory.createIdentifier(effectSchemaName),
|
|
3057
|
+
ts.factory.createIdentifier("Schema")
|
|
3058
|
+
),
|
|
3059
|
+
[
|
|
3060
|
+
ts.factory.createTypeReferenceNode(opaqueType.name),
|
|
3061
|
+
ts.factory.createTypeReferenceNode(encodedType.name),
|
|
3062
|
+
ts.factory.createTypeReferenceNode(contextType.name)
|
|
3063
|
+
]
|
|
3064
|
+
);
|
|
3065
|
+
const newConstDeclaration = ts.factory.createVariableStatement(
|
|
3066
|
+
variableStatement.modifiers,
|
|
3067
|
+
ts.factory.createVariableDeclarationList(
|
|
3068
|
+
[ts.factory.createVariableDeclaration(
|
|
3069
|
+
identifier.text,
|
|
3070
|
+
void 0,
|
|
3071
|
+
newSchemaType,
|
|
3072
|
+
ts.factory.createIdentifier(newIdentifier.text)
|
|
3073
|
+
)],
|
|
3074
|
+
variableDeclarationList.flags
|
|
3075
|
+
)
|
|
3076
|
+
);
|
|
3077
|
+
changeTracker.insertNodeAfter(sourceFile, variableStatement, newConstDeclaration);
|
|
3078
|
+
changeTracker.insertText(sourceFile, variableStatement.end, "\n");
|
|
3079
|
+
}),
|
|
3080
|
+
provideService(TypeScriptApi, ts)
|
|
3081
|
+
)
|
|
3082
|
+
};
|
|
3083
|
+
})
|
|
3084
|
+
});
|
|
3085
|
+
|
|
2846
3086
|
// src/refactors/pipeableToDatafirst.ts
|
|
2847
3087
|
var pipeableToDatafirst = createRefactor({
|
|
2848
3088
|
name: "effect/pipeableToDatafirst",
|
|
2849
3089
|
description: "Rewrite to datafirst",
|
|
2850
|
-
apply: (
|
|
3090
|
+
apply: fn("pipeableToDatafirst.apply")(function* (sourceFile, textRange) {
|
|
2851
3091
|
const ts = yield* service(TypeScriptApi);
|
|
2852
3092
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2853
3093
|
function isPipeCall(node2) {
|
|
@@ -2930,7 +3170,7 @@ var pipeableToDatafirst = createRefactor({
|
|
|
2930
3170
|
var removeUnnecessaryEffectGen = createRefactor({
|
|
2931
3171
|
name: "effect/removeUnnecessaryEffectGen",
|
|
2932
3172
|
description: "Remove unnecessary Effect.gen",
|
|
2933
|
-
apply: (
|
|
3173
|
+
apply: fn("removeUnnecessaryEffectGen.apply")(function* (sourceFile, textRange) {
|
|
2934
3174
|
for (const nodeToReplace of yield* getAncestorNodesInRange(sourceFile, textRange)) {
|
|
2935
3175
|
const maybeNode = yield* pipe(
|
|
2936
3176
|
effectGen(nodeToReplace),
|
|
@@ -2956,7 +3196,7 @@ var removeUnnecessaryEffectGen = createRefactor({
|
|
|
2956
3196
|
var toggleLazyConst = createRefactor({
|
|
2957
3197
|
name: "effect/toggleLazyConst",
|
|
2958
3198
|
description: "Toggle lazy const",
|
|
2959
|
-
apply: (
|
|
3199
|
+
apply: fn("toggleLazyConst.apply")(function* (sourceFile, textRange) {
|
|
2960
3200
|
const ts = yield* service(TypeScriptApi);
|
|
2961
3201
|
const maybeNode = pipe(
|
|
2962
3202
|
yield* getAncestorNodesInRange(sourceFile, textRange),
|
|
@@ -2996,7 +3236,7 @@ var toggleLazyConst = createRefactor({
|
|
|
2996
3236
|
var toggleReturnTypeAnnotation = createRefactor({
|
|
2997
3237
|
name: "effect/toggleReturnTypeAnnotation",
|
|
2998
3238
|
description: "Toggle return type annotation",
|
|
2999
|
-
apply: (
|
|
3239
|
+
apply: fn("toggleReturnTypeAnnotation.apply")(function* (sourceFile, textRange) {
|
|
3000
3240
|
const ts = yield* service(TypeScriptApi);
|
|
3001
3241
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3002
3242
|
const maybeNode = pipe(
|
|
@@ -3046,7 +3286,7 @@ var toggleReturnTypeAnnotation = createRefactor({
|
|
|
3046
3286
|
var toggleTypeAnnotation = createRefactor({
|
|
3047
3287
|
name: "effect/toggleTypeAnnotation",
|
|
3048
3288
|
description: "Toggle type annotation",
|
|
3049
|
-
apply: (
|
|
3289
|
+
apply: fn("toggleTypeAnnotation.apply")(function* (sourceFile, textRange) {
|
|
3050
3290
|
const ts = yield* service(TypeScriptApi);
|
|
3051
3291
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3052
3292
|
const maybeNode = pipe(
|
|
@@ -3103,11 +3343,76 @@ var toggleTypeAnnotation = createRefactor({
|
|
|
3103
3343
|
})
|
|
3104
3344
|
});
|
|
3105
3345
|
|
|
3346
|
+
// src/refactors/wrapWithEffectGen.ts
|
|
3347
|
+
var wrapWithEffectGen = createRefactor({
|
|
3348
|
+
name: "effect/wrapWithEffectGen",
|
|
3349
|
+
description: "Wrap with Effect.gen",
|
|
3350
|
+
apply: fn("wrapWithEffectGen.apply")(function* (sourceFile, textRange) {
|
|
3351
|
+
const ts = yield* service(TypeScriptApi);
|
|
3352
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
3353
|
+
const findEffectToWrap = fn("wrapWithEffectGen.apply.findEffectToWrap")(
|
|
3354
|
+
function* (node) {
|
|
3355
|
+
if (!ts.isExpression(node)) return yield* fail("is not an expression");
|
|
3356
|
+
const parent = node.parent;
|
|
3357
|
+
if (parent != null && ts.isVariableDeclaration(parent) && parent.initializer !== node) return yield* fail("is LHS of variable declaration");
|
|
3358
|
+
const type = typeChecker.getTypeAtLocation(node);
|
|
3359
|
+
yield* effectType(type, node);
|
|
3360
|
+
return node;
|
|
3361
|
+
}
|
|
3362
|
+
);
|
|
3363
|
+
const maybeNode = yield* pipe(
|
|
3364
|
+
yield* getAncestorNodesInRange(sourceFile, textRange),
|
|
3365
|
+
map2(findEffectToWrap),
|
|
3366
|
+
firstSuccessOf,
|
|
3367
|
+
option
|
|
3368
|
+
);
|
|
3369
|
+
if (isNone2(maybeNode)) return yield* fail(new RefactorNotApplicableError());
|
|
3370
|
+
return {
|
|
3371
|
+
kind: "refactor.rewrite.effect.wrapWithEffectGen",
|
|
3372
|
+
description: `Wrap with Effect.gen`,
|
|
3373
|
+
apply: pipe(
|
|
3374
|
+
gen2(function* () {
|
|
3375
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
3376
|
+
const effectGen2 = yield* pipe(
|
|
3377
|
+
createEffectGenCallExpressionWithBlock(
|
|
3378
|
+
yield* getEffectModuleIdentifierName(sourceFile),
|
|
3379
|
+
yield* createReturnYieldStarStatement(maybeNode.value)
|
|
3380
|
+
)
|
|
3381
|
+
);
|
|
3382
|
+
changeTracker.replaceNode(sourceFile, maybeNode.value, effectGen2);
|
|
3383
|
+
}),
|
|
3384
|
+
provideService(TypeScriptApi, ts),
|
|
3385
|
+
provideService(TypeCheckerApi, typeChecker)
|
|
3386
|
+
)
|
|
3387
|
+
};
|
|
3388
|
+
})
|
|
3389
|
+
});
|
|
3390
|
+
var getEffectModuleIdentifierName = fn("getEffectModuleIdentifierName")(
|
|
3391
|
+
function* (sourceFile) {
|
|
3392
|
+
return match2(
|
|
3393
|
+
yield* option(
|
|
3394
|
+
findImportedModuleIdentifier(
|
|
3395
|
+
sourceFile,
|
|
3396
|
+
(node) => pipe(
|
|
3397
|
+
importedEffectModule(node),
|
|
3398
|
+
option,
|
|
3399
|
+
map3(isSome2)
|
|
3400
|
+
)
|
|
3401
|
+
)
|
|
3402
|
+
),
|
|
3403
|
+
{
|
|
3404
|
+
onNone: () => "Effect",
|
|
3405
|
+
onSome: (node) => node.text
|
|
3406
|
+
}
|
|
3407
|
+
);
|
|
3408
|
+
}
|
|
3409
|
+
);
|
|
3410
|
+
|
|
3106
3411
|
// src/refactors/wrapWithPipe.ts
|
|
3107
3412
|
var wrapWithPipe = createRefactor({
|
|
3108
3413
|
name: "effect/wrapWithPipe",
|
|
3109
3414
|
description: "Wrap with pipe",
|
|
3110
|
-
apply: (
|
|
3415
|
+
apply: fn("wrapWithPipe.apply")(function* (sourceFile, textRange) {
|
|
3111
3416
|
if (textRange.end - textRange.pos === 0) {
|
|
3112
3417
|
return yield* fail(new RefactorNotApplicableError());
|
|
3113
3418
|
}
|
|
@@ -3128,11 +3433,13 @@ var refactors = [
|
|
|
3128
3433
|
asyncAwaitToGen,
|
|
3129
3434
|
asyncAwaitToGenTryPromise,
|
|
3130
3435
|
functionToArrow,
|
|
3436
|
+
makeSchemaOpaque,
|
|
3131
3437
|
pipeableToDatafirst,
|
|
3132
3438
|
removeUnnecessaryEffectGen,
|
|
3133
3439
|
toggleLazyConst,
|
|
3134
3440
|
toggleReturnTypeAnnotation,
|
|
3135
3441
|
toggleTypeAnnotation,
|
|
3442
|
+
wrapWithEffectGen,
|
|
3136
3443
|
wrapWithPipe,
|
|
3137
3444
|
effectGenToFn
|
|
3138
3445
|
];
|