@effect/language-service 0.83.1 → 0.84.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 -1
- package/cli.js +529 -46
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +334 -43
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +334 -43
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/schema.json +109 -1
- package/transform.js +334 -43
- package/transform.js.map +1 -1
package/package.json
CHANGED
package/schema.json
CHANGED
|
@@ -2363,6 +2363,54 @@
|
|
|
2363
2363
|
"default": "warning",
|
|
2364
2364
|
"description": "Prevents services with type parameters that cannot be discriminated at runtime Default severity: warning."
|
|
2365
2365
|
},
|
|
2366
|
+
"globalConsole": {
|
|
2367
|
+
"type": "string",
|
|
2368
|
+
"enum": [
|
|
2369
|
+
"off",
|
|
2370
|
+
"error",
|
|
2371
|
+
"warning",
|
|
2372
|
+
"message",
|
|
2373
|
+
"suggestion"
|
|
2374
|
+
],
|
|
2375
|
+
"default": "off",
|
|
2376
|
+
"description": "Warns when using console methods outside Effect generators instead of Effect.log/Logger Default severity: off."
|
|
2377
|
+
},
|
|
2378
|
+
"globalConsoleInEffect": {
|
|
2379
|
+
"type": "string",
|
|
2380
|
+
"enum": [
|
|
2381
|
+
"off",
|
|
2382
|
+
"error",
|
|
2383
|
+
"warning",
|
|
2384
|
+
"message",
|
|
2385
|
+
"suggestion"
|
|
2386
|
+
],
|
|
2387
|
+
"default": "off",
|
|
2388
|
+
"description": "Warns when using console methods inside Effect generators instead of Effect.log/Logger Default severity: off."
|
|
2389
|
+
},
|
|
2390
|
+
"globalDate": {
|
|
2391
|
+
"type": "string",
|
|
2392
|
+
"enum": [
|
|
2393
|
+
"off",
|
|
2394
|
+
"error",
|
|
2395
|
+
"warning",
|
|
2396
|
+
"message",
|
|
2397
|
+
"suggestion"
|
|
2398
|
+
],
|
|
2399
|
+
"default": "off",
|
|
2400
|
+
"description": "Warns when using Date.now() or new Date() outside Effect generators instead of Clock/DateTime Default severity: off."
|
|
2401
|
+
},
|
|
2402
|
+
"globalDateInEffect": {
|
|
2403
|
+
"type": "string",
|
|
2404
|
+
"enum": [
|
|
2405
|
+
"off",
|
|
2406
|
+
"error",
|
|
2407
|
+
"warning",
|
|
2408
|
+
"message",
|
|
2409
|
+
"suggestion"
|
|
2410
|
+
],
|
|
2411
|
+
"default": "off",
|
|
2412
|
+
"description": "Warns when using Date.now() or new Date() inside Effect generators instead of Clock/DateTime Default severity: off."
|
|
2413
|
+
},
|
|
2366
2414
|
"globalErrorInEffectCatch": {
|
|
2367
2415
|
"type": "string",
|
|
2368
2416
|
"enum": [
|
|
@@ -2397,7 +2445,67 @@
|
|
|
2397
2445
|
"suggestion"
|
|
2398
2446
|
],
|
|
2399
2447
|
"default": "off",
|
|
2400
|
-
"description": "Warns when using the global fetch function instead of the Effect HTTP client Default severity: off."
|
|
2448
|
+
"description": "Warns when using the global fetch function outside Effect generators instead of the Effect HTTP client Default severity: off."
|
|
2449
|
+
},
|
|
2450
|
+
"globalFetchInEffect": {
|
|
2451
|
+
"type": "string",
|
|
2452
|
+
"enum": [
|
|
2453
|
+
"off",
|
|
2454
|
+
"error",
|
|
2455
|
+
"warning",
|
|
2456
|
+
"message",
|
|
2457
|
+
"suggestion"
|
|
2458
|
+
],
|
|
2459
|
+
"default": "off",
|
|
2460
|
+
"description": "Warns when using the global fetch function inside Effect generators instead of the Effect HTTP client Default severity: off."
|
|
2461
|
+
},
|
|
2462
|
+
"globalRandom": {
|
|
2463
|
+
"type": "string",
|
|
2464
|
+
"enum": [
|
|
2465
|
+
"off",
|
|
2466
|
+
"error",
|
|
2467
|
+
"warning",
|
|
2468
|
+
"message",
|
|
2469
|
+
"suggestion"
|
|
2470
|
+
],
|
|
2471
|
+
"default": "off",
|
|
2472
|
+
"description": "Warns when using Math.random() outside Effect generators instead of the Random service Default severity: off."
|
|
2473
|
+
},
|
|
2474
|
+
"globalRandomInEffect": {
|
|
2475
|
+
"type": "string",
|
|
2476
|
+
"enum": [
|
|
2477
|
+
"off",
|
|
2478
|
+
"error",
|
|
2479
|
+
"warning",
|
|
2480
|
+
"message",
|
|
2481
|
+
"suggestion"
|
|
2482
|
+
],
|
|
2483
|
+
"default": "off",
|
|
2484
|
+
"description": "Warns when using Math.random() inside Effect generators instead of the Random service Default severity: off."
|
|
2485
|
+
},
|
|
2486
|
+
"globalTimers": {
|
|
2487
|
+
"type": "string",
|
|
2488
|
+
"enum": [
|
|
2489
|
+
"off",
|
|
2490
|
+
"error",
|
|
2491
|
+
"warning",
|
|
2492
|
+
"message",
|
|
2493
|
+
"suggestion"
|
|
2494
|
+
],
|
|
2495
|
+
"default": "off",
|
|
2496
|
+
"description": "Warns when using setTimeout/setInterval outside Effect generators instead of Effect.sleep/Schedule Default severity: off."
|
|
2497
|
+
},
|
|
2498
|
+
"globalTimersInEffect": {
|
|
2499
|
+
"type": "string",
|
|
2500
|
+
"enum": [
|
|
2501
|
+
"off",
|
|
2502
|
+
"error",
|
|
2503
|
+
"warning",
|
|
2504
|
+
"message",
|
|
2505
|
+
"suggestion"
|
|
2506
|
+
],
|
|
2507
|
+
"default": "off",
|
|
2508
|
+
"description": "Warns when using setTimeout/setInterval inside Effect generators instead of Effect.sleep/Schedule Default severity: off."
|
|
2401
2509
|
},
|
|
2402
2510
|
"importFromBarrel": {
|
|
2403
2511
|
"type": "string",
|
package/transform.js
CHANGED
|
@@ -3122,6 +3122,25 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
|
|
|
3122
3122
|
return typeChecker.getTypeAtLocation(node);
|
|
3123
3123
|
}
|
|
3124
3124
|
}
|
|
3125
|
+
function resolveToGlobalSymbol(symbol3) {
|
|
3126
|
+
if (symbol3.flags & ts.SymbolFlags.Alias) {
|
|
3127
|
+
symbol3 = typeChecker.getAliasedSymbol(symbol3);
|
|
3128
|
+
}
|
|
3129
|
+
let depth = 0;
|
|
3130
|
+
while (depth < 2 && symbol3.valueDeclaration && ts.isVariableDeclaration(symbol3.valueDeclaration)) {
|
|
3131
|
+
const initializer = symbol3.valueDeclaration.initializer;
|
|
3132
|
+
if (!initializer) break;
|
|
3133
|
+
let nextSymbol = typeChecker.getSymbolAtLocation(initializer);
|
|
3134
|
+
if (!nextSymbol) break;
|
|
3135
|
+
if (nextSymbol.flags & ts.SymbolFlags.Alias) {
|
|
3136
|
+
nextSymbol = typeChecker.getAliasedSymbol(nextSymbol);
|
|
3137
|
+
}
|
|
3138
|
+
if (nextSymbol === symbol3) break;
|
|
3139
|
+
symbol3 = nextSymbol;
|
|
3140
|
+
depth++;
|
|
3141
|
+
}
|
|
3142
|
+
return symbol3;
|
|
3143
|
+
}
|
|
3125
3144
|
return {
|
|
3126
3145
|
isUnion,
|
|
3127
3146
|
isReadonlyArrayType,
|
|
@@ -3135,7 +3154,8 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
|
|
|
3135
3154
|
expectedAndRealType,
|
|
3136
3155
|
typeToSimplifiedTypeNode,
|
|
3137
3156
|
isGlobalErrorType,
|
|
3138
|
-
getTypeAtLocation
|
|
3157
|
+
getTypeAtLocation,
|
|
3158
|
+
resolveToGlobalSymbol
|
|
3139
3159
|
};
|
|
3140
3160
|
}
|
|
3141
3161
|
|
|
@@ -3823,7 +3843,11 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3823
3843
|
}
|
|
3824
3844
|
currentParent = nodeToCheck.parent;
|
|
3825
3845
|
}
|
|
3826
|
-
return {
|
|
3846
|
+
return {
|
|
3847
|
+
inEffect: effectGenResult !== void 0 && effectGenResult.body.statements.length > 0 && scopeNode === effectGenResult.generatorFunction,
|
|
3848
|
+
scopeNode,
|
|
3849
|
+
effectGen: effectGenResult
|
|
3850
|
+
};
|
|
3827
3851
|
});
|
|
3828
3852
|
const effectFn = cachedBy(
|
|
3829
3853
|
function(node) {
|
|
@@ -7018,6 +7042,128 @@ var genericEffectServices = createDiagnostic({
|
|
|
7018
7042
|
})
|
|
7019
7043
|
});
|
|
7020
7044
|
|
|
7045
|
+
// src/diagnostics/globalConsoleInEffect.ts
|
|
7046
|
+
var consoleMethodAlternatives = {
|
|
7047
|
+
"log": "Effect.log or Logger",
|
|
7048
|
+
"warn": "Effect.logWarning or Logger",
|
|
7049
|
+
"error": "Effect.logError or Logger",
|
|
7050
|
+
"info": "Effect.logInfo or Logger",
|
|
7051
|
+
"debug": "Effect.logDebug or Logger",
|
|
7052
|
+
"trace": "Effect.logTrace or Logger"
|
|
7053
|
+
};
|
|
7054
|
+
var makeGlobalConsoleApply = (checkInEffect) => fn(`globalConsole${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
|
|
7055
|
+
const ts = yield* service(TypeScriptApi);
|
|
7056
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
7057
|
+
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
7058
|
+
const typeParser = yield* service(TypeParser);
|
|
7059
|
+
const consoleSymbol = typeChecker.resolveName("console", void 0, ts.SymbolFlags.Value, false);
|
|
7060
|
+
if (!consoleSymbol) return;
|
|
7061
|
+
const nodeToVisit = [];
|
|
7062
|
+
const appendNodeToVisit = (node) => {
|
|
7063
|
+
nodeToVisit.push(node);
|
|
7064
|
+
return void 0;
|
|
7065
|
+
};
|
|
7066
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
7067
|
+
while (nodeToVisit.length > 0) {
|
|
7068
|
+
const node = nodeToVisit.shift();
|
|
7069
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
7070
|
+
if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression)) continue;
|
|
7071
|
+
const method = ts.idText(node.expression.name);
|
|
7072
|
+
const alternative = consoleMethodAlternatives[method];
|
|
7073
|
+
if (!alternative) continue;
|
|
7074
|
+
const symbol3 = typeChecker.getSymbolAtLocation(node.expression.expression);
|
|
7075
|
+
if (!symbol3) continue;
|
|
7076
|
+
if (typeCheckerUtils.resolveToGlobalSymbol(symbol3) !== consoleSymbol) continue;
|
|
7077
|
+
const { inEffect } = yield* typeParser.findEnclosingScopes(node);
|
|
7078
|
+
if (inEffect !== checkInEffect) continue;
|
|
7079
|
+
report({
|
|
7080
|
+
location: node,
|
|
7081
|
+
messageText: checkInEffect ? `Prefer using ${alternative} instead of console.${method} inside Effect generators.` : `Prefer using ${alternative} instead of console.${method}.`,
|
|
7082
|
+
fixes: []
|
|
7083
|
+
});
|
|
7084
|
+
}
|
|
7085
|
+
});
|
|
7086
|
+
var globalConsoleInEffect = createDiagnostic({
|
|
7087
|
+
name: "globalConsoleInEffect",
|
|
7088
|
+
code: 56,
|
|
7089
|
+
description: "Warns when using console methods inside Effect generators instead of Effect.log/Logger",
|
|
7090
|
+
group: "effectNative",
|
|
7091
|
+
severity: "off",
|
|
7092
|
+
fixable: false,
|
|
7093
|
+
supportedEffect: ["v3", "v4"],
|
|
7094
|
+
apply: makeGlobalConsoleApply(true)
|
|
7095
|
+
});
|
|
7096
|
+
|
|
7097
|
+
// src/diagnostics/globalConsole.ts
|
|
7098
|
+
var globalConsole = createDiagnostic({
|
|
7099
|
+
name: "globalConsole",
|
|
7100
|
+
code: 60,
|
|
7101
|
+
description: "Warns when using console methods outside Effect generators instead of Effect.log/Logger",
|
|
7102
|
+
group: "effectNative",
|
|
7103
|
+
severity: "off",
|
|
7104
|
+
fixable: false,
|
|
7105
|
+
supportedEffect: ["v3", "v4"],
|
|
7106
|
+
apply: makeGlobalConsoleApply(false)
|
|
7107
|
+
});
|
|
7108
|
+
|
|
7109
|
+
// src/diagnostics/globalDateInEffect.ts
|
|
7110
|
+
var makeGlobalDateApply = (checkInEffect) => fn(`globalDate${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
|
|
7111
|
+
const ts = yield* service(TypeScriptApi);
|
|
7112
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
7113
|
+
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
7114
|
+
const typeParser = yield* service(TypeParser);
|
|
7115
|
+
const dateSymbol = typeChecker.resolveName("Date", void 0, ts.SymbolFlags.Value, false);
|
|
7116
|
+
if (!dateSymbol) return;
|
|
7117
|
+
const nodeToVisit = [];
|
|
7118
|
+
const appendNodeToVisit = (node) => {
|
|
7119
|
+
nodeToVisit.push(node);
|
|
7120
|
+
return void 0;
|
|
7121
|
+
};
|
|
7122
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
7123
|
+
while (nodeToVisit.length > 0) {
|
|
7124
|
+
const node = nodeToVisit.shift();
|
|
7125
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
7126
|
+
let messageText;
|
|
7127
|
+
let objectNode;
|
|
7128
|
+
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.idText(node.expression.name) === "now") {
|
|
7129
|
+
objectNode = node.expression.expression;
|
|
7130
|
+
messageText = checkInEffect ? "Prefer using Clock or DateTime from Effect instead of Date.now() inside Effect generators." : "Prefer using Clock or DateTime from Effect instead of Date.now().";
|
|
7131
|
+
} else if (ts.isNewExpression(node)) {
|
|
7132
|
+
objectNode = node.expression;
|
|
7133
|
+
messageText = checkInEffect ? "Prefer using DateTime from Effect instead of new Date() inside Effect generators." : "Prefer using DateTime from Effect instead of new Date().";
|
|
7134
|
+
}
|
|
7135
|
+
if (!messageText || !objectNode) continue;
|
|
7136
|
+
const symbol3 = typeChecker.getSymbolAtLocation(objectNode);
|
|
7137
|
+
if (!symbol3) continue;
|
|
7138
|
+
if (typeCheckerUtils.resolveToGlobalSymbol(symbol3) !== dateSymbol) continue;
|
|
7139
|
+
const { inEffect } = yield* typeParser.findEnclosingScopes(node);
|
|
7140
|
+
if (inEffect !== checkInEffect) continue;
|
|
7141
|
+
report({ location: node, messageText, fixes: [] });
|
|
7142
|
+
}
|
|
7143
|
+
});
|
|
7144
|
+
var globalDateInEffect = createDiagnostic({
|
|
7145
|
+
name: "globalDateInEffect",
|
|
7146
|
+
code: 55,
|
|
7147
|
+
description: "Warns when using Date.now() or new Date() inside Effect generators instead of Clock/DateTime",
|
|
7148
|
+
group: "effectNative",
|
|
7149
|
+
severity: "off",
|
|
7150
|
+
fixable: false,
|
|
7151
|
+
supportedEffect: ["v3", "v4"],
|
|
7152
|
+
apply: makeGlobalDateApply(true)
|
|
7153
|
+
});
|
|
7154
|
+
|
|
7155
|
+
// src/diagnostics/globalDate.ts
|
|
7156
|
+
var globalDate = createDiagnostic({
|
|
7157
|
+
name: "globalDate",
|
|
7158
|
+
code: 59,
|
|
7159
|
+
description: "Warns when using Date.now() or new Date() outside Effect generators instead of Clock/DateTime",
|
|
7160
|
+
group: "effectNative",
|
|
7161
|
+
severity: "off",
|
|
7162
|
+
fixable: false,
|
|
7163
|
+
supportedEffect: ["v3", "v4"],
|
|
7164
|
+
apply: makeGlobalDateApply(false)
|
|
7165
|
+
});
|
|
7166
|
+
|
|
7021
7167
|
// src/diagnostics/globalErrorInEffectCatch.ts
|
|
7022
7168
|
var globalErrorInEffectCatch = createDiagnostic({
|
|
7023
7169
|
name: "globalErrorInEffectCatch",
|
|
@@ -7137,46 +7283,186 @@ var globalErrorInEffectFailure = createDiagnostic({
|
|
|
7137
7283
|
})
|
|
7138
7284
|
});
|
|
7139
7285
|
|
|
7286
|
+
// src/diagnostics/globalFetchInEffect.ts
|
|
7287
|
+
var makeGlobalFetchApply = (checkInEffect) => fn(`globalFetch${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
|
|
7288
|
+
const ts = yield* service(TypeScriptApi);
|
|
7289
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
7290
|
+
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
7291
|
+
const typeParser = yield* service(TypeParser);
|
|
7292
|
+
const fetchSymbol = typeChecker.resolveName("fetch", void 0, ts.SymbolFlags.Value, false);
|
|
7293
|
+
if (!fetchSymbol) return;
|
|
7294
|
+
const effectVersion = typeParser.supportedEffect();
|
|
7295
|
+
const packageName = effectVersion === "v3" ? "@effect/platform" : "effect/unstable/http";
|
|
7296
|
+
const messageText = checkInEffect ? `Prefer using HttpClient from ${packageName} instead of the global 'fetch' function inside Effect generators.` : `Prefer using HttpClient from ${packageName} instead of the global 'fetch' function.`;
|
|
7297
|
+
const nodeToVisit = [];
|
|
7298
|
+
const appendNodeToVisit = (node) => {
|
|
7299
|
+
nodeToVisit.push(node);
|
|
7300
|
+
return void 0;
|
|
7301
|
+
};
|
|
7302
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
7303
|
+
while (nodeToVisit.length > 0) {
|
|
7304
|
+
const node = nodeToVisit.shift();
|
|
7305
|
+
if (ts.isCallExpression(node)) {
|
|
7306
|
+
const symbol3 = typeChecker.getSymbolAtLocation(node.expression);
|
|
7307
|
+
if (symbol3 && typeCheckerUtils.resolveToGlobalSymbol(symbol3) === fetchSymbol) {
|
|
7308
|
+
const { inEffect } = yield* typeParser.findEnclosingScopes(node);
|
|
7309
|
+
if (inEffect === checkInEffect) {
|
|
7310
|
+
report({
|
|
7311
|
+
location: node.expression,
|
|
7312
|
+
messageText,
|
|
7313
|
+
fixes: []
|
|
7314
|
+
});
|
|
7315
|
+
}
|
|
7316
|
+
}
|
|
7317
|
+
}
|
|
7318
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
7319
|
+
}
|
|
7320
|
+
});
|
|
7321
|
+
var globalFetchInEffect = createDiagnostic({
|
|
7322
|
+
name: "globalFetchInEffect",
|
|
7323
|
+
code: 63,
|
|
7324
|
+
description: "Warns when using the global fetch function inside Effect generators instead of the Effect HTTP client",
|
|
7325
|
+
group: "effectNative",
|
|
7326
|
+
severity: "off",
|
|
7327
|
+
fixable: false,
|
|
7328
|
+
supportedEffect: ["v3", "v4"],
|
|
7329
|
+
apply: makeGlobalFetchApply(true)
|
|
7330
|
+
});
|
|
7331
|
+
|
|
7140
7332
|
// src/diagnostics/globalFetch.ts
|
|
7141
7333
|
var globalFetch = createDiagnostic({
|
|
7142
7334
|
name: "globalFetch",
|
|
7143
7335
|
code: 53,
|
|
7144
|
-
description: "Warns when using the global fetch function instead of the Effect HTTP client",
|
|
7336
|
+
description: "Warns when using the global fetch function outside Effect generators instead of the Effect HTTP client",
|
|
7145
7337
|
group: "effectNative",
|
|
7146
7338
|
severity: "off",
|
|
7147
7339
|
fixable: false,
|
|
7148
7340
|
supportedEffect: ["v3", "v4"],
|
|
7149
|
-
apply:
|
|
7150
|
-
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
|
|
7154
|
-
|
|
7155
|
-
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7341
|
+
apply: makeGlobalFetchApply(false)
|
|
7342
|
+
});
|
|
7343
|
+
|
|
7344
|
+
// src/diagnostics/globalRandomInEffect.ts
|
|
7345
|
+
var makeGlobalRandomApply = (checkInEffect) => fn(`globalRandom${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
|
|
7346
|
+
const ts = yield* service(TypeScriptApi);
|
|
7347
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
7348
|
+
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
7349
|
+
const typeParser = yield* service(TypeParser);
|
|
7350
|
+
const mathSymbol = typeChecker.resolveName("Math", void 0, ts.SymbolFlags.Value, false);
|
|
7351
|
+
if (!mathSymbol) return;
|
|
7352
|
+
const nodeToVisit = [];
|
|
7353
|
+
const appendNodeToVisit = (node) => {
|
|
7354
|
+
nodeToVisit.push(node);
|
|
7355
|
+
return void 0;
|
|
7356
|
+
};
|
|
7357
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
7358
|
+
while (nodeToVisit.length > 0) {
|
|
7359
|
+
const node = nodeToVisit.shift();
|
|
7360
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
7361
|
+
if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression) || ts.idText(node.expression.name) !== "random") continue;
|
|
7362
|
+
const symbol3 = typeChecker.getSymbolAtLocation(node.expression.expression);
|
|
7363
|
+
if (!symbol3) continue;
|
|
7364
|
+
if (typeCheckerUtils.resolveToGlobalSymbol(symbol3) !== mathSymbol) continue;
|
|
7365
|
+
const { inEffect } = yield* typeParser.findEnclosingScopes(node);
|
|
7366
|
+
if (inEffect !== checkInEffect) continue;
|
|
7367
|
+
report({
|
|
7368
|
+
location: node,
|
|
7369
|
+
messageText: checkInEffect ? "Prefer using the Random service from Effect instead of Math.random() inside Effect generators." : "Prefer using the Random service from Effect instead of Math.random().",
|
|
7370
|
+
fixes: []
|
|
7371
|
+
});
|
|
7372
|
+
}
|
|
7373
|
+
});
|
|
7374
|
+
var globalRandomInEffect = createDiagnostic({
|
|
7375
|
+
name: "globalRandomInEffect",
|
|
7376
|
+
code: 57,
|
|
7377
|
+
description: "Warns when using Math.random() inside Effect generators instead of the Random service",
|
|
7378
|
+
group: "effectNative",
|
|
7379
|
+
severity: "off",
|
|
7380
|
+
fixable: false,
|
|
7381
|
+
supportedEffect: ["v3", "v4"],
|
|
7382
|
+
apply: makeGlobalRandomApply(true)
|
|
7383
|
+
});
|
|
7384
|
+
|
|
7385
|
+
// src/diagnostics/globalRandom.ts
|
|
7386
|
+
var globalRandom = createDiagnostic({
|
|
7387
|
+
name: "globalRandom",
|
|
7388
|
+
code: 61,
|
|
7389
|
+
description: "Warns when using Math.random() outside Effect generators instead of the Random service",
|
|
7390
|
+
group: "effectNative",
|
|
7391
|
+
severity: "off",
|
|
7392
|
+
fixable: false,
|
|
7393
|
+
supportedEffect: ["v3", "v4"],
|
|
7394
|
+
apply: makeGlobalRandomApply(false)
|
|
7395
|
+
});
|
|
7396
|
+
|
|
7397
|
+
// src/diagnostics/globalTimersInEffect.ts
|
|
7398
|
+
var timerAlternatives = {
|
|
7399
|
+
"setTimeout": {
|
|
7400
|
+
inEffect: "Prefer using Effect.sleep or Schedule from Effect instead of setTimeout inside Effect generators.",
|
|
7401
|
+
outsideEffect: "Prefer using Effect.sleep or Schedule from Effect instead of setTimeout."
|
|
7402
|
+
},
|
|
7403
|
+
"setInterval": {
|
|
7404
|
+
inEffect: "Prefer using Schedule or Effect.repeat from Effect instead of setInterval inside Effect generators.",
|
|
7405
|
+
outsideEffect: "Prefer using Schedule or Effect.repeat from Effect instead of setInterval."
|
|
7406
|
+
}
|
|
7407
|
+
};
|
|
7408
|
+
var makeGlobalTimersApply = (checkInEffect) => fn(`globalTimers${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
|
|
7409
|
+
const ts = yield* service(TypeScriptApi);
|
|
7410
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
7411
|
+
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
7412
|
+
const typeParser = yield* service(TypeParser);
|
|
7413
|
+
const globalSymbols = /* @__PURE__ */ new Map();
|
|
7414
|
+
for (const name of Object.keys(timerAlternatives)) {
|
|
7415
|
+
const symbol3 = typeChecker.resolveName(name, void 0, ts.SymbolFlags.Value, false);
|
|
7416
|
+
if (symbol3) globalSymbols.set(name, symbol3);
|
|
7417
|
+
}
|
|
7418
|
+
if (globalSymbols.size === 0) return;
|
|
7419
|
+
const nodeToVisit = [];
|
|
7420
|
+
const appendNodeToVisit = (node) => {
|
|
7421
|
+
nodeToVisit.push(node);
|
|
7422
|
+
return void 0;
|
|
7423
|
+
};
|
|
7424
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
7425
|
+
while (nodeToVisit.length > 0) {
|
|
7426
|
+
const node = nodeToVisit.shift();
|
|
7427
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
7428
|
+
if (!ts.isCallExpression(node)) continue;
|
|
7429
|
+
const symbol3 = typeChecker.getSymbolAtLocation(node.expression);
|
|
7430
|
+
if (!symbol3) continue;
|
|
7431
|
+
const resolvedSymbol = typeCheckerUtils.resolveToGlobalSymbol(symbol3);
|
|
7432
|
+
let messageText;
|
|
7433
|
+
for (const [name, symbol4] of globalSymbols) {
|
|
7434
|
+
if (resolvedSymbol === symbol4) {
|
|
7435
|
+
messageText = checkInEffect ? timerAlternatives[name].inEffect : timerAlternatives[name].outsideEffect;
|
|
7436
|
+
break;
|
|
7176
7437
|
}
|
|
7177
|
-
ts.forEachChild(node, appendNodeToVisit);
|
|
7178
7438
|
}
|
|
7179
|
-
|
|
7439
|
+
if (!messageText) continue;
|
|
7440
|
+
const { inEffect } = yield* typeParser.findEnclosingScopes(node);
|
|
7441
|
+
if (inEffect !== checkInEffect) continue;
|
|
7442
|
+
report({ location: node, messageText, fixes: [] });
|
|
7443
|
+
}
|
|
7444
|
+
});
|
|
7445
|
+
var globalTimersInEffect = createDiagnostic({
|
|
7446
|
+
name: "globalTimersInEffect",
|
|
7447
|
+
code: 58,
|
|
7448
|
+
description: "Warns when using setTimeout/setInterval inside Effect generators instead of Effect.sleep/Schedule",
|
|
7449
|
+
group: "effectNative",
|
|
7450
|
+
severity: "off",
|
|
7451
|
+
fixable: false,
|
|
7452
|
+
supportedEffect: ["v3", "v4"],
|
|
7453
|
+
apply: makeGlobalTimersApply(true)
|
|
7454
|
+
});
|
|
7455
|
+
|
|
7456
|
+
// src/diagnostics/globalTimers.ts
|
|
7457
|
+
var globalTimers = createDiagnostic({
|
|
7458
|
+
name: "globalTimers",
|
|
7459
|
+
code: 62,
|
|
7460
|
+
description: "Warns when using setTimeout/setInterval outside Effect generators instead of Effect.sleep/Schedule",
|
|
7461
|
+
group: "effectNative",
|
|
7462
|
+
severity: "off",
|
|
7463
|
+
fixable: false,
|
|
7464
|
+
supportedEffect: ["v3", "v4"],
|
|
7465
|
+
apply: makeGlobalTimersApply(false)
|
|
7180
7466
|
});
|
|
7181
7467
|
|
|
7182
7468
|
// src/diagnostics/importFromBarrel.ts
|
|
@@ -8241,8 +8527,8 @@ var missingReturnYieldStar = createDiagnostic({
|
|
|
8241
8527
|
if (!type) continue;
|
|
8242
8528
|
const maybeEffect = yield* option(typeParser.effectYieldableType(type, unwrapped.expression));
|
|
8243
8529
|
if (!(isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never)) continue;
|
|
8244
|
-
const {
|
|
8245
|
-
if (!
|
|
8530
|
+
const { inEffect } = yield* typeParser.findEnclosingScopes(node);
|
|
8531
|
+
if (!inEffect) continue;
|
|
8246
8532
|
const fix = [{
|
|
8247
8533
|
fixName: "missingReturnYieldStar_fix",
|
|
8248
8534
|
description: "Add return statement",
|
|
@@ -10705,11 +10991,8 @@ var preferSchemaOverJson = createDiagnostic({
|
|
|
10705
10991
|
});
|
|
10706
10992
|
const jsonMethodInEffectGen = fn("preferSchemaOverJson.jsonMethodInEffectGen")(
|
|
10707
10993
|
function* (jsonCall) {
|
|
10708
|
-
const {
|
|
10709
|
-
if (!
|
|
10710
|
-
return yield* TypeParserIssue.issue;
|
|
10711
|
-
}
|
|
10712
|
-
if (scopeNode && scopeNode !== effectGen.generatorFunction) {
|
|
10994
|
+
const { inEffect } = yield* typeParser.findEnclosingScopes(jsonCall);
|
|
10995
|
+
if (!inEffect) {
|
|
10713
10996
|
return yield* TypeParserIssue.issue;
|
|
10714
10997
|
}
|
|
10715
10998
|
return jsonCall;
|
|
@@ -11125,9 +11408,8 @@ var schemaSyncInEffect = createDiagnostic({
|
|
|
11125
11408
|
option
|
|
11126
11409
|
);
|
|
11127
11410
|
if (isNone2(isSchemaSyncCall)) continue;
|
|
11128
|
-
const {
|
|
11129
|
-
if (!
|
|
11130
|
-
if (scopeNode && scopeNode !== effectGen.generatorFunction) continue;
|
|
11411
|
+
const { inEffect } = yield* typeParser.findEnclosingScopes(node);
|
|
11412
|
+
if (!inEffect) continue;
|
|
11131
11413
|
const nodeText = sourceFile.text.substring(
|
|
11132
11414
|
ts.getTokenPosOfNode(node.expression, sourceFile),
|
|
11133
11415
|
node.expression.end
|
|
@@ -11969,6 +12251,7 @@ var diagnostics = [
|
|
|
11969
12251
|
unnecessaryPipe,
|
|
11970
12252
|
genericEffectServices,
|
|
11971
12253
|
globalFetch,
|
|
12254
|
+
globalFetchInEffect,
|
|
11972
12255
|
returnEffectInGen,
|
|
11973
12256
|
tryCatchInEffectGen,
|
|
11974
12257
|
importFromBarrel,
|
|
@@ -12000,7 +12283,15 @@ var diagnostics = [
|
|
|
12000
12283
|
preferSchemaOverJson,
|
|
12001
12284
|
extendsNativeError,
|
|
12002
12285
|
serviceNotAsClass,
|
|
12003
|
-
nodeBuiltinImport
|
|
12286
|
+
nodeBuiltinImport,
|
|
12287
|
+
globalDate,
|
|
12288
|
+
globalDateInEffect,
|
|
12289
|
+
globalConsole,
|
|
12290
|
+
globalConsoleInEffect,
|
|
12291
|
+
globalRandom,
|
|
12292
|
+
globalRandomInEffect,
|
|
12293
|
+
globalTimers,
|
|
12294
|
+
globalTimersInEffect
|
|
12004
12295
|
];
|
|
12005
12296
|
|
|
12006
12297
|
// src/transform.ts
|