@effect/language-service 0.55.5 → 0.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/cli.js +517 -361
- package/cli.js.map +1 -1
- package/package.json +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 {
|
|
@@ -33063,6 +33091,449 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
33063
33091
|
};
|
|
33064
33092
|
}
|
|
33065
33093
|
|
|
33094
|
+
// src/refactors/writeTagClassAccessors.ts
|
|
33095
|
+
var generate = fn2("writeTagClassAccessors.generate")(function* (sourceFile, service3, className, atLocation, involvedMembers) {
|
|
33096
|
+
const ts = yield* service2(TypeScriptApi);
|
|
33097
|
+
const tsUtils = yield* service2(TypeScriptUtils);
|
|
33098
|
+
const typeChecker = yield* service2(TypeCheckerApi);
|
|
33099
|
+
const typeParser = yield* service2(TypeParser);
|
|
33100
|
+
const changeTracker = yield* service2(ChangeTracker);
|
|
33101
|
+
const insertLocation = atLocation.members.length > 0 ? atLocation.members[0].pos : atLocation.end - 1;
|
|
33102
|
+
const effectIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
33103
|
+
sourceFile,
|
|
33104
|
+
"effect",
|
|
33105
|
+
"Effect"
|
|
33106
|
+
) || "Effect";
|
|
33107
|
+
const createFunctionProperty = (className2, propertyName, type2, forceAny) => {
|
|
33108
|
+
const arrowBody = ts.factory.createCallExpression(
|
|
33109
|
+
ts.factory.createPropertyAccessExpression(
|
|
33110
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
33111
|
+
"andThen"
|
|
33112
|
+
),
|
|
33113
|
+
void 0,
|
|
33114
|
+
[
|
|
33115
|
+
ts.factory.createIdentifier(ts.idText(className2)),
|
|
33116
|
+
ts.factory.createArrowFunction(
|
|
33117
|
+
void 0,
|
|
33118
|
+
void 0,
|
|
33119
|
+
[ts.factory.createParameterDeclaration(
|
|
33120
|
+
void 0,
|
|
33121
|
+
void 0,
|
|
33122
|
+
"_",
|
|
33123
|
+
void 0,
|
|
33124
|
+
forceAny ? ts.factory.createTypeReferenceNode("any") : void 0
|
|
33125
|
+
)],
|
|
33126
|
+
void 0,
|
|
33127
|
+
void 0,
|
|
33128
|
+
ts.factory.createCallExpression(
|
|
33129
|
+
ts.factory.createPropertyAccessExpression(
|
|
33130
|
+
ts.factory.createIdentifier("_"),
|
|
33131
|
+
propertyName
|
|
33132
|
+
),
|
|
33133
|
+
void 0,
|
|
33134
|
+
[
|
|
33135
|
+
ts.factory.createSpreadElement(ts.factory.createIdentifier("args"))
|
|
33136
|
+
]
|
|
33137
|
+
)
|
|
33138
|
+
)
|
|
33139
|
+
]
|
|
33140
|
+
);
|
|
33141
|
+
return ts.factory.createPropertyDeclaration(
|
|
33142
|
+
[
|
|
33143
|
+
ts.factory.createModifier(ts.SyntaxKind.StaticKeyword),
|
|
33144
|
+
ts.factory.createModifier(ts.SyntaxKind.OverrideKeyword)
|
|
33145
|
+
],
|
|
33146
|
+
propertyName,
|
|
33147
|
+
void 0,
|
|
33148
|
+
type2,
|
|
33149
|
+
ts.factory.createArrowFunction(
|
|
33150
|
+
void 0,
|
|
33151
|
+
void 0,
|
|
33152
|
+
[ts.factory.createParameterDeclaration(
|
|
33153
|
+
void 0,
|
|
33154
|
+
ts.factory.createToken(ts.SyntaxKind.DotDotDotToken),
|
|
33155
|
+
"args",
|
|
33156
|
+
void 0,
|
|
33157
|
+
forceAny ? ts.factory.createArrayTypeNode(ts.factory.createTypeReferenceNode("any")) : void 0
|
|
33158
|
+
)],
|
|
33159
|
+
void 0,
|
|
33160
|
+
void 0,
|
|
33161
|
+
forceAny ? ts.factory.createAsExpression(arrowBody, ts.factory.createTypeReferenceNode("any")) : arrowBody
|
|
33162
|
+
)
|
|
33163
|
+
);
|
|
33164
|
+
};
|
|
33165
|
+
const generateReturnType = (type2, atLocation2, className2) => pipe(
|
|
33166
|
+
typeParser.effectType(type2, atLocation2),
|
|
33167
|
+
flatMap18((returnedEffect) => {
|
|
33168
|
+
const contextType = returnedEffect.R.flags & ts.TypeFlags.Never ? ts.factory.createTypeReferenceNode(ts.idText(className2)) : ts.factory.createUnionTypeNode(
|
|
33169
|
+
[
|
|
33170
|
+
ts.factory.createTypeReferenceNode(ts.idText(className2)),
|
|
33171
|
+
typeChecker.typeToTypeNode(returnedEffect.R, atLocation2, ts.NodeBuilderFlags.NoTruncation)
|
|
33172
|
+
]
|
|
33173
|
+
);
|
|
33174
|
+
const successType = typeChecker.typeToTypeNode(
|
|
33175
|
+
returnedEffect.A,
|
|
33176
|
+
atLocation2,
|
|
33177
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
33178
|
+
);
|
|
33179
|
+
if (!successType) return fail18("error generating success type");
|
|
33180
|
+
const failureType = typeChecker.typeToTypeNode(
|
|
33181
|
+
returnedEffect.E,
|
|
33182
|
+
atLocation2,
|
|
33183
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
33184
|
+
);
|
|
33185
|
+
if (!failureType) return fail18("error generating failure type");
|
|
33186
|
+
const typeNode = ts.factory.createTypeReferenceNode(
|
|
33187
|
+
ts.factory.createQualifiedName(
|
|
33188
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
33189
|
+
ts.factory.createIdentifier("Effect")
|
|
33190
|
+
),
|
|
33191
|
+
[successType, failureType, contextType]
|
|
33192
|
+
);
|
|
33193
|
+
return succeed17(typeNode);
|
|
33194
|
+
}),
|
|
33195
|
+
orElse14(
|
|
33196
|
+
() => pipe(
|
|
33197
|
+
typeParser.promiseLike(type2, atLocation2),
|
|
33198
|
+
flatMap18(({ type: type3 }) => {
|
|
33199
|
+
const successType = typeChecker.typeToTypeNode(
|
|
33200
|
+
type3,
|
|
33201
|
+
atLocation2,
|
|
33202
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
33203
|
+
);
|
|
33204
|
+
if (!successType) return fail18("error generating success type");
|
|
33205
|
+
return succeed17(ts.factory.createTypeReferenceNode(
|
|
33206
|
+
ts.factory.createQualifiedName(
|
|
33207
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
33208
|
+
ts.factory.createIdentifier("Effect")
|
|
33209
|
+
),
|
|
33210
|
+
[
|
|
33211
|
+
successType,
|
|
33212
|
+
ts.factory.createTypeReferenceNode(
|
|
33213
|
+
ts.factory.createQualifiedName(
|
|
33214
|
+
ts.factory.createIdentifier("Cause"),
|
|
33215
|
+
ts.factory.createIdentifier("UnknownException")
|
|
33216
|
+
)
|
|
33217
|
+
),
|
|
33218
|
+
ts.factory.createTypeReferenceNode(ts.idText(className2))
|
|
33219
|
+
]
|
|
33220
|
+
));
|
|
33221
|
+
})
|
|
33222
|
+
)
|
|
33223
|
+
),
|
|
33224
|
+
orElse14(() => {
|
|
33225
|
+
const successType = typeChecker.typeToTypeNode(type2, atLocation2, ts.NodeBuilderFlags.NoTruncation);
|
|
33226
|
+
if (!successType) return fail18("error generating success type");
|
|
33227
|
+
const typeNode = ts.factory.createTypeReferenceNode(
|
|
33228
|
+
ts.factory.createQualifiedName(
|
|
33229
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
33230
|
+
ts.factory.createIdentifier("Effect")
|
|
33231
|
+
),
|
|
33232
|
+
[
|
|
33233
|
+
successType,
|
|
33234
|
+
ts.factory.createTypeReferenceNode("never"),
|
|
33235
|
+
ts.factory.createTypeReferenceNode(ts.idText(className2))
|
|
33236
|
+
]
|
|
33237
|
+
);
|
|
33238
|
+
return succeed17(typeNode);
|
|
33239
|
+
})
|
|
33240
|
+
);
|
|
33241
|
+
const proxySignature = (signature, atLocation2, className2) => gen3(function* () {
|
|
33242
|
+
const signatureDeclaration = typeChecker.signatureToSignatureDeclaration(
|
|
33243
|
+
signature,
|
|
33244
|
+
ts.SyntaxKind.FunctionType,
|
|
33245
|
+
atLocation2,
|
|
33246
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
33247
|
+
);
|
|
33248
|
+
if (!signatureDeclaration) return yield* fail18("error generating signature");
|
|
33249
|
+
const returnType = yield* generateReturnType(
|
|
33250
|
+
typeChecker.getReturnTypeOfSignature(signature),
|
|
33251
|
+
atLocation2,
|
|
33252
|
+
className2
|
|
33253
|
+
);
|
|
33254
|
+
return ts.factory.createFunctionTypeNode(
|
|
33255
|
+
signatureDeclaration.typeParameters,
|
|
33256
|
+
signatureDeclaration.parameters,
|
|
33257
|
+
returnType
|
|
33258
|
+
);
|
|
33259
|
+
});
|
|
33260
|
+
for (const { property, propertyType } of involvedMembers) {
|
|
33261
|
+
const callSignatures = [];
|
|
33262
|
+
let propertyDeclaration = void 0;
|
|
33263
|
+
for (const signature of typeChecker.getSignaturesOfType(propertyType, ts.SignatureKind.Call)) {
|
|
33264
|
+
yield* pipe(
|
|
33265
|
+
proxySignature(signature, atLocation, className),
|
|
33266
|
+
map34((sig) => {
|
|
33267
|
+
callSignatures.push(sig);
|
|
33268
|
+
}),
|
|
33269
|
+
ignore3
|
|
33270
|
+
);
|
|
33271
|
+
}
|
|
33272
|
+
const allSignatures = ts.factory.createIntersectionTypeNode(callSignatures);
|
|
33273
|
+
const type2 = tsUtils.simplifyTypeNode(allSignatures);
|
|
33274
|
+
propertyDeclaration = createFunctionProperty(className, ts.symbolName(property), type2, callSignatures.length > 1);
|
|
33275
|
+
const oldProperty = atLocation.members.filter(ts.isPropertyDeclaration).find((p2) => {
|
|
33276
|
+
const symbol3 = typeChecker.getSymbolAtLocation(p2.name);
|
|
33277
|
+
return symbol3 && ts.symbolName(symbol3) === ts.symbolName(property);
|
|
33278
|
+
});
|
|
33279
|
+
if (oldProperty) {
|
|
33280
|
+
const start4 = ts.getTokenPosOfNode(oldProperty, sourceFile);
|
|
33281
|
+
changeTracker.deleteRange(sourceFile, {
|
|
33282
|
+
pos: start4,
|
|
33283
|
+
end: oldProperty.end
|
|
33284
|
+
});
|
|
33285
|
+
changeTracker.insertNodeAt(sourceFile, start4, propertyDeclaration);
|
|
33286
|
+
} else {
|
|
33287
|
+
changeTracker.insertNodeAt(sourceFile, insertLocation, propertyDeclaration, { suffix: "\n" });
|
|
33288
|
+
}
|
|
33289
|
+
}
|
|
33290
|
+
});
|
|
33291
|
+
var parse5 = fn2("writeTagClassAccessors.parse")(function* (node) {
|
|
33292
|
+
const ts = yield* service2(TypeScriptApi);
|
|
33293
|
+
const typeChecker = yield* service2(TypeCheckerApi);
|
|
33294
|
+
const typeParser = yield* service2(TypeParser);
|
|
33295
|
+
const typeCheckerUtils = yield* service2(TypeCheckerUtils);
|
|
33296
|
+
if (!ts.isClassDeclaration(node)) return yield* fail18("not a class declaration");
|
|
33297
|
+
const { Service, accessors: accessors2, className } = yield* pipe(
|
|
33298
|
+
typeParser.extendsEffectService(node),
|
|
33299
|
+
orElse14(() => map34(typeParser.extendsEffectTag(node), (_) => ({ accessors: true, ..._ }))),
|
|
33300
|
+
orElse14(() => fail18("not a class extending Effect.Service call"))
|
|
33301
|
+
);
|
|
33302
|
+
if (accessors2 !== true) return yield* fail18("accessors are not enabled in the Effect.Service call");
|
|
33303
|
+
const involvedMembers = [];
|
|
33304
|
+
const nonPrimitiveServices = typeCheckerUtils.unrollUnionMembers(Service).filter(
|
|
33305
|
+
(_) => !(_.flags & ts.TypeFlags.Number || _.flags & ts.TypeFlags.String || _.flags & ts.TypeFlags.Boolean || _.flags & ts.TypeFlags.Literal)
|
|
33306
|
+
);
|
|
33307
|
+
if (nonPrimitiveServices.length === 0) return yield* fail18("Service type is a primitive type");
|
|
33308
|
+
for (const serviceShape of nonPrimitiveServices) {
|
|
33309
|
+
for (const property of typeChecker.getPropertiesOfType(serviceShape)) {
|
|
33310
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(property, node);
|
|
33311
|
+
const callSignatures = typeChecker.getSignaturesOfType(propertyType, ts.SignatureKind.Call);
|
|
33312
|
+
if (callSignatures.length > 0) {
|
|
33313
|
+
const withTypeParameters = callSignatures.filter((_) => _.typeParameters && _.typeParameters.length > 0);
|
|
33314
|
+
if (callSignatures.length > 1 || withTypeParameters.length > 0) involvedMembers.push({ property, propertyType });
|
|
33315
|
+
}
|
|
33316
|
+
}
|
|
33317
|
+
}
|
|
33318
|
+
const hash2 = involvedMembers.map(({ property, propertyType }) => {
|
|
33319
|
+
return ts.symbolName(property) + ": " + typeChecker.typeToString(propertyType);
|
|
33320
|
+
}).concat([ts.idText(className)]).join("\n");
|
|
33321
|
+
return { Service, className, atLocation: node, hash: cyrb53(hash2), involvedMembers };
|
|
33322
|
+
});
|
|
33323
|
+
var writeTagClassAccessors = createRefactor({
|
|
33324
|
+
name: "writeTagClassAccessors",
|
|
33325
|
+
description: "Implement accessors methods with generics or multiple signatures",
|
|
33326
|
+
apply: fn2("writeTagClassAccessors.apply")(function* (sourceFile, textRange) {
|
|
33327
|
+
const ts = yield* service2(TypeScriptApi);
|
|
33328
|
+
const tsUtils = yield* service2(TypeScriptUtils);
|
|
33329
|
+
const typeChecker = yield* service2(TypeCheckerApi);
|
|
33330
|
+
const typeParser = yield* service2(TypeParser);
|
|
33331
|
+
const parseNode = (node) => pipe(
|
|
33332
|
+
parse5(node),
|
|
33333
|
+
map34(({ Service, atLocation, className, involvedMembers }) => ({
|
|
33334
|
+
kind: "refactor.rewrite.effect.writeTagClassAccessors",
|
|
33335
|
+
description: "Implement Service accessors",
|
|
33336
|
+
apply: pipe(
|
|
33337
|
+
generate(sourceFile, Service, className, atLocation, involvedMembers),
|
|
33338
|
+
provideService7(TypeScriptUtils, tsUtils),
|
|
33339
|
+
provideService7(TypeParser, typeParser),
|
|
33340
|
+
provideService7(TypeCheckerApi, typeChecker),
|
|
33341
|
+
provideService7(TypeScriptApi, ts)
|
|
33342
|
+
)
|
|
33343
|
+
}))
|
|
33344
|
+
);
|
|
33345
|
+
const parentNodes = tsUtils.getAncestorNodesInRange(sourceFile, textRange);
|
|
33346
|
+
return yield* pipe(
|
|
33347
|
+
firstSuccessOf2(parentNodes.map(parseNode)),
|
|
33348
|
+
orElse14(() => fail18(new RefactorNotApplicableError()))
|
|
33349
|
+
);
|
|
33350
|
+
})
|
|
33351
|
+
});
|
|
33352
|
+
|
|
33353
|
+
// src/codegens/accessors.ts
|
|
33354
|
+
var accessors = createCodegen({
|
|
33355
|
+
name: "accessors",
|
|
33356
|
+
apply: fn2("accessors.apply")(function* (sourceFile, textRange) {
|
|
33357
|
+
const ts = yield* service2(TypeScriptApi);
|
|
33358
|
+
const tsUtils = yield* service2(TypeScriptUtils);
|
|
33359
|
+
const typeChecker = yield* service2(TypeCheckerApi);
|
|
33360
|
+
const typeParser = yield* service2(TypeParser);
|
|
33361
|
+
const typeCheckerUtils = yield* service2(TypeCheckerUtils);
|
|
33362
|
+
const nodeAndCommentRange = tsUtils.findNodeWithLeadingCommentAtPosition(sourceFile, textRange.pos);
|
|
33363
|
+
if (!nodeAndCommentRange) return yield* fail18(new CodegenNotApplicableError("no node and comment range"));
|
|
33364
|
+
return yield* pipe(
|
|
33365
|
+
parse5(nodeAndCommentRange.node),
|
|
33366
|
+
map34(
|
|
33367
|
+
(_) => ({
|
|
33368
|
+
hash: _.hash,
|
|
33369
|
+
description: "Generate accessors for the service",
|
|
33370
|
+
apply: pipe(
|
|
33371
|
+
generate(sourceFile, _.Service, _.className, _.atLocation, _.involvedMembers),
|
|
33372
|
+
provideService7(TypeScriptApi, ts),
|
|
33373
|
+
provideService7(TypeScriptUtils, tsUtils),
|
|
33374
|
+
provideService7(TypeCheckerApi, typeChecker),
|
|
33375
|
+
provideService7(TypeParser, typeParser),
|
|
33376
|
+
provideService7(TypeCheckerUtils, typeCheckerUtils)
|
|
33377
|
+
)
|
|
33378
|
+
})
|
|
33379
|
+
),
|
|
33380
|
+
orElse14((cause2) => fail18(new CodegenNotApplicableError(cause2)))
|
|
33381
|
+
);
|
|
33382
|
+
})
|
|
33383
|
+
});
|
|
33384
|
+
|
|
33385
|
+
// src/codegens.ts
|
|
33386
|
+
var codegens = [accessors];
|
|
33387
|
+
|
|
33388
|
+
// src/cli/codegen.ts
|
|
33389
|
+
var NoFilesToCodegenError = class extends TaggedError("NoFilesToCodegenError") {
|
|
33390
|
+
get message() {
|
|
33391
|
+
return "No files to codegen. Please provide an existing .ts file or a project tsconfig.json";
|
|
33392
|
+
}
|
|
33393
|
+
};
|
|
33394
|
+
var file4 = file3("file").pipe(
|
|
33395
|
+
optional4,
|
|
33396
|
+
withDescription3("The full path of the file to codegen.")
|
|
33397
|
+
);
|
|
33398
|
+
var project2 = file3("project").pipe(
|
|
33399
|
+
optional4,
|
|
33400
|
+
withDescription3("The full path of the project tsconfig.json file to codegen.")
|
|
33401
|
+
);
|
|
33402
|
+
var verbose = boolean5("verbose").pipe(
|
|
33403
|
+
withDefault3(false),
|
|
33404
|
+
withDescription3("Verbose output.")
|
|
33405
|
+
);
|
|
33406
|
+
var BATCH_SIZE = 50;
|
|
33407
|
+
var codegen = make58(
|
|
33408
|
+
"codegen",
|
|
33409
|
+
{ file: file4, project: project2, verbose },
|
|
33410
|
+
fn("codegen")(function* ({ file: file6, project: project4, verbose: verbose2 }) {
|
|
33411
|
+
const path2 = yield* Path2;
|
|
33412
|
+
const fs = yield* FileSystem;
|
|
33413
|
+
const tsInstance = yield* getTypeScript;
|
|
33414
|
+
let filesToCodegen = /* @__PURE__ */ new Set();
|
|
33415
|
+
let checkedFilesCount = 0;
|
|
33416
|
+
let updatedFilesCount = 0;
|
|
33417
|
+
if (isSome2(project4)) {
|
|
33418
|
+
filesToCodegen = yield* getFileNamesInTsConfig(project4.value);
|
|
33419
|
+
}
|
|
33420
|
+
if (isSome2(file6)) {
|
|
33421
|
+
filesToCodegen.add(path2.resolve(file6.value));
|
|
33422
|
+
}
|
|
33423
|
+
if (filesToCodegen.size === 0) {
|
|
33424
|
+
return yield* new NoFilesToCodegenError();
|
|
33425
|
+
}
|
|
33426
|
+
const filesWithCodegenDirective = /* @__PURE__ */ new Set();
|
|
33427
|
+
for (const filePath of filesToCodegen) {
|
|
33428
|
+
const sourceText = yield* fs.readFileString(filePath);
|
|
33429
|
+
if (sourceText.toLowerCase().indexOf("@effect-codegens") !== -1) {
|
|
33430
|
+
filesWithCodegenDirective.add(filePath);
|
|
33431
|
+
}
|
|
33432
|
+
}
|
|
33433
|
+
if (filesWithCodegenDirective.size === 0) {
|
|
33434
|
+
return yield* new NoFilesToCodegenError();
|
|
33435
|
+
}
|
|
33436
|
+
const filesToCodegenArray = fromIterable(filesWithCodegenDirective);
|
|
33437
|
+
const batches = chunksOf(filesToCodegenArray, BATCH_SIZE);
|
|
33438
|
+
let lastLanguageService;
|
|
33439
|
+
const disposeIfLanguageServiceChanged = (languageService) => {
|
|
33440
|
+
if (lastLanguageService !== languageService) {
|
|
33441
|
+
lastLanguageService?.dispose();
|
|
33442
|
+
lastLanguageService = languageService;
|
|
33443
|
+
}
|
|
33444
|
+
};
|
|
33445
|
+
for (const batch of batches) {
|
|
33446
|
+
const { service: service3 } = (0, import_project_service.createProjectService)({ options: { loadTypeScriptPlugins: false } });
|
|
33447
|
+
for (const filePath of batch) {
|
|
33448
|
+
service3.openClientFile(filePath);
|
|
33449
|
+
try {
|
|
33450
|
+
const scriptInfo = service3.getScriptInfo(filePath);
|
|
33451
|
+
if (!scriptInfo) continue;
|
|
33452
|
+
const project5 = scriptInfo.getDefaultProject();
|
|
33453
|
+
const languageService = project5.getLanguageService(true);
|
|
33454
|
+
disposeIfLanguageServiceChanged(languageService);
|
|
33455
|
+
const program = languageService.getProgram();
|
|
33456
|
+
if (!program) continue;
|
|
33457
|
+
const sourceFile = program.getSourceFile(filePath);
|
|
33458
|
+
if (!sourceFile) continue;
|
|
33459
|
+
const pluginConfig = extractEffectLspOptions(program.getCompilerOptions());
|
|
33460
|
+
if (!pluginConfig) continue;
|
|
33461
|
+
const formatContext = tsInstance.formatting.getFormatContext(
|
|
33462
|
+
tsInstance.getDefaultFormatCodeSettings(project5.getNewLine()),
|
|
33463
|
+
project5
|
|
33464
|
+
);
|
|
33465
|
+
const allFileChanges = pipe(
|
|
33466
|
+
gen3(function* () {
|
|
33467
|
+
let allChanges = [];
|
|
33468
|
+
const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
|
|
33469
|
+
for (const { codegen: codegen2, hash: hash2, range: range3 } of codegensWithRanges) {
|
|
33470
|
+
const applicable = yield* pipe(
|
|
33471
|
+
getEditsForCodegen([codegen2], sourceFile, range3),
|
|
33472
|
+
orElse14(() => void_8)
|
|
33473
|
+
);
|
|
33474
|
+
if (applicable && applicable.hash !== hash2) {
|
|
33475
|
+
const changes2 = tsInstance.textChanges.ChangeTracker.with(
|
|
33476
|
+
{
|
|
33477
|
+
formatContext,
|
|
33478
|
+
host: project5,
|
|
33479
|
+
preferences: {}
|
|
33480
|
+
},
|
|
33481
|
+
(changeTracker) => pipe(
|
|
33482
|
+
applicable.apply,
|
|
33483
|
+
provideService7(ChangeTracker, changeTracker),
|
|
33484
|
+
run9
|
|
33485
|
+
)
|
|
33486
|
+
);
|
|
33487
|
+
allChanges = [...allChanges, ...changes2];
|
|
33488
|
+
}
|
|
33489
|
+
}
|
|
33490
|
+
return allChanges;
|
|
33491
|
+
}),
|
|
33492
|
+
nanoLayer3,
|
|
33493
|
+
nanoLayer2,
|
|
33494
|
+
nanoLayer,
|
|
33495
|
+
provideService7(TypeCheckerApi, program.getTypeChecker()),
|
|
33496
|
+
provideService7(TypeScriptProgram, program),
|
|
33497
|
+
provideService7(TypeScriptApi, tsInstance),
|
|
33498
|
+
provideService7(
|
|
33499
|
+
LanguageServicePluginOptions,
|
|
33500
|
+
{ ...parse4(pluginConfig), diagnosticsName: false }
|
|
33501
|
+
),
|
|
33502
|
+
run9,
|
|
33503
|
+
getOrElse(() => [])
|
|
33504
|
+
);
|
|
33505
|
+
checkedFilesCount++;
|
|
33506
|
+
const thisFileChanges = allFileChanges.filter((change) => change.fileName === sourceFile.fileName);
|
|
33507
|
+
const flattenedChanges = flatten(thisFileChanges.map((change) => change.textChanges));
|
|
33508
|
+
if (verbose2) {
|
|
33509
|
+
if (flattenedChanges.length > 0) {
|
|
33510
|
+
console.log(`${filePath}: with ${flattenedChanges.length} changes`);
|
|
33511
|
+
} else {
|
|
33512
|
+
console.log(`${filePath}: no changes`);
|
|
33513
|
+
}
|
|
33514
|
+
}
|
|
33515
|
+
if (flattenedChanges.length === 0) continue;
|
|
33516
|
+
const sourceText = yield* fs.readFileString(filePath);
|
|
33517
|
+
const newSourceText = yield* applyTextChanges(sourceText, flattenedChanges);
|
|
33518
|
+
yield* fs.writeFileString(filePath, newSourceText);
|
|
33519
|
+
updatedFilesCount++;
|
|
33520
|
+
} finally {
|
|
33521
|
+
service3.closeClientFile(filePath);
|
|
33522
|
+
}
|
|
33523
|
+
}
|
|
33524
|
+
yield* yieldNow4();
|
|
33525
|
+
}
|
|
33526
|
+
disposeIfLanguageServiceChanged(void 0);
|
|
33527
|
+
console.log(
|
|
33528
|
+
`${filesToCodegen.size} involved files, of which ${filesWithCodegenDirective.size} with codegens.
|
|
33529
|
+
${checkedFilesCount} checked and ${updatedFilesCount} updated.`
|
|
33530
|
+
);
|
|
33531
|
+
})
|
|
33532
|
+
);
|
|
33533
|
+
|
|
33534
|
+
// src/cli/diagnostics.ts
|
|
33535
|
+
var import_project_service2 = __toESM(require_dist2());
|
|
33536
|
+
|
|
33066
33537
|
// src/diagnostics/anyUnknownInErrorContext.ts
|
|
33067
33538
|
var anyUnknownInErrorContext = createDiagnostic({
|
|
33068
33539
|
name: "anyUnknownInErrorContext",
|
|
@@ -34671,300 +35142,6 @@ var nonObjectEffectServiceType = createDiagnostic({
|
|
|
34671
35142
|
})
|
|
34672
35143
|
});
|
|
34673
35144
|
|
|
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
35145
|
// src/diagnostics/outdatedEffectCodegen.ts
|
|
34969
35146
|
var outdatedEffectCodegen = createDiagnostic({
|
|
34970
35147
|
name: "outdatedEffectCodegen",
|
|
@@ -34972,23 +35149,23 @@ var outdatedEffectCodegen = createDiagnostic({
|
|
|
34972
35149
|
severity: "warning",
|
|
34973
35150
|
apply: fn2("outdatedEffectCodegen.apply")(function* (sourceFile, _report) {
|
|
34974
35151
|
const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
|
|
34975
|
-
for (const { codegen, hash: hash2, range: range3 } of codegensWithRanges) {
|
|
35152
|
+
for (const { codegen: codegen2, hash: hash2, range: range3 } of codegensWithRanges) {
|
|
34976
35153
|
yield* pipe(
|
|
34977
|
-
getEditsForCodegen([
|
|
35154
|
+
getEditsForCodegen([codegen2], sourceFile, range3),
|
|
34978
35155
|
map34((applicable) => {
|
|
34979
35156
|
if (applicable.hash !== hash2) {
|
|
34980
35157
|
_report({
|
|
34981
35158
|
location: range3,
|
|
34982
|
-
messageText: `Codegen ${
|
|
35159
|
+
messageText: `Codegen ${codegen2.name} result is outdated`,
|
|
34983
35160
|
fixes: [
|
|
34984
35161
|
{
|
|
34985
35162
|
fixName: "outdatedEffectCodegen_fix",
|
|
34986
|
-
description: `Re-run ${
|
|
35163
|
+
description: `Re-run ${codegen2.name}`,
|
|
34987
35164
|
apply: applicable.apply
|
|
34988
35165
|
},
|
|
34989
35166
|
{
|
|
34990
35167
|
fixName: "outdatedEffectCodegen_ignore",
|
|
34991
|
-
description: `Ignore this ${
|
|
35168
|
+
description: `Ignore this ${codegen2.name} update`,
|
|
34992
35169
|
apply: applicable.ignore
|
|
34993
35170
|
}
|
|
34994
35171
|
]
|
|
@@ -34999,7 +35176,7 @@ var outdatedEffectCodegen = createDiagnostic({
|
|
|
34999
35176
|
(e) => sync11(() => {
|
|
35000
35177
|
_report({
|
|
35001
35178
|
location: range3,
|
|
35002
|
-
messageText: `Codegen ${
|
|
35179
|
+
messageText: `Codegen ${codegen2.name} is not applicable here: ${e.cause}`,
|
|
35003
35180
|
fixes: []
|
|
35004
35181
|
});
|
|
35005
35182
|
})
|
|
@@ -35912,58 +36089,37 @@ var NoFilesToCheckError = class extends TaggedError("NoFilesToCheckError") {
|
|
|
35912
36089
|
return "No files to check. Please provide an existing .ts file or a project tsconfig.json";
|
|
35913
36090
|
}
|
|
35914
36091
|
};
|
|
35915
|
-
var
|
|
36092
|
+
var file5 = file3("file").pipe(
|
|
35916
36093
|
optional4,
|
|
35917
36094
|
withDescription3("The full path of the file to check for diagnostics.")
|
|
35918
36095
|
);
|
|
35919
|
-
var
|
|
36096
|
+
var project3 = file3("project").pipe(
|
|
35920
36097
|
optional4,
|
|
35921
36098
|
withDescription3("The full path of the project tsconfig.json file to check for diagnostics.")
|
|
35922
36099
|
);
|
|
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;
|
|
36100
|
+
var BATCH_SIZE2 = 50;
|
|
35927
36101
|
var diagnostics2 = make58(
|
|
35928
36102
|
"diagnostics",
|
|
35929
|
-
{ file:
|
|
35930
|
-
fn("diagnostics")(function* ({ file:
|
|
36103
|
+
{ file: file5, project: project3 },
|
|
36104
|
+
fn("diagnostics")(function* ({ file: file6, project: project4 }) {
|
|
35931
36105
|
const path2 = yield* Path2;
|
|
35932
36106
|
const tsInstance = yield* getTypeScript;
|
|
35933
|
-
|
|
36107
|
+
let filesToCheck = /* @__PURE__ */ new Set();
|
|
35934
36108
|
let checkedFilesCount = 0;
|
|
35935
36109
|
let errorsCount = 0;
|
|
35936
36110
|
let warningsCount = 0;
|
|
35937
36111
|
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
|
-
}
|
|
36112
|
+
if (isSome2(project4)) {
|
|
36113
|
+
filesToCheck = yield* getFileNamesInTsConfig(project4.value);
|
|
36114
|
+
}
|
|
36115
|
+
if (isSome2(file6)) {
|
|
36116
|
+
filesToCheck.add(path2.resolve(file6.value));
|
|
35961
36117
|
}
|
|
35962
36118
|
if (filesToCheck.size === 0) {
|
|
35963
36119
|
return yield* new NoFilesToCheckError();
|
|
35964
36120
|
}
|
|
35965
36121
|
const filesToCheckArray = fromIterable(filesToCheck);
|
|
35966
|
-
const batches = chunksOf(filesToCheckArray,
|
|
36122
|
+
const batches = chunksOf(filesToCheckArray, BATCH_SIZE2);
|
|
35967
36123
|
let lastLanguageService;
|
|
35968
36124
|
const disposeIfLanguageServiceChanged = (languageService) => {
|
|
35969
36125
|
if (lastLanguageService !== languageService) {
|
|
@@ -35972,14 +36128,14 @@ var diagnostics2 = make58(
|
|
|
35972
36128
|
}
|
|
35973
36129
|
};
|
|
35974
36130
|
for (const batch of batches) {
|
|
35975
|
-
const { service: service3 } = (0,
|
|
36131
|
+
const { service: service3 } = (0, import_project_service2.createProjectService)({ options: { loadTypeScriptPlugins: false } });
|
|
35976
36132
|
for (const filePath of batch) {
|
|
35977
36133
|
service3.openClientFile(filePath);
|
|
35978
36134
|
try {
|
|
35979
36135
|
const scriptInfo = service3.getScriptInfo(filePath);
|
|
35980
36136
|
if (!scriptInfo) continue;
|
|
35981
|
-
const
|
|
35982
|
-
const languageService =
|
|
36137
|
+
const project5 = scriptInfo.getDefaultProject();
|
|
36138
|
+
const languageService = project5.getLanguageService(true);
|
|
35983
36139
|
disposeIfLanguageServiceChanged(languageService);
|
|
35984
36140
|
const program = languageService.getProgram();
|
|
35985
36141
|
if (!program) continue;
|
|
@@ -36070,7 +36226,7 @@ var getPatchesForModule = fn("getPatchesForModule")(
|
|
|
36070
36226
|
let insertCheckSourceFilePosition = none2();
|
|
36071
36227
|
let insertSkipPrecedingCommentDirectivePosition = none2();
|
|
36072
36228
|
let insertAppendMetadataRelationErrorPosition = none2();
|
|
36073
|
-
|
|
36229
|
+
let nodesToCheck = [];
|
|
36074
36230
|
function findNodeAtPositionIncludingTrivia(sourceFile2, position) {
|
|
36075
36231
|
function find3(node) {
|
|
36076
36232
|
if (position >= node.pos && position < node.end) {
|
|
@@ -36098,7 +36254,7 @@ var getPatchesForModule = fn("getPatchesForModule")(
|
|
|
36098
36254
|
if (!pushFunctionDeclarationNode("checkSourceFileWorker")) requiresFullScan = true;
|
|
36099
36255
|
if (!pushFunctionDeclarationNode("markPrecedingCommentDirectiveLine")) requiresFullScan = true;
|
|
36100
36256
|
if (!pushFunctionDeclarationNode("reportRelationError")) requiresFullScan = true;
|
|
36101
|
-
if (requiresFullScan) nodesToCheck
|
|
36257
|
+
if (requiresFullScan) nodesToCheck = [sourceFile];
|
|
36102
36258
|
while (nodesToCheck.length > 0) {
|
|
36103
36259
|
const node = nodesToCheck.shift();
|
|
36104
36260
|
if (!node) continue;
|
|
@@ -36328,7 +36484,7 @@ var cliCommand = make58(
|
|
|
36328
36484
|
"effect-language-service",
|
|
36329
36485
|
{},
|
|
36330
36486
|
() => log3("Please select a command or run --help.")
|
|
36331
|
-
).pipe(withSubcommands3([patch9, unpatch, check2, diagnostics2]));
|
|
36487
|
+
).pipe(withSubcommands3([patch9, unpatch, check2, diagnostics2, codegen]));
|
|
36332
36488
|
var main = run8(cliCommand, {
|
|
36333
36489
|
name: "effect-language-service",
|
|
36334
36490
|
version: "0.0.2"
|