@effect/language-service 0.58.4 → 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 +140 -56
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +140 -56
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +5877 -5704
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +140 -56
- package/transform.js.map +1 -1
package/package.json
CHANGED
package/transform.js
CHANGED
|
@@ -2840,67 +2840,69 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2840
2840
|
"TypeParser.effectSubtype",
|
|
2841
2841
|
(type) => type
|
|
2842
2842
|
);
|
|
2843
|
-
const
|
|
2844
|
-
fn("TypeParser.
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
const
|
|
2850
|
-
if (!
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
);
|
|
2862
|
-
if (!contextIdentifier) {
|
|
2863
|
-
return yield* typeParserIssue("Context module not found", void 0, node);
|
|
2864
|
-
}
|
|
2865
|
-
if (ts.idText(node) !== contextIdentifier) {
|
|
2866
|
-
return yield* typeParserIssue("Node is not a context module reference", void 0, node);
|
|
2867
|
-
}
|
|
2868
|
-
return node;
|
|
2843
|
+
const isEffectContextSourceFile = cachedBy(
|
|
2844
|
+
fn("TypeParser.isEffectContextSourceFile")(function* (sourceFile) {
|
|
2845
|
+
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
2846
|
+
if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
|
|
2847
|
+
const contextSymbol = typeChecker.tryGetMemberInModuleExports("Context", moduleSymbol);
|
|
2848
|
+
if (!contextSymbol) return yield* typeParserIssue("Context not found", void 0, sourceFile);
|
|
2849
|
+
const tagSymbol = typeChecker.tryGetMemberInModuleExports("Tag", moduleSymbol);
|
|
2850
|
+
if (!tagSymbol) return yield* typeParserIssue("Tag not found", void 0, sourceFile);
|
|
2851
|
+
const tagType = typeChecker.getDeclaredTypeOfSymbol(tagSymbol);
|
|
2852
|
+
yield* contextTag(tagType, sourceFile);
|
|
2853
|
+
return sourceFile;
|
|
2854
|
+
}),
|
|
2855
|
+
"TypeParser.isEffectContextSourceFile",
|
|
2856
|
+
(sourceFile) => sourceFile
|
|
2857
|
+
);
|
|
2858
|
+
const isNodeReferenceToEffectContextModuleApi = (memberName) => cachedBy(
|
|
2859
|
+
fn("TypeParser.isNodeReferenceToEffectContextModuleApi")(function* (node) {
|
|
2860
|
+
return yield* isNodeReferenceToExportOfPackageModule(node, "effect", isEffectContextSourceFile, memberName);
|
|
2869
2861
|
}),
|
|
2862
|
+
`TypeParser.isNodeReferenceToEffectContextModuleApi(${memberName})`,
|
|
2863
|
+
(node) => node
|
|
2864
|
+
);
|
|
2865
|
+
const importedContextModule = cachedBy(
|
|
2866
|
+
(node) => pipe(
|
|
2867
|
+
isNodeReferenceToPackageModule(node, "effect", isEffectContextSourceFile),
|
|
2868
|
+
map4(() => node)
|
|
2869
|
+
),
|
|
2870
2870
|
"TypeParser.importedContextModule",
|
|
2871
2871
|
(node) => node
|
|
2872
2872
|
);
|
|
2873
|
-
const importedEffectModule = (
|
|
2874
|
-
|
|
2875
|
-
|
|
2873
|
+
const importedEffectModule = cachedBy(
|
|
2874
|
+
(node) => pipe(
|
|
2875
|
+
isNodeReferenceToPackageModule(node, "effect", isEffectTypeSourceFile),
|
|
2876
|
+
map4(() => node)
|
|
2877
|
+
),
|
|
2878
|
+
"TypeParser.importedEffectModule",
|
|
2879
|
+
(node) => node
|
|
2880
|
+
);
|
|
2881
|
+
const isEffectDataSourceFile = cachedBy(
|
|
2882
|
+
fn("TypeParser.isEffectDataSourceFile")(function* (sourceFile) {
|
|
2883
|
+
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
2884
|
+
if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
|
|
2885
|
+
const taggedEnumSymbol = typeChecker.tryGetMemberInModuleExports("TaggedEnum", moduleSymbol);
|
|
2886
|
+
if (!taggedEnumSymbol) return yield* typeParserIssue("TaggedEnum not found", void 0, sourceFile);
|
|
2887
|
+
const taggedErrorSymbol = typeChecker.tryGetMemberInModuleExports("TaggedError", moduleSymbol);
|
|
2888
|
+
if (!taggedErrorSymbol) return yield* typeParserIssue("TaggedError not found", void 0, sourceFile);
|
|
2889
|
+
return sourceFile;
|
|
2890
|
+
}),
|
|
2891
|
+
"TypeParser.isEffectDataSourceFile",
|
|
2892
|
+
(sourceFile) => sourceFile
|
|
2876
2893
|
);
|
|
2877
|
-
const
|
|
2878
|
-
fn("TypeParser.
|
|
2879
|
-
|
|
2880
|
-
return yield* typeParserIssue("Node is not an expression", void 0, node);
|
|
2881
|
-
}
|
|
2882
|
-
const type = typeChecker.getTypeAtLocation(node);
|
|
2883
|
-
const propertySymbol = typeChecker.getPropertyOfType(type, "TaggedError");
|
|
2884
|
-
if (!propertySymbol) {
|
|
2885
|
-
return yield* typeParserIssue("Type has no 'TaggedError' property", type, node);
|
|
2886
|
-
}
|
|
2887
|
-
const sourceFile = tsUtils.getSourceFileOfNode(node);
|
|
2888
|
-
if (!sourceFile) {
|
|
2889
|
-
return yield* typeParserIssue("Node is not in a source file", void 0, node);
|
|
2890
|
-
}
|
|
2891
|
-
const dataIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
2892
|
-
sourceFile,
|
|
2893
|
-
"effect",
|
|
2894
|
-
"Data"
|
|
2895
|
-
);
|
|
2896
|
-
if (!dataIdentifier) {
|
|
2897
|
-
return yield* typeParserIssue("Data module not found", void 0, node);
|
|
2898
|
-
}
|
|
2899
|
-
if (ts.idText(node) !== dataIdentifier) {
|
|
2900
|
-
return yield* typeParserIssue("Node is not a data module reference", void 0, node);
|
|
2901
|
-
}
|
|
2902
|
-
return node;
|
|
2894
|
+
const isNodeReferenceToEffectDataModuleApi = (memberName) => cachedBy(
|
|
2895
|
+
fn("TypeParser.isNodeReferenceToEffectDataModuleApi")(function* (node) {
|
|
2896
|
+
return yield* isNodeReferenceToExportOfPackageModule(node, "effect", isEffectDataSourceFile, memberName);
|
|
2903
2897
|
}),
|
|
2898
|
+
`TypeParser.isNodeReferenceToEffectDataModuleApi(${memberName})`,
|
|
2899
|
+
(node) => node
|
|
2900
|
+
);
|
|
2901
|
+
const importedDataModule = cachedBy(
|
|
2902
|
+
(node) => pipe(
|
|
2903
|
+
isNodeReferenceToPackageModule(node, "effect", isEffectDataSourceFile),
|
|
2904
|
+
map4(() => node)
|
|
2905
|
+
),
|
|
2904
2906
|
"TypeParser.importedDataModule",
|
|
2905
2907
|
(node) => node
|
|
2906
2908
|
);
|
|
@@ -3639,6 +3641,8 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3639
3641
|
return {
|
|
3640
3642
|
isNodeReferenceToEffectModuleApi,
|
|
3641
3643
|
isNodeReferenceToEffectSchemaModuleApi,
|
|
3644
|
+
isNodeReferenceToEffectDataModuleApi,
|
|
3645
|
+
isNodeReferenceToEffectContextModuleApi,
|
|
3642
3646
|
effectType,
|
|
3643
3647
|
strictEffectType,
|
|
3644
3648
|
layerType,
|
|
@@ -6042,6 +6046,85 @@ Consider extracting the Runtime by using for example Effect.runtime and then use
|
|
|
6042
6046
|
})
|
|
6043
6047
|
});
|
|
6044
6048
|
|
|
6049
|
+
// src/diagnostics/schemaStructWithTag.ts
|
|
6050
|
+
var schemaStructWithTag = createDiagnostic({
|
|
6051
|
+
name: "schemaStructWithTag",
|
|
6052
|
+
code: 34,
|
|
6053
|
+
severity: "suggestion",
|
|
6054
|
+
apply: fn("schemaStructWithTag.apply")(function* (sourceFile, report) {
|
|
6055
|
+
const ts = yield* service(TypeScriptApi);
|
|
6056
|
+
const typeParser = yield* service(TypeParser);
|
|
6057
|
+
const nodeToVisit = [];
|
|
6058
|
+
const appendNodeToVisit = (node) => {
|
|
6059
|
+
nodeToVisit.push(node);
|
|
6060
|
+
return void 0;
|
|
6061
|
+
};
|
|
6062
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
6063
|
+
while (nodeToVisit.length > 0) {
|
|
6064
|
+
const node = nodeToVisit.shift();
|
|
6065
|
+
if (ts.isCallExpression(node)) {
|
|
6066
|
+
const isSchemaStructCall = yield* pipe(
|
|
6067
|
+
typeParser.isNodeReferenceToEffectSchemaModuleApi("Struct")(node.expression),
|
|
6068
|
+
orElse2(() => void_)
|
|
6069
|
+
);
|
|
6070
|
+
if (isSchemaStructCall && node.arguments.length === 1) {
|
|
6071
|
+
const arg = node.arguments[0];
|
|
6072
|
+
if (ts.isObjectLiteralExpression(arg)) {
|
|
6073
|
+
const tagProperty = arg.properties.find(
|
|
6074
|
+
(prop) => ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && ts.idText(prop.name) === "_tag"
|
|
6075
|
+
);
|
|
6076
|
+
if (tagProperty && ts.isCallExpression(tagProperty.initializer)) {
|
|
6077
|
+
const isSchemaLiteralCall = yield* pipe(
|
|
6078
|
+
typeParser.isNodeReferenceToEffectSchemaModuleApi("Literal")(
|
|
6079
|
+
tagProperty.initializer.expression
|
|
6080
|
+
),
|
|
6081
|
+
option
|
|
6082
|
+
);
|
|
6083
|
+
if (isSchemaLiteralCall._tag === "Some") {
|
|
6084
|
+
const literalCall = tagProperty.initializer;
|
|
6085
|
+
const literalArgs = fromIterable(literalCall.arguments);
|
|
6086
|
+
if (literalArgs.length === 1 && ts.isStringLiteral(literalArgs[0])) {
|
|
6087
|
+
const tagValue = literalArgs[0].text;
|
|
6088
|
+
const otherProperties = arg.properties.filter((prop) => prop !== tagProperty);
|
|
6089
|
+
report({
|
|
6090
|
+
location: node,
|
|
6091
|
+
messageText: "Schema.Struct with a _tag field can be simplified to Schema.TaggedStruct to make the tag optional in the constructor.",
|
|
6092
|
+
fixes: [{
|
|
6093
|
+
fixName: "schemaStructWithTag_fix",
|
|
6094
|
+
description: "Replace with Schema.TaggedStruct",
|
|
6095
|
+
apply: gen(function* () {
|
|
6096
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
6097
|
+
const newObjectLiteral = ts.factory.createObjectLiteralExpression(
|
|
6098
|
+
otherProperties,
|
|
6099
|
+
true
|
|
6100
|
+
);
|
|
6101
|
+
const newNode = ts.factory.createCallExpression(
|
|
6102
|
+
ts.factory.createPropertyAccessExpression(
|
|
6103
|
+
// Reuse the Schema identifier from the original expression
|
|
6104
|
+
ts.isPropertyAccessExpression(node.expression) ? node.expression.expression : ts.factory.createIdentifier("Schema"),
|
|
6105
|
+
"TaggedStruct"
|
|
6106
|
+
),
|
|
6107
|
+
void 0,
|
|
6108
|
+
[
|
|
6109
|
+
ts.factory.createStringLiteral(tagValue),
|
|
6110
|
+
newObjectLiteral
|
|
6111
|
+
]
|
|
6112
|
+
);
|
|
6113
|
+
changeTracker.replaceNode(sourceFile, node, newNode);
|
|
6114
|
+
})
|
|
6115
|
+
}]
|
|
6116
|
+
});
|
|
6117
|
+
}
|
|
6118
|
+
}
|
|
6119
|
+
}
|
|
6120
|
+
}
|
|
6121
|
+
}
|
|
6122
|
+
}
|
|
6123
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
6124
|
+
}
|
|
6125
|
+
})
|
|
6126
|
+
});
|
|
6127
|
+
|
|
6045
6128
|
// src/diagnostics/schemaUnionOfLiterals.ts
|
|
6046
6129
|
var schemaUnionOfLiterals = createDiagnostic({
|
|
6047
6130
|
name: "schemaUnionOfLiterals",
|
|
@@ -6733,7 +6816,8 @@ var diagnostics = [
|
|
|
6733
6816
|
strictEffectProvide,
|
|
6734
6817
|
unknownInEffectCatch,
|
|
6735
6818
|
runEffectInsideEffect,
|
|
6736
|
-
schemaUnionOfLiterals
|
|
6819
|
+
schemaUnionOfLiterals,
|
|
6820
|
+
schemaStructWithTag
|
|
6737
6821
|
];
|
|
6738
6822
|
|
|
6739
6823
|
// src/transform.ts
|