@effect/language-service 0.21.2 → 0.21.4
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 +40 -1
- package/index.js +133 -6
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +133 -6
- package/transform.js.map +1 -1
package/package.json
CHANGED
package/transform.js
CHANGED
|
@@ -1014,6 +1014,8 @@ function parsePackageContentNameAndVersionFromScope(v) {
|
|
|
1014
1014
|
const packageJsonContent = packageJsonScope.contents.packageJsonContent;
|
|
1015
1015
|
if (!hasProperty(packageJsonContent, "name")) return;
|
|
1016
1016
|
if (!hasProperty(packageJsonContent, "version")) return;
|
|
1017
|
+
if (!hasProperty(packageJsonScope, "packageDirectory")) return;
|
|
1018
|
+
if (!isString(packageJsonScope.packageDirectory)) return;
|
|
1017
1019
|
const { name, version } = packageJsonContent;
|
|
1018
1020
|
if (!isString(name)) return;
|
|
1019
1021
|
if (!isString(version)) return;
|
|
@@ -1022,7 +1024,8 @@ function parsePackageContentNameAndVersionFromScope(v) {
|
|
|
1022
1024
|
name: name.toLowerCase(),
|
|
1023
1025
|
version: version.toLowerCase(),
|
|
1024
1026
|
hasEffectInPeerDependencies,
|
|
1025
|
-
contents: packageJsonContent
|
|
1027
|
+
contents: packageJsonContent,
|
|
1028
|
+
packageDirectory: packageJsonScope.packageDirectory
|
|
1026
1029
|
};
|
|
1027
1030
|
}
|
|
1028
1031
|
|
|
@@ -2369,7 +2372,7 @@ var duplicatePackage = createDiagnostic({
|
|
|
2369
2372
|
if (!(packageInfo.name === "effect" || packageInfo.hasEffectInPeerDependencies)) return;
|
|
2370
2373
|
if (options.allowedDuplicatedPackages.indexOf(packageInfo.name) > -1) return;
|
|
2371
2374
|
resolvedPackages[packageInfo.name] = resolvedPackages[packageInfo.name] || {};
|
|
2372
|
-
resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.
|
|
2375
|
+
resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.packageDirectory;
|
|
2373
2376
|
});
|
|
2374
2377
|
checkedPackagesCache.set(sourceFile.fileName, resolvedPackages);
|
|
2375
2378
|
programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
|
|
@@ -2382,7 +2385,9 @@ var duplicatePackage = createDiagnostic({
|
|
|
2382
2385
|
category: ts.DiagnosticCategory.Warning,
|
|
2383
2386
|
messageText: `Package ${packageName} is referenced multiple times with different versions (${versions.join(", ")}) and may cause unexpected type errors.
|
|
2384
2387
|
Cleanup your dependencies and your package lockfile to avoid multiple instances of this package and reload the project.
|
|
2385
|
-
If this is intended set the LSP config "allowedDuplicatedPackages" to ${JSON.stringify(options.allowedDuplicatedPackages.concat([packageName]))}
|
|
2388
|
+
If this is intended set the LSP config "allowedDuplicatedPackages" to ${JSON.stringify(options.allowedDuplicatedPackages.concat([packageName]))}.
|
|
2389
|
+
|
|
2390
|
+
${versions.map((version) => `- found ${version} at ${resolvedPackages[packageName][version]}`).join("\n")}`,
|
|
2386
2391
|
fixes: []
|
|
2387
2392
|
});
|
|
2388
2393
|
}
|
|
@@ -2439,6 +2444,54 @@ var floatingEffect = createDiagnostic({
|
|
|
2439
2444
|
})
|
|
2440
2445
|
});
|
|
2441
2446
|
|
|
2447
|
+
// src/diagnostics/genericEffectServices.ts
|
|
2448
|
+
var genericEffectServices = createDiagnostic({
|
|
2449
|
+
name: "genericEffectServices",
|
|
2450
|
+
code: 10,
|
|
2451
|
+
apply: fn("genericEffectServices.apply")(function* (sourceFile) {
|
|
2452
|
+
const ts = yield* service(TypeScriptApi);
|
|
2453
|
+
const typeParser = yield* service(TypeParser);
|
|
2454
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
2455
|
+
const effectDiagnostics = [];
|
|
2456
|
+
const nodeToVisit = [];
|
|
2457
|
+
const appendNodeToVisit = (node) => {
|
|
2458
|
+
nodeToVisit.push(node);
|
|
2459
|
+
return void 0;
|
|
2460
|
+
};
|
|
2461
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
2462
|
+
while (nodeToVisit.length > 0) {
|
|
2463
|
+
const node = nodeToVisit.shift();
|
|
2464
|
+
const typesToCheck = [];
|
|
2465
|
+
if (ts.isClassDeclaration(node) && node.name && node.typeParameters && node.heritageClauses) {
|
|
2466
|
+
const classSym = typeChecker.getSymbolAtLocation(node.name);
|
|
2467
|
+
if (classSym) {
|
|
2468
|
+
const type = typeChecker.getTypeOfSymbol(classSym);
|
|
2469
|
+
typesToCheck.push([type, node.name]);
|
|
2470
|
+
}
|
|
2471
|
+
} else {
|
|
2472
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
2473
|
+
continue;
|
|
2474
|
+
}
|
|
2475
|
+
for (const [type, reportAt] of typesToCheck) {
|
|
2476
|
+
yield* pipe(
|
|
2477
|
+
typeParser.contextTag(type, node),
|
|
2478
|
+
map3(() => {
|
|
2479
|
+
effectDiagnostics.push({
|
|
2480
|
+
node: reportAt,
|
|
2481
|
+
category: ts.DiagnosticCategory.Warning,
|
|
2482
|
+
messageText: `Effect Services with type parameters are not supported because they cannot be properly discriminated at runtime, which may cause unexpected behavior.`,
|
|
2483
|
+
fixes: []
|
|
2484
|
+
});
|
|
2485
|
+
}),
|
|
2486
|
+
orElse2(() => sync(() => ts.forEachChild(node, appendNodeToVisit))),
|
|
2487
|
+
ignore
|
|
2488
|
+
);
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2491
|
+
return effectDiagnostics;
|
|
2492
|
+
})
|
|
2493
|
+
});
|
|
2494
|
+
|
|
2442
2495
|
// src/diagnostics/leakingRequirements.ts
|
|
2443
2496
|
var leakingRequirements = createDiagnostic({
|
|
2444
2497
|
name: "leakingRequirements",
|
|
@@ -2517,7 +2570,7 @@ var leakingRequirements = createDiagnostic({
|
|
|
2517
2570
|
const typesToCheck = [];
|
|
2518
2571
|
if (ts.isCallExpression(node)) {
|
|
2519
2572
|
typesToCheck.push([typeChecker.getTypeAtLocation(node), node]);
|
|
2520
|
-
} else if (ts.isClassDeclaration(node) && node.name) {
|
|
2573
|
+
} else if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
|
|
2521
2574
|
const classSym = typeChecker.getSymbolAtLocation(node.name);
|
|
2522
2575
|
if (classSym) {
|
|
2523
2576
|
const type = typeChecker.getTypeOfSymbol(classSym);
|
|
@@ -2713,7 +2766,7 @@ var missingReturnYieldStar = createDiagnostic({
|
|
|
2713
2766
|
effectDiagnostics.push({
|
|
2714
2767
|
node,
|
|
2715
2768
|
category: ts.DiagnosticCategory.Error,
|
|
2716
|
-
messageText: `Yielded Effect never
|
|
2769
|
+
messageText: `Yielded Effect never succeeds, so it is best to use a 'return yield*' instead.`,
|
|
2717
2770
|
fixes: fix
|
|
2718
2771
|
});
|
|
2719
2772
|
});
|
|
@@ -2797,6 +2850,78 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
2797
2850
|
})
|
|
2798
2851
|
});
|
|
2799
2852
|
|
|
2853
|
+
// src/diagnostics/returnEffectInGen.ts
|
|
2854
|
+
var returnEffectInGen = createDiagnostic({
|
|
2855
|
+
name: "returnEffectInGen",
|
|
2856
|
+
code: 11,
|
|
2857
|
+
apply: fn("returnEffectInGen.apply")(function* (sourceFile) {
|
|
2858
|
+
const ts = yield* service(TypeScriptApi);
|
|
2859
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
2860
|
+
const typeParser = yield* service(TypeParser);
|
|
2861
|
+
const effectDiagnostics = [];
|
|
2862
|
+
const brokenReturnStatements = /* @__PURE__ */ new Set();
|
|
2863
|
+
const nodeToVisit = [];
|
|
2864
|
+
const appendNodeToVisit = (node) => {
|
|
2865
|
+
nodeToVisit.push(node);
|
|
2866
|
+
return void 0;
|
|
2867
|
+
};
|
|
2868
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
2869
|
+
while (nodeToVisit.length > 0) {
|
|
2870
|
+
const node = nodeToVisit.shift();
|
|
2871
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
2872
|
+
if (ts.isReturnStatement(node) && node.expression) {
|
|
2873
|
+
if (ts.isYieldExpression(node.expression)) continue;
|
|
2874
|
+
const generatorOrRegularFunction = ts.findAncestor(
|
|
2875
|
+
node,
|
|
2876
|
+
(_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isArrowFunction(_) || ts.isGetAccessor(_)
|
|
2877
|
+
);
|
|
2878
|
+
if (!(generatorOrRegularFunction && "asteriskToken" in generatorOrRegularFunction && generatorOrRegularFunction.asteriskToken)) continue;
|
|
2879
|
+
const type = typeChecker.getTypeAtLocation(node.expression);
|
|
2880
|
+
const maybeEffect = yield* option(typeParser.effectType(type, node.expression));
|
|
2881
|
+
if (isSome2(maybeEffect)) {
|
|
2882
|
+
const maybeEffectSubtype = yield* option(typeParser.effectSubtype(type, node.expression));
|
|
2883
|
+
if (isNone2(maybeEffectSubtype)) {
|
|
2884
|
+
if (generatorOrRegularFunction && generatorOrRegularFunction.parent) {
|
|
2885
|
+
const effectGenNode = generatorOrRegularFunction.parent;
|
|
2886
|
+
yield* pipe(
|
|
2887
|
+
typeParser.effectGen(effectGenNode),
|
|
2888
|
+
orElse2(() => typeParser.effectFnUntracedGen(effectGenNode)),
|
|
2889
|
+
orElse2(() => typeParser.effectFnGen(effectGenNode)),
|
|
2890
|
+
map3(() => brokenReturnStatements.add(node)),
|
|
2891
|
+
ignore
|
|
2892
|
+
);
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
brokenReturnStatements.forEach((node) => {
|
|
2899
|
+
const fix = node.expression ? [{
|
|
2900
|
+
fixName: "returnEffectInGen_fix",
|
|
2901
|
+
description: "Add yield* statement",
|
|
2902
|
+
apply: gen(function* () {
|
|
2903
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
2904
|
+
changeTracker.replaceNode(
|
|
2905
|
+
sourceFile,
|
|
2906
|
+
node.expression,
|
|
2907
|
+
ts.factory.createYieldExpression(
|
|
2908
|
+
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
2909
|
+
node.expression
|
|
2910
|
+
)
|
|
2911
|
+
);
|
|
2912
|
+
})
|
|
2913
|
+
}] : [];
|
|
2914
|
+
effectDiagnostics.push({
|
|
2915
|
+
node,
|
|
2916
|
+
category: ts.DiagnosticCategory.Suggestion,
|
|
2917
|
+
messageText: `You are returning an Effect-able type inside a generator function, and will result in nested Effect<Effect<...>>. Maybe you wanted to return yield* instead? Nested Effect-able types may be intended if you plan to later manually flatten or unwrap this Effect.`,
|
|
2918
|
+
fixes: fix
|
|
2919
|
+
});
|
|
2920
|
+
});
|
|
2921
|
+
return effectDiagnostics;
|
|
2922
|
+
})
|
|
2923
|
+
});
|
|
2924
|
+
|
|
2800
2925
|
// src/diagnostics/unnecessaryEffectGen.ts
|
|
2801
2926
|
var unnecessaryEffectGen = createDiagnostic({
|
|
2802
2927
|
name: "unnecessaryEffectGen",
|
|
@@ -2901,7 +3026,9 @@ var diagnostics = [
|
|
|
2901
3026
|
unnecessaryEffectGen,
|
|
2902
3027
|
missingReturnYieldStar,
|
|
2903
3028
|
leakingRequirements,
|
|
2904
|
-
unnecessaryPipe
|
|
3029
|
+
unnecessaryPipe,
|
|
3030
|
+
genericEffectServices,
|
|
3031
|
+
returnEffectInGen
|
|
2905
3032
|
];
|
|
2906
3033
|
|
|
2907
3034
|
// src/transform.ts
|