@effect/language-service 0.28.0 → 0.28.2
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 +2 -0
- package/cli.js +149 -2
- package/cli.js.map +1 -1
- package/index.js +418 -3
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +149 -2
- package/transform.js.map +1 -1
package/index.js
CHANGED
|
@@ -2859,6 +2859,47 @@ function make3(ts, typeChecker) {
|
|
|
2859
2859
|
"TypeParser.scopeType",
|
|
2860
2860
|
(type) => type
|
|
2861
2861
|
);
|
|
2862
|
+
const promiseLike = cachedBy(
|
|
2863
|
+
function(type, atLocation) {
|
|
2864
|
+
const thenProperty = type.getProperty("then");
|
|
2865
|
+
if (!thenProperty) return typeParserIssue("not a promise - missing then property", type, atLocation);
|
|
2866
|
+
const thenType = typeChecker.getTypeOfSymbolAtLocation(thenProperty, atLocation);
|
|
2867
|
+
if (!thenType) return typeParserIssue("not a promise - missing then property", type, atLocation);
|
|
2868
|
+
for (const callSignature of thenType.getCallSignatures()) {
|
|
2869
|
+
const parameter = callSignature.parameters[0];
|
|
2870
|
+
if (!parameter) continue;
|
|
2871
|
+
const parameterType = callSignature.getTypeParameterAtPosition(0);
|
|
2872
|
+
if (!parameterType) continue;
|
|
2873
|
+
let callbackCallSignatures = [];
|
|
2874
|
+
let toTest = [parameterType];
|
|
2875
|
+
while (toTest.length > 0) {
|
|
2876
|
+
const type2 = toTest.shift();
|
|
2877
|
+
if (!type2) continue;
|
|
2878
|
+
const callSignatures = type2.getCallSignatures();
|
|
2879
|
+
callbackCallSignatures = callbackCallSignatures.concat(callSignatures);
|
|
2880
|
+
if (type2.isUnion()) {
|
|
2881
|
+
toTest = toTest.concat(type2.types);
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
for (const callableType of callbackCallSignatures) {
|
|
2885
|
+
const callbackParameter = callableType.parameters[0];
|
|
2886
|
+
if (!callbackParameter) {
|
|
2887
|
+
continue;
|
|
2888
|
+
}
|
|
2889
|
+
const callbackParameterType = callableType.getTypeParameterAtPosition(0);
|
|
2890
|
+
if (!callbackParameterType) {
|
|
2891
|
+
continue;
|
|
2892
|
+
}
|
|
2893
|
+
return succeed({
|
|
2894
|
+
type: callbackParameterType
|
|
2895
|
+
});
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
return typeParserIssue("not a promise", type, atLocation);
|
|
2899
|
+
},
|
|
2900
|
+
"TypeParser.promiseLike",
|
|
2901
|
+
(type) => type
|
|
2902
|
+
);
|
|
2862
2903
|
return {
|
|
2863
2904
|
effectType,
|
|
2864
2905
|
strictEffectType,
|
|
@@ -2874,7 +2915,8 @@ function make3(ts, typeChecker) {
|
|
|
2874
2915
|
contextTag,
|
|
2875
2916
|
pipeableType,
|
|
2876
2917
|
pipeCall,
|
|
2877
|
-
scopeType
|
|
2918
|
+
scopeType,
|
|
2919
|
+
promiseLike
|
|
2878
2920
|
};
|
|
2879
2921
|
}
|
|
2880
2922
|
|
|
@@ -3589,6 +3631,110 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
3589
3631
|
})
|
|
3590
3632
|
});
|
|
3591
3633
|
|
|
3634
|
+
// src/diagnostics/multipleEffectProvide.ts
|
|
3635
|
+
var multipleEffectProvide = createDiagnostic({
|
|
3636
|
+
name: "multipleEffectProvide",
|
|
3637
|
+
code: 18,
|
|
3638
|
+
severity: "warning",
|
|
3639
|
+
apply: fn("multipleEffectProvide.apply")(function* (sourceFile, report) {
|
|
3640
|
+
const ts = yield* service(TypeScriptApi);
|
|
3641
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
3642
|
+
const typeParser = yield* service(TypeParser);
|
|
3643
|
+
const effectModuleIdentifier = yield* pipe(
|
|
3644
|
+
findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3645
|
+
sourceFile,
|
|
3646
|
+
"effect",
|
|
3647
|
+
"Effect"
|
|
3648
|
+
),
|
|
3649
|
+
map4((_) => _.text),
|
|
3650
|
+
orElse2(() => succeed("Effect"))
|
|
3651
|
+
);
|
|
3652
|
+
const layerModuleIdentifier = yield* pipe(
|
|
3653
|
+
findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3654
|
+
sourceFile,
|
|
3655
|
+
"effect",
|
|
3656
|
+
"Layer"
|
|
3657
|
+
),
|
|
3658
|
+
map4((_) => _.text),
|
|
3659
|
+
orElse2(() => succeed("Layer"))
|
|
3660
|
+
);
|
|
3661
|
+
const parseEffectProvideLayer = (node) => {
|
|
3662
|
+
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && node.expression.name.text === "provide" && node.arguments.length > 0) {
|
|
3663
|
+
const layer = node.arguments[0];
|
|
3664
|
+
const type = typeChecker.getTypeAtLocation(layer);
|
|
3665
|
+
return pipe(
|
|
3666
|
+
typeParser.importedEffectModule(node.expression.expression),
|
|
3667
|
+
flatMap2(() => typeParser.layerType(type, layer)),
|
|
3668
|
+
map4(() => ({ layer, node })),
|
|
3669
|
+
orElse2(() => void_)
|
|
3670
|
+
);
|
|
3671
|
+
}
|
|
3672
|
+
return void_;
|
|
3673
|
+
};
|
|
3674
|
+
const parsePipeCall = (node) => gen(function* () {
|
|
3675
|
+
const { args: args2 } = yield* typeParser.pipeCall(node);
|
|
3676
|
+
let currentChunk = 0;
|
|
3677
|
+
const previousLayers = [[]];
|
|
3678
|
+
for (const pipeArg of args2) {
|
|
3679
|
+
const parsedProvide = yield* parseEffectProvideLayer(pipeArg);
|
|
3680
|
+
if (parsedProvide) {
|
|
3681
|
+
previousLayers[currentChunk].push(parsedProvide);
|
|
3682
|
+
} else {
|
|
3683
|
+
currentChunk++;
|
|
3684
|
+
previousLayers.push([]);
|
|
3685
|
+
}
|
|
3686
|
+
}
|
|
3687
|
+
for (const chunk of previousLayers) {
|
|
3688
|
+
if (chunk.length < 2) continue;
|
|
3689
|
+
report({
|
|
3690
|
+
node: chunk[0].node,
|
|
3691
|
+
messageText: "Calling multiple subsequent times Effect.provide is an anti-pattern and can lead to service lifecycle issues. You should combine the layers and provide them once instead.",
|
|
3692
|
+
fixes: [{
|
|
3693
|
+
fixName: "multipleEffectProvide_fix",
|
|
3694
|
+
description: "Combine into a single provide",
|
|
3695
|
+
apply: gen(function* () {
|
|
3696
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
3697
|
+
changeTracker.deleteRange(sourceFile, {
|
|
3698
|
+
pos: chunk[0].node.getStart(sourceFile),
|
|
3699
|
+
end: chunk[chunk.length - 1].node.getEnd()
|
|
3700
|
+
});
|
|
3701
|
+
const newNode = ts.factory.createCallExpression(
|
|
3702
|
+
ts.factory.createPropertyAccessExpression(
|
|
3703
|
+
ts.factory.createIdentifier(effectModuleIdentifier),
|
|
3704
|
+
ts.factory.createIdentifier("provide")
|
|
3705
|
+
),
|
|
3706
|
+
void 0,
|
|
3707
|
+
[ts.factory.createCallExpression(
|
|
3708
|
+
ts.factory.createPropertyAccessExpression(
|
|
3709
|
+
ts.factory.createIdentifier(layerModuleIdentifier),
|
|
3710
|
+
ts.factory.createIdentifier("mergeAll")
|
|
3711
|
+
),
|
|
3712
|
+
void 0,
|
|
3713
|
+
chunk.map((c) => c.layer)
|
|
3714
|
+
)]
|
|
3715
|
+
);
|
|
3716
|
+
changeTracker.insertNodeAt(sourceFile, chunk[0].node.getStart(sourceFile), newNode);
|
|
3717
|
+
})
|
|
3718
|
+
}]
|
|
3719
|
+
});
|
|
3720
|
+
}
|
|
3721
|
+
});
|
|
3722
|
+
const nodeToVisit = [];
|
|
3723
|
+
const appendNodeToVisit = (node) => {
|
|
3724
|
+
nodeToVisit.push(node);
|
|
3725
|
+
return void 0;
|
|
3726
|
+
};
|
|
3727
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
3728
|
+
while (nodeToVisit.length > 0) {
|
|
3729
|
+
const node = nodeToVisit.shift();
|
|
3730
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
3731
|
+
if (ts.isCallExpression(node)) {
|
|
3732
|
+
yield* pipe(parsePipeCall(node), ignore);
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3735
|
+
})
|
|
3736
|
+
});
|
|
3737
|
+
|
|
3592
3738
|
// src/diagnostics/returnEffectInGen.ts
|
|
3593
3739
|
var returnEffectInGen = createDiagnostic({
|
|
3594
3740
|
name: "returnEffectInGen",
|
|
@@ -4050,7 +4196,8 @@ var diagnostics = [
|
|
|
4050
4196
|
scopeInLayerEffect,
|
|
4051
4197
|
effectInVoidSuccess,
|
|
4052
4198
|
unnecessaryPipeChain,
|
|
4053
|
-
strictBooleanExpressions
|
|
4199
|
+
strictBooleanExpressions,
|
|
4200
|
+
multipleEffectProvide
|
|
4054
4201
|
];
|
|
4055
4202
|
|
|
4056
4203
|
// src/completions/effectDiagnosticsComment.ts
|
|
@@ -11083,6 +11230,273 @@ var wrapWithPipe = createRefactor({
|
|
|
11083
11230
|
})
|
|
11084
11231
|
});
|
|
11085
11232
|
|
|
11233
|
+
// src/refactors/writeTagClassAccessors.ts
|
|
11234
|
+
var writeTagClassAccessors = createRefactor({
|
|
11235
|
+
name: "writeTagClassAccessors",
|
|
11236
|
+
description: "Implement Service accessors",
|
|
11237
|
+
apply: fn("writeTagClassAccessors.apply")(function* (sourceFile, textRange) {
|
|
11238
|
+
const ts = yield* service(TypeScriptApi);
|
|
11239
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
11240
|
+
const typeParser = yield* service(TypeParser);
|
|
11241
|
+
const effectIdentifier = pipe(
|
|
11242
|
+
yield* option(
|
|
11243
|
+
findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", "Effect")
|
|
11244
|
+
),
|
|
11245
|
+
match({
|
|
11246
|
+
onNone: () => "Effect",
|
|
11247
|
+
onSome: (_) => _.text
|
|
11248
|
+
})
|
|
11249
|
+
);
|
|
11250
|
+
const createConstantProperty = (className, propertyName, type) => ts.factory.createPropertyDeclaration(
|
|
11251
|
+
[ts.factory.createModifier(ts.SyntaxKind.StaticKeyword)],
|
|
11252
|
+
propertyName,
|
|
11253
|
+
void 0,
|
|
11254
|
+
type,
|
|
11255
|
+
ts.factory.createCallExpression(
|
|
11256
|
+
ts.factory.createPropertyAccessExpression(
|
|
11257
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
11258
|
+
"andThen"
|
|
11259
|
+
),
|
|
11260
|
+
void 0,
|
|
11261
|
+
[
|
|
11262
|
+
ts.factory.createIdentifier(className.text),
|
|
11263
|
+
ts.factory.createArrowFunction(
|
|
11264
|
+
void 0,
|
|
11265
|
+
void 0,
|
|
11266
|
+
[ts.factory.createParameterDeclaration(
|
|
11267
|
+
void 0,
|
|
11268
|
+
void 0,
|
|
11269
|
+
"_"
|
|
11270
|
+
)],
|
|
11271
|
+
void 0,
|
|
11272
|
+
void 0,
|
|
11273
|
+
ts.factory.createPropertyAccessExpression(
|
|
11274
|
+
ts.factory.createIdentifier("_"),
|
|
11275
|
+
propertyName
|
|
11276
|
+
)
|
|
11277
|
+
)
|
|
11278
|
+
]
|
|
11279
|
+
)
|
|
11280
|
+
);
|
|
11281
|
+
const createFunctionProperty = (className, propertyName, type, forceAny) => {
|
|
11282
|
+
const arrowBody = ts.factory.createCallExpression(
|
|
11283
|
+
ts.factory.createPropertyAccessExpression(
|
|
11284
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
11285
|
+
"andThen"
|
|
11286
|
+
),
|
|
11287
|
+
void 0,
|
|
11288
|
+
[
|
|
11289
|
+
ts.factory.createIdentifier(className.text),
|
|
11290
|
+
ts.factory.createArrowFunction(
|
|
11291
|
+
void 0,
|
|
11292
|
+
void 0,
|
|
11293
|
+
[ts.factory.createParameterDeclaration(
|
|
11294
|
+
void 0,
|
|
11295
|
+
void 0,
|
|
11296
|
+
"_",
|
|
11297
|
+
void 0,
|
|
11298
|
+
forceAny ? ts.factory.createTypeReferenceNode("any") : void 0
|
|
11299
|
+
)],
|
|
11300
|
+
void 0,
|
|
11301
|
+
void 0,
|
|
11302
|
+
ts.factory.createCallExpression(
|
|
11303
|
+
ts.factory.createPropertyAccessExpression(
|
|
11304
|
+
ts.factory.createIdentifier("_"),
|
|
11305
|
+
propertyName
|
|
11306
|
+
),
|
|
11307
|
+
void 0,
|
|
11308
|
+
[
|
|
11309
|
+
ts.factory.createSpreadElement(ts.factory.createIdentifier("args"))
|
|
11310
|
+
]
|
|
11311
|
+
)
|
|
11312
|
+
)
|
|
11313
|
+
]
|
|
11314
|
+
);
|
|
11315
|
+
return ts.factory.createPropertyDeclaration(
|
|
11316
|
+
[ts.factory.createModifier(ts.SyntaxKind.StaticKeyword)],
|
|
11317
|
+
propertyName,
|
|
11318
|
+
void 0,
|
|
11319
|
+
type,
|
|
11320
|
+
ts.factory.createArrowFunction(
|
|
11321
|
+
void 0,
|
|
11322
|
+
void 0,
|
|
11323
|
+
[ts.factory.createParameterDeclaration(
|
|
11324
|
+
void 0,
|
|
11325
|
+
ts.factory.createToken(ts.SyntaxKind.DotDotDotToken),
|
|
11326
|
+
"args",
|
|
11327
|
+
void 0,
|
|
11328
|
+
forceAny ? ts.factory.createArrayTypeNode(ts.factory.createTypeReferenceNode("any")) : void 0
|
|
11329
|
+
)],
|
|
11330
|
+
void 0,
|
|
11331
|
+
void 0,
|
|
11332
|
+
forceAny ? ts.factory.createAsExpression(arrowBody, ts.factory.createTypeReferenceNode("any")) : arrowBody
|
|
11333
|
+
)
|
|
11334
|
+
);
|
|
11335
|
+
};
|
|
11336
|
+
const generateReturnType = (type, atLocation, className) => pipe(
|
|
11337
|
+
typeParser.effectType(type, atLocation),
|
|
11338
|
+
flatMap2((returnedEffect) => {
|
|
11339
|
+
const contextType = returnedEffect.R.flags & ts.TypeFlags.Never ? ts.factory.createTypeReferenceNode(className.text) : ts.factory.createUnionTypeNode(
|
|
11340
|
+
[
|
|
11341
|
+
ts.factory.createTypeReferenceNode(className.text),
|
|
11342
|
+
typeChecker.typeToTypeNode(returnedEffect.R, atLocation, ts.NodeBuilderFlags.NoTruncation)
|
|
11343
|
+
]
|
|
11344
|
+
);
|
|
11345
|
+
const successType = typeChecker.typeToTypeNode(
|
|
11346
|
+
returnedEffect.A,
|
|
11347
|
+
atLocation,
|
|
11348
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
11349
|
+
);
|
|
11350
|
+
if (!successType) return fail("error generating success type");
|
|
11351
|
+
const failureType = typeChecker.typeToTypeNode(
|
|
11352
|
+
returnedEffect.E,
|
|
11353
|
+
atLocation,
|
|
11354
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
11355
|
+
);
|
|
11356
|
+
if (!failureType) return fail("error generating failure type");
|
|
11357
|
+
const typeNode = ts.factory.createTypeReferenceNode(
|
|
11358
|
+
ts.factory.createQualifiedName(
|
|
11359
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
11360
|
+
ts.factory.createIdentifier("Effect")
|
|
11361
|
+
),
|
|
11362
|
+
[successType, failureType, contextType]
|
|
11363
|
+
);
|
|
11364
|
+
return succeed(typeNode);
|
|
11365
|
+
}),
|
|
11366
|
+
orElse2(
|
|
11367
|
+
() => pipe(
|
|
11368
|
+
typeParser.promiseLike(type, atLocation),
|
|
11369
|
+
flatMap2(({ type: type2 }) => {
|
|
11370
|
+
const successType = typeChecker.typeToTypeNode(
|
|
11371
|
+
type2,
|
|
11372
|
+
atLocation,
|
|
11373
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
11374
|
+
);
|
|
11375
|
+
if (!successType) return fail("error generating success type");
|
|
11376
|
+
return succeed(ts.factory.createTypeReferenceNode(
|
|
11377
|
+
ts.factory.createQualifiedName(
|
|
11378
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
11379
|
+
ts.factory.createIdentifier("Effect")
|
|
11380
|
+
),
|
|
11381
|
+
[
|
|
11382
|
+
successType,
|
|
11383
|
+
ts.factory.createTypeReferenceNode(
|
|
11384
|
+
ts.factory.createQualifiedName(
|
|
11385
|
+
ts.factory.createIdentifier("Cause"),
|
|
11386
|
+
ts.factory.createIdentifier("UnknownException")
|
|
11387
|
+
)
|
|
11388
|
+
),
|
|
11389
|
+
ts.factory.createTypeReferenceNode(className.text)
|
|
11390
|
+
]
|
|
11391
|
+
));
|
|
11392
|
+
})
|
|
11393
|
+
)
|
|
11394
|
+
),
|
|
11395
|
+
orElse2(() => {
|
|
11396
|
+
const successType = typeChecker.typeToTypeNode(type, atLocation, ts.NodeBuilderFlags.NoTruncation);
|
|
11397
|
+
if (!successType) return fail("error generating success type");
|
|
11398
|
+
const typeNode = ts.factory.createTypeReferenceNode(
|
|
11399
|
+
ts.factory.createQualifiedName(
|
|
11400
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
11401
|
+
ts.factory.createIdentifier("Effect")
|
|
11402
|
+
),
|
|
11403
|
+
[
|
|
11404
|
+
successType,
|
|
11405
|
+
ts.factory.createTypeReferenceNode("never"),
|
|
11406
|
+
ts.factory.createTypeReferenceNode(className.text)
|
|
11407
|
+
]
|
|
11408
|
+
);
|
|
11409
|
+
return succeed(typeNode);
|
|
11410
|
+
})
|
|
11411
|
+
);
|
|
11412
|
+
const proxySignature = (signature, atLocation, className) => gen(function* () {
|
|
11413
|
+
const signatureDeclaration = typeChecker.signatureToSignatureDeclaration(
|
|
11414
|
+
signature,
|
|
11415
|
+
ts.SyntaxKind.FunctionType,
|
|
11416
|
+
atLocation,
|
|
11417
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
11418
|
+
);
|
|
11419
|
+
if (!signatureDeclaration) return yield* fail("error generating signature");
|
|
11420
|
+
const returnType = yield* generateReturnType(signature.getReturnType(), atLocation, className);
|
|
11421
|
+
return ts.factory.createFunctionTypeNode(
|
|
11422
|
+
signatureDeclaration.typeParameters,
|
|
11423
|
+
signatureDeclaration.parameters,
|
|
11424
|
+
returnType
|
|
11425
|
+
);
|
|
11426
|
+
});
|
|
11427
|
+
const writeAccessors = fn("writeTagClassAccessors.writeAccessors")(
|
|
11428
|
+
function* (service2, className, atLocation) {
|
|
11429
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
11430
|
+
const insertLocation = atLocation.members.length > 0 ? atLocation.members[0].pos : atLocation.getEnd() - 1;
|
|
11431
|
+
for (const property of typeChecker.getPropertiesOfType(service2)) {
|
|
11432
|
+
const servicePropertyType = typeChecker.getTypeOfSymbolAtLocation(property, atLocation);
|
|
11433
|
+
const callSignatures = [];
|
|
11434
|
+
let propertyDeclaration = void 0;
|
|
11435
|
+
for (const signature of servicePropertyType.getCallSignatures()) {
|
|
11436
|
+
yield* pipe(
|
|
11437
|
+
proxySignature(signature, atLocation, className),
|
|
11438
|
+
map4((sig) => {
|
|
11439
|
+
callSignatures.push(sig);
|
|
11440
|
+
}),
|
|
11441
|
+
ignore
|
|
11442
|
+
);
|
|
11443
|
+
}
|
|
11444
|
+
if (callSignatures.length === 0) {
|
|
11445
|
+
yield* pipe(
|
|
11446
|
+
generateReturnType(servicePropertyType, atLocation, className),
|
|
11447
|
+
map4((type) => {
|
|
11448
|
+
propertyDeclaration = createConstantProperty(className, property.getName(), type);
|
|
11449
|
+
}),
|
|
11450
|
+
ignore
|
|
11451
|
+
);
|
|
11452
|
+
} else {
|
|
11453
|
+
const allSignatures = ts.factory.createIntersectionTypeNode(callSignatures);
|
|
11454
|
+
const type = yield* simplifyTypeNode(allSignatures);
|
|
11455
|
+
propertyDeclaration = createFunctionProperty(className, property.getName(), type, callSignatures.length > 1);
|
|
11456
|
+
}
|
|
11457
|
+
if (propertyDeclaration) {
|
|
11458
|
+
const oldProperty = atLocation.members.filter(ts.isPropertyDeclaration).find((p) => {
|
|
11459
|
+
const symbol3 = typeChecker.getSymbolAtLocation(p.name);
|
|
11460
|
+
return symbol3?.getName() === property.getName();
|
|
11461
|
+
});
|
|
11462
|
+
if (oldProperty) {
|
|
11463
|
+
changeTracker.deleteRange(sourceFile, {
|
|
11464
|
+
pos: oldProperty.getStart(sourceFile),
|
|
11465
|
+
end: oldProperty.getEnd()
|
|
11466
|
+
});
|
|
11467
|
+
changeTracker.insertNodeAt(sourceFile, oldProperty.getStart(sourceFile), propertyDeclaration);
|
|
11468
|
+
} else {
|
|
11469
|
+
changeTracker.insertNodeAt(sourceFile, insertLocation, propertyDeclaration, { suffix: "\n" });
|
|
11470
|
+
}
|
|
11471
|
+
}
|
|
11472
|
+
}
|
|
11473
|
+
}
|
|
11474
|
+
);
|
|
11475
|
+
const writeTagClassAccessors2 = (node) => gen(function* () {
|
|
11476
|
+
if (!ts.isClassDeclaration(node)) return yield* fail(new RefactorNotApplicableError());
|
|
11477
|
+
if (!node.name) return yield* fail(new RefactorNotApplicableError());
|
|
11478
|
+
const classSym = typeChecker.getSymbolAtLocation(node.name);
|
|
11479
|
+
if (!classSym) return yield* fail(new RefactorNotApplicableError());
|
|
11480
|
+
const type = typeChecker.getTypeOfSymbol(classSym);
|
|
11481
|
+
const { Service } = yield* pipe(
|
|
11482
|
+
typeParser.contextTag(type, node),
|
|
11483
|
+
orElse2(() => fail(new RefactorNotApplicableError()))
|
|
11484
|
+
);
|
|
11485
|
+
return {
|
|
11486
|
+
kind: "refactor.rewrite.effect.writeTagClassAccessors",
|
|
11487
|
+
description: "Implement Service accessors",
|
|
11488
|
+
apply: pipe(
|
|
11489
|
+
writeAccessors(Service, node.name, node),
|
|
11490
|
+
provideService(TypeCheckerApi, typeChecker),
|
|
11491
|
+
provideService(TypeScriptApi, ts)
|
|
11492
|
+
)
|
|
11493
|
+
};
|
|
11494
|
+
});
|
|
11495
|
+
const parentNodes = yield* getAncestorNodesInRange(sourceFile, textRange);
|
|
11496
|
+
return yield* firstSuccessOf(parentNodes.map(writeTagClassAccessors2));
|
|
11497
|
+
})
|
|
11498
|
+
});
|
|
11499
|
+
|
|
11086
11500
|
// src/refactors.ts
|
|
11087
11501
|
var refactors = [
|
|
11088
11502
|
asyncAwaitToGen,
|
|
@@ -11100,7 +11514,8 @@ var refactors = [
|
|
|
11100
11514
|
wrapWithEffectGen,
|
|
11101
11515
|
wrapWithPipe,
|
|
11102
11516
|
effectGenToFn,
|
|
11103
|
-
togglePipeStyle
|
|
11517
|
+
togglePipeStyle,
|
|
11518
|
+
writeTagClassAccessors
|
|
11104
11519
|
];
|
|
11105
11520
|
|
|
11106
11521
|
// src/index.ts
|