@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/package.json
CHANGED
package/transform.js
CHANGED
|
@@ -2576,7 +2576,16 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2576
2576
|
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
2577
2577
|
if (!moduleSymbol) continue;
|
|
2578
2578
|
const memberSymbol = typeChecker.tryGetMemberInModuleExports(memberName, moduleSymbol);
|
|
2579
|
-
if (memberSymbol
|
|
2579
|
+
if (memberSymbol) {
|
|
2580
|
+
if (memberSymbol === symbol3) {
|
|
2581
|
+
result.push({ memberSymbol, moduleSymbol, sourceFile });
|
|
2582
|
+
} else if (memberSymbol.flags & ts.SymbolFlags.Alias) {
|
|
2583
|
+
const aliased = typeChecker.getAliasedSymbol(memberSymbol);
|
|
2584
|
+
if (aliased === symbol3) {
|
|
2585
|
+
result.push({ memberSymbol, moduleSymbol, sourceFile });
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2580
2589
|
}
|
|
2581
2590
|
if (result.length > 0) {
|
|
2582
2591
|
return result;
|
|
@@ -2831,67 +2840,69 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2831
2840
|
"TypeParser.effectSubtype",
|
|
2832
2841
|
(type) => type
|
|
2833
2842
|
);
|
|
2834
|
-
const
|
|
2835
|
-
fn("TypeParser.
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
const
|
|
2841
|
-
if (!
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
);
|
|
2853
|
-
if (!contextIdentifier) {
|
|
2854
|
-
return yield* typeParserIssue("Context module not found", void 0, node);
|
|
2855
|
-
}
|
|
2856
|
-
if (ts.idText(node) !== contextIdentifier) {
|
|
2857
|
-
return yield* typeParserIssue("Node is not a context module reference", void 0, node);
|
|
2858
|
-
}
|
|
2859
|
-
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);
|
|
2860
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
|
+
),
|
|
2861
2870
|
"TypeParser.importedContextModule",
|
|
2862
2871
|
(node) => node
|
|
2863
2872
|
);
|
|
2864
|
-
const importedEffectModule = (
|
|
2865
|
-
|
|
2866
|
-
|
|
2873
|
+
const importedEffectModule = cachedBy(
|
|
2874
|
+
(node) => pipe(
|
|
2875
|
+
isNodeReferenceToPackageModule(node, "effect", isEffectTypeSourceFile),
|
|
2876
|
+
map4(() => node)
|
|
2877
|
+
),
|
|
2878
|
+
"TypeParser.importedEffectModule",
|
|
2879
|
+
(node) => node
|
|
2867
2880
|
);
|
|
2868
|
-
const
|
|
2869
|
-
fn("TypeParser.
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
const
|
|
2875
|
-
if (!
|
|
2876
|
-
|
|
2877
|
-
}
|
|
2878
|
-
const sourceFile = tsUtils.getSourceFileOfNode(node);
|
|
2879
|
-
if (!sourceFile) {
|
|
2880
|
-
return yield* typeParserIssue("Node is not in a source file", void 0, node);
|
|
2881
|
-
}
|
|
2882
|
-
const dataIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
2883
|
-
sourceFile,
|
|
2884
|
-
"effect",
|
|
2885
|
-
"Data"
|
|
2886
|
-
);
|
|
2887
|
-
if (!dataIdentifier) {
|
|
2888
|
-
return yield* typeParserIssue("Data module not found", void 0, node);
|
|
2889
|
-
}
|
|
2890
|
-
if (ts.idText(node) !== dataIdentifier) {
|
|
2891
|
-
return yield* typeParserIssue("Node is not a data module reference", void 0, node);
|
|
2892
|
-
}
|
|
2893
|
-
return node;
|
|
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;
|
|
2894
2890
|
}),
|
|
2891
|
+
"TypeParser.isEffectDataSourceFile",
|
|
2892
|
+
(sourceFile) => sourceFile
|
|
2893
|
+
);
|
|
2894
|
+
const isNodeReferenceToEffectDataModuleApi = (memberName) => cachedBy(
|
|
2895
|
+
fn("TypeParser.isNodeReferenceToEffectDataModuleApi")(function* (node) {
|
|
2896
|
+
return yield* isNodeReferenceToExportOfPackageModule(node, "effect", isEffectDataSourceFile, memberName);
|
|
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
|
+
),
|
|
2895
2906
|
"TypeParser.importedDataModule",
|
|
2896
2907
|
(node) => node
|
|
2897
2908
|
);
|
|
@@ -3630,6 +3641,8 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3630
3641
|
return {
|
|
3631
3642
|
isNodeReferenceToEffectModuleApi,
|
|
3632
3643
|
isNodeReferenceToEffectSchemaModuleApi,
|
|
3644
|
+
isNodeReferenceToEffectDataModuleApi,
|
|
3645
|
+
isNodeReferenceToEffectContextModuleApi,
|
|
3633
3646
|
effectType,
|
|
3634
3647
|
strictEffectType,
|
|
3635
3648
|
layerType,
|
|
@@ -5593,7 +5606,7 @@ var annotate = createCodegen({
|
|
|
5593
5606
|
const initializerTypeNode = fromNullable(typeCheckerUtils.typeToSimplifiedTypeNode(
|
|
5594
5607
|
initializerType,
|
|
5595
5608
|
enclosingNode,
|
|
5596
|
-
ts.NodeBuilderFlags.NoTruncation
|
|
5609
|
+
ts.NodeBuilderFlags.NoTruncation | ts.NodeBuilderFlags.IgnoreErrors
|
|
5597
5610
|
)).pipe(
|
|
5598
5611
|
getOrUndefined
|
|
5599
5612
|
);
|
|
@@ -6033,6 +6046,85 @@ Consider extracting the Runtime by using for example Effect.runtime and then use
|
|
|
6033
6046
|
})
|
|
6034
6047
|
});
|
|
6035
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
|
+
|
|
6036
6128
|
// src/diagnostics/schemaUnionOfLiterals.ts
|
|
6037
6129
|
var schemaUnionOfLiterals = createDiagnostic({
|
|
6038
6130
|
name: "schemaUnionOfLiterals",
|
|
@@ -6724,7 +6816,8 @@ var diagnostics = [
|
|
|
6724
6816
|
strictEffectProvide,
|
|
6725
6817
|
unknownInEffectCatch,
|
|
6726
6818
|
runEffectInsideEffect,
|
|
6727
|
-
schemaUnionOfLiterals
|
|
6819
|
+
schemaUnionOfLiterals,
|
|
6820
|
+
schemaStructWithTag
|
|
6728
6821
|
];
|
|
6729
6822
|
|
|
6730
6823
|
// src/transform.ts
|