@effect/language-service 0.74.0 → 0.75.1
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 -1
- package/cli.js +250 -168
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +249 -168
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +416 -230
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +249 -167
- package/transform.js.map +1 -1
|
@@ -852,6 +852,7 @@ var dedupe = (self) => dedupeWith(self, equivalence());
|
|
|
852
852
|
var join = /* @__PURE__ */ dual(2, (self, sep) => fromIterable(self).join(sep));
|
|
853
853
|
|
|
854
854
|
// src/core/Nano.ts
|
|
855
|
+
var debugPerformance = false;
|
|
855
856
|
var NanoTag = class {
|
|
856
857
|
constructor(key) {
|
|
857
858
|
this.key = key;
|
|
@@ -949,7 +950,6 @@ var NanoFiber = class {
|
|
|
949
950
|
_yielded = void 0;
|
|
950
951
|
_services = {};
|
|
951
952
|
_cache = {};
|
|
952
|
-
_perf = false;
|
|
953
953
|
_lastSpan = "";
|
|
954
954
|
runLoop(nano) {
|
|
955
955
|
let current = nano;
|
|
@@ -980,7 +980,7 @@ var WithSpanProto = {
|
|
|
980
980
|
...PrimitiveProto,
|
|
981
981
|
[evaluate](fiber) {
|
|
982
982
|
const [fa, name] = this[args];
|
|
983
|
-
if (!
|
|
983
|
+
if (!debugPerformance) return fa;
|
|
984
984
|
const previousSpan = fiber._lastSpan;
|
|
985
985
|
fiber._lastSpan = name;
|
|
986
986
|
const start = performance.now();
|
|
@@ -1008,7 +1008,6 @@ var withSpan = (name) => (fa) => {
|
|
|
1008
1008
|
};
|
|
1009
1009
|
var unsafeRun = (nano) => {
|
|
1010
1010
|
const fiber = new NanoFiber();
|
|
1011
|
-
globalThis.currentFiber = fiber;
|
|
1012
1011
|
const result = fiber.runLoop(nano);
|
|
1013
1012
|
if (result._tag === "Success") {
|
|
1014
1013
|
return right2(result.value);
|
|
@@ -1920,6 +1919,26 @@ var getApplicableRefactors = fn("LSP.getApplicableRefactors")(function* (refacto
|
|
|
1920
1919
|
}
|
|
1921
1920
|
return effectRefactors;
|
|
1922
1921
|
});
|
|
1922
|
+
function codeFixNameToFullyQualifiedName(name) {
|
|
1923
|
+
return `@effect/language-service/codefixes/${name}`;
|
|
1924
|
+
}
|
|
1925
|
+
var codeFixesToApplicableRefactor = fn("LSP.codeFixesToApplicableRefactor")(function* (codeFixes, sourceFile, positionOrRange) {
|
|
1926
|
+
const effectRefactors = [];
|
|
1927
|
+
const range = typeof positionOrRange === "number" ? { pos: positionOrRange, end: positionOrRange } : positionOrRange;
|
|
1928
|
+
const inRangeCodeFixes = codeFixes.filter((_) => _.start <= range.pos && _.end >= range.end);
|
|
1929
|
+
for (const codeFix of inRangeCodeFixes) {
|
|
1930
|
+
effectRefactors.push({
|
|
1931
|
+
name: codeFixNameToFullyQualifiedName(codeFix.fixName),
|
|
1932
|
+
description: "Quick Fix: " + codeFix.description,
|
|
1933
|
+
actions: [{
|
|
1934
|
+
name: codeFixNameToFullyQualifiedName(codeFix.fixName),
|
|
1935
|
+
description: "Quick Fix: " + codeFix.description,
|
|
1936
|
+
kind: "refactor.rewrite.codeFixEffect." + codeFix.fixName
|
|
1937
|
+
}]
|
|
1938
|
+
});
|
|
1939
|
+
}
|
|
1940
|
+
return effectRefactors;
|
|
1941
|
+
});
|
|
1923
1942
|
var getEditsForRefactor = fn("LSP.getEditsForRefactor")(function* (refactors, sourceFile, positionOrRange, refactorName) {
|
|
1924
1943
|
const refactor = refactors.find((refactor2) => refactorNameToFullyQualifiedName(refactor2.name) === refactorName);
|
|
1925
1944
|
if (!refactor) {
|
|
@@ -1928,6 +1947,16 @@ var getEditsForRefactor = fn("LSP.getEditsForRefactor")(function* (refactors, so
|
|
|
1928
1947
|
const textRange = typeof positionOrRange === "number" ? { pos: positionOrRange, end: positionOrRange } : positionOrRange;
|
|
1929
1948
|
return yield* refactor.apply(sourceFile, textRange);
|
|
1930
1949
|
});
|
|
1950
|
+
var getEditsForCodeFixes = fn("LSP.getEditsForCodeFixes")(function* (codeFixes, positionOrRange, refactorName) {
|
|
1951
|
+
const textRange = typeof positionOrRange === "number" ? { pos: positionOrRange, end: positionOrRange } : positionOrRange;
|
|
1952
|
+
const fixToRun = codeFixes.find(
|
|
1953
|
+
(_) => codeFixNameToFullyQualifiedName(_.fixName) === refactorName && _.start <= textRange.pos && _.end >= textRange.end
|
|
1954
|
+
);
|
|
1955
|
+
if (!fixToRun) {
|
|
1956
|
+
return yield* fail(new RefactorNotApplicableError());
|
|
1957
|
+
}
|
|
1958
|
+
return fixToRun;
|
|
1959
|
+
});
|
|
1931
1960
|
var getCompletionsAtPosition = fn("LSP.getCompletionsAtPosition")(function* (completions, sourceFile, position, options, formatCodeSettings) {
|
|
1932
1961
|
let effectCompletions = [];
|
|
1933
1962
|
for (const completion of completions) {
|
|
@@ -2011,7 +2040,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
2011
2040
|
message: ts.DiagnosticCategory.Message,
|
|
2012
2041
|
suggestion: ts.DiagnosticCategory.Suggestion
|
|
2013
2042
|
};
|
|
2014
|
-
const execute = (
|
|
2043
|
+
const execute = fn("LSP.execute")(function* (rule) {
|
|
2015
2044
|
const diagnostics2 = [];
|
|
2016
2045
|
const codeFixes = [];
|
|
2017
2046
|
const ruleNameLowered = rule.name.toLowerCase();
|
|
@@ -2797,6 +2826,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2797
2826
|
if (signatures.length !== 1) {
|
|
2798
2827
|
return typeParserIssue("Covariant type has no call signature", type);
|
|
2799
2828
|
}
|
|
2829
|
+
if (signatures[0].typeParameters && signatures[0].typeParameters.length > 0) {
|
|
2830
|
+
return typeParserIssue("Invariant type should not have type parameters", type);
|
|
2831
|
+
}
|
|
2800
2832
|
return succeed(typeChecker.getReturnTypeOfSignature(signatures[0]));
|
|
2801
2833
|
}
|
|
2802
2834
|
function contravariantTypeArgument(type) {
|
|
@@ -2804,6 +2836,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2804
2836
|
if (signatures.length !== 1) {
|
|
2805
2837
|
return typeParserIssue("Contravariant type has no call signature", type);
|
|
2806
2838
|
}
|
|
2839
|
+
if (signatures[0].typeParameters && signatures[0].typeParameters.length > 0) {
|
|
2840
|
+
return typeParserIssue("Invariant type should not have type parameters", type);
|
|
2841
|
+
}
|
|
2807
2842
|
return succeed(typeCheckerUtils.getTypeParameterAtPosition(signatures[0], 0));
|
|
2808
2843
|
}
|
|
2809
2844
|
function invariantTypeArgument(type) {
|
|
@@ -2811,6 +2846,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2811
2846
|
if (signatures.length !== 1) {
|
|
2812
2847
|
return typeParserIssue("Invariant type has no call signature", type);
|
|
2813
2848
|
}
|
|
2849
|
+
if (signatures[0].typeParameters && signatures[0].typeParameters.length > 0) {
|
|
2850
|
+
return typeParserIssue("Invariant type should not have type parameters", type);
|
|
2851
|
+
}
|
|
2814
2852
|
return succeed(typeChecker.getReturnTypeOfSignature(signatures[0]));
|
|
2815
2853
|
}
|
|
2816
2854
|
const pipeableType = cachedBy(
|
|
@@ -4698,32 +4736,38 @@ var catchAllToMapError = createDiagnostic({
|
|
|
4698
4736
|
return void 0;
|
|
4699
4737
|
};
|
|
4700
4738
|
const getEffectFailCallInfo = (body) => {
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
return { failCall: body, failArg: body.arguments[0] };
|
|
4709
|
-
}
|
|
4710
|
-
}
|
|
4711
|
-
if (ts.isBlock(body)) {
|
|
4712
|
-
const statements = body.statements;
|
|
4713
|
-
if (statements.length === 1) {
|
|
4714
|
-
const stmt = statements[0];
|
|
4715
|
-
if (ts.isReturnStatement(stmt) && stmt.expression && ts.isCallExpression(stmt.expression)) {
|
|
4716
|
-
const isFailCall = yield* pipe(
|
|
4717
|
-
typeParser.isNodeReferenceToEffectModuleApi("fail")(stmt.expression.expression),
|
|
4718
|
-
orUndefined
|
|
4719
|
-
);
|
|
4720
|
-
if (isFailCall && stmt.expression.arguments.length >= 1) {
|
|
4721
|
-
return { failCall: stmt.expression, failArg: stmt.expression.arguments[0] };
|
|
4722
|
-
}
|
|
4739
|
+
if (ts.isCallExpression(body)) {
|
|
4740
|
+
return pipe(
|
|
4741
|
+
typeParser.isNodeReferenceToEffectModuleApi("fail")(body.expression),
|
|
4742
|
+
orUndefined,
|
|
4743
|
+
map4((isFailCall) => {
|
|
4744
|
+
if (isFailCall && body.arguments.length >= 1) {
|
|
4745
|
+
return { failCall: body, failArg: body.arguments[0] };
|
|
4723
4746
|
}
|
|
4747
|
+
return void 0;
|
|
4748
|
+
})
|
|
4749
|
+
);
|
|
4750
|
+
}
|
|
4751
|
+
if (ts.isBlock(body)) {
|
|
4752
|
+
const statements = body.statements;
|
|
4753
|
+
if (statements.length === 1) {
|
|
4754
|
+
const stmt = statements[0];
|
|
4755
|
+
if (ts.isReturnStatement(stmt) && stmt.expression && ts.isCallExpression(stmt.expression)) {
|
|
4756
|
+
const callExpr = stmt.expression;
|
|
4757
|
+
return pipe(
|
|
4758
|
+
typeParser.isNodeReferenceToEffectModuleApi("fail")(callExpr.expression),
|
|
4759
|
+
orUndefined,
|
|
4760
|
+
map4((isFailCall) => {
|
|
4761
|
+
if (isFailCall && callExpr.arguments.length >= 1) {
|
|
4762
|
+
return { failCall: callExpr, failArg: callExpr.arguments[0] };
|
|
4763
|
+
}
|
|
4764
|
+
return void 0;
|
|
4765
|
+
})
|
|
4766
|
+
);
|
|
4724
4767
|
}
|
|
4725
4768
|
}
|
|
4726
|
-
}
|
|
4769
|
+
}
|
|
4770
|
+
return void_;
|
|
4727
4771
|
};
|
|
4728
4772
|
const flows = yield* typeParser.pipingFlows(true)(sourceFile);
|
|
4729
4773
|
for (const flow2 of flows) {
|
|
@@ -4968,20 +5012,21 @@ var deterministicKeys = createDiagnostic({
|
|
|
4968
5012
|
const typeScriptUtils = yield* service(TypeScriptUtils);
|
|
4969
5013
|
const options = yield* service(LanguageServicePluginOptions);
|
|
4970
5014
|
const parseExtendsCustom = cachedBy(
|
|
4971
|
-
|
|
5015
|
+
(classDeclaration) => {
|
|
4972
5016
|
if (!options.extendedKeyDetection) {
|
|
4973
|
-
return
|
|
5017
|
+
return TypeParserIssue.issue;
|
|
4974
5018
|
}
|
|
4975
5019
|
if (!classDeclaration.name) {
|
|
4976
|
-
return
|
|
5020
|
+
return TypeParserIssue.issue;
|
|
4977
5021
|
}
|
|
4978
5022
|
if (!ts.isIdentifier(classDeclaration.name)) {
|
|
4979
|
-
return
|
|
5023
|
+
return TypeParserIssue.issue;
|
|
4980
5024
|
}
|
|
4981
5025
|
const heritageClauses = classDeclaration.heritageClauses;
|
|
4982
5026
|
if (!heritageClauses) {
|
|
4983
|
-
return
|
|
5027
|
+
return TypeParserIssue.issue;
|
|
4984
5028
|
}
|
|
5029
|
+
const className = classDeclaration.name;
|
|
4985
5030
|
const nodeToVisit2 = [...classDeclaration.heritageClauses];
|
|
4986
5031
|
const appendNodeToVisit2 = (node) => {
|
|
4987
5032
|
nodeToVisit2.push(node);
|
|
@@ -5002,7 +5047,7 @@ var deterministicKeys = createDiagnostic({
|
|
|
5002
5047
|
const parameterSourceFile = typeScriptUtils.getSourceFileOfNode(declaration);
|
|
5003
5048
|
const paramText = parameterSourceFile.text.substring(declaration.pos, declaration.end);
|
|
5004
5049
|
if (paramText.toLowerCase().includes("@effect-identifier")) {
|
|
5005
|
-
return { className
|
|
5050
|
+
return succeed({ className, keyStringLiteral: arg, target: "custom" });
|
|
5006
5051
|
}
|
|
5007
5052
|
}
|
|
5008
5053
|
}
|
|
@@ -5011,12 +5056,8 @@ var deterministicKeys = createDiagnostic({
|
|
|
5011
5056
|
}
|
|
5012
5057
|
ts.forEachChild(node, appendNodeToVisit2);
|
|
5013
5058
|
}
|
|
5014
|
-
return
|
|
5015
|
-
|
|
5016
|
-
void 0,
|
|
5017
|
-
classDeclaration
|
|
5018
|
-
);
|
|
5019
|
-
}),
|
|
5059
|
+
return TypeParserIssue.issue;
|
|
5060
|
+
},
|
|
5020
5061
|
"deterministicKeys.parseExtendsCustom",
|
|
5021
5062
|
(classDeclaration) => classDeclaration
|
|
5022
5063
|
);
|
|
@@ -5295,7 +5336,7 @@ var effectFnOpportunity = createDiagnostic({
|
|
|
5295
5336
|
}
|
|
5296
5337
|
return false;
|
|
5297
5338
|
};
|
|
5298
|
-
const tryExtractWithSpanExpression = (
|
|
5339
|
+
const tryExtractWithSpanExpression = fn("effectFnOpportunity.tryExtractWithSpanExpression")(function* (expr) {
|
|
5299
5340
|
if (!ts.isCallExpression(expr)) return void 0;
|
|
5300
5341
|
const callee = expr.expression;
|
|
5301
5342
|
const isWithSpan = yield* pipe(
|
|
@@ -5307,7 +5348,9 @@ var effectFnOpportunity = createDiagnostic({
|
|
|
5307
5348
|
if (expr.arguments.length === 0) return void 0;
|
|
5308
5349
|
return expr.arguments[0];
|
|
5309
5350
|
});
|
|
5310
|
-
const tryParseGenOpportunity = (
|
|
5351
|
+
const tryParseGenOpportunity = fn(
|
|
5352
|
+
"effectFnOpportunity.tryParseGenOpportunity"
|
|
5353
|
+
)(function* (fnNode) {
|
|
5311
5354
|
const bodyExpression = getBodyExpression(fnNode);
|
|
5312
5355
|
if (!bodyExpression) return yield* TypeParserIssue.issue;
|
|
5313
5356
|
const { pipeArguments: pipeArguments2, subject } = yield* pipe(
|
|
@@ -5343,62 +5386,67 @@ var effectFnOpportunity = createDiagnostic({
|
|
|
5343
5386
|
orElse2(() => succeed(false))
|
|
5344
5387
|
);
|
|
5345
5388
|
};
|
|
5346
|
-
const
|
|
5389
|
+
const parseEffectFnOpportunityTargetGen = fn("effectFnOpportunity.parseEffectFnOpportunityTarget")(
|
|
5390
|
+
function* (node, returnType, traceName, nameIdentifier) {
|
|
5391
|
+
if (yield* isInsideEffectFn(node)) {
|
|
5392
|
+
return yield* TypeParserIssue.issue;
|
|
5393
|
+
}
|
|
5394
|
+
const unionMembers = typeCheckerUtils.unrollUnionMembers(returnType);
|
|
5395
|
+
yield* all(...unionMembers.map((member) => typeParser.strictEffectType(member, node)));
|
|
5396
|
+
const opportunity = yield* pipe(
|
|
5397
|
+
tryParseGenOpportunity(node),
|
|
5398
|
+
orElse2(() => {
|
|
5399
|
+
if (ts.isArrowFunction(node) && !ts.isBlock(node.body)) {
|
|
5400
|
+
return TypeParserIssue.issue;
|
|
5401
|
+
}
|
|
5402
|
+
const body = ts.isArrowFunction(node) ? node.body : node.body;
|
|
5403
|
+
if (!body || !ts.isBlock(body) || body.statements.length <= 5) {
|
|
5404
|
+
return TypeParserIssue.issue;
|
|
5405
|
+
}
|
|
5406
|
+
return succeed({
|
|
5407
|
+
effectModuleName: sourceEffectModuleName,
|
|
5408
|
+
pipeArguments: [],
|
|
5409
|
+
generatorFunction: void 0,
|
|
5410
|
+
explicitTraceExpression: void 0
|
|
5411
|
+
});
|
|
5412
|
+
})
|
|
5413
|
+
);
|
|
5414
|
+
return {
|
|
5415
|
+
node,
|
|
5416
|
+
nameIdentifier,
|
|
5417
|
+
effectModuleName: opportunity.effectModuleName,
|
|
5418
|
+
inferredTraceName: traceName,
|
|
5419
|
+
explicitTraceExpression: opportunity.explicitTraceExpression,
|
|
5420
|
+
pipeArguments: opportunity.pipeArguments,
|
|
5421
|
+
generatorFunction: opportunity.generatorFunction,
|
|
5422
|
+
hasParamsInPipeArgs: areParametersReferencedIn(node, opportunity.pipeArguments)
|
|
5423
|
+
};
|
|
5424
|
+
}
|
|
5425
|
+
);
|
|
5426
|
+
const parseEffectFnOpportunityTarget = (node) => {
|
|
5347
5427
|
if (!ts.isFunctionExpression(node) && !ts.isArrowFunction(node) && !ts.isFunctionDeclaration(node)) {
|
|
5348
|
-
return
|
|
5428
|
+
return TypeParserIssue.issue;
|
|
5349
5429
|
}
|
|
5350
5430
|
if ((ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node)) && node.asteriskToken) {
|
|
5351
|
-
return
|
|
5431
|
+
return TypeParserIssue.issue;
|
|
5352
5432
|
}
|
|
5353
5433
|
if (ts.isFunctionExpression(node) && node.name) {
|
|
5354
|
-
return
|
|
5434
|
+
return TypeParserIssue.issue;
|
|
5355
5435
|
}
|
|
5356
5436
|
if (node.type) {
|
|
5357
|
-
return
|
|
5358
|
-
}
|
|
5359
|
-
if (yield* isInsideEffectFn(node)) {
|
|
5360
|
-
return yield* TypeParserIssue.issue;
|
|
5437
|
+
return TypeParserIssue.issue;
|
|
5361
5438
|
}
|
|
5362
5439
|
const functionType = typeChecker.getTypeAtLocation(node);
|
|
5363
|
-
if (!functionType) return
|
|
5440
|
+
if (!functionType) return TypeParserIssue.issue;
|
|
5364
5441
|
const callSignatures = typeChecker.getSignaturesOfType(functionType, ts.SignatureKind.Call);
|
|
5365
|
-
if (callSignatures.length !== 1) return
|
|
5442
|
+
if (callSignatures.length !== 1) return TypeParserIssue.issue;
|
|
5366
5443
|
const signature = callSignatures[0];
|
|
5367
5444
|
const returnType = typeChecker.getReturnTypeOfSignature(signature);
|
|
5368
|
-
const unionMembers = typeCheckerUtils.unrollUnionMembers(returnType);
|
|
5369
|
-
yield* all(...unionMembers.map((member) => typeParser.strictEffectType(member, node)));
|
|
5370
5445
|
const nameIdentifier = getNameIdentifier(node);
|
|
5371
5446
|
const traceName = nameIdentifier ? ts.isIdentifier(nameIdentifier) ? ts.idText(nameIdentifier) : nameIdentifier.text : void 0;
|
|
5372
|
-
if (!traceName) return
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
orElse2(() => {
|
|
5376
|
-
if (ts.isArrowFunction(node) && !ts.isBlock(node.body)) {
|
|
5377
|
-
return TypeParserIssue.issue;
|
|
5378
|
-
}
|
|
5379
|
-
const body = ts.isArrowFunction(node) ? node.body : node.body;
|
|
5380
|
-
if (!body || !ts.isBlock(body) || body.statements.length <= 5) {
|
|
5381
|
-
return TypeParserIssue.issue;
|
|
5382
|
-
}
|
|
5383
|
-
return succeed({
|
|
5384
|
-
effectModuleName: sourceEffectModuleName,
|
|
5385
|
-
pipeArguments: [],
|
|
5386
|
-
generatorFunction: void 0,
|
|
5387
|
-
explicitTraceExpression: void 0
|
|
5388
|
-
});
|
|
5389
|
-
})
|
|
5390
|
-
);
|
|
5391
|
-
return {
|
|
5392
|
-
node,
|
|
5393
|
-
nameIdentifier,
|
|
5394
|
-
effectModuleName: opportunity.effectModuleName,
|
|
5395
|
-
inferredTraceName: traceName,
|
|
5396
|
-
explicitTraceExpression: opportunity.explicitTraceExpression,
|
|
5397
|
-
pipeArguments: opportunity.pipeArguments,
|
|
5398
|
-
generatorFunction: opportunity.generatorFunction,
|
|
5399
|
-
hasParamsInPipeArgs: areParametersReferencedIn(node, opportunity.pipeArguments)
|
|
5400
|
-
};
|
|
5401
|
-
});
|
|
5447
|
+
if (!traceName) return TypeParserIssue.issue;
|
|
5448
|
+
return parseEffectFnOpportunityTargetGen(node, returnType, traceName, nameIdentifier);
|
|
5449
|
+
};
|
|
5402
5450
|
const getFunctionBodyBlock = (node) => {
|
|
5403
5451
|
if (ts.isArrowFunction(node)) {
|
|
5404
5452
|
if (ts.isBlock(node.body)) {
|
|
@@ -5639,7 +5687,7 @@ var effectInVoidSuccess = createDiagnostic({
|
|
|
5639
5687
|
);
|
|
5640
5688
|
return { voidedEffect };
|
|
5641
5689
|
}
|
|
5642
|
-
return yield*
|
|
5690
|
+
return yield* TypeParserIssue.issue;
|
|
5643
5691
|
});
|
|
5644
5692
|
const entries = typeCheckerUtils.expectedAndRealType(sourceFile);
|
|
5645
5693
|
for (const [node, expectedType, valueNode, realType] of entries) {
|
|
@@ -7451,25 +7499,27 @@ var generate = fn("writeTagClassAccessors.generate")(function* (sourceFile, serv
|
|
|
7451
7499
|
return succeed(typeNode);
|
|
7452
7500
|
})
|
|
7453
7501
|
);
|
|
7454
|
-
const proxySignature = (
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7502
|
+
const proxySignature = fn("writeTagClassAccessors.proxySignature")(
|
|
7503
|
+
function* (signature, atLocation2, className2) {
|
|
7504
|
+
const signatureDeclaration = typeChecker.signatureToSignatureDeclaration(
|
|
7505
|
+
signature,
|
|
7506
|
+
ts.SyntaxKind.FunctionType,
|
|
7507
|
+
atLocation2,
|
|
7508
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
7509
|
+
);
|
|
7510
|
+
if (!signatureDeclaration) return yield* fail("error generating signature");
|
|
7511
|
+
const returnType = yield* generateReturnType(
|
|
7512
|
+
typeChecker.getReturnTypeOfSignature(signature),
|
|
7513
|
+
atLocation2,
|
|
7514
|
+
className2
|
|
7515
|
+
);
|
|
7516
|
+
return ts.factory.createFunctionTypeNode(
|
|
7517
|
+
signatureDeclaration.typeParameters,
|
|
7518
|
+
signatureDeclaration.parameters,
|
|
7519
|
+
returnType
|
|
7520
|
+
);
|
|
7521
|
+
}
|
|
7522
|
+
);
|
|
7473
7523
|
for (const { property, propertyType } of involvedMembers) {
|
|
7474
7524
|
const callSignatures = [];
|
|
7475
7525
|
let propertyDeclaration = void 0;
|
|
@@ -7606,7 +7656,7 @@ var annotate = createCodegen({
|
|
|
7606
7656
|
const tsUtils = yield* service(TypeScriptUtils);
|
|
7607
7657
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
7608
7658
|
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
7609
|
-
const parse3 = (
|
|
7659
|
+
const parse3 = fn("annotate.parse")(function* (node) {
|
|
7610
7660
|
let variableDeclarations = [];
|
|
7611
7661
|
const result = [];
|
|
7612
7662
|
if (ts.isVariableStatement(node)) {
|
|
@@ -8286,7 +8336,7 @@ var typeToSchema = createCodegen({
|
|
|
8286
8336
|
new CodegenNotApplicableError("the typeToSchema codegen can be used only once per file")
|
|
8287
8337
|
);
|
|
8288
8338
|
}
|
|
8289
|
-
const parse3 = (
|
|
8339
|
+
const parse3 = fn("typeToSchema.parse")(function* (node) {
|
|
8290
8340
|
if (!ts.isTypeAliasDeclaration(node)) {
|
|
8291
8341
|
return yield* fail(
|
|
8292
8342
|
new CodegenNotApplicableError(
|
|
@@ -8563,73 +8613,99 @@ var preferSchemaOverJson = createDiagnostic({
|
|
|
8563
8613
|
apply: fn("preferSchemaOverJson.apply")(function* (sourceFile, report) {
|
|
8564
8614
|
const ts = yield* service(TypeScriptApi);
|
|
8565
8615
|
const typeParser = yield* service(TypeParser);
|
|
8566
|
-
const
|
|
8567
|
-
|
|
8568
|
-
const
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
|
|
8616
|
+
const isJsonCall = (node) => ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.expression) && ts.idText(node.expression.expression) === "JSON" && (ts.idText(node.expression.name) === "parse" || ts.idText(node.expression.name) === "stringify");
|
|
8617
|
+
const findEnclosingEffectTry = (jsonCall) => {
|
|
8618
|
+
const parent = jsonCall.parent;
|
|
8619
|
+
let lazy;
|
|
8620
|
+
if (ts.isArrowFunction(parent) && parent.body === jsonCall && parent.parameters.length === 0 && (!parent.typeParameters || parent.typeParameters.length === 0)) {
|
|
8621
|
+
lazy = parent;
|
|
8622
|
+
}
|
|
8623
|
+
if (!lazy && ts.isReturnStatement(parent) && parent.expression === jsonCall) {
|
|
8624
|
+
const block = parent.parent;
|
|
8625
|
+
if (ts.isBlock(block) && block.statements.length === 1) {
|
|
8626
|
+
const fn2 = block.parent;
|
|
8627
|
+
if ((ts.isArrowFunction(fn2) || ts.isFunctionExpression(fn2)) && fn2.parameters.length === 0 && (!fn2.typeParameters || fn2.typeParameters.length === 0)) {
|
|
8628
|
+
lazy = fn2;
|
|
8629
|
+
}
|
|
8630
|
+
}
|
|
8574
8631
|
}
|
|
8575
|
-
if (
|
|
8576
|
-
|
|
8632
|
+
if (!lazy) return void 0;
|
|
8633
|
+
const lazyParent = lazy.parent;
|
|
8634
|
+
if (ts.isCallExpression(lazyParent) && lazyParent.arguments.length > 0 && lazyParent.arguments[0] === lazy) {
|
|
8635
|
+
return lazyParent;
|
|
8577
8636
|
}
|
|
8578
|
-
|
|
8579
|
-
|
|
8580
|
-
|
|
8581
|
-
|
|
8637
|
+
if (ts.isPropertyAssignment(lazyParent) && ts.isIdentifier(lazyParent.name) && ts.idText(lazyParent.name) === "try") {
|
|
8638
|
+
const objLiteral = lazyParent.parent;
|
|
8639
|
+
if (ts.isObjectLiteralExpression(objLiteral)) {
|
|
8640
|
+
const callExpr = objLiteral.parent;
|
|
8641
|
+
if (ts.isCallExpression(callExpr) && callExpr.arguments.length > 0 && callExpr.arguments[0] === objLiteral) {
|
|
8642
|
+
return callExpr;
|
|
8643
|
+
}
|
|
8644
|
+
}
|
|
8645
|
+
}
|
|
8646
|
+
return void 0;
|
|
8647
|
+
};
|
|
8648
|
+
const jsonCalls = [];
|
|
8649
|
+
const collectJsonCalls = (node) => {
|
|
8650
|
+
if (isJsonCall(node)) {
|
|
8651
|
+
jsonCalls.push(node);
|
|
8652
|
+
}
|
|
8653
|
+
ts.forEachChild(node, collectJsonCalls);
|
|
8654
|
+
};
|
|
8655
|
+
ts.forEachChild(sourceFile, collectJsonCalls);
|
|
8656
|
+
if (jsonCalls.length === 0) return;
|
|
8657
|
+
const effectTrySimple = fn("preferSchemaOverJson.effectTrySimple")(function* (node) {
|
|
8582
8658
|
yield* typeParser.isNodeReferenceToEffectModuleApi("try")(node.expression);
|
|
8583
|
-
if (node.arguments.length === 0) return yield*
|
|
8659
|
+
if (node.arguments.length === 0) return yield* TypeParserIssue.issue;
|
|
8584
8660
|
const lazyFn = yield* typeParser.lazyExpression(node.arguments[0]);
|
|
8585
|
-
|
|
8586
|
-
return
|
|
8661
|
+
if (!isJsonCall(lazyFn.expression)) return yield* TypeParserIssue.issue;
|
|
8662
|
+
return lazyFn.expression;
|
|
8587
8663
|
});
|
|
8588
|
-
const effectTryObject = (
|
|
8589
|
-
if (!ts.isCallExpression(node)) return yield* fail("node is not a call expression");
|
|
8664
|
+
const effectTryObject = fn("preferSchemaOverJson.effectTryObject")(function* (node) {
|
|
8590
8665
|
yield* typeParser.isNodeReferenceToEffectModuleApi("try")(node.expression);
|
|
8591
|
-
if (node.arguments.length === 0) return yield*
|
|
8666
|
+
if (node.arguments.length === 0) return yield* TypeParserIssue.issue;
|
|
8592
8667
|
const arg = node.arguments[0];
|
|
8593
|
-
if (!ts.isObjectLiteralExpression(arg)) return yield*
|
|
8668
|
+
if (!ts.isObjectLiteralExpression(arg)) return yield* TypeParserIssue.issue;
|
|
8594
8669
|
const tryProp = arg.properties.find(
|
|
8595
8670
|
(p) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && ts.idText(p.name) === "try"
|
|
8596
8671
|
);
|
|
8597
|
-
if (!tryProp) return yield*
|
|
8672
|
+
if (!tryProp) return yield* TypeParserIssue.issue;
|
|
8598
8673
|
const lazyFn = yield* typeParser.lazyExpression(tryProp.initializer);
|
|
8599
|
-
|
|
8600
|
-
return
|
|
8674
|
+
if (!isJsonCall(lazyFn.expression)) return yield* TypeParserIssue.issue;
|
|
8675
|
+
return lazyFn.expression;
|
|
8601
8676
|
});
|
|
8602
|
-
const jsonMethodInEffectGen = (
|
|
8603
|
-
|
|
8604
|
-
|
|
8605
|
-
|
|
8606
|
-
|
|
8677
|
+
const jsonMethodInEffectGen = fn("preferSchemaOverJson.jsonMethodInEffectGen")(
|
|
8678
|
+
function* (jsonCall) {
|
|
8679
|
+
const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(jsonCall);
|
|
8680
|
+
if (!effectGen || effectGen.body.statements.length === 0) {
|
|
8681
|
+
return yield* TypeParserIssue.issue;
|
|
8682
|
+
}
|
|
8683
|
+
if (scopeNode && scopeNode !== effectGen.generatorFunction) {
|
|
8684
|
+
return yield* TypeParserIssue.issue;
|
|
8685
|
+
}
|
|
8686
|
+
return jsonCall;
|
|
8607
8687
|
}
|
|
8608
|
-
|
|
8609
|
-
|
|
8688
|
+
);
|
|
8689
|
+
for (const jsonCall of jsonCalls) {
|
|
8690
|
+
const effectTryCall = findEnclosingEffectTry(jsonCall);
|
|
8691
|
+
let match2;
|
|
8692
|
+
if (effectTryCall) {
|
|
8693
|
+
match2 = yield* pipe(
|
|
8694
|
+
firstSuccessOf([
|
|
8695
|
+
effectTrySimple(effectTryCall),
|
|
8696
|
+
effectTryObject(effectTryCall)
|
|
8697
|
+
]),
|
|
8698
|
+
option
|
|
8699
|
+
);
|
|
8700
|
+
} else {
|
|
8701
|
+
match2 = yield* pipe(
|
|
8702
|
+
jsonMethodInEffectGen(jsonCall),
|
|
8703
|
+
option
|
|
8704
|
+
);
|
|
8610
8705
|
}
|
|
8611
|
-
return { node: jsonMethod.node, methodName: jsonMethod.methodName };
|
|
8612
|
-
});
|
|
8613
|
-
const nodeToVisit = [];
|
|
8614
|
-
const appendNodeToVisit = (node) => {
|
|
8615
|
-
nodeToVisit.push(node);
|
|
8616
|
-
return void 0;
|
|
8617
|
-
};
|
|
8618
|
-
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
8619
|
-
while (nodeToVisit.length > 0) {
|
|
8620
|
-
const node = nodeToVisit.shift();
|
|
8621
|
-
ts.forEachChild(node, appendNodeToVisit);
|
|
8622
|
-
const match2 = yield* pipe(
|
|
8623
|
-
firstSuccessOf([
|
|
8624
|
-
effectTrySimple(node),
|
|
8625
|
-
effectTryObject(node),
|
|
8626
|
-
jsonMethodInEffectGen(node)
|
|
8627
|
-
]),
|
|
8628
|
-
option
|
|
8629
|
-
);
|
|
8630
8706
|
if (isSome2(match2)) {
|
|
8631
8707
|
report({
|
|
8632
|
-
location: match2.value
|
|
8708
|
+
location: match2.value,
|
|
8633
8709
|
messageText: "Consider using Effect Schema for JSON operations instead of JSON.parse/JSON.stringify",
|
|
8634
8710
|
fixes: []
|
|
8635
8711
|
});
|
|
@@ -9273,19 +9349,24 @@ var strictEffectProvide = createDiagnostic({
|
|
|
9273
9349
|
const ts = yield* service(TypeScriptApi);
|
|
9274
9350
|
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
9275
9351
|
const typeParser = yield* service(TypeParser);
|
|
9276
|
-
const
|
|
9352
|
+
const parseEffectProvideWithLayerGen = fn("strictEffectProvide.parseEffectProvideWithLayer")(
|
|
9353
|
+
function* (node) {
|
|
9354
|
+
yield* typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression);
|
|
9355
|
+
return yield* firstSuccessOf(
|
|
9356
|
+
node.arguments.map((arg) => {
|
|
9357
|
+
const argType = typeCheckerUtils.getTypeAtLocation(arg);
|
|
9358
|
+
if (!argType) return typeParserIssue("Could not get argument type");
|
|
9359
|
+
return typeParser.layerType(argType, arg);
|
|
9360
|
+
})
|
|
9361
|
+
);
|
|
9362
|
+
}
|
|
9363
|
+
);
|
|
9364
|
+
const parseEffectProvideWithLayer = (node) => {
|
|
9277
9365
|
if (!ts.isCallExpression(node) || node.arguments.length === 0) {
|
|
9278
|
-
return
|
|
9279
|
-
}
|
|
9280
|
-
|
|
9281
|
-
|
|
9282
|
-
node.arguments.map((arg) => {
|
|
9283
|
-
const argType = typeCheckerUtils.getTypeAtLocation(arg);
|
|
9284
|
-
if (!argType) return typeParserIssue("Could not get argument type");
|
|
9285
|
-
return typeParser.layerType(argType, arg);
|
|
9286
|
-
})
|
|
9287
|
-
);
|
|
9288
|
-
});
|
|
9366
|
+
return TypeParserIssue.issue;
|
|
9367
|
+
}
|
|
9368
|
+
return parseEffectProvideWithLayerGen(node);
|
|
9369
|
+
};
|
|
9289
9370
|
const nodeToVisit = [];
|
|
9290
9371
|
const appendNodeToVisit = (node) => {
|
|
9291
9372
|
nodeToVisit.push(node);
|