@effect/language-service 0.29.0 → 0.31.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 +3 -24
- package/cli.js +467 -3
- package/cli.js.map +1 -1
- package/index.js +502 -38
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +467 -3
- package/transform.js.map +1 -1
package/package.json
CHANGED
package/transform.js
CHANGED
|
@@ -2266,6 +2266,36 @@ function make2(ts, tsUtils, typeChecker) {
|
|
|
2266
2266
|
"TypeParser.effectSubtype",
|
|
2267
2267
|
(type) => type
|
|
2268
2268
|
);
|
|
2269
|
+
const importedSchemaModule = cachedBy(
|
|
2270
|
+
fn("TypeParser.importedSchemaModule")(function* (node) {
|
|
2271
|
+
const type = typeChecker.getTypeAtLocation(node);
|
|
2272
|
+
const propertySymbol = typeChecker.getPropertyOfType(type, "Class");
|
|
2273
|
+
if (!propertySymbol) {
|
|
2274
|
+
return yield* typeParserIssue("Type has no 'Class' property", type, node);
|
|
2275
|
+
}
|
|
2276
|
+
if (!ts.isExpression(node)) {
|
|
2277
|
+
return yield* typeParserIssue("Node is not an expression", type, node);
|
|
2278
|
+
}
|
|
2279
|
+
return node;
|
|
2280
|
+
}),
|
|
2281
|
+
"TypeParser.importedSchemaModule",
|
|
2282
|
+
(node) => node
|
|
2283
|
+
);
|
|
2284
|
+
const importedContextModule = cachedBy(
|
|
2285
|
+
fn("TypeParser.importedContextModule")(function* (node) {
|
|
2286
|
+
const type = typeChecker.getTypeAtLocation(node);
|
|
2287
|
+
const propertySymbol = typeChecker.getPropertyOfType(type, "Tag");
|
|
2288
|
+
if (!propertySymbol) {
|
|
2289
|
+
return yield* typeParserIssue("Type has no 'Tag' property", type, node);
|
|
2290
|
+
}
|
|
2291
|
+
if (!ts.isExpression(node)) {
|
|
2292
|
+
return yield* typeParserIssue("Node is not an expression", type, node);
|
|
2293
|
+
}
|
|
2294
|
+
return node;
|
|
2295
|
+
}),
|
|
2296
|
+
"TypeParser.importedContextModule",
|
|
2297
|
+
(node) => node
|
|
2298
|
+
);
|
|
2269
2299
|
const importedEffectModule = cachedBy(
|
|
2270
2300
|
fn("TypeParser.importedEffectModule")(function* (node) {
|
|
2271
2301
|
const type = typeChecker.getTypeAtLocation(node);
|
|
@@ -2622,6 +2652,226 @@ function make2(ts, tsUtils, typeChecker) {
|
|
|
2622
2652
|
"TypeParser.promiseLike",
|
|
2623
2653
|
(type) => type
|
|
2624
2654
|
);
|
|
2655
|
+
const extendsSchemaClass = cachedBy(
|
|
2656
|
+
fn("TypeParser.extendsSchemaClass")(function* (atLocation) {
|
|
2657
|
+
if (!atLocation.name) {
|
|
2658
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
2659
|
+
}
|
|
2660
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
2661
|
+
if (!heritageClauses) {
|
|
2662
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
2663
|
+
}
|
|
2664
|
+
for (const heritageClause of heritageClauses) {
|
|
2665
|
+
for (const typeX of heritageClause.types) {
|
|
2666
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
2667
|
+
const expression = typeX.expression;
|
|
2668
|
+
if (ts.isCallExpression(expression)) {
|
|
2669
|
+
const schemaCall = expression.expression;
|
|
2670
|
+
if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
|
|
2671
|
+
const selfTypeNode = schemaCall.typeArguments[0];
|
|
2672
|
+
const schemaIdentifier = schemaCall.expression;
|
|
2673
|
+
if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && schemaIdentifier.name.text === "Class") {
|
|
2674
|
+
const parsedSchemaModule = yield* pipe(
|
|
2675
|
+
importedSchemaModule(schemaIdentifier.expression),
|
|
2676
|
+
option
|
|
2677
|
+
);
|
|
2678
|
+
if (isSome2(parsedSchemaModule)) {
|
|
2679
|
+
return {
|
|
2680
|
+
className: atLocation.name,
|
|
2681
|
+
selfTypeNode,
|
|
2682
|
+
Schema: parsedSchemaModule.value
|
|
2683
|
+
};
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2691
|
+
return yield* typeParserIssue("Class does not extend Schema.Class", void 0, atLocation);
|
|
2692
|
+
}),
|
|
2693
|
+
"TypeParser.extendsSchemaClass",
|
|
2694
|
+
(atLocation) => atLocation
|
|
2695
|
+
);
|
|
2696
|
+
const extendsSchemaTaggedClass = cachedBy(
|
|
2697
|
+
fn("TypeParser.extendsSchemaTaggedClass")(function* (atLocation) {
|
|
2698
|
+
if (!atLocation.name) {
|
|
2699
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
2700
|
+
}
|
|
2701
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
2702
|
+
if (!heritageClauses) {
|
|
2703
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
2704
|
+
}
|
|
2705
|
+
for (const heritageClause of heritageClauses) {
|
|
2706
|
+
for (const typeX of heritageClause.types) {
|
|
2707
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
2708
|
+
const expression = typeX.expression;
|
|
2709
|
+
if (ts.isCallExpression(expression)) {
|
|
2710
|
+
const tagCall = expression.expression;
|
|
2711
|
+
if (ts.isCallExpression(tagCall)) {
|
|
2712
|
+
const schemaCall = tagCall.expression;
|
|
2713
|
+
if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
|
|
2714
|
+
const selfTypeNode = schemaCall.typeArguments[0];
|
|
2715
|
+
const schemaIdentifier = schemaCall.expression;
|
|
2716
|
+
if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && schemaIdentifier.name.text === "TaggedClass") {
|
|
2717
|
+
const parsedSchemaModule = yield* pipe(
|
|
2718
|
+
importedSchemaModule(schemaIdentifier.expression),
|
|
2719
|
+
option
|
|
2720
|
+
);
|
|
2721
|
+
if (isSome2(parsedSchemaModule)) {
|
|
2722
|
+
return {
|
|
2723
|
+
className: atLocation.name,
|
|
2724
|
+
selfTypeNode,
|
|
2725
|
+
Schema: parsedSchemaModule.value
|
|
2726
|
+
};
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
return yield* typeParserIssue("Class does not extend Schema.TaggedClass", void 0, atLocation);
|
|
2736
|
+
}),
|
|
2737
|
+
"TypeParser.extendsSchemaTaggedClass",
|
|
2738
|
+
(atLocation) => atLocation
|
|
2739
|
+
);
|
|
2740
|
+
const extendsSchemaTaggedError = cachedBy(
|
|
2741
|
+
fn("TypeParser.extendsSchemaTaggedError")(function* (atLocation) {
|
|
2742
|
+
if (!atLocation.name) {
|
|
2743
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
2744
|
+
}
|
|
2745
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
2746
|
+
if (!heritageClauses) {
|
|
2747
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
2748
|
+
}
|
|
2749
|
+
for (const heritageClause of heritageClauses) {
|
|
2750
|
+
for (const typeX of heritageClause.types) {
|
|
2751
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
2752
|
+
const expression = typeX.expression;
|
|
2753
|
+
if (ts.isCallExpression(expression)) {
|
|
2754
|
+
const tagCall = expression.expression;
|
|
2755
|
+
if (ts.isCallExpression(tagCall)) {
|
|
2756
|
+
const schemaCall = tagCall.expression;
|
|
2757
|
+
if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
|
|
2758
|
+
const selfTypeNode = schemaCall.typeArguments[0];
|
|
2759
|
+
const schemaIdentifier = schemaCall.expression;
|
|
2760
|
+
if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && schemaIdentifier.name.text === "TaggedError") {
|
|
2761
|
+
const parsedSchemaModule = yield* pipe(
|
|
2762
|
+
importedSchemaModule(schemaIdentifier.expression),
|
|
2763
|
+
option
|
|
2764
|
+
);
|
|
2765
|
+
if (isSome2(parsedSchemaModule)) {
|
|
2766
|
+
return {
|
|
2767
|
+
className: atLocation.name,
|
|
2768
|
+
selfTypeNode,
|
|
2769
|
+
Schema: parsedSchemaModule.value
|
|
2770
|
+
};
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
return yield* typeParserIssue("Class does not extend Schema.TaggedError", void 0, atLocation);
|
|
2780
|
+
}),
|
|
2781
|
+
"TypeParser.extendsSchemaTaggedError",
|
|
2782
|
+
(atLocation) => atLocation
|
|
2783
|
+
);
|
|
2784
|
+
const extendsSchemaTaggedRequest = cachedBy(
|
|
2785
|
+
fn("TypeParser.extendsSchemaTaggedRequest")(function* (atLocation) {
|
|
2786
|
+
if (!atLocation.name) {
|
|
2787
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
2788
|
+
}
|
|
2789
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
2790
|
+
if (!heritageClauses) {
|
|
2791
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
2792
|
+
}
|
|
2793
|
+
for (const heritageClause of heritageClauses) {
|
|
2794
|
+
for (const typeX of heritageClause.types) {
|
|
2795
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
2796
|
+
const expression = typeX.expression;
|
|
2797
|
+
if (ts.isCallExpression(expression)) {
|
|
2798
|
+
const tagCall = expression.expression;
|
|
2799
|
+
if (ts.isCallExpression(tagCall)) {
|
|
2800
|
+
const schemaCall = tagCall.expression;
|
|
2801
|
+
if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
|
|
2802
|
+
const selfTypeNode = schemaCall.typeArguments[0];
|
|
2803
|
+
const schemaIdentifier = schemaCall.expression;
|
|
2804
|
+
if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && schemaIdentifier.name.text === "TaggedRequest") {
|
|
2805
|
+
const parsedSchemaModule = yield* pipe(
|
|
2806
|
+
importedSchemaModule(schemaIdentifier.expression),
|
|
2807
|
+
option
|
|
2808
|
+
);
|
|
2809
|
+
if (isSome2(parsedSchemaModule)) {
|
|
2810
|
+
return {
|
|
2811
|
+
className: atLocation.name,
|
|
2812
|
+
selfTypeNode,
|
|
2813
|
+
Schema: parsedSchemaModule.value
|
|
2814
|
+
};
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
}
|
|
2823
|
+
return yield* typeParserIssue("Class does not extend Schema.TaggedRequest", void 0, atLocation);
|
|
2824
|
+
}),
|
|
2825
|
+
"TypeParser.extendsSchemaTaggedRequest",
|
|
2826
|
+
(atLocation) => atLocation
|
|
2827
|
+
);
|
|
2828
|
+
const extendsContextTag = cachedBy(
|
|
2829
|
+
fn("TypeParser.extendsContextTag")(function* (atLocation) {
|
|
2830
|
+
if (!atLocation.name) {
|
|
2831
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
2832
|
+
}
|
|
2833
|
+
const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
|
|
2834
|
+
if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
|
|
2835
|
+
const type = typeChecker.getTypeOfSymbol(classSym);
|
|
2836
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
2837
|
+
if (!heritageClauses) {
|
|
2838
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
2839
|
+
}
|
|
2840
|
+
for (const heritageClause of heritageClauses) {
|
|
2841
|
+
for (const typeX of heritageClause.types) {
|
|
2842
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
2843
|
+
const wholeCall = typeX.expression;
|
|
2844
|
+
if (ts.isCallExpression(wholeCall)) {
|
|
2845
|
+
const contextTagCall = wholeCall.expression;
|
|
2846
|
+
if (ts.isCallExpression(contextTagCall) && wholeCall.typeArguments && wholeCall.typeArguments.length > 0) {
|
|
2847
|
+
const contextTagIdentifier = contextTagCall.expression;
|
|
2848
|
+
const selfTypeNode = wholeCall.typeArguments[0];
|
|
2849
|
+
if (ts.isPropertyAccessExpression(contextTagIdentifier) && ts.isIdentifier(contextTagIdentifier.name) && contextTagIdentifier.name.text === "Tag") {
|
|
2850
|
+
const parsedContextModule = yield* pipe(
|
|
2851
|
+
importedContextModule(contextTagIdentifier.expression),
|
|
2852
|
+
option
|
|
2853
|
+
);
|
|
2854
|
+
if (isSome2(parsedContextModule)) {
|
|
2855
|
+
const tagType = yield* contextTag(type, atLocation);
|
|
2856
|
+
return {
|
|
2857
|
+
className: atLocation.name,
|
|
2858
|
+
selfTypeNode,
|
|
2859
|
+
args: contextTagCall.arguments,
|
|
2860
|
+
Identifier: tagType.Identifier,
|
|
2861
|
+
Tag: parsedContextModule.value
|
|
2862
|
+
};
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
return yield* typeParserIssue("Class does not extend Context.Tag", void 0, atLocation);
|
|
2871
|
+
}),
|
|
2872
|
+
"TypeParser.extendsContextTag",
|
|
2873
|
+
(atLocation) => atLocation
|
|
2874
|
+
);
|
|
2625
2875
|
const extendsEffectService = cachedBy(
|
|
2626
2876
|
fn("TypeParser.extendsEffectService")(function* (atLocation) {
|
|
2627
2877
|
if (!atLocation.name) {
|
|
@@ -2651,6 +2901,7 @@ function make2(ts, tsUtils, typeChecker) {
|
|
|
2651
2901
|
);
|
|
2652
2902
|
if (isSome2(parsedContextTag)) {
|
|
2653
2903
|
let accessors2 = void 0;
|
|
2904
|
+
let dependencies = void 0;
|
|
2654
2905
|
if (wholeCall.arguments.length >= 2) {
|
|
2655
2906
|
const args2 = wholeCall.arguments[1];
|
|
2656
2907
|
if (ts.isObjectLiteralExpression(args2)) {
|
|
@@ -2658,6 +2909,9 @@ function make2(ts, tsUtils, typeChecker) {
|
|
|
2658
2909
|
if (ts.isPropertyAssignment(property) && property.name && ts.isIdentifier(property.name) && property.name.text === "accessors" && property.initializer && property.initializer.kind === ts.SyntaxKind.TrueKeyword) {
|
|
2659
2910
|
accessors2 = true;
|
|
2660
2911
|
}
|
|
2912
|
+
if (ts.isPropertyAssignment(property) && property.name && ts.isIdentifier(property.name) && property.name.text === "dependencies" && property.initializer && ts.isArrayLiteralExpression(property.initializer)) {
|
|
2913
|
+
dependencies = property.initializer.elements;
|
|
2914
|
+
}
|
|
2661
2915
|
}
|
|
2662
2916
|
}
|
|
2663
2917
|
}
|
|
@@ -2666,7 +2920,8 @@ function make2(ts, tsUtils, typeChecker) {
|
|
|
2666
2920
|
className: atLocation.name,
|
|
2667
2921
|
selfTypeNode,
|
|
2668
2922
|
args: wholeCall.arguments,
|
|
2669
|
-
accessors: accessors2
|
|
2923
|
+
accessors: accessors2,
|
|
2924
|
+
dependencies
|
|
2670
2925
|
};
|
|
2671
2926
|
}
|
|
2672
2927
|
}
|
|
@@ -2697,10 +2952,78 @@ function make2(ts, tsUtils, typeChecker) {
|
|
|
2697
2952
|
pipeCall,
|
|
2698
2953
|
scopeType,
|
|
2699
2954
|
promiseLike,
|
|
2700
|
-
extendsEffectService
|
|
2955
|
+
extendsEffectService,
|
|
2956
|
+
extendsContextTag,
|
|
2957
|
+
extendsSchemaClass,
|
|
2958
|
+
extendsSchemaTaggedClass,
|
|
2959
|
+
extendsSchemaTaggedError,
|
|
2960
|
+
extendsSchemaTaggedRequest
|
|
2701
2961
|
};
|
|
2702
2962
|
}
|
|
2703
2963
|
|
|
2964
|
+
// src/diagnostics/classSelfMismatch.ts
|
|
2965
|
+
var classSelfMismatch = createDiagnostic({
|
|
2966
|
+
name: "classSelfMismatch",
|
|
2967
|
+
code: 20,
|
|
2968
|
+
severity: "error",
|
|
2969
|
+
apply: fn("classSelfMismatch.apply")(function* (sourceFile, report) {
|
|
2970
|
+
const ts = yield* service(TypeScriptApi);
|
|
2971
|
+
const typeParser = yield* service(TypeParser);
|
|
2972
|
+
const nodeToVisit = [];
|
|
2973
|
+
const appendNodeToVisit = (node) => {
|
|
2974
|
+
nodeToVisit.push(node);
|
|
2975
|
+
return void 0;
|
|
2976
|
+
};
|
|
2977
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
2978
|
+
while (nodeToVisit.length > 0) {
|
|
2979
|
+
const node = nodeToVisit.shift();
|
|
2980
|
+
if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
|
|
2981
|
+
const result = yield* pipe(
|
|
2982
|
+
typeParser.extendsEffectService(node),
|
|
2983
|
+
orElse2(() => typeParser.extendsContextTag(node)),
|
|
2984
|
+
orElse2(() => typeParser.extendsSchemaClass(node)),
|
|
2985
|
+
orElse2(() => typeParser.extendsSchemaTaggedClass(node)),
|
|
2986
|
+
orElse2(() => typeParser.extendsSchemaTaggedError(node)),
|
|
2987
|
+
orElse2(() => typeParser.extendsSchemaTaggedRequest(node)),
|
|
2988
|
+
orElse2(() => void_)
|
|
2989
|
+
);
|
|
2990
|
+
if (result) {
|
|
2991
|
+
const { className, selfTypeNode } = result;
|
|
2992
|
+
let actualName = "";
|
|
2993
|
+
if (ts.isTypeReferenceNode(selfTypeNode)) {
|
|
2994
|
+
if (ts.isIdentifier(selfTypeNode.typeName)) {
|
|
2995
|
+
actualName = selfTypeNode.typeName.text;
|
|
2996
|
+
} else if (ts.isQualifiedName(selfTypeNode.typeName)) {
|
|
2997
|
+
actualName = selfTypeNode.typeName.right.text;
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
3000
|
+
const expectedName = className.text;
|
|
3001
|
+
if (actualName !== expectedName) {
|
|
3002
|
+
report({
|
|
3003
|
+
location: selfTypeNode,
|
|
3004
|
+
messageText: `Self type parameter should be '${expectedName}'`,
|
|
3005
|
+
fixes: [{
|
|
3006
|
+
fixName: "classSelfMismatch_fix",
|
|
3007
|
+
description: `Replace '${actualName}' with '${expectedName}'`,
|
|
3008
|
+
apply: gen(function* () {
|
|
3009
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
3010
|
+
const typeArgs = ts.isTypeReferenceNode(selfTypeNode) ? selfTypeNode.typeArguments : void 0;
|
|
3011
|
+
const newTypeReference = ts.factory.createTypeReferenceNode(
|
|
3012
|
+
ts.factory.createIdentifier(expectedName),
|
|
3013
|
+
typeArgs
|
|
3014
|
+
);
|
|
3015
|
+
changeTracker.replaceNode(sourceFile, selfTypeNode, newTypeReference);
|
|
3016
|
+
})
|
|
3017
|
+
}]
|
|
3018
|
+
});
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
3023
|
+
}
|
|
3024
|
+
})
|
|
3025
|
+
});
|
|
3026
|
+
|
|
2704
3027
|
// src/diagnostics/duplicatePackage.ts
|
|
2705
3028
|
var checkedPackagesCache = /* @__PURE__ */ new Map();
|
|
2706
3029
|
var programResolvedCacheSize = /* @__PURE__ */ new Map();
|
|
@@ -3320,6 +3643,89 @@ var missingEffectError = createDiagnostic({
|
|
|
3320
3643
|
})
|
|
3321
3644
|
});
|
|
3322
3645
|
|
|
3646
|
+
// src/diagnostics/missingEffectServiceDependency.ts
|
|
3647
|
+
var missingEffectServiceDependency = createDiagnostic({
|
|
3648
|
+
name: "missingEffectServiceDependency",
|
|
3649
|
+
code: 21,
|
|
3650
|
+
severity: "off",
|
|
3651
|
+
apply: fn("missingEffectServiceDependency.apply")(function* (sourceFile, report) {
|
|
3652
|
+
const ts = yield* service(TypeScriptApi);
|
|
3653
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
3654
|
+
const typeParser = yield* service(TypeParser);
|
|
3655
|
+
const nodeToVisit = [];
|
|
3656
|
+
const appendNodeToVisit = (node) => {
|
|
3657
|
+
nodeToVisit.push(node);
|
|
3658
|
+
return void 0;
|
|
3659
|
+
};
|
|
3660
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
3661
|
+
while (nodeToVisit.length > 0) {
|
|
3662
|
+
const node = nodeToVisit.shift();
|
|
3663
|
+
if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
|
|
3664
|
+
const serviceResult = yield* pipe(
|
|
3665
|
+
typeParser.extendsEffectService(node),
|
|
3666
|
+
orElse2(() => void_)
|
|
3667
|
+
);
|
|
3668
|
+
if (serviceResult) {
|
|
3669
|
+
const { className, dependencies } = serviceResult;
|
|
3670
|
+
const classSymbol = typeChecker.getSymbolAtLocation(className);
|
|
3671
|
+
if (classSymbol) {
|
|
3672
|
+
const classType = typeChecker.getTypeOfSymbol(classSymbol);
|
|
3673
|
+
const defaultWithoutDepsProperty = typeChecker.getPropertyOfType(classType, "DefaultWithoutDependencies");
|
|
3674
|
+
const defaultProperty = defaultWithoutDepsProperty || typeChecker.getPropertyOfType(classType, "Default");
|
|
3675
|
+
if (defaultProperty) {
|
|
3676
|
+
const defaultType = typeChecker.getTypeOfSymbolAtLocation(defaultProperty, node);
|
|
3677
|
+
const layerResult = yield* pipe(
|
|
3678
|
+
typeParser.layerType(defaultType, node),
|
|
3679
|
+
orElse2(() => void_)
|
|
3680
|
+
);
|
|
3681
|
+
if (layerResult) {
|
|
3682
|
+
const servicesMemory = /* @__PURE__ */ new Map();
|
|
3683
|
+
const excludeNever = (type) => succeed((type.flags & ts.TypeFlags.Never) !== 0);
|
|
3684
|
+
const { allIndexes: requiredIndexes } = yield* appendToUniqueTypesMap(
|
|
3685
|
+
servicesMemory,
|
|
3686
|
+
layerResult.RIn,
|
|
3687
|
+
excludeNever
|
|
3688
|
+
);
|
|
3689
|
+
const providedIndexes = /* @__PURE__ */ new Set();
|
|
3690
|
+
const dependenciesToProcess = dependencies || [];
|
|
3691
|
+
for (const depExpression of dependenciesToProcess) {
|
|
3692
|
+
const depType = typeChecker.getTypeAtLocation(depExpression);
|
|
3693
|
+
const depLayerResult = yield* pipe(
|
|
3694
|
+
typeParser.layerType(depType, depExpression),
|
|
3695
|
+
orElse2(() => void_)
|
|
3696
|
+
);
|
|
3697
|
+
if (depLayerResult) {
|
|
3698
|
+
const { allIndexes } = yield* appendToUniqueTypesMap(
|
|
3699
|
+
servicesMemory,
|
|
3700
|
+
depLayerResult.ROut,
|
|
3701
|
+
excludeNever
|
|
3702
|
+
);
|
|
3703
|
+
for (const index of allIndexes) {
|
|
3704
|
+
providedIndexes.add(index);
|
|
3705
|
+
}
|
|
3706
|
+
}
|
|
3707
|
+
}
|
|
3708
|
+
const missingIndexes = requiredIndexes.filter((index) => !providedIndexes.has(index));
|
|
3709
|
+
if (missingIndexes.length > 0) {
|
|
3710
|
+
const missingTypes = missingIndexes.map((index) => servicesMemory.get(index));
|
|
3711
|
+
const missingTypeNames = missingTypes.map((t) => typeChecker.typeToString(t));
|
|
3712
|
+
const message = missingTypeNames.length === 1 ? `Service '${missingTypeNames[0]}' is required but not provided by dependencies` : `Services ${missingTypeNames.map((s) => `'${s}'`).join(", ")} are required but not provided by dependencies`;
|
|
3713
|
+
report({
|
|
3714
|
+
location: className,
|
|
3715
|
+
messageText: message,
|
|
3716
|
+
fixes: []
|
|
3717
|
+
});
|
|
3718
|
+
}
|
|
3719
|
+
}
|
|
3720
|
+
}
|
|
3721
|
+
}
|
|
3722
|
+
}
|
|
3723
|
+
}
|
|
3724
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
3725
|
+
}
|
|
3726
|
+
})
|
|
3727
|
+
});
|
|
3728
|
+
|
|
3323
3729
|
// src/diagnostics/missingReturnYieldStar.ts
|
|
3324
3730
|
var missingReturnYieldStar = createDiagnostic({
|
|
3325
3731
|
name: "missingReturnYieldStar",
|
|
@@ -4315,11 +4721,68 @@ var unnecessaryPipeChain = createDiagnostic({
|
|
|
4315
4721
|
})
|
|
4316
4722
|
});
|
|
4317
4723
|
|
|
4724
|
+
// src/diagnostics/unsupportedServiceAccessors.ts
|
|
4725
|
+
var unsupportedServiceAccessors = createDiagnostic({
|
|
4726
|
+
name: "unsupportedServiceAccessors",
|
|
4727
|
+
code: 21,
|
|
4728
|
+
severity: "warning",
|
|
4729
|
+
apply: fn("unsupportedServiceAccessors.apply")(function* (sourceFile, report) {
|
|
4730
|
+
const ts = yield* service(TypeScriptApi);
|
|
4731
|
+
const nodeToVisit = [];
|
|
4732
|
+
const appendNodeToVisit = (node) => {
|
|
4733
|
+
nodeToVisit.push(node);
|
|
4734
|
+
return void 0;
|
|
4735
|
+
};
|
|
4736
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
4737
|
+
while (nodeToVisit.length > 0) {
|
|
4738
|
+
const node = nodeToVisit.shift();
|
|
4739
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
4740
|
+
if (ts.isClassDeclaration(node)) {
|
|
4741
|
+
const parseResult = yield* pipe(
|
|
4742
|
+
parse2(node),
|
|
4743
|
+
orElse2(() => succeed(null))
|
|
4744
|
+
);
|
|
4745
|
+
if (parseResult && parseResult.involvedMembers.length > 0) {
|
|
4746
|
+
const existingStaticMembers = /* @__PURE__ */ new Set();
|
|
4747
|
+
node.members?.forEach((member) => {
|
|
4748
|
+
if (ts.isPropertyDeclaration(member) && member.modifiers?.some((mod) => mod.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
4749
|
+
if (member.name && ts.isIdentifier(member.name)) {
|
|
4750
|
+
existingStaticMembers.add(member.name.text);
|
|
4751
|
+
}
|
|
4752
|
+
}
|
|
4753
|
+
});
|
|
4754
|
+
const missingMembers = parseResult.involvedMembers.filter(
|
|
4755
|
+
({ property }) => !existingStaticMembers.has(property.getName())
|
|
4756
|
+
);
|
|
4757
|
+
if (missingMembers.length > 0) {
|
|
4758
|
+
const memberNames = missingMembers.map(({ property }) => `'${property.getName()}'`).join(", ");
|
|
4759
|
+
report({
|
|
4760
|
+
location: parseResult.className,
|
|
4761
|
+
messageText: `Even if accessors are enabled, accessors for ${memberNames} won't be available because the signature have generic type parameters or multiple call signatures.`,
|
|
4762
|
+
fixes: [{
|
|
4763
|
+
fixName: "unsupportedServiceAccessors_enableCodegen",
|
|
4764
|
+
description: "Enable accessors codegen",
|
|
4765
|
+
apply: gen(function* () {
|
|
4766
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
4767
|
+
const comment = "// @effect-codegens accessors\n";
|
|
4768
|
+
changeTracker.insertText(sourceFile, node.getStart(sourceFile), comment);
|
|
4769
|
+
})
|
|
4770
|
+
}]
|
|
4771
|
+
});
|
|
4772
|
+
}
|
|
4773
|
+
}
|
|
4774
|
+
}
|
|
4775
|
+
}
|
|
4776
|
+
})
|
|
4777
|
+
});
|
|
4778
|
+
|
|
4318
4779
|
// src/diagnostics.ts
|
|
4319
4780
|
var diagnostics = [
|
|
4781
|
+
classSelfMismatch,
|
|
4320
4782
|
duplicatePackage,
|
|
4321
4783
|
missingEffectContext,
|
|
4322
4784
|
missingEffectError,
|
|
4785
|
+
missingEffectServiceDependency,
|
|
4323
4786
|
floatingEffect,
|
|
4324
4787
|
missingStarInYieldEffectGen,
|
|
4325
4788
|
unnecessaryEffectGen,
|
|
@@ -4335,7 +4798,8 @@ var diagnostics = [
|
|
|
4335
4798
|
unnecessaryPipeChain,
|
|
4336
4799
|
strictBooleanExpressions,
|
|
4337
4800
|
multipleEffectProvide,
|
|
4338
|
-
outdatedEffectCodegen
|
|
4801
|
+
outdatedEffectCodegen,
|
|
4802
|
+
unsupportedServiceAccessors
|
|
4339
4803
|
];
|
|
4340
4804
|
|
|
4341
4805
|
// src/transform.ts
|