@effect/language-service 0.58.3 → 0.59.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/cli.js +151 -58
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +151 -58
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +5874 -5692
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +151 -58
- package/transform.js.map +1 -1
package/README.md
CHANGED
|
@@ -72,6 +72,7 @@ And you're done! You'll now be able to use a set of refactors and diagnostics th
|
|
|
72
72
|
- Warn when catch callbacks in `Effect.tryPromise`, `Effect.tryMap`, or `Effect.tryMapPromise` return `unknown` or `any` types
|
|
73
73
|
- Warn when using `Effect.runSync`, `Effect.runPromise`, `Effect.runFork`, or `Effect.runCallback` inside an Effect
|
|
74
74
|
- Warn when using `Schema.Union` with multiple `Schema.Literal` calls that can be simplified to a single `Schema.Literal` call
|
|
75
|
+
- Suggest using `Schema.TaggedStruct` instead of `Schema.Struct` when a `_tag` field with `Schema.Literal` is present to make the tag optional in the constructor
|
|
75
76
|
- Warn when using `yield* Effect.fail()` with yieldable error types that can be yielded directly
|
|
76
77
|
|
|
77
78
|
### Completions
|
package/cli.js
CHANGED
|
@@ -32065,7 +32065,16 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
32065
32065
|
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
32066
32066
|
if (!moduleSymbol) continue;
|
|
32067
32067
|
const memberSymbol = typeChecker.tryGetMemberInModuleExports(memberName, moduleSymbol);
|
|
32068
|
-
if (memberSymbol
|
|
32068
|
+
if (memberSymbol) {
|
|
32069
|
+
if (memberSymbol === symbol3) {
|
|
32070
|
+
result.push({ memberSymbol, moduleSymbol, sourceFile });
|
|
32071
|
+
} else if (memberSymbol.flags & ts.SymbolFlags.Alias) {
|
|
32072
|
+
const aliased = typeChecker.getAliasedSymbol(memberSymbol);
|
|
32073
|
+
if (aliased === symbol3) {
|
|
32074
|
+
result.push({ memberSymbol, moduleSymbol, sourceFile });
|
|
32075
|
+
}
|
|
32076
|
+
}
|
|
32077
|
+
}
|
|
32069
32078
|
}
|
|
32070
32079
|
if (result.length > 0) {
|
|
32071
32080
|
return result;
|
|
@@ -32320,67 +32329,69 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
32320
32329
|
"TypeParser.effectSubtype",
|
|
32321
32330
|
(type2) => type2
|
|
32322
32331
|
);
|
|
32323
|
-
const
|
|
32324
|
-
fn2("TypeParser.
|
|
32325
|
-
|
|
32326
|
-
|
|
32327
|
-
|
|
32328
|
-
|
|
32329
|
-
const
|
|
32330
|
-
if (!
|
|
32331
|
-
|
|
32332
|
-
|
|
32333
|
-
|
|
32334
|
-
|
|
32335
|
-
|
|
32336
|
-
|
|
32337
|
-
|
|
32338
|
-
|
|
32339
|
-
|
|
32340
|
-
|
|
32341
|
-
);
|
|
32342
|
-
if (!contextIdentifier) {
|
|
32343
|
-
return yield* typeParserIssue("Context module not found", void 0, node);
|
|
32344
|
-
}
|
|
32345
|
-
if (ts.idText(node) !== contextIdentifier) {
|
|
32346
|
-
return yield* typeParserIssue("Node is not a context module reference", void 0, node);
|
|
32347
|
-
}
|
|
32348
|
-
return node;
|
|
32332
|
+
const isEffectContextSourceFile = cachedBy(
|
|
32333
|
+
fn2("TypeParser.isEffectContextSourceFile")(function* (sourceFile) {
|
|
32334
|
+
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
32335
|
+
if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
|
|
32336
|
+
const contextSymbol = typeChecker.tryGetMemberInModuleExports("Context", moduleSymbol);
|
|
32337
|
+
if (!contextSymbol) return yield* typeParserIssue("Context not found", void 0, sourceFile);
|
|
32338
|
+
const tagSymbol = typeChecker.tryGetMemberInModuleExports("Tag", moduleSymbol);
|
|
32339
|
+
if (!tagSymbol) return yield* typeParserIssue("Tag not found", void 0, sourceFile);
|
|
32340
|
+
const tagType = typeChecker.getDeclaredTypeOfSymbol(tagSymbol);
|
|
32341
|
+
yield* contextTag(tagType, sourceFile);
|
|
32342
|
+
return sourceFile;
|
|
32343
|
+
}),
|
|
32344
|
+
"TypeParser.isEffectContextSourceFile",
|
|
32345
|
+
(sourceFile) => sourceFile
|
|
32346
|
+
);
|
|
32347
|
+
const isNodeReferenceToEffectContextModuleApi = (memberName) => cachedBy(
|
|
32348
|
+
fn2("TypeParser.isNodeReferenceToEffectContextModuleApi")(function* (node) {
|
|
32349
|
+
return yield* isNodeReferenceToExportOfPackageModule(node, "effect", isEffectContextSourceFile, memberName);
|
|
32349
32350
|
}),
|
|
32351
|
+
`TypeParser.isNodeReferenceToEffectContextModuleApi(${memberName})`,
|
|
32352
|
+
(node) => node
|
|
32353
|
+
);
|
|
32354
|
+
const importedContextModule = cachedBy(
|
|
32355
|
+
(node) => pipe(
|
|
32356
|
+
isNodeReferenceToPackageModule(node, "effect", isEffectContextSourceFile),
|
|
32357
|
+
map34(() => node)
|
|
32358
|
+
),
|
|
32350
32359
|
"TypeParser.importedContextModule",
|
|
32351
32360
|
(node) => node
|
|
32352
32361
|
);
|
|
32353
|
-
const importedEffectModule = (
|
|
32354
|
-
|
|
32355
|
-
|
|
32362
|
+
const importedEffectModule = cachedBy(
|
|
32363
|
+
(node) => pipe(
|
|
32364
|
+
isNodeReferenceToPackageModule(node, "effect", isEffectTypeSourceFile),
|
|
32365
|
+
map34(() => node)
|
|
32366
|
+
),
|
|
32367
|
+
"TypeParser.importedEffectModule",
|
|
32368
|
+
(node) => node
|
|
32356
32369
|
);
|
|
32357
|
-
const
|
|
32358
|
-
fn2("TypeParser.
|
|
32359
|
-
|
|
32360
|
-
|
|
32361
|
-
|
|
32362
|
-
|
|
32363
|
-
const
|
|
32364
|
-
if (!
|
|
32365
|
-
|
|
32366
|
-
}
|
|
32367
|
-
const sourceFile = tsUtils.getSourceFileOfNode(node);
|
|
32368
|
-
if (!sourceFile) {
|
|
32369
|
-
return yield* typeParserIssue("Node is not in a source file", void 0, node);
|
|
32370
|
-
}
|
|
32371
|
-
const dataIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
32372
|
-
sourceFile,
|
|
32373
|
-
"effect",
|
|
32374
|
-
"Data"
|
|
32375
|
-
);
|
|
32376
|
-
if (!dataIdentifier) {
|
|
32377
|
-
return yield* typeParserIssue("Data module not found", void 0, node);
|
|
32378
|
-
}
|
|
32379
|
-
if (ts.idText(node) !== dataIdentifier) {
|
|
32380
|
-
return yield* typeParserIssue("Node is not a data module reference", void 0, node);
|
|
32381
|
-
}
|
|
32382
|
-
return node;
|
|
32370
|
+
const isEffectDataSourceFile = cachedBy(
|
|
32371
|
+
fn2("TypeParser.isEffectDataSourceFile")(function* (sourceFile) {
|
|
32372
|
+
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
32373
|
+
if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
|
|
32374
|
+
const taggedEnumSymbol = typeChecker.tryGetMemberInModuleExports("TaggedEnum", moduleSymbol);
|
|
32375
|
+
if (!taggedEnumSymbol) return yield* typeParserIssue("TaggedEnum not found", void 0, sourceFile);
|
|
32376
|
+
const taggedErrorSymbol = typeChecker.tryGetMemberInModuleExports("TaggedError", moduleSymbol);
|
|
32377
|
+
if (!taggedErrorSymbol) return yield* typeParserIssue("TaggedError not found", void 0, sourceFile);
|
|
32378
|
+
return sourceFile;
|
|
32383
32379
|
}),
|
|
32380
|
+
"TypeParser.isEffectDataSourceFile",
|
|
32381
|
+
(sourceFile) => sourceFile
|
|
32382
|
+
);
|
|
32383
|
+
const isNodeReferenceToEffectDataModuleApi = (memberName) => cachedBy(
|
|
32384
|
+
fn2("TypeParser.isNodeReferenceToEffectDataModuleApi")(function* (node) {
|
|
32385
|
+
return yield* isNodeReferenceToExportOfPackageModule(node, "effect", isEffectDataSourceFile, memberName);
|
|
32386
|
+
}),
|
|
32387
|
+
`TypeParser.isNodeReferenceToEffectDataModuleApi(${memberName})`,
|
|
32388
|
+
(node) => node
|
|
32389
|
+
);
|
|
32390
|
+
const importedDataModule = cachedBy(
|
|
32391
|
+
(node) => pipe(
|
|
32392
|
+
isNodeReferenceToPackageModule(node, "effect", isEffectDataSourceFile),
|
|
32393
|
+
map34(() => node)
|
|
32394
|
+
),
|
|
32384
32395
|
"TypeParser.importedDataModule",
|
|
32385
32396
|
(node) => node
|
|
32386
32397
|
);
|
|
@@ -33119,6 +33130,8 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
33119
33130
|
return {
|
|
33120
33131
|
isNodeReferenceToEffectModuleApi,
|
|
33121
33132
|
isNodeReferenceToEffectSchemaModuleApi,
|
|
33133
|
+
isNodeReferenceToEffectDataModuleApi,
|
|
33134
|
+
isNodeReferenceToEffectContextModuleApi,
|
|
33122
33135
|
effectType,
|
|
33123
33136
|
strictEffectType,
|
|
33124
33137
|
layerType,
|
|
@@ -33467,7 +33480,7 @@ var annotate3 = createCodegen({
|
|
|
33467
33480
|
const initializerTypeNode = fromNullable(typeCheckerUtils.typeToSimplifiedTypeNode(
|
|
33468
33481
|
initializerType,
|
|
33469
33482
|
enclosingNode,
|
|
33470
|
-
ts.NodeBuilderFlags.NoTruncation
|
|
33483
|
+
ts.NodeBuilderFlags.NoTruncation | ts.NodeBuilderFlags.IgnoreErrors
|
|
33471
33484
|
)).pipe(
|
|
33472
33485
|
getOrUndefined
|
|
33473
33486
|
);
|
|
@@ -35671,6 +35684,85 @@ Consider extracting the Runtime by using for example Effect.runtime and then use
|
|
|
35671
35684
|
})
|
|
35672
35685
|
});
|
|
35673
35686
|
|
|
35687
|
+
// src/diagnostics/schemaStructWithTag.ts
|
|
35688
|
+
var schemaStructWithTag = createDiagnostic({
|
|
35689
|
+
name: "schemaStructWithTag",
|
|
35690
|
+
code: 34,
|
|
35691
|
+
severity: "suggestion",
|
|
35692
|
+
apply: fn2("schemaStructWithTag.apply")(function* (sourceFile, report) {
|
|
35693
|
+
const ts = yield* service2(TypeScriptApi);
|
|
35694
|
+
const typeParser = yield* service2(TypeParser);
|
|
35695
|
+
const nodeToVisit = [];
|
|
35696
|
+
const appendNodeToVisit = (node) => {
|
|
35697
|
+
nodeToVisit.push(node);
|
|
35698
|
+
return void 0;
|
|
35699
|
+
};
|
|
35700
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
35701
|
+
while (nodeToVisit.length > 0) {
|
|
35702
|
+
const node = nodeToVisit.shift();
|
|
35703
|
+
if (ts.isCallExpression(node)) {
|
|
35704
|
+
const isSchemaStructCall = yield* pipe(
|
|
35705
|
+
typeParser.isNodeReferenceToEffectSchemaModuleApi("Struct")(node.expression),
|
|
35706
|
+
orElse14(() => void_8)
|
|
35707
|
+
);
|
|
35708
|
+
if (isSchemaStructCall && node.arguments.length === 1) {
|
|
35709
|
+
const arg = node.arguments[0];
|
|
35710
|
+
if (ts.isObjectLiteralExpression(arg)) {
|
|
35711
|
+
const tagProperty = arg.properties.find(
|
|
35712
|
+
(prop) => ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && ts.idText(prop.name) === "_tag"
|
|
35713
|
+
);
|
|
35714
|
+
if (tagProperty && ts.isCallExpression(tagProperty.initializer)) {
|
|
35715
|
+
const isSchemaLiteralCall = yield* pipe(
|
|
35716
|
+
typeParser.isNodeReferenceToEffectSchemaModuleApi("Literal")(
|
|
35717
|
+
tagProperty.initializer.expression
|
|
35718
|
+
),
|
|
35719
|
+
option4
|
|
35720
|
+
);
|
|
35721
|
+
if (isSchemaLiteralCall._tag === "Some") {
|
|
35722
|
+
const literalCall = tagProperty.initializer;
|
|
35723
|
+
const literalArgs = fromIterable(literalCall.arguments);
|
|
35724
|
+
if (literalArgs.length === 1 && ts.isStringLiteral(literalArgs[0])) {
|
|
35725
|
+
const tagValue = literalArgs[0].text;
|
|
35726
|
+
const otherProperties = arg.properties.filter((prop) => prop !== tagProperty);
|
|
35727
|
+
report({
|
|
35728
|
+
location: node,
|
|
35729
|
+
messageText: "Schema.Struct with a _tag field can be simplified to Schema.TaggedStruct to make the tag optional in the constructor.",
|
|
35730
|
+
fixes: [{
|
|
35731
|
+
fixName: "schemaStructWithTag_fix",
|
|
35732
|
+
description: "Replace with Schema.TaggedStruct",
|
|
35733
|
+
apply: gen3(function* () {
|
|
35734
|
+
const changeTracker = yield* service2(ChangeTracker);
|
|
35735
|
+
const newObjectLiteral = ts.factory.createObjectLiteralExpression(
|
|
35736
|
+
otherProperties,
|
|
35737
|
+
true
|
|
35738
|
+
);
|
|
35739
|
+
const newNode = ts.factory.createCallExpression(
|
|
35740
|
+
ts.factory.createPropertyAccessExpression(
|
|
35741
|
+
// Reuse the Schema identifier from the original expression
|
|
35742
|
+
ts.isPropertyAccessExpression(node.expression) ? node.expression.expression : ts.factory.createIdentifier("Schema"),
|
|
35743
|
+
"TaggedStruct"
|
|
35744
|
+
),
|
|
35745
|
+
void 0,
|
|
35746
|
+
[
|
|
35747
|
+
ts.factory.createStringLiteral(tagValue),
|
|
35748
|
+
newObjectLiteral
|
|
35749
|
+
]
|
|
35750
|
+
);
|
|
35751
|
+
changeTracker.replaceNode(sourceFile, node, newNode);
|
|
35752
|
+
})
|
|
35753
|
+
}]
|
|
35754
|
+
});
|
|
35755
|
+
}
|
|
35756
|
+
}
|
|
35757
|
+
}
|
|
35758
|
+
}
|
|
35759
|
+
}
|
|
35760
|
+
}
|
|
35761
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
35762
|
+
}
|
|
35763
|
+
})
|
|
35764
|
+
});
|
|
35765
|
+
|
|
35674
35766
|
// src/diagnostics/schemaUnionOfLiterals.ts
|
|
35675
35767
|
var schemaUnionOfLiterals = createDiagnostic({
|
|
35676
35768
|
name: "schemaUnionOfLiterals",
|
|
@@ -36362,7 +36454,8 @@ var diagnostics = [
|
|
|
36362
36454
|
strictEffectProvide,
|
|
36363
36455
|
unknownInEffectCatch,
|
|
36364
36456
|
runEffectInsideEffect,
|
|
36365
|
-
schemaUnionOfLiterals
|
|
36457
|
+
schemaUnionOfLiterals,
|
|
36458
|
+
schemaStructWithTag
|
|
36366
36459
|
];
|
|
36367
36460
|
|
|
36368
36461
|
// src/cli/diagnostics.ts
|