@effect/language-service 0.21.8 → 0.22.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 +10 -6
- package/index.js +546 -370
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +185 -84
- package/transform.js.map +1 -1
package/package.json
CHANGED
package/transform.js
CHANGED
|
@@ -754,8 +754,6 @@ var fromIterable = (collection) => Array.isArray(collection) ? collection : Arra
|
|
|
754
754
|
var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
|
|
755
755
|
var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable(self).concat(fromIterable(that)));
|
|
756
756
|
var isArray = Array.isArray;
|
|
757
|
-
var isEmptyArray = (self) => self.length === 0;
|
|
758
|
-
var isEmptyReadonlyArray = isEmptyArray;
|
|
759
757
|
var sort = /* @__PURE__ */ dual(2, (self, O) => {
|
|
760
758
|
const out = Array.from(self);
|
|
761
759
|
out.sort(O);
|
|
@@ -777,20 +775,6 @@ var intersectionWith = (isEquivalent) => {
|
|
|
777
775
|
var intersection = /* @__PURE__ */ intersectionWith(_equivalence);
|
|
778
776
|
var empty = () => [];
|
|
779
777
|
var map2 = /* @__PURE__ */ dual(2, (self, f) => self.map(f));
|
|
780
|
-
var flatMap = /* @__PURE__ */ dual(2, (self, f) => {
|
|
781
|
-
if (isEmptyReadonlyArray(self)) {
|
|
782
|
-
return [];
|
|
783
|
-
}
|
|
784
|
-
const out = [];
|
|
785
|
-
for (let i = 0; i < self.length; i++) {
|
|
786
|
-
const inner = f(self[i], i);
|
|
787
|
-
for (let j = 0; j < inner.length; j++) {
|
|
788
|
-
out.push(inner[j]);
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
return out;
|
|
792
|
-
});
|
|
793
|
-
var flatten = /* @__PURE__ */ flatMap(identity);
|
|
794
778
|
var filter = /* @__PURE__ */ dual(2, (self, predicate) => {
|
|
795
779
|
const as = fromIterable(self);
|
|
796
780
|
const out = [];
|
|
@@ -874,7 +858,7 @@ var run = (fa) => {
|
|
|
874
858
|
var succeed = (value) => make2(() => makeInternalSuccess(value));
|
|
875
859
|
var fail = (value) => make2(() => makeInternalFailure(value));
|
|
876
860
|
var sync = (value) => make2(() => makeInternalSuccess(value()));
|
|
877
|
-
var
|
|
861
|
+
var flatMap = dual(2, (fa, f) => make2((ctx) => {
|
|
878
862
|
const result = fa.run(ctx);
|
|
879
863
|
if (result._tag !== "Right") return result;
|
|
880
864
|
return f(result.value).run(ctx);
|
|
@@ -996,7 +980,8 @@ function parse(config) {
|
|
|
996
980
|
quickinfo: isObject(config) && hasProperty(config, "quickinfo") && isBoolean(config.quickinfo) ? config.quickinfo : true,
|
|
997
981
|
completions: isObject(config) && hasProperty(config, "completions") && isBoolean(config.completions) ? config.completions : true,
|
|
998
982
|
goto: isObject(config) && hasProperty(config, "goto") && isBoolean(config.goto) ? config.goto : true,
|
|
999
|
-
allowedDuplicatedPackages: isObject(config) && hasProperty(config, "allowedDuplicatedPackages") && isArray(config.allowedDuplicatedPackages) && config.allowedDuplicatedPackages.every(isString) ? config.allowedDuplicatedPackages.map((_) => _.toLowerCase()) : []
|
|
983
|
+
allowedDuplicatedPackages: isObject(config) && hasProperty(config, "allowedDuplicatedPackages") && isArray(config.allowedDuplicatedPackages) && config.allowedDuplicatedPackages.every(isString) ? config.allowedDuplicatedPackages.map((_) => _.toLowerCase()) : [],
|
|
984
|
+
namespaceImportPackages: isObject(config) && hasProperty(config, "namespaceImportPackages") && isArray(config.namespaceImportPackages) && config.namespaceImportPackages.every(isString) ? config.namespaceImportPackages.map((_) => _.toLowerCase()) : []
|
|
1000
985
|
};
|
|
1001
986
|
}
|
|
1002
987
|
|
|
@@ -1028,6 +1013,20 @@ function parsePackageContentNameAndVersionFromScope(v) {
|
|
|
1028
1013
|
packageDirectory: packageJsonScope.packageDirectory
|
|
1029
1014
|
};
|
|
1030
1015
|
}
|
|
1016
|
+
function makeGetModuleSpecifier(ts) {
|
|
1017
|
+
if (!(hasProperty(ts, "moduleSpecifiers") && hasProperty(ts.moduleSpecifiers, "getModuleSpecifier") && isFunction2(ts.moduleSpecifiers.getModuleSpecifier))) return;
|
|
1018
|
+
const _internal = ts.moduleSpecifiers.getModuleSpecifier;
|
|
1019
|
+
return (compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, options) => {
|
|
1020
|
+
return _internal(
|
|
1021
|
+
compilerOptions,
|
|
1022
|
+
importingSourceFile,
|
|
1023
|
+
importingSourceFileName,
|
|
1024
|
+
toFileName,
|
|
1025
|
+
host,
|
|
1026
|
+
options
|
|
1027
|
+
);
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1031
1030
|
|
|
1032
1031
|
// src/core/LSP.ts
|
|
1033
1032
|
var RefactorNotApplicableError = class {
|
|
@@ -1043,40 +1042,9 @@ var getSemanticDiagnosticsWithCodeFixes = fn(
|
|
|
1043
1042
|
let effectCodeFixes = [];
|
|
1044
1043
|
const executor = yield* createDiagnosticExecutor(sourceFile);
|
|
1045
1044
|
for (const rule of rules) {
|
|
1046
|
-
const
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
pipe(
|
|
1050
|
-
result.value,
|
|
1051
|
-
map2((_) => ({
|
|
1052
|
-
file: sourceFile,
|
|
1053
|
-
start: _.node.getStart(sourceFile),
|
|
1054
|
-
length: _.node.getEnd() - _.node.getStart(sourceFile),
|
|
1055
|
-
messageText: _.messageText,
|
|
1056
|
-
category: _.category,
|
|
1057
|
-
code: rule.code,
|
|
1058
|
-
source: "effect"
|
|
1059
|
-
}))
|
|
1060
|
-
)
|
|
1061
|
-
);
|
|
1062
|
-
effectCodeFixes = effectCodeFixes.concat(
|
|
1063
|
-
pipe(
|
|
1064
|
-
result.value,
|
|
1065
|
-
map2(
|
|
1066
|
-
(_) => map2(
|
|
1067
|
-
_.fixes,
|
|
1068
|
-
(fix) => ({
|
|
1069
|
-
...fix,
|
|
1070
|
-
code: rule.code,
|
|
1071
|
-
start: _.node.getStart(sourceFile),
|
|
1072
|
-
end: _.node.getEnd()
|
|
1073
|
-
})
|
|
1074
|
-
)
|
|
1075
|
-
),
|
|
1076
|
-
flatten
|
|
1077
|
-
)
|
|
1078
|
-
);
|
|
1079
|
-
}
|
|
1045
|
+
const { codeFixes, diagnostics: diagnostics2 } = yield* executor.execute(rule);
|
|
1046
|
+
effectDiagnostics = effectDiagnostics.concat(diagnostics2);
|
|
1047
|
+
effectCodeFixes = effectCodeFixes.concat(codeFixes);
|
|
1080
1048
|
}
|
|
1081
1049
|
return {
|
|
1082
1050
|
diagnostics: effectDiagnostics,
|
|
@@ -1207,12 +1175,14 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1207
1175
|
suggestion: ts.DiagnosticCategory.Suggestion
|
|
1208
1176
|
};
|
|
1209
1177
|
const execute = fn("LSP.ruleExecutor")(function* (rule) {
|
|
1178
|
+
const diagnostics2 = [];
|
|
1179
|
+
const codeFixes = [];
|
|
1210
1180
|
const ruleNameLowered = rule.name.toLowerCase();
|
|
1211
|
-
if (skippedRules.indexOf(ruleNameLowered) > -1) return
|
|
1181
|
+
if (skippedRules.indexOf(ruleNameLowered) > -1) return { diagnostics: diagnostics2, codeFixes };
|
|
1212
1182
|
const fixByDisableNextLine = (_) => ({
|
|
1213
1183
|
fixName: rule.name + "_skipNextLine",
|
|
1214
1184
|
description: "Disable " + rule.name + " for this line",
|
|
1215
|
-
apply:
|
|
1185
|
+
apply: flatMap(
|
|
1216
1186
|
service(ChangeTracker),
|
|
1217
1187
|
(changeTracker) => sync(() => {
|
|
1218
1188
|
const disableAtNode = findParentStatementForDisableNextLine(_.node);
|
|
@@ -1229,7 +1199,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1229
1199
|
const fixByDisableEntireFile = {
|
|
1230
1200
|
fixName: rule.name + "_skipFile",
|
|
1231
1201
|
description: "Disable " + rule.name + " for this entire file",
|
|
1232
|
-
apply:
|
|
1202
|
+
apply: flatMap(
|
|
1233
1203
|
service(ChangeTracker),
|
|
1234
1204
|
(changeTracker) => sync(
|
|
1235
1205
|
() => changeTracker.insertText(
|
|
@@ -1241,16 +1211,15 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1241
1211
|
)
|
|
1242
1212
|
)
|
|
1243
1213
|
};
|
|
1244
|
-
|
|
1214
|
+
const applicableDiagnostics = [];
|
|
1245
1215
|
yield* rule.apply(sourceFile, (entry) => {
|
|
1246
|
-
|
|
1216
|
+
applicableDiagnostics.push({
|
|
1247
1217
|
...entry,
|
|
1248
1218
|
fixes: entry.fixes.concat([fixByDisableNextLine(entry), fixByDisableEntireFile])
|
|
1249
1219
|
});
|
|
1250
1220
|
});
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
let newLevel = pluginOptions.diagnosticSeverity[ruleNameLowered];
|
|
1221
|
+
for (const emitted of applicableDiagnostics.slice(0)) {
|
|
1222
|
+
let newLevel = pluginOptions.diagnosticSeverity[ruleNameLowered] || rule.severity;
|
|
1254
1223
|
const lineOverride = (lineOverrides[ruleNameLowered] || []).find(
|
|
1255
1224
|
(_) => _.pos < emitted.node.getStart(sourceFile) && _.end >= emitted.node.getEnd()
|
|
1256
1225
|
);
|
|
@@ -1262,13 +1231,26 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1262
1231
|
);
|
|
1263
1232
|
if (sectionOverride) newLevel = sectionOverride.level;
|
|
1264
1233
|
}
|
|
1265
|
-
if (newLevel
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1234
|
+
if (!(newLevel in levelToDiagnosticCategory)) continue;
|
|
1235
|
+
diagnostics2.push({
|
|
1236
|
+
file: sourceFile,
|
|
1237
|
+
start: emitted.node.getStart(sourceFile),
|
|
1238
|
+
length: emitted.node.getEnd() - emitted.node.getStart(sourceFile),
|
|
1239
|
+
messageText: emitted.messageText,
|
|
1240
|
+
category: levelToDiagnosticCategory[newLevel],
|
|
1241
|
+
code: rule.code,
|
|
1242
|
+
source: "effect"
|
|
1243
|
+
});
|
|
1244
|
+
for (const fix of emitted.fixes) {
|
|
1245
|
+
codeFixes.push({
|
|
1246
|
+
...fix,
|
|
1247
|
+
code: rule.code,
|
|
1248
|
+
start: emitted.node.getStart(sourceFile),
|
|
1249
|
+
end: emitted.node.getEnd()
|
|
1250
|
+
});
|
|
1269
1251
|
}
|
|
1270
1252
|
}
|
|
1271
|
-
return
|
|
1253
|
+
return { diagnostics: diagnostics2, codeFixes };
|
|
1272
1254
|
});
|
|
1273
1255
|
return { execute };
|
|
1274
1256
|
}
|
|
@@ -1525,6 +1507,15 @@ var appendToUniqueTypesMap = fn(
|
|
|
1525
1507
|
};
|
|
1526
1508
|
}
|
|
1527
1509
|
);
|
|
1510
|
+
function makeResolveExternalModuleName(typeChecker) {
|
|
1511
|
+
if (!(hasProperty(typeChecker, "resolveExternalModuleName") && isFunction(typeChecker.resolveExternalModuleName))) {
|
|
1512
|
+
return;
|
|
1513
|
+
}
|
|
1514
|
+
const _internal = typeChecker.resolveExternalModuleName;
|
|
1515
|
+
return (moduleSpecifier) => {
|
|
1516
|
+
return _internal(moduleSpecifier);
|
|
1517
|
+
};
|
|
1518
|
+
}
|
|
1528
1519
|
|
|
1529
1520
|
// src/core/AST.ts
|
|
1530
1521
|
function collectSelfAndAncestorNodesInRange(node, textRange) {
|
|
@@ -2359,8 +2350,8 @@ var programResolvedCacheSize = /* @__PURE__ */ new Map();
|
|
|
2359
2350
|
var duplicatePackage = createDiagnostic({
|
|
2360
2351
|
name: "duplicatePackage",
|
|
2361
2352
|
code: 6,
|
|
2353
|
+
severity: "warning",
|
|
2362
2354
|
apply: fn("duplicatePackage.apply")(function* (sourceFile, report) {
|
|
2363
|
-
const ts = yield* service(TypeScriptApi);
|
|
2364
2355
|
const program = yield* service(TypeScriptProgram);
|
|
2365
2356
|
const options = yield* service(LanguageServicePluginOptions);
|
|
2366
2357
|
if (sourceFile.statements.length < 1) return;
|
|
@@ -2389,7 +2380,6 @@ var duplicatePackage = createDiagnostic({
|
|
|
2389
2380
|
const versions = Object.keys(resolvedPackages[packageName]);
|
|
2390
2381
|
report({
|
|
2391
2382
|
node: sourceFile.statements[0],
|
|
2392
|
-
category: ts.DiagnosticCategory.Warning,
|
|
2393
2383
|
messageText: `Package ${packageName} is referenced multiple times with different versions (${versions.join(", ")}) and may cause unexpected type errors.
|
|
2394
2384
|
Cleanup your dependencies and your package lockfile to avoid multiple instances of this package and reload the project.
|
|
2395
2385
|
If this is intended set the LSP config "allowedDuplicatedPackages" to ${JSON.stringify(options.allowedDuplicatedPackages.concat([packageName]))}.
|
|
@@ -2406,6 +2396,7 @@ ${versions.map((version) => `- found ${version} at ${resolvedPackages[packageNam
|
|
|
2406
2396
|
var floatingEffect = createDiagnostic({
|
|
2407
2397
|
name: "floatingEffect",
|
|
2408
2398
|
code: 3,
|
|
2399
|
+
severity: "error",
|
|
2409
2400
|
apply: fn("floatingEffect.apply")(function* (sourceFile, report) {
|
|
2410
2401
|
const ts = yield* service(TypeScriptApi);
|
|
2411
2402
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -2438,7 +2429,6 @@ var floatingEffect = createDiagnostic({
|
|
|
2438
2429
|
if (isNone2(allowedFloatingEffects)) {
|
|
2439
2430
|
report({
|
|
2440
2431
|
node,
|
|
2441
|
-
category: ts.DiagnosticCategory.Error,
|
|
2442
2432
|
messageText: `Effect must be yielded or assigned to a variable.`,
|
|
2443
2433
|
fixes: []
|
|
2444
2434
|
});
|
|
@@ -2452,6 +2442,7 @@ var floatingEffect = createDiagnostic({
|
|
|
2452
2442
|
var genericEffectServices = createDiagnostic({
|
|
2453
2443
|
name: "genericEffectServices",
|
|
2454
2444
|
code: 10,
|
|
2445
|
+
severity: "warning",
|
|
2455
2446
|
apply: fn("genericEffectServices.apply")(function* (sourceFile, report) {
|
|
2456
2447
|
const ts = yield* service(TypeScriptApi);
|
|
2457
2448
|
const typeParser = yield* service(TypeParser);
|
|
@@ -2481,7 +2472,6 @@ var genericEffectServices = createDiagnostic({
|
|
|
2481
2472
|
map3(() => {
|
|
2482
2473
|
report({
|
|
2483
2474
|
node: reportAt,
|
|
2484
|
-
category: ts.DiagnosticCategory.Warning,
|
|
2485
2475
|
messageText: `Effect Services with type parameters are not supported because they cannot be properly discriminated at runtime, which may cause unexpected behavior.`,
|
|
2486
2476
|
fixes: []
|
|
2487
2477
|
});
|
|
@@ -2494,10 +2484,124 @@ var genericEffectServices = createDiagnostic({
|
|
|
2494
2484
|
})
|
|
2495
2485
|
});
|
|
2496
2486
|
|
|
2487
|
+
// src/diagnostics/importFromBarrel.ts
|
|
2488
|
+
var importFromBarrel = createDiagnostic({
|
|
2489
|
+
name: "importFromBarrel",
|
|
2490
|
+
code: 12,
|
|
2491
|
+
severity: "off",
|
|
2492
|
+
apply: fn("importFromBarrel.apply")(function* (sourceFile, report) {
|
|
2493
|
+
const languageServicePluginOptions = yield* service(LanguageServicePluginOptions);
|
|
2494
|
+
if (languageServicePluginOptions.namespaceImportPackages.length === 0) return;
|
|
2495
|
+
const ts = yield* service(TypeScriptApi);
|
|
2496
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
2497
|
+
const program = yield* service(TypeScriptProgram);
|
|
2498
|
+
const isImportedFromBarrelExport = (element, languageServicePluginOptions2) => {
|
|
2499
|
+
const getModuleSpecifier = makeGetModuleSpecifier(ts);
|
|
2500
|
+
const resolveExternalModuleName = makeResolveExternalModuleName(typeChecker);
|
|
2501
|
+
if (!(getModuleSpecifier && resolveExternalModuleName)) return;
|
|
2502
|
+
const importDeclaration = ts.findAncestor(element, (node) => ts.isImportDeclaration(node));
|
|
2503
|
+
if (!importDeclaration) return;
|
|
2504
|
+
if (!ts.isStringLiteral(importDeclaration.moduleSpecifier)) return;
|
|
2505
|
+
const importClause = importDeclaration.importClause;
|
|
2506
|
+
if (!importClause) return;
|
|
2507
|
+
const namedBindings = importClause.namedBindings;
|
|
2508
|
+
if (!namedBindings) return;
|
|
2509
|
+
if (!ts.isNamedImports(namedBindings)) return;
|
|
2510
|
+
const barrelModuleName = importDeclaration.moduleSpecifier.text;
|
|
2511
|
+
if (languageServicePluginOptions2.namespaceImportPackages.indexOf(barrelModuleName.toLowerCase()) === -1) return;
|
|
2512
|
+
const moduleSymbol = resolveExternalModuleName(importDeclaration.moduleSpecifier);
|
|
2513
|
+
if (!moduleSymbol) return;
|
|
2514
|
+
if (!moduleSymbol.exports) return;
|
|
2515
|
+
const sourceFile2 = importDeclaration.getSourceFile();
|
|
2516
|
+
const nodeForSymbol = element.propertyName || element.name;
|
|
2517
|
+
if (!ts.isIdentifier(nodeForSymbol)) return;
|
|
2518
|
+
const importedName = nodeForSymbol.text;
|
|
2519
|
+
const reexportedSymbol = moduleSymbol.exports.get(ts.escapeLeadingUnderscores(importedName));
|
|
2520
|
+
if (!reexportedSymbol) return;
|
|
2521
|
+
if (!(reexportedSymbol.declarations && reexportedSymbol.declarations.length === 1)) return;
|
|
2522
|
+
const namespaceExport = reexportedSymbol.declarations[0];
|
|
2523
|
+
if (!ts.isNamespaceExport(namespaceExport)) return;
|
|
2524
|
+
const exportDeclaration = namespaceExport.parent;
|
|
2525
|
+
if (!ts.isExportDeclaration(exportDeclaration)) return;
|
|
2526
|
+
if (!exportDeclaration.moduleSpecifier) return;
|
|
2527
|
+
const originalModuleSymbol = resolveExternalModuleName(exportDeclaration.moduleSpecifier);
|
|
2528
|
+
if (!originalModuleSymbol) return;
|
|
2529
|
+
if (!originalModuleSymbol.valueDeclaration) return;
|
|
2530
|
+
const originalSourceFile = originalModuleSymbol.valueDeclaration.getSourceFile();
|
|
2531
|
+
const unbarrelledFileName = getModuleSpecifier(
|
|
2532
|
+
program.getCompilerOptions(),
|
|
2533
|
+
sourceFile2,
|
|
2534
|
+
sourceFile2.fileName,
|
|
2535
|
+
originalSourceFile.fileName,
|
|
2536
|
+
program
|
|
2537
|
+
);
|
|
2538
|
+
if (unbarrelledFileName.toLowerCase().indexOf(barrelModuleName.toLowerCase() + "/") === -1) return;
|
|
2539
|
+
return { unbarrelledFileName, importedName, barrelModuleName, importClause, namedBindings, importDeclaration };
|
|
2540
|
+
};
|
|
2541
|
+
const nodeToVisit = [];
|
|
2542
|
+
const appendNodeToVisit = (node) => {
|
|
2543
|
+
nodeToVisit.push(node);
|
|
2544
|
+
return void 0;
|
|
2545
|
+
};
|
|
2546
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
2547
|
+
while (nodeToVisit.length > 0) {
|
|
2548
|
+
const node = nodeToVisit.shift();
|
|
2549
|
+
const parent = node.parent;
|
|
2550
|
+
if (!(ts.isImportSpecifier(node) && ts.isNamedImports(parent))) {
|
|
2551
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
2552
|
+
continue;
|
|
2553
|
+
}
|
|
2554
|
+
const result = isImportedFromBarrelExport(node, languageServicePluginOptions);
|
|
2555
|
+
if (!result) continue;
|
|
2556
|
+
const { barrelModuleName, importClause, importDeclaration, importedName, namedBindings, unbarrelledFileName } = result;
|
|
2557
|
+
report({
|
|
2558
|
+
node,
|
|
2559
|
+
messageText: `Importing from barrel module ${barrelModuleName} is not allowed.`,
|
|
2560
|
+
fixes: [
|
|
2561
|
+
{
|
|
2562
|
+
fixName: "replaceWithUnbarrelledImport",
|
|
2563
|
+
description: `Import * as ${importedName} from ${unbarrelledFileName}`,
|
|
2564
|
+
apply: gen(function* () {
|
|
2565
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
2566
|
+
const newImport = ts.factory.createImportDeclaration(
|
|
2567
|
+
void 0,
|
|
2568
|
+
ts.factory.createImportClause(
|
|
2569
|
+
importClause.isTypeOnly || node.isTypeOnly,
|
|
2570
|
+
void 0,
|
|
2571
|
+
ts.factory.createNamespaceImport(ts.factory.createIdentifier(importedName))
|
|
2572
|
+
),
|
|
2573
|
+
ts.factory.createStringLiteral(unbarrelledFileName)
|
|
2574
|
+
);
|
|
2575
|
+
if (namedBindings.elements.length === 1) {
|
|
2576
|
+
changeTracker.replaceNode(
|
|
2577
|
+
sourceFile,
|
|
2578
|
+
importDeclaration,
|
|
2579
|
+
newImport
|
|
2580
|
+
);
|
|
2581
|
+
} else {
|
|
2582
|
+
changeTracker.insertNodeAfter(sourceFile, importDeclaration, newImport);
|
|
2583
|
+
changeTracker.replaceNode(
|
|
2584
|
+
sourceFile,
|
|
2585
|
+
namedBindings,
|
|
2586
|
+
ts.factory.updateNamedImports(
|
|
2587
|
+
namedBindings,
|
|
2588
|
+
namedBindings.elements.filter((e) => e !== node)
|
|
2589
|
+
)
|
|
2590
|
+
);
|
|
2591
|
+
}
|
|
2592
|
+
})
|
|
2593
|
+
}
|
|
2594
|
+
]
|
|
2595
|
+
});
|
|
2596
|
+
}
|
|
2597
|
+
})
|
|
2598
|
+
});
|
|
2599
|
+
|
|
2497
2600
|
// src/diagnostics/leakingRequirements.ts
|
|
2498
2601
|
var leakingRequirements = createDiagnostic({
|
|
2499
2602
|
name: "leakingRequirements",
|
|
2500
2603
|
code: 8,
|
|
2604
|
+
severity: "suggestion",
|
|
2501
2605
|
apply: fn("leakingRequirements.apply")(function* (sourceFile, report) {
|
|
2502
2606
|
const ts = yield* service(TypeScriptApi);
|
|
2503
2607
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -2555,7 +2659,6 @@ var leakingRequirements = createDiagnostic({
|
|
|
2555
2659
|
if (requirements.length === 0) return;
|
|
2556
2660
|
report({
|
|
2557
2661
|
node,
|
|
2558
|
-
category: ts.DiagnosticCategory.Warning,
|
|
2559
2662
|
messageText: `This Service is leaking the ${requirements.map((_) => typeChecker.typeToString(_)).join(" | ")} requirement.
|
|
2560
2663
|
If these requirements cannot be cached and are expected to be provided per method invocation (e.g. HttpServerRequest), you can safely disable this diagnostic for this line through quickfixes.
|
|
2561
2664
|
More info at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage`,
|
|
@@ -2586,7 +2689,7 @@ More info at https://effect.website/docs/requirements-management/layers/#avoidin
|
|
|
2586
2689
|
for (const [type, reportAt] of typesToCheck) {
|
|
2587
2690
|
yield* pipe(
|
|
2588
2691
|
typeParser.contextTag(type, node),
|
|
2589
|
-
|
|
2692
|
+
flatMap(
|
|
2590
2693
|
({ Service }) => pipe(
|
|
2591
2694
|
parseLeakedRequirements(Service, node),
|
|
2592
2695
|
map3((requirements) => reportLeakingRequirements(reportAt, sort(requirements, typeOrder)))
|
|
@@ -2604,8 +2707,8 @@ More info at https://effect.website/docs/requirements-management/layers/#avoidin
|
|
|
2604
2707
|
var missingEffectContext = createDiagnostic({
|
|
2605
2708
|
name: "missingEffectContext",
|
|
2606
2709
|
code: 1,
|
|
2710
|
+
severity: "error",
|
|
2607
2711
|
apply: fn("missingEffectContext.apply")(function* (sourceFile, report) {
|
|
2608
|
-
const ts = yield* service(TypeScriptApi);
|
|
2609
2712
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2610
2713
|
const typeParser = yield* service(TypeParser);
|
|
2611
2714
|
const typeOrder = yield* deterministicTypeOrder;
|
|
@@ -2614,7 +2717,7 @@ var missingEffectContext = createDiagnostic({
|
|
|
2614
2717
|
typeParser.effectType(expectedType, node),
|
|
2615
2718
|
typeParser.effectType(realType, valueNode)
|
|
2616
2719
|
),
|
|
2617
|
-
|
|
2720
|
+
flatMap(
|
|
2618
2721
|
([expectedEffect, realEffect]) => getMissingTypeEntriesInTargetType(
|
|
2619
2722
|
realEffect.R,
|
|
2620
2723
|
expectedEffect.R
|
|
@@ -2637,7 +2740,6 @@ var missingEffectContext = createDiagnostic({
|
|
|
2637
2740
|
report(
|
|
2638
2741
|
{
|
|
2639
2742
|
node,
|
|
2640
|
-
category: ts.DiagnosticCategory.Error,
|
|
2641
2743
|
messageText: `Missing '${sortTypes(missingContext).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect context.`,
|
|
2642
2744
|
fixes: []
|
|
2643
2745
|
}
|
|
@@ -2651,8 +2753,8 @@ var missingEffectContext = createDiagnostic({
|
|
|
2651
2753
|
var missingEffectError = createDiagnostic({
|
|
2652
2754
|
name: "missingEffectError",
|
|
2653
2755
|
code: 1,
|
|
2756
|
+
severity: "error",
|
|
2654
2757
|
apply: fn("missingEffectError.apply")(function* (sourceFile, report) {
|
|
2655
|
-
const ts = yield* service(TypeScriptApi);
|
|
2656
2758
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2657
2759
|
const typeParser = yield* service(TypeParser);
|
|
2658
2760
|
const typeOrder = yield* deterministicTypeOrder;
|
|
@@ -2661,7 +2763,7 @@ var missingEffectError = createDiagnostic({
|
|
|
2661
2763
|
typeParser.effectType(expectedType, node),
|
|
2662
2764
|
typeParser.effectType(realType, valueNode)
|
|
2663
2765
|
),
|
|
2664
|
-
|
|
2766
|
+
flatMap(
|
|
2665
2767
|
([expectedEffect, realEffect]) => getMissingTypeEntriesInTargetType(
|
|
2666
2768
|
realEffect.E,
|
|
2667
2769
|
expectedEffect.E
|
|
@@ -2684,7 +2786,6 @@ var missingEffectError = createDiagnostic({
|
|
|
2684
2786
|
report(
|
|
2685
2787
|
{
|
|
2686
2788
|
node,
|
|
2687
|
-
category: ts.DiagnosticCategory.Error,
|
|
2688
2789
|
messageText: `Missing '${sortTypes(missingContext).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect errors.`,
|
|
2689
2790
|
fixes: []
|
|
2690
2791
|
}
|
|
@@ -2698,6 +2799,7 @@ var missingEffectError = createDiagnostic({
|
|
|
2698
2799
|
var missingReturnYieldStar = createDiagnostic({
|
|
2699
2800
|
name: "missingReturnYieldStar",
|
|
2700
2801
|
code: 7,
|
|
2802
|
+
severity: "error",
|
|
2701
2803
|
apply: fn("missingReturnYieldStar.apply")(function* (sourceFile, report) {
|
|
2702
2804
|
const ts = yield* service(TypeScriptApi);
|
|
2703
2805
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -2745,7 +2847,6 @@ var missingReturnYieldStar = createDiagnostic({
|
|
|
2745
2847
|
}] : [];
|
|
2746
2848
|
report({
|
|
2747
2849
|
node,
|
|
2748
|
-
category: ts.DiagnosticCategory.Error,
|
|
2749
2850
|
messageText: `Yielded Effect never succeeds, so it is best to use a 'return yield*' instead.`,
|
|
2750
2851
|
fixes: fix
|
|
2751
2852
|
});
|
|
@@ -2762,6 +2863,7 @@ var missingReturnYieldStar = createDiagnostic({
|
|
|
2762
2863
|
var missingStarInYieldEffectGen = createDiagnostic({
|
|
2763
2864
|
name: "missingStarInYieldEffectGen",
|
|
2764
2865
|
code: 4,
|
|
2866
|
+
severity: "error",
|
|
2765
2867
|
apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile, report) {
|
|
2766
2868
|
const ts = yield* service(TypeScriptApi);
|
|
2767
2869
|
const typeParser = yield* service(TypeParser);
|
|
@@ -2801,7 +2903,6 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
2801
2903
|
brokenGenerators.forEach(
|
|
2802
2904
|
(node) => report({
|
|
2803
2905
|
node,
|
|
2804
|
-
category: ts.DiagnosticCategory.Error,
|
|
2805
2906
|
messageText: `Seems like you used yield instead of yield* inside this Effect.gen.`,
|
|
2806
2907
|
fixes: []
|
|
2807
2908
|
})
|
|
@@ -2824,7 +2925,6 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
2824
2925
|
}] : [];
|
|
2825
2926
|
report({
|
|
2826
2927
|
node,
|
|
2827
|
-
category: ts.DiagnosticCategory.Error,
|
|
2828
2928
|
messageText: `When yielding Effects inside Effect.gen, you should use yield* instead of yield.`,
|
|
2829
2929
|
fixes: fix
|
|
2830
2930
|
});
|
|
@@ -2836,6 +2936,7 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
2836
2936
|
var returnEffectInGen = createDiagnostic({
|
|
2837
2937
|
name: "returnEffectInGen",
|
|
2838
2938
|
code: 11,
|
|
2939
|
+
severity: "suggestion",
|
|
2839
2940
|
apply: fn("returnEffectInGen.apply")(function* (sourceFile, report) {
|
|
2840
2941
|
const ts = yield* service(TypeScriptApi);
|
|
2841
2942
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -2883,7 +2984,6 @@ var returnEffectInGen = createDiagnostic({
|
|
|
2883
2984
|
}] : [];
|
|
2884
2985
|
report({
|
|
2885
2986
|
node,
|
|
2886
|
-
category: ts.DiagnosticCategory.Suggestion,
|
|
2887
2987
|
messageText: `You are returning an Effect-able type inside a generator function, and will result in nested Effect<Effect<...>>.
|
|
2888
2988
|
Maybe you wanted to return yield* instead?
|
|
2889
2989
|
Nested Effect-able types may be intended if you plan to later manually flatten or unwrap this Effect, if so you can safely disable this diagnostic for this line through quickfixes.`,
|
|
@@ -2903,6 +3003,7 @@ Nested Effect-able types may be intended if you plan to later manually flatten o
|
|
|
2903
3003
|
var unnecessaryEffectGen = createDiagnostic({
|
|
2904
3004
|
name: "unnecessaryEffectGen",
|
|
2905
3005
|
code: 5,
|
|
3006
|
+
severity: "suggestion",
|
|
2906
3007
|
apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile, report) {
|
|
2907
3008
|
const ts = yield* service(TypeScriptApi);
|
|
2908
3009
|
const typeParser = yield* service(TypeParser);
|
|
@@ -2921,7 +3022,6 @@ var unnecessaryEffectGen = createDiagnostic({
|
|
|
2921
3022
|
map3(
|
|
2922
3023
|
({ replacementNode }) => report({
|
|
2923
3024
|
node,
|
|
2924
|
-
category: ts.DiagnosticCategory.Suggestion,
|
|
2925
3025
|
messageText: `This Effect.gen contains a single return statement.`,
|
|
2926
3026
|
fixes: [{
|
|
2927
3027
|
fixName: "unnecessaryEffectGen_fix",
|
|
@@ -2946,6 +3046,7 @@ var unnecessaryEffectGen = createDiagnostic({
|
|
|
2946
3046
|
var unnecessaryPipe = createDiagnostic({
|
|
2947
3047
|
name: "unnecessaryPipe",
|
|
2948
3048
|
code: 9,
|
|
3049
|
+
severity: "suggestion",
|
|
2949
3050
|
apply: fn("unnecessaryPipe.apply")(function* (sourceFile, report) {
|
|
2950
3051
|
const ts = yield* service(TypeScriptApi);
|
|
2951
3052
|
const typeParser = yield* service(TypeParser);
|
|
@@ -2965,7 +3066,6 @@ var unnecessaryPipe = createDiagnostic({
|
|
|
2965
3066
|
if (args.length === 0) {
|
|
2966
3067
|
report({
|
|
2967
3068
|
node,
|
|
2968
|
-
category: ts.DiagnosticCategory.Suggestion,
|
|
2969
3069
|
messageText: `This pipe call contains no arguments.`,
|
|
2970
3070
|
fixes: [{
|
|
2971
3071
|
fixName: "unnecessaryPipe_fix",
|
|
@@ -2999,7 +3099,8 @@ var diagnostics = [
|
|
|
2999
3099
|
leakingRequirements,
|
|
3000
3100
|
unnecessaryPipe,
|
|
3001
3101
|
genericEffectServices,
|
|
3002
|
-
returnEffectInGen
|
|
3102
|
+
returnEffectInGen,
|
|
3103
|
+
importFromBarrel
|
|
3003
3104
|
];
|
|
3004
3105
|
|
|
3005
3106
|
// src/transform.ts
|