@effect/language-service 0.55.5 → 0.57.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 +9 -0
- package/cli.js +709 -361
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +197 -1
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +193 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +197 -1
- package/transform.js.map +1 -1
package/cli.js
CHANGED
|
@@ -867,7 +867,7 @@ var require_getParsedConfigFile = __commonJS({
|
|
|
867
867
|
throw new Error(formatDiagnostics([diag]));
|
|
868
868
|
},
|
|
869
869
|
readDirectory: tsserver.sys.readDirectory,
|
|
870
|
-
readFile: (
|
|
870
|
+
readFile: (file6) => fs.readFileSync(path2.isAbsolute(file6) ? file6 : path2.join(getCurrentDirectory(), file6), "utf-8"),
|
|
871
871
|
useCaseSensitiveFileNames: tsserver.sys.useCaseSensitiveFileNames
|
|
872
872
|
});
|
|
873
873
|
if (parsed?.errors.length) {
|
|
@@ -942,7 +942,7 @@ var require_createProjectService = __commonJS({
|
|
|
942
942
|
return mod && mod.__esModule ? mod : { "default": mod };
|
|
943
943
|
};
|
|
944
944
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
945
|
-
exports2.createProjectService =
|
|
945
|
+
exports2.createProjectService = createProjectService3;
|
|
946
946
|
var debug_1 = __importDefault(require_src());
|
|
947
947
|
var getParsedConfigFileFromTSServer_js_1 = require_getParsedConfigFileFromTSServer();
|
|
948
948
|
var DEFAULT_PROJECT_MATCHED_FILES_THRESHOLD = 8;
|
|
@@ -956,7 +956,7 @@ var require_createProjectService = __commonJS({
|
|
|
956
956
|
var createStubFileWatcher = () => ({
|
|
957
957
|
close: doNothing
|
|
958
958
|
});
|
|
959
|
-
function
|
|
959
|
+
function createProjectService3({ jsDocParsingMode, options: optionsRaw = {}, tsconfigRootDir } = {}) {
|
|
960
960
|
const options3 = {
|
|
961
961
|
defaultProject: "tsconfig.json",
|
|
962
962
|
...optionsRaw
|
|
@@ -22834,11 +22834,11 @@ var make53 = (impl) => {
|
|
|
22834
22834
|
}),
|
|
22835
22835
|
stream: (path2, options3) => pipe(impl.open(path2, {
|
|
22836
22836
|
flag: "r"
|
|
22837
|
-
}), options3?.offset ? tap2((
|
|
22837
|
+
}), options3?.offset ? tap2((file6) => file6.seek(options3.offset, "start")) : identity, map17((file6) => stream(file6, options3)), unwrapScoped6),
|
|
22838
22838
|
sink: (path2, options3) => pipe(impl.open(path2, {
|
|
22839
22839
|
flag: "w",
|
|
22840
22840
|
...options3
|
|
22841
|
-
}), map17((
|
|
22841
|
+
}), map17((file6) => forEach10((_) => file6.writeAll(_))), unwrapScoped5),
|
|
22842
22842
|
writeFileString: (path2, data, options3) => flatMap9(try_3({
|
|
22843
22843
|
try: () => new TextEncoder().encode(data),
|
|
22844
22844
|
catch: (cause2) => new BadArgument({
|
|
@@ -22850,7 +22850,7 @@ var make53 = (impl) => {
|
|
|
22850
22850
|
}), (_) => impl.writeFile(path2, _, options3))
|
|
22851
22851
|
});
|
|
22852
22852
|
};
|
|
22853
|
-
var stream = (
|
|
22853
|
+
var stream = (file6, {
|
|
22854
22854
|
bufferSize = 16,
|
|
22855
22855
|
bytesToRead: bytesToRead_,
|
|
22856
22856
|
chunkSize: chunkSize_ = Size(64 * 1024)
|
|
@@ -22862,7 +22862,7 @@ var stream = (file5, {
|
|
|
22862
22862
|
return void_6;
|
|
22863
22863
|
}
|
|
22864
22864
|
const toRead = bytesToRead !== void 0 && bytesToRead - totalBytesRead < chunkSize ? bytesToRead - totalBytesRead : chunkSize;
|
|
22865
|
-
return flatMap15(
|
|
22865
|
+
return flatMap15(file6.readAlloc(toRead), match2({
|
|
22866
22866
|
onNone: () => void_6,
|
|
22867
22867
|
onSome: (buf) => flatMap15(write2(of2(buf)), (_) => loop2(totalBytesRead + BigInt(buf.length)))
|
|
22868
22868
|
}));
|
|
@@ -24168,10 +24168,10 @@ function getFileList(directory3, options3) {
|
|
|
24168
24168
|
// to be filtered out if the user so desires
|
|
24169
24169
|
map17((files2) => ["..", ...files2])
|
|
24170
24170
|
);
|
|
24171
|
-
return yield* filter8(files, (
|
|
24172
|
-
const result = options3.filter(
|
|
24171
|
+
return yield* filter8(files, (file6) => {
|
|
24172
|
+
const result = options3.filter(file6);
|
|
24173
24173
|
const userDefinedFilter = isEffect2(result) ? result : succeed7(result);
|
|
24174
|
-
const directoryFilter = options3.type === "directory" ? map17(orDie2(fs.stat(path2.join(directory3,
|
|
24174
|
+
const directoryFilter = options3.type === "directory" ? map17(orDie2(fs.stat(path2.join(directory3, file6))), (info2) => info2.type === "Directory") : succeed7(true);
|
|
24175
24175
|
return zipWith4(userDefinedFilter, directoryFilter, (a, b) => a && b);
|
|
24176
24176
|
}, {
|
|
24177
24177
|
concurrency: files.length
|
|
@@ -24220,8 +24220,8 @@ function renderPrefix(state, toDisplay, currentIndex, length3, figures2) {
|
|
|
24220
24220
|
}
|
|
24221
24221
|
return state.cursor === currentIndex ? figures2.pointer.pipe(annotate2(cyanBright2), cat2(prefix)) : prefix.pipe(cat2(space2));
|
|
24222
24222
|
}
|
|
24223
|
-
function renderFileName(
|
|
24224
|
-
return isSelected ? annotate2(text3(
|
|
24223
|
+
function renderFileName(file6, isSelected) {
|
|
24224
|
+
return isSelected ? annotate2(text3(file6), combine10(underlined2, cyanBright2)) : text3(file6);
|
|
24225
24225
|
}
|
|
24226
24226
|
function renderFiles(state, files, figures2, options3) {
|
|
24227
24227
|
const length3 = files.length;
|
|
@@ -24325,7 +24325,7 @@ function processSelection(state, options3) {
|
|
|
24325
24325
|
const info2 = yield* orDie2(fs.stat(resolvedPath));
|
|
24326
24326
|
if (info2.type === "Directory") {
|
|
24327
24327
|
const files = yield* getFileList(resolvedPath, options3);
|
|
24328
|
-
const filesWithoutParent = files.filter((
|
|
24328
|
+
const filesWithoutParent = files.filter((file6) => file6 !== "..");
|
|
24329
24329
|
if (options3.type === "directory" || options3.type === "either") {
|
|
24330
24330
|
return filesWithoutParent.length === 0 ? Action.Submit({
|
|
24331
24331
|
value: resolvedPath
|
|
@@ -28899,7 +28899,7 @@ var makeTempFile = /* @__PURE__ */ makeTempFileFactory("makeTempFile");
|
|
|
28899
28899
|
var makeTempFileScoped = /* @__PURE__ */ (() => {
|
|
28900
28900
|
const makeFile2 = /* @__PURE__ */ makeTempFileFactory("makeTempFileScoped");
|
|
28901
28901
|
const removeDirectory = /* @__PURE__ */ removeFactory("makeTempFileScoped");
|
|
28902
|
-
return (options3) => acquireRelease2(makeFile2(options3), (
|
|
28902
|
+
return (options3) => acquireRelease2(makeFile2(options3), (file6) => orDie2(removeDirectory(Path3.dirname(file6), {
|
|
28903
28903
|
recursive: true
|
|
28904
28904
|
})));
|
|
28905
28905
|
})();
|
|
@@ -31150,6 +31150,34 @@ var omitBundlerSourceFileComment = fn("omitBundlerSourceFileComment")(
|
|
|
31150
31150
|
return yield* applyTextChanges(sourceFile.text, deleteChanges);
|
|
31151
31151
|
}
|
|
31152
31152
|
);
|
|
31153
|
+
var extractEffectLspOptions = (compilerOptions) => {
|
|
31154
|
+
return (hasProperty(compilerOptions, "plugins") && Array.isArray(compilerOptions.plugins) ? compilerOptions.plugins : []).find((_) => hasProperty(_, "name") && _.name === "@effect/language-service");
|
|
31155
|
+
};
|
|
31156
|
+
var getFileNamesInTsConfig = fn("getFileNamesInTsConfig")(function* (tsconfigPath) {
|
|
31157
|
+
const path2 = yield* Path2;
|
|
31158
|
+
const tsInstance = yield* getTypeScript;
|
|
31159
|
+
const filesToCheck = /* @__PURE__ */ new Set();
|
|
31160
|
+
let tsconfigToHandle = [tsconfigPath];
|
|
31161
|
+
while (tsconfigToHandle.length > 0) {
|
|
31162
|
+
const tsconfigPath2 = tsconfigToHandle.shift();
|
|
31163
|
+
const tsconfigAbsolutePath = path2.resolve(tsconfigPath2);
|
|
31164
|
+
const configFile = tsInstance.readConfigFile(tsconfigAbsolutePath, tsInstance.sys.readFile);
|
|
31165
|
+
if (configFile.error) {
|
|
31166
|
+
if (!tsconfigAbsolutePath.endsWith("tsconfig.json")) {
|
|
31167
|
+
tsconfigToHandle = [...tsconfigToHandle, path2.resolve(tsconfigPath2, "tsconfig.json")];
|
|
31168
|
+
}
|
|
31169
|
+
continue;
|
|
31170
|
+
}
|
|
31171
|
+
const parsedConfig = tsInstance.parseJsonConfigFileContent(
|
|
31172
|
+
configFile.config,
|
|
31173
|
+
tsInstance.sys,
|
|
31174
|
+
path2.dirname(tsconfigAbsolutePath)
|
|
31175
|
+
);
|
|
31176
|
+
tsconfigToHandle = [...tsconfigToHandle, ...parsedConfig.projectReferences?.map((_) => _.path) ?? []];
|
|
31177
|
+
parsedConfig.fileNames.forEach((_) => filesToCheck.add(_));
|
|
31178
|
+
}
|
|
31179
|
+
return filesToCheck;
|
|
31180
|
+
});
|
|
31153
31181
|
|
|
31154
31182
|
// src/cli/check.ts
|
|
31155
31183
|
var LOCAL_TYPESCRIPT_DIR = "./node_modules/typescript";
|
|
@@ -31186,7 +31214,7 @@ var check2 = make58(
|
|
|
31186
31214
|
})
|
|
31187
31215
|
);
|
|
31188
31216
|
|
|
31189
|
-
// src/cli/
|
|
31217
|
+
// src/cli/codegen.ts
|
|
31190
31218
|
var import_project_service = __toESM(require_dist2());
|
|
31191
31219
|
|
|
31192
31220
|
// src/core/LanguageServicePluginOptions.ts
|
|
@@ -31565,9 +31593,9 @@ var getCodegensForSourceFile = fn2("LSP.getApplicableCodegens")(function* (codeg
|
|
|
31565
31593
|
pos: codegenMatch.index + pos + whitespace.length,
|
|
31566
31594
|
end: codegenMatch.index + pos + codegenMatch[0].length
|
|
31567
31595
|
};
|
|
31568
|
-
const
|
|
31569
|
-
if (!
|
|
31570
|
-
result.push({ codegen, hash: codegenHash, range: range3 });
|
|
31596
|
+
const codegen2 = codegens2.find((codegen3) => codegen3.name === codegenName);
|
|
31597
|
+
if (!codegen2) continue;
|
|
31598
|
+
result.push({ codegen: codegen2, hash: codegenHash, range: range3 });
|
|
31571
31599
|
}
|
|
31572
31600
|
}
|
|
31573
31601
|
return result;
|
|
@@ -31575,18 +31603,18 @@ var getCodegensForSourceFile = fn2("LSP.getApplicableCodegens")(function* (codeg
|
|
|
31575
31603
|
var getEditsForCodegen = fn2("LSP.getEditsForCodegen")(function* (codegens2, sourceFile, textRange) {
|
|
31576
31604
|
const applicableCodegens = yield* getCodegensForSourceFile(codegens2, sourceFile);
|
|
31577
31605
|
const inRangeCodegens = applicableCodegens.filter(
|
|
31578
|
-
(
|
|
31606
|
+
(codegen3) => codegen3.range.pos <= textRange.pos && codegen3.range.end >= textRange.end
|
|
31579
31607
|
);
|
|
31580
31608
|
if (inRangeCodegens.length !== 1) {
|
|
31581
31609
|
return yield* fail18(new CodegenNotApplicableError("zero or multiple codegens in range"));
|
|
31582
31610
|
}
|
|
31583
|
-
const { codegen, range: range3 } = inRangeCodegens[0];
|
|
31584
|
-
const edit = yield*
|
|
31611
|
+
const { codegen: codegen2, range: range3 } = inRangeCodegens[0];
|
|
31612
|
+
const edit = yield* codegen2.apply(sourceFile, range3);
|
|
31585
31613
|
const updateHashComment = pipe(
|
|
31586
31614
|
service2(ChangeTracker),
|
|
31587
31615
|
map34((changeTracker) => {
|
|
31588
31616
|
changeTracker.deleteRange(sourceFile, range3);
|
|
31589
|
-
changeTracker.insertText(sourceFile, range3.pos, `${
|
|
31617
|
+
changeTracker.insertText(sourceFile, range3.pos, `${codegen2.name}:${edit.hash}`);
|
|
31590
31618
|
})
|
|
31591
31619
|
);
|
|
31592
31620
|
return {
|
|
@@ -32055,6 +32083,51 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
32055
32083
|
if (!symbol3) return typeParserIssue("Node has no symbol", void 0, givenNode);
|
|
32056
32084
|
return isSymbolExportOfPackageModule(symbol3, packageName, memberName, isCorrectSourceFile);
|
|
32057
32085
|
};
|
|
32086
|
+
const findSymbolsMatchingPackageAndExportedName = (packageName, exportedSymbolName) => cachedBy(
|
|
32087
|
+
fn2("TypeParser.findSymbolsMatchingPackageAndExportedName")(function* (_fromSourceFile) {
|
|
32088
|
+
const result = [];
|
|
32089
|
+
for (const sourceFile of program.getSourceFiles()) {
|
|
32090
|
+
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
32091
|
+
if (!moduleSymbol) continue;
|
|
32092
|
+
const symbol3 = typeChecker.tryGetMemberInModuleExports(exportedSymbolName, moduleSymbol);
|
|
32093
|
+
if (!symbol3) continue;
|
|
32094
|
+
const packageInfo = yield* getSourceFilePackageInfo(sourceFile);
|
|
32095
|
+
if (!packageInfo || packageInfo.name.toLowerCase() !== packageName.toLowerCase()) continue;
|
|
32096
|
+
result.push([symbol3, sourceFile]);
|
|
32097
|
+
}
|
|
32098
|
+
return result;
|
|
32099
|
+
}),
|
|
32100
|
+
`TypeParser.findSymbolsMatchingPackageAndExportedName(${packageName}, ${exportedSymbolName})`,
|
|
32101
|
+
(sourceFile) => sourceFile
|
|
32102
|
+
);
|
|
32103
|
+
const isCauseTypeSourceFile = cachedBy(
|
|
32104
|
+
fn2("TypeParser.isCauseTypeSourceFile")(function* (sourceFile) {
|
|
32105
|
+
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
32106
|
+
if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
|
|
32107
|
+
const causeTypeSymbol = typeChecker.tryGetMemberInModuleExports("Cause", moduleSymbol);
|
|
32108
|
+
if (!causeTypeSymbol) return yield* typeParserIssue("Cause type not found", void 0, sourceFile);
|
|
32109
|
+
const type2 = typeChecker.getDeclaredTypeOfSymbol(causeTypeSymbol);
|
|
32110
|
+
yield* pipeableType(type2, sourceFile);
|
|
32111
|
+
return sourceFile;
|
|
32112
|
+
}),
|
|
32113
|
+
"TypeParser.isCauseTypeSourceFile",
|
|
32114
|
+
(sourceFile) => sourceFile
|
|
32115
|
+
);
|
|
32116
|
+
const effectCauseYieldableErrorTypes = cachedBy(
|
|
32117
|
+
fn2("TypeParser.effectCauseYieldableErrorTypes")(function* (fromSourceFile) {
|
|
32118
|
+
const symbols = yield* findSymbolsMatchingPackageAndExportedName("effect", "YieldableError")(fromSourceFile);
|
|
32119
|
+
const result = [];
|
|
32120
|
+
for (const [symbol3, sourceFile] of symbols) {
|
|
32121
|
+
const causeFile = yield* isCauseTypeSourceFile(sourceFile);
|
|
32122
|
+
if (!causeFile) continue;
|
|
32123
|
+
const type2 = typeChecker.getDeclaredTypeOfSymbol(symbol3);
|
|
32124
|
+
result.push(type2);
|
|
32125
|
+
}
|
|
32126
|
+
return result;
|
|
32127
|
+
}),
|
|
32128
|
+
"TypeParser.effectCauseYieldableErrorTypes",
|
|
32129
|
+
(fromSourceFile) => fromSourceFile
|
|
32130
|
+
);
|
|
32058
32131
|
function covariantTypeArgument(type2) {
|
|
32059
32132
|
const signatures = typeChecker.getSignaturesOfType(type2, ts.SignatureKind.Call);
|
|
32060
32133
|
if (signatures.length !== 1) {
|
|
@@ -33044,6 +33117,7 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
33044
33117
|
effectGen,
|
|
33045
33118
|
effectFnUntracedGen,
|
|
33046
33119
|
effectFnGen,
|
|
33120
|
+
effectCauseYieldableErrorTypes,
|
|
33047
33121
|
unnecessaryEffectGen: unnecessaryEffectGen2,
|
|
33048
33122
|
effectSchemaType,
|
|
33049
33123
|
contextTag,
|
|
@@ -33063,6 +33137,534 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
33063
33137
|
};
|
|
33064
33138
|
}
|
|
33065
33139
|
|
|
33140
|
+
// src/refactors/writeTagClassAccessors.ts
|
|
33141
|
+
var generate = fn2("writeTagClassAccessors.generate")(function* (sourceFile, service3, className, atLocation, involvedMembers) {
|
|
33142
|
+
const ts = yield* service2(TypeScriptApi);
|
|
33143
|
+
const tsUtils = yield* service2(TypeScriptUtils);
|
|
33144
|
+
const typeChecker = yield* service2(TypeCheckerApi);
|
|
33145
|
+
const typeParser = yield* service2(TypeParser);
|
|
33146
|
+
const changeTracker = yield* service2(ChangeTracker);
|
|
33147
|
+
const insertLocation = atLocation.members.length > 0 ? atLocation.members[0].pos : atLocation.end - 1;
|
|
33148
|
+
const effectIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
33149
|
+
sourceFile,
|
|
33150
|
+
"effect",
|
|
33151
|
+
"Effect"
|
|
33152
|
+
) || "Effect";
|
|
33153
|
+
const createFunctionProperty = (className2, propertyName, type2, forceAny) => {
|
|
33154
|
+
const arrowBody = ts.factory.createCallExpression(
|
|
33155
|
+
ts.factory.createPropertyAccessExpression(
|
|
33156
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
33157
|
+
"andThen"
|
|
33158
|
+
),
|
|
33159
|
+
void 0,
|
|
33160
|
+
[
|
|
33161
|
+
ts.factory.createIdentifier(ts.idText(className2)),
|
|
33162
|
+
ts.factory.createArrowFunction(
|
|
33163
|
+
void 0,
|
|
33164
|
+
void 0,
|
|
33165
|
+
[ts.factory.createParameterDeclaration(
|
|
33166
|
+
void 0,
|
|
33167
|
+
void 0,
|
|
33168
|
+
"_",
|
|
33169
|
+
void 0,
|
|
33170
|
+
forceAny ? ts.factory.createTypeReferenceNode("any") : void 0
|
|
33171
|
+
)],
|
|
33172
|
+
void 0,
|
|
33173
|
+
void 0,
|
|
33174
|
+
ts.factory.createCallExpression(
|
|
33175
|
+
ts.factory.createPropertyAccessExpression(
|
|
33176
|
+
ts.factory.createIdentifier("_"),
|
|
33177
|
+
propertyName
|
|
33178
|
+
),
|
|
33179
|
+
void 0,
|
|
33180
|
+
[
|
|
33181
|
+
ts.factory.createSpreadElement(ts.factory.createIdentifier("args"))
|
|
33182
|
+
]
|
|
33183
|
+
)
|
|
33184
|
+
)
|
|
33185
|
+
]
|
|
33186
|
+
);
|
|
33187
|
+
return ts.factory.createPropertyDeclaration(
|
|
33188
|
+
[
|
|
33189
|
+
ts.factory.createModifier(ts.SyntaxKind.StaticKeyword),
|
|
33190
|
+
ts.factory.createModifier(ts.SyntaxKind.OverrideKeyword)
|
|
33191
|
+
],
|
|
33192
|
+
propertyName,
|
|
33193
|
+
void 0,
|
|
33194
|
+
type2,
|
|
33195
|
+
ts.factory.createArrowFunction(
|
|
33196
|
+
void 0,
|
|
33197
|
+
void 0,
|
|
33198
|
+
[ts.factory.createParameterDeclaration(
|
|
33199
|
+
void 0,
|
|
33200
|
+
ts.factory.createToken(ts.SyntaxKind.DotDotDotToken),
|
|
33201
|
+
"args",
|
|
33202
|
+
void 0,
|
|
33203
|
+
forceAny ? ts.factory.createArrayTypeNode(ts.factory.createTypeReferenceNode("any")) : void 0
|
|
33204
|
+
)],
|
|
33205
|
+
void 0,
|
|
33206
|
+
void 0,
|
|
33207
|
+
forceAny ? ts.factory.createAsExpression(arrowBody, ts.factory.createTypeReferenceNode("any")) : arrowBody
|
|
33208
|
+
)
|
|
33209
|
+
);
|
|
33210
|
+
};
|
|
33211
|
+
const generateReturnType = (type2, atLocation2, className2) => pipe(
|
|
33212
|
+
typeParser.effectType(type2, atLocation2),
|
|
33213
|
+
flatMap18((returnedEffect) => {
|
|
33214
|
+
const contextType = returnedEffect.R.flags & ts.TypeFlags.Never ? ts.factory.createTypeReferenceNode(ts.idText(className2)) : ts.factory.createUnionTypeNode(
|
|
33215
|
+
[
|
|
33216
|
+
ts.factory.createTypeReferenceNode(ts.idText(className2)),
|
|
33217
|
+
typeChecker.typeToTypeNode(returnedEffect.R, atLocation2, ts.NodeBuilderFlags.NoTruncation)
|
|
33218
|
+
]
|
|
33219
|
+
);
|
|
33220
|
+
const successType = typeChecker.typeToTypeNode(
|
|
33221
|
+
returnedEffect.A,
|
|
33222
|
+
atLocation2,
|
|
33223
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
33224
|
+
);
|
|
33225
|
+
if (!successType) return fail18("error generating success type");
|
|
33226
|
+
const failureType = typeChecker.typeToTypeNode(
|
|
33227
|
+
returnedEffect.E,
|
|
33228
|
+
atLocation2,
|
|
33229
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
33230
|
+
);
|
|
33231
|
+
if (!failureType) return fail18("error generating failure type");
|
|
33232
|
+
const typeNode = ts.factory.createTypeReferenceNode(
|
|
33233
|
+
ts.factory.createQualifiedName(
|
|
33234
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
33235
|
+
ts.factory.createIdentifier("Effect")
|
|
33236
|
+
),
|
|
33237
|
+
[successType, failureType, contextType]
|
|
33238
|
+
);
|
|
33239
|
+
return succeed17(typeNode);
|
|
33240
|
+
}),
|
|
33241
|
+
orElse14(
|
|
33242
|
+
() => pipe(
|
|
33243
|
+
typeParser.promiseLike(type2, atLocation2),
|
|
33244
|
+
flatMap18(({ type: type3 }) => {
|
|
33245
|
+
const successType = typeChecker.typeToTypeNode(
|
|
33246
|
+
type3,
|
|
33247
|
+
atLocation2,
|
|
33248
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
33249
|
+
);
|
|
33250
|
+
if (!successType) return fail18("error generating success type");
|
|
33251
|
+
return succeed17(ts.factory.createTypeReferenceNode(
|
|
33252
|
+
ts.factory.createQualifiedName(
|
|
33253
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
33254
|
+
ts.factory.createIdentifier("Effect")
|
|
33255
|
+
),
|
|
33256
|
+
[
|
|
33257
|
+
successType,
|
|
33258
|
+
ts.factory.createTypeReferenceNode(
|
|
33259
|
+
ts.factory.createQualifiedName(
|
|
33260
|
+
ts.factory.createIdentifier("Cause"),
|
|
33261
|
+
ts.factory.createIdentifier("UnknownException")
|
|
33262
|
+
)
|
|
33263
|
+
),
|
|
33264
|
+
ts.factory.createTypeReferenceNode(ts.idText(className2))
|
|
33265
|
+
]
|
|
33266
|
+
));
|
|
33267
|
+
})
|
|
33268
|
+
)
|
|
33269
|
+
),
|
|
33270
|
+
orElse14(() => {
|
|
33271
|
+
const successType = typeChecker.typeToTypeNode(type2, atLocation2, ts.NodeBuilderFlags.NoTruncation);
|
|
33272
|
+
if (!successType) return fail18("error generating success type");
|
|
33273
|
+
const typeNode = ts.factory.createTypeReferenceNode(
|
|
33274
|
+
ts.factory.createQualifiedName(
|
|
33275
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
33276
|
+
ts.factory.createIdentifier("Effect")
|
|
33277
|
+
),
|
|
33278
|
+
[
|
|
33279
|
+
successType,
|
|
33280
|
+
ts.factory.createTypeReferenceNode("never"),
|
|
33281
|
+
ts.factory.createTypeReferenceNode(ts.idText(className2))
|
|
33282
|
+
]
|
|
33283
|
+
);
|
|
33284
|
+
return succeed17(typeNode);
|
|
33285
|
+
})
|
|
33286
|
+
);
|
|
33287
|
+
const proxySignature = (signature, atLocation2, className2) => gen3(function* () {
|
|
33288
|
+
const signatureDeclaration = typeChecker.signatureToSignatureDeclaration(
|
|
33289
|
+
signature,
|
|
33290
|
+
ts.SyntaxKind.FunctionType,
|
|
33291
|
+
atLocation2,
|
|
33292
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
33293
|
+
);
|
|
33294
|
+
if (!signatureDeclaration) return yield* fail18("error generating signature");
|
|
33295
|
+
const returnType = yield* generateReturnType(
|
|
33296
|
+
typeChecker.getReturnTypeOfSignature(signature),
|
|
33297
|
+
atLocation2,
|
|
33298
|
+
className2
|
|
33299
|
+
);
|
|
33300
|
+
return ts.factory.createFunctionTypeNode(
|
|
33301
|
+
signatureDeclaration.typeParameters,
|
|
33302
|
+
signatureDeclaration.parameters,
|
|
33303
|
+
returnType
|
|
33304
|
+
);
|
|
33305
|
+
});
|
|
33306
|
+
for (const { property, propertyType } of involvedMembers) {
|
|
33307
|
+
const callSignatures = [];
|
|
33308
|
+
let propertyDeclaration = void 0;
|
|
33309
|
+
for (const signature of typeChecker.getSignaturesOfType(propertyType, ts.SignatureKind.Call)) {
|
|
33310
|
+
yield* pipe(
|
|
33311
|
+
proxySignature(signature, atLocation, className),
|
|
33312
|
+
map34((sig) => {
|
|
33313
|
+
callSignatures.push(sig);
|
|
33314
|
+
}),
|
|
33315
|
+
ignore3
|
|
33316
|
+
);
|
|
33317
|
+
}
|
|
33318
|
+
const allSignatures = ts.factory.createIntersectionTypeNode(callSignatures);
|
|
33319
|
+
const type2 = tsUtils.simplifyTypeNode(allSignatures);
|
|
33320
|
+
propertyDeclaration = createFunctionProperty(className, ts.symbolName(property), type2, callSignatures.length > 1);
|
|
33321
|
+
const oldProperty = atLocation.members.filter(ts.isPropertyDeclaration).find((p2) => {
|
|
33322
|
+
const symbol3 = typeChecker.getSymbolAtLocation(p2.name);
|
|
33323
|
+
return symbol3 && ts.symbolName(symbol3) === ts.symbolName(property);
|
|
33324
|
+
});
|
|
33325
|
+
if (oldProperty) {
|
|
33326
|
+
const start4 = ts.getTokenPosOfNode(oldProperty, sourceFile);
|
|
33327
|
+
changeTracker.deleteRange(sourceFile, {
|
|
33328
|
+
pos: start4,
|
|
33329
|
+
end: oldProperty.end
|
|
33330
|
+
});
|
|
33331
|
+
changeTracker.insertNodeAt(sourceFile, start4, propertyDeclaration);
|
|
33332
|
+
} else {
|
|
33333
|
+
changeTracker.insertNodeAt(sourceFile, insertLocation, propertyDeclaration, { suffix: "\n" });
|
|
33334
|
+
}
|
|
33335
|
+
}
|
|
33336
|
+
});
|
|
33337
|
+
var parse5 = fn2("writeTagClassAccessors.parse")(function* (node) {
|
|
33338
|
+
const ts = yield* service2(TypeScriptApi);
|
|
33339
|
+
const typeChecker = yield* service2(TypeCheckerApi);
|
|
33340
|
+
const typeParser = yield* service2(TypeParser);
|
|
33341
|
+
const typeCheckerUtils = yield* service2(TypeCheckerUtils);
|
|
33342
|
+
if (!ts.isClassDeclaration(node)) return yield* fail18("not a class declaration");
|
|
33343
|
+
const { Service, accessors: accessors2, className } = yield* pipe(
|
|
33344
|
+
typeParser.extendsEffectService(node),
|
|
33345
|
+
orElse14(() => map34(typeParser.extendsEffectTag(node), (_) => ({ accessors: true, ..._ }))),
|
|
33346
|
+
orElse14(() => fail18("not a class extending Effect.Service call"))
|
|
33347
|
+
);
|
|
33348
|
+
if (accessors2 !== true) return yield* fail18("accessors are not enabled in the Effect.Service call");
|
|
33349
|
+
const involvedMembers = [];
|
|
33350
|
+
const nonPrimitiveServices = typeCheckerUtils.unrollUnionMembers(Service).filter(
|
|
33351
|
+
(_) => !(_.flags & ts.TypeFlags.Number || _.flags & ts.TypeFlags.String || _.flags & ts.TypeFlags.Boolean || _.flags & ts.TypeFlags.Literal)
|
|
33352
|
+
);
|
|
33353
|
+
if (nonPrimitiveServices.length === 0) return yield* fail18("Service type is a primitive type");
|
|
33354
|
+
for (const serviceShape of nonPrimitiveServices) {
|
|
33355
|
+
for (const property of typeChecker.getPropertiesOfType(serviceShape)) {
|
|
33356
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(property, node);
|
|
33357
|
+
const callSignatures = typeChecker.getSignaturesOfType(propertyType, ts.SignatureKind.Call);
|
|
33358
|
+
if (callSignatures.length > 0) {
|
|
33359
|
+
const withTypeParameters = callSignatures.filter((_) => _.typeParameters && _.typeParameters.length > 0);
|
|
33360
|
+
if (callSignatures.length > 1 || withTypeParameters.length > 0) involvedMembers.push({ property, propertyType });
|
|
33361
|
+
}
|
|
33362
|
+
}
|
|
33363
|
+
}
|
|
33364
|
+
const hash2 = involvedMembers.map(({ property, propertyType }) => {
|
|
33365
|
+
return ts.symbolName(property) + ": " + typeChecker.typeToString(propertyType);
|
|
33366
|
+
}).concat([ts.idText(className)]).join("\n");
|
|
33367
|
+
return { Service, className, atLocation: node, hash: cyrb53(hash2), involvedMembers };
|
|
33368
|
+
});
|
|
33369
|
+
var writeTagClassAccessors = createRefactor({
|
|
33370
|
+
name: "writeTagClassAccessors",
|
|
33371
|
+
description: "Implement accessors methods with generics or multiple signatures",
|
|
33372
|
+
apply: fn2("writeTagClassAccessors.apply")(function* (sourceFile, textRange) {
|
|
33373
|
+
const ts = yield* service2(TypeScriptApi);
|
|
33374
|
+
const tsUtils = yield* service2(TypeScriptUtils);
|
|
33375
|
+
const typeChecker = yield* service2(TypeCheckerApi);
|
|
33376
|
+
const typeParser = yield* service2(TypeParser);
|
|
33377
|
+
const parseNode = (node) => pipe(
|
|
33378
|
+
parse5(node),
|
|
33379
|
+
map34(({ Service, atLocation, className, involvedMembers }) => ({
|
|
33380
|
+
kind: "refactor.rewrite.effect.writeTagClassAccessors",
|
|
33381
|
+
description: "Implement Service accessors",
|
|
33382
|
+
apply: pipe(
|
|
33383
|
+
generate(sourceFile, Service, className, atLocation, involvedMembers),
|
|
33384
|
+
provideService7(TypeScriptUtils, tsUtils),
|
|
33385
|
+
provideService7(TypeParser, typeParser),
|
|
33386
|
+
provideService7(TypeCheckerApi, typeChecker),
|
|
33387
|
+
provideService7(TypeScriptApi, ts)
|
|
33388
|
+
)
|
|
33389
|
+
}))
|
|
33390
|
+
);
|
|
33391
|
+
const parentNodes = tsUtils.getAncestorNodesInRange(sourceFile, textRange);
|
|
33392
|
+
return yield* pipe(
|
|
33393
|
+
firstSuccessOf2(parentNodes.map(parseNode)),
|
|
33394
|
+
orElse14(() => fail18(new RefactorNotApplicableError()))
|
|
33395
|
+
);
|
|
33396
|
+
})
|
|
33397
|
+
});
|
|
33398
|
+
|
|
33399
|
+
// src/codegens/accessors.ts
|
|
33400
|
+
var accessors = createCodegen({
|
|
33401
|
+
name: "accessors",
|
|
33402
|
+
apply: fn2("accessors.apply")(function* (sourceFile, textRange) {
|
|
33403
|
+
const ts = yield* service2(TypeScriptApi);
|
|
33404
|
+
const tsUtils = yield* service2(TypeScriptUtils);
|
|
33405
|
+
const typeChecker = yield* service2(TypeCheckerApi);
|
|
33406
|
+
const typeParser = yield* service2(TypeParser);
|
|
33407
|
+
const typeCheckerUtils = yield* service2(TypeCheckerUtils);
|
|
33408
|
+
const nodeAndCommentRange = tsUtils.findNodeWithLeadingCommentAtPosition(sourceFile, textRange.pos);
|
|
33409
|
+
if (!nodeAndCommentRange) return yield* fail18(new CodegenNotApplicableError("no node and comment range"));
|
|
33410
|
+
return yield* pipe(
|
|
33411
|
+
parse5(nodeAndCommentRange.node),
|
|
33412
|
+
map34(
|
|
33413
|
+
(_) => ({
|
|
33414
|
+
hash: _.hash,
|
|
33415
|
+
description: "Generate accessors for the service",
|
|
33416
|
+
apply: pipe(
|
|
33417
|
+
generate(sourceFile, _.Service, _.className, _.atLocation, _.involvedMembers),
|
|
33418
|
+
provideService7(TypeScriptApi, ts),
|
|
33419
|
+
provideService7(TypeScriptUtils, tsUtils),
|
|
33420
|
+
provideService7(TypeCheckerApi, typeChecker),
|
|
33421
|
+
provideService7(TypeParser, typeParser),
|
|
33422
|
+
provideService7(TypeCheckerUtils, typeCheckerUtils)
|
|
33423
|
+
)
|
|
33424
|
+
})
|
|
33425
|
+
),
|
|
33426
|
+
orElse14((cause2) => fail18(new CodegenNotApplicableError(cause2)))
|
|
33427
|
+
);
|
|
33428
|
+
})
|
|
33429
|
+
});
|
|
33430
|
+
|
|
33431
|
+
// src/codegens/annotate.ts
|
|
33432
|
+
var annotate3 = createCodegen({
|
|
33433
|
+
name: "annotate",
|
|
33434
|
+
apply: fn2("annotate.apply")(function* (sourceFile, textRange) {
|
|
33435
|
+
const ts = yield* service2(TypeScriptApi);
|
|
33436
|
+
const tsUtils = yield* service2(TypeScriptUtils);
|
|
33437
|
+
const typeChecker = yield* service2(TypeCheckerApi);
|
|
33438
|
+
const typeCheckerUtils = yield* service2(TypeCheckerUtils);
|
|
33439
|
+
const parse6 = (node) => gen3(function* () {
|
|
33440
|
+
let variableDeclarations = [];
|
|
33441
|
+
const result = [];
|
|
33442
|
+
if (ts.isVariableStatement(node)) {
|
|
33443
|
+
variableDeclarations = [...variableDeclarations, ...node.declarationList.declarations];
|
|
33444
|
+
} else if (ts.isVariableDeclarationList(node)) {
|
|
33445
|
+
variableDeclarations = [...variableDeclarations, ...node.declarations];
|
|
33446
|
+
} else if (ts.isVariableDeclaration(node)) {
|
|
33447
|
+
variableDeclarations = [...variableDeclarations, node];
|
|
33448
|
+
}
|
|
33449
|
+
if (variableDeclarations.length === 0) {
|
|
33450
|
+
return yield* fail18(new CodegenNotApplicableError("not a variable declaration"));
|
|
33451
|
+
}
|
|
33452
|
+
for (const variableDeclaration of variableDeclarations) {
|
|
33453
|
+
if (!variableDeclaration.initializer) continue;
|
|
33454
|
+
const initializerType = typeChecker.getTypeAtLocation(variableDeclaration.initializer);
|
|
33455
|
+
const initializerTypeNode = fromNullable(typeCheckerUtils.typeToSimplifiedTypeNode(
|
|
33456
|
+
initializerType,
|
|
33457
|
+
node,
|
|
33458
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
33459
|
+
)).pipe(
|
|
33460
|
+
orElse(
|
|
33461
|
+
() => fromNullable(typeCheckerUtils.typeToSimplifiedTypeNode(
|
|
33462
|
+
initializerType,
|
|
33463
|
+
void 0,
|
|
33464
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
33465
|
+
))
|
|
33466
|
+
),
|
|
33467
|
+
getOrUndefined
|
|
33468
|
+
);
|
|
33469
|
+
if (!initializerTypeNode) continue;
|
|
33470
|
+
const typeNodeString = typeChecker.typeToString(initializerType, void 0, ts.TypeFormatFlags.NoTruncation);
|
|
33471
|
+
const hash3 = cyrb53(typeNodeString);
|
|
33472
|
+
result.push({ variableDeclaration, initializerTypeNode, hash: hash3 });
|
|
33473
|
+
}
|
|
33474
|
+
if (result.length === 0) {
|
|
33475
|
+
return yield* fail18(new CodegenNotApplicableError("no variable declarations with initializers"));
|
|
33476
|
+
}
|
|
33477
|
+
const hash2 = cyrb53(result.map((_) => _.hash).join("/"));
|
|
33478
|
+
return {
|
|
33479
|
+
hash: hash2,
|
|
33480
|
+
result
|
|
33481
|
+
};
|
|
33482
|
+
});
|
|
33483
|
+
const nodeAndCommentRange = tsUtils.findNodeWithLeadingCommentAtPosition(sourceFile, textRange.pos);
|
|
33484
|
+
if (!nodeAndCommentRange) return yield* fail18(new CodegenNotApplicableError("no node and comment range"));
|
|
33485
|
+
return yield* pipe(
|
|
33486
|
+
parse6(nodeAndCommentRange.node),
|
|
33487
|
+
map34(
|
|
33488
|
+
(_) => ({
|
|
33489
|
+
hash: _.hash,
|
|
33490
|
+
description: "Annotate with type",
|
|
33491
|
+
apply: gen3(function* () {
|
|
33492
|
+
const changeTracker = yield* service2(ChangeTracker);
|
|
33493
|
+
for (const { initializerTypeNode, variableDeclaration } of _.result) {
|
|
33494
|
+
if (variableDeclaration.type) {
|
|
33495
|
+
changeTracker.deleteRange(sourceFile, {
|
|
33496
|
+
pos: variableDeclaration.name.end,
|
|
33497
|
+
end: variableDeclaration.type.end
|
|
33498
|
+
});
|
|
33499
|
+
}
|
|
33500
|
+
changeTracker.insertNodeAt(
|
|
33501
|
+
sourceFile,
|
|
33502
|
+
variableDeclaration.name.end,
|
|
33503
|
+
initializerTypeNode,
|
|
33504
|
+
{
|
|
33505
|
+
prefix: ": "
|
|
33506
|
+
}
|
|
33507
|
+
);
|
|
33508
|
+
}
|
|
33509
|
+
})
|
|
33510
|
+
})
|
|
33511
|
+
)
|
|
33512
|
+
);
|
|
33513
|
+
})
|
|
33514
|
+
});
|
|
33515
|
+
|
|
33516
|
+
// src/codegens.ts
|
|
33517
|
+
var codegens = [accessors, annotate3];
|
|
33518
|
+
|
|
33519
|
+
// src/cli/codegen.ts
|
|
33520
|
+
var NoFilesToCodegenError = class extends TaggedError("NoFilesToCodegenError") {
|
|
33521
|
+
get message() {
|
|
33522
|
+
return "No files to codegen. Please provide an existing .ts file or a project tsconfig.json";
|
|
33523
|
+
}
|
|
33524
|
+
};
|
|
33525
|
+
var file4 = file3("file").pipe(
|
|
33526
|
+
optional4,
|
|
33527
|
+
withDescription3("The full path of the file to codegen.")
|
|
33528
|
+
);
|
|
33529
|
+
var project2 = file3("project").pipe(
|
|
33530
|
+
optional4,
|
|
33531
|
+
withDescription3("The full path of the project tsconfig.json file to codegen.")
|
|
33532
|
+
);
|
|
33533
|
+
var verbose = boolean5("verbose").pipe(
|
|
33534
|
+
withDefault3(false),
|
|
33535
|
+
withDescription3("Verbose output.")
|
|
33536
|
+
);
|
|
33537
|
+
var BATCH_SIZE = 50;
|
|
33538
|
+
var codegen = make58(
|
|
33539
|
+
"codegen",
|
|
33540
|
+
{ file: file4, project: project2, verbose },
|
|
33541
|
+
fn("codegen")(function* ({ file: file6, project: project4, verbose: verbose2 }) {
|
|
33542
|
+
const path2 = yield* Path2;
|
|
33543
|
+
const fs = yield* FileSystem;
|
|
33544
|
+
const tsInstance = yield* getTypeScript;
|
|
33545
|
+
let filesToCodegen = /* @__PURE__ */ new Set();
|
|
33546
|
+
let checkedFilesCount = 0;
|
|
33547
|
+
let updatedFilesCount = 0;
|
|
33548
|
+
if (isSome2(project4)) {
|
|
33549
|
+
filesToCodegen = yield* getFileNamesInTsConfig(project4.value);
|
|
33550
|
+
}
|
|
33551
|
+
if (isSome2(file6)) {
|
|
33552
|
+
filesToCodegen.add(path2.resolve(file6.value));
|
|
33553
|
+
}
|
|
33554
|
+
if (filesToCodegen.size === 0) {
|
|
33555
|
+
return yield* new NoFilesToCodegenError();
|
|
33556
|
+
}
|
|
33557
|
+
const filesWithCodegenDirective = /* @__PURE__ */ new Set();
|
|
33558
|
+
for (const filePath of filesToCodegen) {
|
|
33559
|
+
const sourceText = yield* fs.readFileString(filePath);
|
|
33560
|
+
if (sourceText.toLowerCase().indexOf("@effect-codegens") !== -1) {
|
|
33561
|
+
filesWithCodegenDirective.add(filePath);
|
|
33562
|
+
}
|
|
33563
|
+
}
|
|
33564
|
+
if (filesWithCodegenDirective.size === 0) {
|
|
33565
|
+
return yield* new NoFilesToCodegenError();
|
|
33566
|
+
}
|
|
33567
|
+
const filesToCodegenArray = fromIterable(filesWithCodegenDirective);
|
|
33568
|
+
const batches = chunksOf(filesToCodegenArray, BATCH_SIZE);
|
|
33569
|
+
let lastLanguageService;
|
|
33570
|
+
const disposeIfLanguageServiceChanged = (languageService) => {
|
|
33571
|
+
if (lastLanguageService !== languageService) {
|
|
33572
|
+
lastLanguageService?.dispose();
|
|
33573
|
+
lastLanguageService = languageService;
|
|
33574
|
+
}
|
|
33575
|
+
};
|
|
33576
|
+
for (const batch of batches) {
|
|
33577
|
+
const { service: service3 } = (0, import_project_service.createProjectService)({ options: { loadTypeScriptPlugins: false } });
|
|
33578
|
+
for (const filePath of batch) {
|
|
33579
|
+
service3.openClientFile(filePath);
|
|
33580
|
+
try {
|
|
33581
|
+
const scriptInfo = service3.getScriptInfo(filePath);
|
|
33582
|
+
if (!scriptInfo) continue;
|
|
33583
|
+
const project5 = scriptInfo.getDefaultProject();
|
|
33584
|
+
const languageService = project5.getLanguageService(true);
|
|
33585
|
+
disposeIfLanguageServiceChanged(languageService);
|
|
33586
|
+
const program = languageService.getProgram();
|
|
33587
|
+
if (!program) continue;
|
|
33588
|
+
const sourceFile = program.getSourceFile(filePath);
|
|
33589
|
+
if (!sourceFile) continue;
|
|
33590
|
+
const pluginConfig = extractEffectLspOptions(program.getCompilerOptions());
|
|
33591
|
+
if (!pluginConfig) continue;
|
|
33592
|
+
const formatContext = tsInstance.formatting.getFormatContext(
|
|
33593
|
+
tsInstance.getDefaultFormatCodeSettings(project5.getNewLine()),
|
|
33594
|
+
project5
|
|
33595
|
+
);
|
|
33596
|
+
const allFileChanges = pipe(
|
|
33597
|
+
gen3(function* () {
|
|
33598
|
+
let allChanges = [];
|
|
33599
|
+
const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
|
|
33600
|
+
for (const { codegen: codegen2, hash: hash2, range: range3 } of codegensWithRanges) {
|
|
33601
|
+
const applicable = yield* pipe(
|
|
33602
|
+
getEditsForCodegen([codegen2], sourceFile, range3),
|
|
33603
|
+
orElse14(() => void_8)
|
|
33604
|
+
);
|
|
33605
|
+
if (applicable && applicable.hash !== hash2) {
|
|
33606
|
+
const changes2 = tsInstance.textChanges.ChangeTracker.with(
|
|
33607
|
+
{
|
|
33608
|
+
formatContext,
|
|
33609
|
+
host: project5,
|
|
33610
|
+
preferences: {}
|
|
33611
|
+
},
|
|
33612
|
+
(changeTracker) => pipe(
|
|
33613
|
+
applicable.apply,
|
|
33614
|
+
provideService7(ChangeTracker, changeTracker),
|
|
33615
|
+
run9
|
|
33616
|
+
)
|
|
33617
|
+
);
|
|
33618
|
+
allChanges = [...allChanges, ...changes2];
|
|
33619
|
+
}
|
|
33620
|
+
}
|
|
33621
|
+
return allChanges;
|
|
33622
|
+
}),
|
|
33623
|
+
nanoLayer3,
|
|
33624
|
+
nanoLayer2,
|
|
33625
|
+
nanoLayer,
|
|
33626
|
+
provideService7(TypeCheckerApi, program.getTypeChecker()),
|
|
33627
|
+
provideService7(TypeScriptProgram, program),
|
|
33628
|
+
provideService7(TypeScriptApi, tsInstance),
|
|
33629
|
+
provideService7(
|
|
33630
|
+
LanguageServicePluginOptions,
|
|
33631
|
+
{ ...parse4(pluginConfig), diagnosticsName: false }
|
|
33632
|
+
),
|
|
33633
|
+
run9,
|
|
33634
|
+
getOrElse(() => [])
|
|
33635
|
+
);
|
|
33636
|
+
checkedFilesCount++;
|
|
33637
|
+
const thisFileChanges = allFileChanges.filter((change) => change.fileName === sourceFile.fileName);
|
|
33638
|
+
const flattenedChanges = flatten(thisFileChanges.map((change) => change.textChanges));
|
|
33639
|
+
if (verbose2) {
|
|
33640
|
+
if (flattenedChanges.length > 0) {
|
|
33641
|
+
console.log(`${filePath}: with ${flattenedChanges.length} changes`);
|
|
33642
|
+
} else {
|
|
33643
|
+
console.log(`${filePath}: no changes`);
|
|
33644
|
+
}
|
|
33645
|
+
}
|
|
33646
|
+
if (flattenedChanges.length === 0) continue;
|
|
33647
|
+
const sourceText = yield* fs.readFileString(filePath);
|
|
33648
|
+
const newSourceText = yield* applyTextChanges(sourceText, flattenedChanges);
|
|
33649
|
+
yield* fs.writeFileString(filePath, newSourceText);
|
|
33650
|
+
updatedFilesCount++;
|
|
33651
|
+
} finally {
|
|
33652
|
+
service3.closeClientFile(filePath);
|
|
33653
|
+
}
|
|
33654
|
+
}
|
|
33655
|
+
yield* yieldNow4();
|
|
33656
|
+
}
|
|
33657
|
+
disposeIfLanguageServiceChanged(void 0);
|
|
33658
|
+
console.log(
|
|
33659
|
+
`${filesToCodegen.size} involved files, of which ${filesWithCodegenDirective.size} with codegens.
|
|
33660
|
+
${checkedFilesCount} checked and ${updatedFilesCount} updated.`
|
|
33661
|
+
);
|
|
33662
|
+
})
|
|
33663
|
+
);
|
|
33664
|
+
|
|
33665
|
+
// src/cli/diagnostics.ts
|
|
33666
|
+
var import_project_service2 = __toESM(require_dist2());
|
|
33667
|
+
|
|
33066
33668
|
// src/diagnostics/anyUnknownInErrorContext.ts
|
|
33067
33669
|
var anyUnknownInErrorContext = createDiagnostic({
|
|
33068
33670
|
name: "anyUnknownInErrorContext",
|
|
@@ -34671,300 +35273,6 @@ var nonObjectEffectServiceType = createDiagnostic({
|
|
|
34671
35273
|
})
|
|
34672
35274
|
});
|
|
34673
35275
|
|
|
34674
|
-
// src/refactors/writeTagClassAccessors.ts
|
|
34675
|
-
var generate = fn2("writeTagClassAccessors.generate")(function* (sourceFile, service3, className, atLocation, involvedMembers) {
|
|
34676
|
-
const ts = yield* service2(TypeScriptApi);
|
|
34677
|
-
const tsUtils = yield* service2(TypeScriptUtils);
|
|
34678
|
-
const typeChecker = yield* service2(TypeCheckerApi);
|
|
34679
|
-
const typeParser = yield* service2(TypeParser);
|
|
34680
|
-
const changeTracker = yield* service2(ChangeTracker);
|
|
34681
|
-
const insertLocation = atLocation.members.length > 0 ? atLocation.members[0].pos : atLocation.end - 1;
|
|
34682
|
-
const effectIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
34683
|
-
sourceFile,
|
|
34684
|
-
"effect",
|
|
34685
|
-
"Effect"
|
|
34686
|
-
) || "Effect";
|
|
34687
|
-
const createFunctionProperty = (className2, propertyName, type2, forceAny) => {
|
|
34688
|
-
const arrowBody = ts.factory.createCallExpression(
|
|
34689
|
-
ts.factory.createPropertyAccessExpression(
|
|
34690
|
-
ts.factory.createIdentifier(effectIdentifier),
|
|
34691
|
-
"andThen"
|
|
34692
|
-
),
|
|
34693
|
-
void 0,
|
|
34694
|
-
[
|
|
34695
|
-
ts.factory.createIdentifier(ts.idText(className2)),
|
|
34696
|
-
ts.factory.createArrowFunction(
|
|
34697
|
-
void 0,
|
|
34698
|
-
void 0,
|
|
34699
|
-
[ts.factory.createParameterDeclaration(
|
|
34700
|
-
void 0,
|
|
34701
|
-
void 0,
|
|
34702
|
-
"_",
|
|
34703
|
-
void 0,
|
|
34704
|
-
forceAny ? ts.factory.createTypeReferenceNode("any") : void 0
|
|
34705
|
-
)],
|
|
34706
|
-
void 0,
|
|
34707
|
-
void 0,
|
|
34708
|
-
ts.factory.createCallExpression(
|
|
34709
|
-
ts.factory.createPropertyAccessExpression(
|
|
34710
|
-
ts.factory.createIdentifier("_"),
|
|
34711
|
-
propertyName
|
|
34712
|
-
),
|
|
34713
|
-
void 0,
|
|
34714
|
-
[
|
|
34715
|
-
ts.factory.createSpreadElement(ts.factory.createIdentifier("args"))
|
|
34716
|
-
]
|
|
34717
|
-
)
|
|
34718
|
-
)
|
|
34719
|
-
]
|
|
34720
|
-
);
|
|
34721
|
-
return ts.factory.createPropertyDeclaration(
|
|
34722
|
-
[
|
|
34723
|
-
ts.factory.createModifier(ts.SyntaxKind.StaticKeyword),
|
|
34724
|
-
ts.factory.createModifier(ts.SyntaxKind.OverrideKeyword)
|
|
34725
|
-
],
|
|
34726
|
-
propertyName,
|
|
34727
|
-
void 0,
|
|
34728
|
-
type2,
|
|
34729
|
-
ts.factory.createArrowFunction(
|
|
34730
|
-
void 0,
|
|
34731
|
-
void 0,
|
|
34732
|
-
[ts.factory.createParameterDeclaration(
|
|
34733
|
-
void 0,
|
|
34734
|
-
ts.factory.createToken(ts.SyntaxKind.DotDotDotToken),
|
|
34735
|
-
"args",
|
|
34736
|
-
void 0,
|
|
34737
|
-
forceAny ? ts.factory.createArrayTypeNode(ts.factory.createTypeReferenceNode("any")) : void 0
|
|
34738
|
-
)],
|
|
34739
|
-
void 0,
|
|
34740
|
-
void 0,
|
|
34741
|
-
forceAny ? ts.factory.createAsExpression(arrowBody, ts.factory.createTypeReferenceNode("any")) : arrowBody
|
|
34742
|
-
)
|
|
34743
|
-
);
|
|
34744
|
-
};
|
|
34745
|
-
const generateReturnType = (type2, atLocation2, className2) => pipe(
|
|
34746
|
-
typeParser.effectType(type2, atLocation2),
|
|
34747
|
-
flatMap18((returnedEffect) => {
|
|
34748
|
-
const contextType = returnedEffect.R.flags & ts.TypeFlags.Never ? ts.factory.createTypeReferenceNode(ts.idText(className2)) : ts.factory.createUnionTypeNode(
|
|
34749
|
-
[
|
|
34750
|
-
ts.factory.createTypeReferenceNode(ts.idText(className2)),
|
|
34751
|
-
typeChecker.typeToTypeNode(returnedEffect.R, atLocation2, ts.NodeBuilderFlags.NoTruncation)
|
|
34752
|
-
]
|
|
34753
|
-
);
|
|
34754
|
-
const successType = typeChecker.typeToTypeNode(
|
|
34755
|
-
returnedEffect.A,
|
|
34756
|
-
atLocation2,
|
|
34757
|
-
ts.NodeBuilderFlags.NoTruncation
|
|
34758
|
-
);
|
|
34759
|
-
if (!successType) return fail18("error generating success type");
|
|
34760
|
-
const failureType = typeChecker.typeToTypeNode(
|
|
34761
|
-
returnedEffect.E,
|
|
34762
|
-
atLocation2,
|
|
34763
|
-
ts.NodeBuilderFlags.NoTruncation
|
|
34764
|
-
);
|
|
34765
|
-
if (!failureType) return fail18("error generating failure type");
|
|
34766
|
-
const typeNode = ts.factory.createTypeReferenceNode(
|
|
34767
|
-
ts.factory.createQualifiedName(
|
|
34768
|
-
ts.factory.createIdentifier(effectIdentifier),
|
|
34769
|
-
ts.factory.createIdentifier("Effect")
|
|
34770
|
-
),
|
|
34771
|
-
[successType, failureType, contextType]
|
|
34772
|
-
);
|
|
34773
|
-
return succeed17(typeNode);
|
|
34774
|
-
}),
|
|
34775
|
-
orElse14(
|
|
34776
|
-
() => pipe(
|
|
34777
|
-
typeParser.promiseLike(type2, atLocation2),
|
|
34778
|
-
flatMap18(({ type: type3 }) => {
|
|
34779
|
-
const successType = typeChecker.typeToTypeNode(
|
|
34780
|
-
type3,
|
|
34781
|
-
atLocation2,
|
|
34782
|
-
ts.NodeBuilderFlags.NoTruncation
|
|
34783
|
-
);
|
|
34784
|
-
if (!successType) return fail18("error generating success type");
|
|
34785
|
-
return succeed17(ts.factory.createTypeReferenceNode(
|
|
34786
|
-
ts.factory.createQualifiedName(
|
|
34787
|
-
ts.factory.createIdentifier(effectIdentifier),
|
|
34788
|
-
ts.factory.createIdentifier("Effect")
|
|
34789
|
-
),
|
|
34790
|
-
[
|
|
34791
|
-
successType,
|
|
34792
|
-
ts.factory.createTypeReferenceNode(
|
|
34793
|
-
ts.factory.createQualifiedName(
|
|
34794
|
-
ts.factory.createIdentifier("Cause"),
|
|
34795
|
-
ts.factory.createIdentifier("UnknownException")
|
|
34796
|
-
)
|
|
34797
|
-
),
|
|
34798
|
-
ts.factory.createTypeReferenceNode(ts.idText(className2))
|
|
34799
|
-
]
|
|
34800
|
-
));
|
|
34801
|
-
})
|
|
34802
|
-
)
|
|
34803
|
-
),
|
|
34804
|
-
orElse14(() => {
|
|
34805
|
-
const successType = typeChecker.typeToTypeNode(type2, atLocation2, ts.NodeBuilderFlags.NoTruncation);
|
|
34806
|
-
if (!successType) return fail18("error generating success type");
|
|
34807
|
-
const typeNode = ts.factory.createTypeReferenceNode(
|
|
34808
|
-
ts.factory.createQualifiedName(
|
|
34809
|
-
ts.factory.createIdentifier(effectIdentifier),
|
|
34810
|
-
ts.factory.createIdentifier("Effect")
|
|
34811
|
-
),
|
|
34812
|
-
[
|
|
34813
|
-
successType,
|
|
34814
|
-
ts.factory.createTypeReferenceNode("never"),
|
|
34815
|
-
ts.factory.createTypeReferenceNode(ts.idText(className2))
|
|
34816
|
-
]
|
|
34817
|
-
);
|
|
34818
|
-
return succeed17(typeNode);
|
|
34819
|
-
})
|
|
34820
|
-
);
|
|
34821
|
-
const proxySignature = (signature, atLocation2, className2) => gen3(function* () {
|
|
34822
|
-
const signatureDeclaration = typeChecker.signatureToSignatureDeclaration(
|
|
34823
|
-
signature,
|
|
34824
|
-
ts.SyntaxKind.FunctionType,
|
|
34825
|
-
atLocation2,
|
|
34826
|
-
ts.NodeBuilderFlags.NoTruncation
|
|
34827
|
-
);
|
|
34828
|
-
if (!signatureDeclaration) return yield* fail18("error generating signature");
|
|
34829
|
-
const returnType = yield* generateReturnType(
|
|
34830
|
-
typeChecker.getReturnTypeOfSignature(signature),
|
|
34831
|
-
atLocation2,
|
|
34832
|
-
className2
|
|
34833
|
-
);
|
|
34834
|
-
return ts.factory.createFunctionTypeNode(
|
|
34835
|
-
signatureDeclaration.typeParameters,
|
|
34836
|
-
signatureDeclaration.parameters,
|
|
34837
|
-
returnType
|
|
34838
|
-
);
|
|
34839
|
-
});
|
|
34840
|
-
for (const { property, propertyType } of involvedMembers) {
|
|
34841
|
-
const callSignatures = [];
|
|
34842
|
-
let propertyDeclaration = void 0;
|
|
34843
|
-
for (const signature of typeChecker.getSignaturesOfType(propertyType, ts.SignatureKind.Call)) {
|
|
34844
|
-
yield* pipe(
|
|
34845
|
-
proxySignature(signature, atLocation, className),
|
|
34846
|
-
map34((sig) => {
|
|
34847
|
-
callSignatures.push(sig);
|
|
34848
|
-
}),
|
|
34849
|
-
ignore3
|
|
34850
|
-
);
|
|
34851
|
-
}
|
|
34852
|
-
const allSignatures = ts.factory.createIntersectionTypeNode(callSignatures);
|
|
34853
|
-
const type2 = tsUtils.simplifyTypeNode(allSignatures);
|
|
34854
|
-
propertyDeclaration = createFunctionProperty(className, ts.symbolName(property), type2, callSignatures.length > 1);
|
|
34855
|
-
const oldProperty = atLocation.members.filter(ts.isPropertyDeclaration).find((p2) => {
|
|
34856
|
-
const symbol3 = typeChecker.getSymbolAtLocation(p2.name);
|
|
34857
|
-
return symbol3 && ts.symbolName(symbol3) === ts.symbolName(property);
|
|
34858
|
-
});
|
|
34859
|
-
if (oldProperty) {
|
|
34860
|
-
const start4 = ts.getTokenPosOfNode(oldProperty, sourceFile);
|
|
34861
|
-
changeTracker.deleteRange(sourceFile, {
|
|
34862
|
-
pos: start4,
|
|
34863
|
-
end: oldProperty.end
|
|
34864
|
-
});
|
|
34865
|
-
changeTracker.insertNodeAt(sourceFile, start4, propertyDeclaration);
|
|
34866
|
-
} else {
|
|
34867
|
-
changeTracker.insertNodeAt(sourceFile, insertLocation, propertyDeclaration, { suffix: "\n" });
|
|
34868
|
-
}
|
|
34869
|
-
}
|
|
34870
|
-
});
|
|
34871
|
-
var parse5 = fn2("writeTagClassAccessors.parse")(function* (node) {
|
|
34872
|
-
const ts = yield* service2(TypeScriptApi);
|
|
34873
|
-
const typeChecker = yield* service2(TypeCheckerApi);
|
|
34874
|
-
const typeParser = yield* service2(TypeParser);
|
|
34875
|
-
const typeCheckerUtils = yield* service2(TypeCheckerUtils);
|
|
34876
|
-
if (!ts.isClassDeclaration(node)) return yield* fail18("not a class declaration");
|
|
34877
|
-
const { Service, accessors: accessors2, className } = yield* pipe(
|
|
34878
|
-
typeParser.extendsEffectService(node),
|
|
34879
|
-
orElse14(() => map34(typeParser.extendsEffectTag(node), (_) => ({ accessors: true, ..._ }))),
|
|
34880
|
-
orElse14(() => fail18("not a class extending Effect.Service call"))
|
|
34881
|
-
);
|
|
34882
|
-
if (accessors2 !== true) return yield* fail18("accessors are not enabled in the Effect.Service call");
|
|
34883
|
-
const involvedMembers = [];
|
|
34884
|
-
const nonPrimitiveServices = typeCheckerUtils.unrollUnionMembers(Service).filter(
|
|
34885
|
-
(_) => !(_.flags & ts.TypeFlags.Number || _.flags & ts.TypeFlags.String || _.flags & ts.TypeFlags.Boolean || _.flags & ts.TypeFlags.Literal)
|
|
34886
|
-
);
|
|
34887
|
-
if (nonPrimitiveServices.length === 0) return yield* fail18("Service type is a primitive type");
|
|
34888
|
-
for (const serviceShape of nonPrimitiveServices) {
|
|
34889
|
-
for (const property of typeChecker.getPropertiesOfType(serviceShape)) {
|
|
34890
|
-
const propertyType = typeChecker.getTypeOfSymbolAtLocation(property, node);
|
|
34891
|
-
const callSignatures = typeChecker.getSignaturesOfType(propertyType, ts.SignatureKind.Call);
|
|
34892
|
-
if (callSignatures.length > 0) {
|
|
34893
|
-
const withTypeParameters = callSignatures.filter((_) => _.typeParameters && _.typeParameters.length > 0);
|
|
34894
|
-
if (callSignatures.length > 1 || withTypeParameters.length > 0) involvedMembers.push({ property, propertyType });
|
|
34895
|
-
}
|
|
34896
|
-
}
|
|
34897
|
-
}
|
|
34898
|
-
const hash2 = involvedMembers.map(({ property, propertyType }) => {
|
|
34899
|
-
return ts.symbolName(property) + ": " + typeChecker.typeToString(propertyType);
|
|
34900
|
-
}).concat([ts.idText(className)]).join("\n");
|
|
34901
|
-
return { Service, className, atLocation: node, hash: cyrb53(hash2), involvedMembers };
|
|
34902
|
-
});
|
|
34903
|
-
var writeTagClassAccessors = createRefactor({
|
|
34904
|
-
name: "writeTagClassAccessors",
|
|
34905
|
-
description: "Implement accessors methods with generics or multiple signatures",
|
|
34906
|
-
apply: fn2("writeTagClassAccessors.apply")(function* (sourceFile, textRange) {
|
|
34907
|
-
const ts = yield* service2(TypeScriptApi);
|
|
34908
|
-
const tsUtils = yield* service2(TypeScriptUtils);
|
|
34909
|
-
const typeChecker = yield* service2(TypeCheckerApi);
|
|
34910
|
-
const typeParser = yield* service2(TypeParser);
|
|
34911
|
-
const parseNode = (node) => pipe(
|
|
34912
|
-
parse5(node),
|
|
34913
|
-
map34(({ Service, atLocation, className, involvedMembers }) => ({
|
|
34914
|
-
kind: "refactor.rewrite.effect.writeTagClassAccessors",
|
|
34915
|
-
description: "Implement Service accessors",
|
|
34916
|
-
apply: pipe(
|
|
34917
|
-
generate(sourceFile, Service, className, atLocation, involvedMembers),
|
|
34918
|
-
provideService7(TypeScriptUtils, tsUtils),
|
|
34919
|
-
provideService7(TypeParser, typeParser),
|
|
34920
|
-
provideService7(TypeCheckerApi, typeChecker),
|
|
34921
|
-
provideService7(TypeScriptApi, ts)
|
|
34922
|
-
)
|
|
34923
|
-
}))
|
|
34924
|
-
);
|
|
34925
|
-
const parentNodes = tsUtils.getAncestorNodesInRange(sourceFile, textRange);
|
|
34926
|
-
return yield* pipe(
|
|
34927
|
-
firstSuccessOf2(parentNodes.map(parseNode)),
|
|
34928
|
-
orElse14(() => fail18(new RefactorNotApplicableError()))
|
|
34929
|
-
);
|
|
34930
|
-
})
|
|
34931
|
-
});
|
|
34932
|
-
|
|
34933
|
-
// src/codegens/accessors.ts
|
|
34934
|
-
var accessors = createCodegen({
|
|
34935
|
-
name: "accessors",
|
|
34936
|
-
apply: fn2("accessors.apply")(function* (sourceFile, textRange) {
|
|
34937
|
-
const ts = yield* service2(TypeScriptApi);
|
|
34938
|
-
const tsUtils = yield* service2(TypeScriptUtils);
|
|
34939
|
-
const typeChecker = yield* service2(TypeCheckerApi);
|
|
34940
|
-
const typeParser = yield* service2(TypeParser);
|
|
34941
|
-
const typeCheckerUtils = yield* service2(TypeCheckerUtils);
|
|
34942
|
-
const nodeAndCommentRange = tsUtils.findNodeWithLeadingCommentAtPosition(sourceFile, textRange.pos);
|
|
34943
|
-
if (!nodeAndCommentRange) return yield* fail18(new CodegenNotApplicableError("no node and comment range"));
|
|
34944
|
-
return yield* pipe(
|
|
34945
|
-
parse5(nodeAndCommentRange.node),
|
|
34946
|
-
map34(
|
|
34947
|
-
(_) => ({
|
|
34948
|
-
hash: _.hash,
|
|
34949
|
-
description: "Generate accessors for the service",
|
|
34950
|
-
apply: pipe(
|
|
34951
|
-
generate(sourceFile, _.Service, _.className, _.atLocation, _.involvedMembers),
|
|
34952
|
-
provideService7(TypeScriptApi, ts),
|
|
34953
|
-
provideService7(TypeScriptUtils, tsUtils),
|
|
34954
|
-
provideService7(TypeCheckerApi, typeChecker),
|
|
34955
|
-
provideService7(TypeParser, typeParser),
|
|
34956
|
-
provideService7(TypeCheckerUtils, typeCheckerUtils)
|
|
34957
|
-
)
|
|
34958
|
-
})
|
|
34959
|
-
),
|
|
34960
|
-
orElse14((cause2) => fail18(new CodegenNotApplicableError(cause2)))
|
|
34961
|
-
);
|
|
34962
|
-
})
|
|
34963
|
-
});
|
|
34964
|
-
|
|
34965
|
-
// src/codegens.ts
|
|
34966
|
-
var codegens = [accessors];
|
|
34967
|
-
|
|
34968
35276
|
// src/diagnostics/outdatedEffectCodegen.ts
|
|
34969
35277
|
var outdatedEffectCodegen = createDiagnostic({
|
|
34970
35278
|
name: "outdatedEffectCodegen",
|
|
@@ -34972,23 +35280,23 @@ var outdatedEffectCodegen = createDiagnostic({
|
|
|
34972
35280
|
severity: "warning",
|
|
34973
35281
|
apply: fn2("outdatedEffectCodegen.apply")(function* (sourceFile, _report) {
|
|
34974
35282
|
const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
|
|
34975
|
-
for (const { codegen, hash: hash2, range: range3 } of codegensWithRanges) {
|
|
35283
|
+
for (const { codegen: codegen2, hash: hash2, range: range3 } of codegensWithRanges) {
|
|
34976
35284
|
yield* pipe(
|
|
34977
|
-
getEditsForCodegen([
|
|
35285
|
+
getEditsForCodegen([codegen2], sourceFile, range3),
|
|
34978
35286
|
map34((applicable) => {
|
|
34979
35287
|
if (applicable.hash !== hash2) {
|
|
34980
35288
|
_report({
|
|
34981
35289
|
location: range3,
|
|
34982
|
-
messageText: `Codegen ${
|
|
35290
|
+
messageText: `Codegen ${codegen2.name} result is outdated`,
|
|
34983
35291
|
fixes: [
|
|
34984
35292
|
{
|
|
34985
35293
|
fixName: "outdatedEffectCodegen_fix",
|
|
34986
|
-
description: `Re-run ${
|
|
35294
|
+
description: `Re-run ${codegen2.name}`,
|
|
34987
35295
|
apply: applicable.apply
|
|
34988
35296
|
},
|
|
34989
35297
|
{
|
|
34990
35298
|
fixName: "outdatedEffectCodegen_ignore",
|
|
34991
|
-
description: `Ignore this ${
|
|
35299
|
+
description: `Ignore this ${codegen2.name} update`,
|
|
34992
35300
|
apply: applicable.ignore
|
|
34993
35301
|
}
|
|
34994
35302
|
]
|
|
@@ -34999,7 +35307,7 @@ var outdatedEffectCodegen = createDiagnostic({
|
|
|
34999
35307
|
(e) => sync11(() => {
|
|
35000
35308
|
_report({
|
|
35001
35309
|
location: range3,
|
|
35002
|
-
messageText: `Codegen ${
|
|
35310
|
+
messageText: `Codegen ${codegen2.name} is not applicable here: ${e.cause}`,
|
|
35003
35311
|
fixes: []
|
|
35004
35312
|
});
|
|
35005
35313
|
})
|
|
@@ -35695,6 +36003,66 @@ var unnecessaryEffectGen = createDiagnostic({
|
|
|
35695
36003
|
})
|
|
35696
36004
|
});
|
|
35697
36005
|
|
|
36006
|
+
// src/diagnostics/unnecessaryFailYieldableError.ts
|
|
36007
|
+
var unnecessaryFailYieldableError = createDiagnostic({
|
|
36008
|
+
name: "unnecessaryFailYieldableError",
|
|
36009
|
+
code: 29,
|
|
36010
|
+
severity: "suggestion",
|
|
36011
|
+
apply: fn2("unnecessaryFailYieldableError.apply")(function* (sourceFile, report) {
|
|
36012
|
+
const ts = yield* service2(TypeScriptApi);
|
|
36013
|
+
const typeParser = yield* service2(TypeParser);
|
|
36014
|
+
const typeChecker = yield* service2(TypeCheckerApi);
|
|
36015
|
+
const yieldableErrorTypes = yield* pipe(
|
|
36016
|
+
typeParser.effectCauseYieldableErrorTypes(sourceFile),
|
|
36017
|
+
orElse14(() => succeed17([]))
|
|
36018
|
+
);
|
|
36019
|
+
const nodeToVisit = [];
|
|
36020
|
+
const appendNodeToVisit = (node) => {
|
|
36021
|
+
nodeToVisit.push(node);
|
|
36022
|
+
return void 0;
|
|
36023
|
+
};
|
|
36024
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
36025
|
+
while (nodeToVisit.length > 0) {
|
|
36026
|
+
const node = nodeToVisit.shift();
|
|
36027
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
36028
|
+
if (ts.isYieldExpression(node) && node.asteriskToken && node.expression && ts.isCallExpression(node.expression)) {
|
|
36029
|
+
const callExpression = node.expression;
|
|
36030
|
+
yield* pipe(
|
|
36031
|
+
typeParser.isNodeReferenceToEffectModuleApi("fail")(callExpression.expression),
|
|
36032
|
+
map34(() => {
|
|
36033
|
+
if (callExpression.arguments.length > 0) {
|
|
36034
|
+
const failArgument = callExpression.arguments[0];
|
|
36035
|
+
const argumentType = typeChecker.getTypeAtLocation(failArgument);
|
|
36036
|
+
const isYieldableError = yieldableErrorTypes.some(
|
|
36037
|
+
(yieldableType) => typeChecker.isTypeAssignableTo(argumentType, yieldableType)
|
|
36038
|
+
);
|
|
36039
|
+
if (isYieldableError) {
|
|
36040
|
+
report({
|
|
36041
|
+
location: node,
|
|
36042
|
+
messageText: `This Effect.fail call uses a yieldable error type as argument. You can yield* the error directly instead.`,
|
|
36043
|
+
fixes: [{
|
|
36044
|
+
fixName: "unnecessaryFailYieldableError_fix",
|
|
36045
|
+
description: "Replace yield* Effect.fail with yield*",
|
|
36046
|
+
apply: gen3(function* () {
|
|
36047
|
+
const changeTracker = yield* service2(ChangeTracker);
|
|
36048
|
+
changeTracker.replaceNode(
|
|
36049
|
+
sourceFile,
|
|
36050
|
+
callExpression,
|
|
36051
|
+
failArgument
|
|
36052
|
+
);
|
|
36053
|
+
})
|
|
36054
|
+
}]
|
|
36055
|
+
});
|
|
36056
|
+
}
|
|
36057
|
+
}
|
|
36058
|
+
}),
|
|
36059
|
+
ignore3
|
|
36060
|
+
);
|
|
36061
|
+
}
|
|
36062
|
+
}
|
|
36063
|
+
})
|
|
36064
|
+
});
|
|
36065
|
+
|
|
35698
36066
|
// src/diagnostics/unnecessaryPipe.ts
|
|
35699
36067
|
var unnecessaryPipe = createDiagnostic({
|
|
35700
36068
|
name: "unnecessaryPipe",
|
|
@@ -35882,6 +36250,7 @@ var diagnostics = [
|
|
|
35882
36250
|
floatingEffect,
|
|
35883
36251
|
missingStarInYieldEffectGen,
|
|
35884
36252
|
unnecessaryEffectGen,
|
|
36253
|
+
unnecessaryFailYieldableError,
|
|
35885
36254
|
missingReturnYieldStar,
|
|
35886
36255
|
leakingRequirements,
|
|
35887
36256
|
unnecessaryPipe,
|
|
@@ -35912,58 +36281,37 @@ var NoFilesToCheckError = class extends TaggedError("NoFilesToCheckError") {
|
|
|
35912
36281
|
return "No files to check. Please provide an existing .ts file or a project tsconfig.json";
|
|
35913
36282
|
}
|
|
35914
36283
|
};
|
|
35915
|
-
var
|
|
36284
|
+
var file5 = file3("file").pipe(
|
|
35916
36285
|
optional4,
|
|
35917
36286
|
withDescription3("The full path of the file to check for diagnostics.")
|
|
35918
36287
|
);
|
|
35919
|
-
var
|
|
36288
|
+
var project3 = file3("project").pipe(
|
|
35920
36289
|
optional4,
|
|
35921
36290
|
withDescription3("The full path of the project tsconfig.json file to check for diagnostics.")
|
|
35922
36291
|
);
|
|
35923
|
-
var
|
|
35924
|
-
return (hasProperty(compilerOptions, "plugins") && isArray(compilerOptions.plugins) ? compilerOptions.plugins : []).find((_) => hasProperty(_, "name") && _.name === "@effect/language-service");
|
|
35925
|
-
};
|
|
35926
|
-
var BATCH_SIZE = 50;
|
|
36292
|
+
var BATCH_SIZE2 = 50;
|
|
35927
36293
|
var diagnostics2 = make58(
|
|
35928
36294
|
"diagnostics",
|
|
35929
|
-
{ file:
|
|
35930
|
-
fn("diagnostics")(function* ({ file:
|
|
36295
|
+
{ file: file5, project: project3 },
|
|
36296
|
+
fn("diagnostics")(function* ({ file: file6, project: project4 }) {
|
|
35931
36297
|
const path2 = yield* Path2;
|
|
35932
36298
|
const tsInstance = yield* getTypeScript;
|
|
35933
|
-
|
|
36299
|
+
let filesToCheck = /* @__PURE__ */ new Set();
|
|
35934
36300
|
let checkedFilesCount = 0;
|
|
35935
36301
|
let errorsCount = 0;
|
|
35936
36302
|
let warningsCount = 0;
|
|
35937
36303
|
let messagesCount = 0;
|
|
35938
|
-
if (isSome2(
|
|
35939
|
-
filesToCheck
|
|
35940
|
-
}
|
|
35941
|
-
if (isSome2(
|
|
35942
|
-
|
|
35943
|
-
while (tsconfigToHandle.length > 0) {
|
|
35944
|
-
const tsconfigPath = tsconfigToHandle.shift();
|
|
35945
|
-
const tsconfigAbsolutePath = path2.resolve(tsconfigPath);
|
|
35946
|
-
const configFile = tsInstance.readConfigFile(tsconfigAbsolutePath, tsInstance.sys.readFile);
|
|
35947
|
-
if (configFile.error) {
|
|
35948
|
-
if (!tsconfigAbsolutePath.endsWith("tsconfig.json")) {
|
|
35949
|
-
tsconfigToHandle = [...tsconfigToHandle, path2.resolve(tsconfigPath, "tsconfig.json")];
|
|
35950
|
-
}
|
|
35951
|
-
continue;
|
|
35952
|
-
}
|
|
35953
|
-
const parsedConfig = tsInstance.parseJsonConfigFileContent(
|
|
35954
|
-
configFile.config,
|
|
35955
|
-
tsInstance.sys,
|
|
35956
|
-
path2.dirname(tsconfigAbsolutePath)
|
|
35957
|
-
);
|
|
35958
|
-
tsconfigToHandle = [...tsconfigToHandle, ...parsedConfig.projectReferences?.map((_) => _.path) ?? []];
|
|
35959
|
-
parsedConfig.fileNames.forEach((_) => filesToCheck.add(_));
|
|
35960
|
-
}
|
|
36304
|
+
if (isSome2(project4)) {
|
|
36305
|
+
filesToCheck = yield* getFileNamesInTsConfig(project4.value);
|
|
36306
|
+
}
|
|
36307
|
+
if (isSome2(file6)) {
|
|
36308
|
+
filesToCheck.add(path2.resolve(file6.value));
|
|
35961
36309
|
}
|
|
35962
36310
|
if (filesToCheck.size === 0) {
|
|
35963
36311
|
return yield* new NoFilesToCheckError();
|
|
35964
36312
|
}
|
|
35965
36313
|
const filesToCheckArray = fromIterable(filesToCheck);
|
|
35966
|
-
const batches = chunksOf(filesToCheckArray,
|
|
36314
|
+
const batches = chunksOf(filesToCheckArray, BATCH_SIZE2);
|
|
35967
36315
|
let lastLanguageService;
|
|
35968
36316
|
const disposeIfLanguageServiceChanged = (languageService) => {
|
|
35969
36317
|
if (lastLanguageService !== languageService) {
|
|
@@ -35972,14 +36320,14 @@ var diagnostics2 = make58(
|
|
|
35972
36320
|
}
|
|
35973
36321
|
};
|
|
35974
36322
|
for (const batch of batches) {
|
|
35975
|
-
const { service: service3 } = (0,
|
|
36323
|
+
const { service: service3 } = (0, import_project_service2.createProjectService)({ options: { loadTypeScriptPlugins: false } });
|
|
35976
36324
|
for (const filePath of batch) {
|
|
35977
36325
|
service3.openClientFile(filePath);
|
|
35978
36326
|
try {
|
|
35979
36327
|
const scriptInfo = service3.getScriptInfo(filePath);
|
|
35980
36328
|
if (!scriptInfo) continue;
|
|
35981
|
-
const
|
|
35982
|
-
const languageService =
|
|
36329
|
+
const project5 = scriptInfo.getDefaultProject();
|
|
36330
|
+
const languageService = project5.getLanguageService(true);
|
|
35983
36331
|
disposeIfLanguageServiceChanged(languageService);
|
|
35984
36332
|
const program = languageService.getProgram();
|
|
35985
36333
|
if (!program) continue;
|
|
@@ -36070,7 +36418,7 @@ var getPatchesForModule = fn("getPatchesForModule")(
|
|
|
36070
36418
|
let insertCheckSourceFilePosition = none2();
|
|
36071
36419
|
let insertSkipPrecedingCommentDirectivePosition = none2();
|
|
36072
36420
|
let insertAppendMetadataRelationErrorPosition = none2();
|
|
36073
|
-
|
|
36421
|
+
let nodesToCheck = [];
|
|
36074
36422
|
function findNodeAtPositionIncludingTrivia(sourceFile2, position) {
|
|
36075
36423
|
function find3(node) {
|
|
36076
36424
|
if (position >= node.pos && position < node.end) {
|
|
@@ -36098,7 +36446,7 @@ var getPatchesForModule = fn("getPatchesForModule")(
|
|
|
36098
36446
|
if (!pushFunctionDeclarationNode("checkSourceFileWorker")) requiresFullScan = true;
|
|
36099
36447
|
if (!pushFunctionDeclarationNode("markPrecedingCommentDirectiveLine")) requiresFullScan = true;
|
|
36100
36448
|
if (!pushFunctionDeclarationNode("reportRelationError")) requiresFullScan = true;
|
|
36101
|
-
if (requiresFullScan) nodesToCheck
|
|
36449
|
+
if (requiresFullScan) nodesToCheck = [sourceFile];
|
|
36102
36450
|
while (nodesToCheck.length > 0) {
|
|
36103
36451
|
const node = nodesToCheck.shift();
|
|
36104
36452
|
if (!node) continue;
|
|
@@ -36328,7 +36676,7 @@ var cliCommand = make58(
|
|
|
36328
36676
|
"effect-language-service",
|
|
36329
36677
|
{},
|
|
36330
36678
|
() => log3("Please select a command or run --help.")
|
|
36331
|
-
).pipe(withSubcommands3([patch9, unpatch, check2, diagnostics2]));
|
|
36679
|
+
).pipe(withSubcommands3([patch9, unpatch, check2, diagnostics2, codegen]));
|
|
36332
36680
|
var main = run8(cliCommand, {
|
|
36333
36681
|
name: "effect-language-service",
|
|
36334
36682
|
version: "0.0.2"
|