@effect/language-service 0.28.2 → 0.29.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 +28 -0
- package/cli.js +3497 -4362
- package/cli.js.map +1 -1
- package/index.js +1705 -1599
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +1107 -703
- package/transform.js.map +1 -1
package/transform.js
CHANGED
|
@@ -24,7 +24,7 @@ __export(transform_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(transform_exports);
|
|
26
26
|
|
|
27
|
-
// node_modules/.pnpm/effect@3.
|
|
27
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/Function.js
|
|
28
28
|
var isFunction = (input) => typeof input === "function";
|
|
29
29
|
var dual = function(arity, body) {
|
|
30
30
|
if (typeof arity === "function") {
|
|
@@ -118,12 +118,8 @@ function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
// node_modules/.pnpm/effect@3.
|
|
122
|
-
var
|
|
123
|
-
var getCurrentVersion = () => moduleVersion;
|
|
124
|
-
|
|
125
|
-
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/GlobalValue.js
|
|
126
|
-
var globalStoreId = `effect/GlobalValue/globalStoreId/${/* @__PURE__ */ getCurrentVersion()}`;
|
|
121
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/GlobalValue.js
|
|
122
|
+
var globalStoreId = `effect/GlobalValue`;
|
|
127
123
|
var globalStore;
|
|
128
124
|
var globalValue = (id, compute) => {
|
|
129
125
|
if (!globalStore) {
|
|
@@ -136,7 +132,7 @@ var globalValue = (id, compute) => {
|
|
|
136
132
|
return globalStore.get(id);
|
|
137
133
|
};
|
|
138
134
|
|
|
139
|
-
// node_modules/.pnpm/effect@3.
|
|
135
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/Predicate.js
|
|
140
136
|
var isString = (input) => typeof input === "string";
|
|
141
137
|
var isNumber = (input) => typeof input === "number";
|
|
142
138
|
var isBoolean = (input) => typeof input === "boolean";
|
|
@@ -146,10 +142,10 @@ var isObject = (input) => isRecordOrArray(input) || isFunction2(input);
|
|
|
146
142
|
var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObject(self) && property in self);
|
|
147
143
|
var isRecord = (input) => isRecordOrArray(input) && !Array.isArray(input);
|
|
148
144
|
|
|
149
|
-
// node_modules/.pnpm/effect@3.
|
|
145
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/internal/errors.js
|
|
150
146
|
var getBugErrorMessage = (message) => `BUG: ${message} - please report an issue at https://github.com/Effect-TS/effect/issues`;
|
|
151
147
|
|
|
152
|
-
// node_modules/.pnpm/effect@3.
|
|
148
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/Utils.js
|
|
153
149
|
var GenKindTypeId = /* @__PURE__ */ Symbol.for("effect/Gen/GenKind");
|
|
154
150
|
var GenKindImpl = class {
|
|
155
151
|
value;
|
|
@@ -277,7 +273,7 @@ var internalCall = isNotOptimizedAway ? standard.effect_internal_function : forc
|
|
|
277
273
|
var genConstructor = function* () {
|
|
278
274
|
}.constructor;
|
|
279
275
|
|
|
280
|
-
// node_modules/.pnpm/effect@3.
|
|
276
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/Hash.js
|
|
281
277
|
var randomHashCache = /* @__PURE__ */ globalValue(/* @__PURE__ */ Symbol.for("effect/Hash/randomHashCache"), () => /* @__PURE__ */ new WeakMap());
|
|
282
278
|
var symbol = /* @__PURE__ */ Symbol.for("effect/Hash");
|
|
283
279
|
var hash = (self) => {
|
|
@@ -376,7 +372,7 @@ var cached = function() {
|
|
|
376
372
|
return hash2;
|
|
377
373
|
};
|
|
378
374
|
|
|
379
|
-
// node_modules/.pnpm/effect@3.
|
|
375
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/Equal.js
|
|
380
376
|
var symbol2 = /* @__PURE__ */ Symbol.for("effect/Equal");
|
|
381
377
|
function equals() {
|
|
382
378
|
if (arguments.length === 1) {
|
|
@@ -430,7 +426,7 @@ function compareBoth(self, that) {
|
|
|
430
426
|
var isEqual = (u) => hasProperty(u, symbol2);
|
|
431
427
|
var equivalence = () => equals;
|
|
432
428
|
|
|
433
|
-
// node_modules/.pnpm/effect@3.
|
|
429
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/Inspectable.js
|
|
434
430
|
var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
|
|
435
431
|
var toJSON = (x) => {
|
|
436
432
|
try {
|
|
@@ -482,7 +478,7 @@ var redact = (u) => {
|
|
|
482
478
|
return u;
|
|
483
479
|
};
|
|
484
480
|
|
|
485
|
-
// node_modules/.pnpm/effect@3.
|
|
481
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/Pipeable.js
|
|
486
482
|
var pipeArguments = (self, args2) => {
|
|
487
483
|
switch (args2.length) {
|
|
488
484
|
case 0:
|
|
@@ -515,10 +511,14 @@ var pipeArguments = (self, args2) => {
|
|
|
515
511
|
}
|
|
516
512
|
};
|
|
517
513
|
|
|
518
|
-
// node_modules/.pnpm/effect@3.
|
|
514
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/internal/opCodes/effect.js
|
|
519
515
|
var OP_COMMIT = "Commit";
|
|
520
516
|
|
|
521
|
-
// node_modules/.pnpm/effect@3.
|
|
517
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/internal/version.js
|
|
518
|
+
var moduleVersion = "3.17.1";
|
|
519
|
+
var getCurrentVersion = () => moduleVersion;
|
|
520
|
+
|
|
521
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/internal/effectable.js
|
|
522
522
|
var EffectTypeId = /* @__PURE__ */ Symbol.for("effect/Effect");
|
|
523
523
|
var StreamTypeId = /* @__PURE__ */ Symbol.for("effect/Stream");
|
|
524
524
|
var SinkTypeId = /* @__PURE__ */ Symbol.for("effect/Sink");
|
|
@@ -605,7 +605,7 @@ var StructuralCommitPrototype = {
|
|
|
605
605
|
...StructuralPrototype
|
|
606
606
|
};
|
|
607
607
|
|
|
608
|
-
// node_modules/.pnpm/effect@3.
|
|
608
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/internal/option.js
|
|
609
609
|
var TypeId = /* @__PURE__ */ Symbol.for("effect/Option");
|
|
610
610
|
var CommonProto = {
|
|
611
611
|
...EffectPrototype,
|
|
@@ -663,7 +663,7 @@ var some = (value) => {
|
|
|
663
663
|
return a;
|
|
664
664
|
};
|
|
665
665
|
|
|
666
|
-
// node_modules/.pnpm/effect@3.
|
|
666
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/internal/either.js
|
|
667
667
|
var TypeId2 = /* @__PURE__ */ Symbol.for("effect/Either");
|
|
668
668
|
var CommonProto2 = {
|
|
669
669
|
...EffectPrototype,
|
|
@@ -725,7 +725,7 @@ var right = (right3) => {
|
|
|
725
725
|
return a;
|
|
726
726
|
};
|
|
727
727
|
|
|
728
|
-
// node_modules/.pnpm/effect@3.
|
|
728
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/Either.js
|
|
729
729
|
var right2 = right;
|
|
730
730
|
var left2 = left;
|
|
731
731
|
var isLeft2 = isLeft;
|
|
@@ -733,26 +733,22 @@ var isRight2 = isRight;
|
|
|
733
733
|
var map = /* @__PURE__ */ dual(2, (self, f) => isRight2(self) ? right2(f(self.right)) : left2(self.left));
|
|
734
734
|
var getOrElse = /* @__PURE__ */ dual(2, (self, onLeft) => isLeft2(self) ? onLeft(self.left) : self.right);
|
|
735
735
|
|
|
736
|
-
// node_modules/.pnpm/effect@3.
|
|
736
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/internal/array.js
|
|
737
737
|
var isNonEmptyArray = (self) => self.length > 0;
|
|
738
738
|
|
|
739
|
-
// node_modules/.pnpm/effect@3.
|
|
739
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/Order.js
|
|
740
740
|
var make = (compare) => (self, that) => self === that ? 0 : compare(self, that);
|
|
741
741
|
var string2 = /* @__PURE__ */ make((self, that) => self < that ? -1 : 1);
|
|
742
742
|
|
|
743
|
-
// node_modules/.pnpm/effect@3.
|
|
743
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/Option.js
|
|
744
744
|
var none2 = () => none;
|
|
745
745
|
var some2 = some;
|
|
746
746
|
var isNone2 = isNone;
|
|
747
747
|
var isSome2 = isSome;
|
|
748
|
-
var match = /* @__PURE__ */ dual(2, (self, {
|
|
749
|
-
onNone,
|
|
750
|
-
onSome
|
|
751
|
-
}) => isNone2(self) ? onNone() : onSome(self.value));
|
|
752
748
|
var orElse = /* @__PURE__ */ dual(2, (self, that) => isNone2(self) ? that() : self);
|
|
753
749
|
var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nullableValue);
|
|
754
750
|
|
|
755
|
-
// node_modules/.pnpm/effect@3.
|
|
751
|
+
// node_modules/.pnpm/effect@3.17.1/node_modules/effect/dist/esm/Array.js
|
|
756
752
|
var fromIterable = (collection) => Array.isArray(collection) ? collection : Array.from(collection);
|
|
757
753
|
var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
|
|
758
754
|
var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable(self).concat(fromIterable(that)));
|
|
@@ -995,7 +991,7 @@ var MatchProto = {
|
|
|
995
991
|
return this[args];
|
|
996
992
|
}
|
|
997
993
|
};
|
|
998
|
-
var
|
|
994
|
+
var match = (fa, opts) => {
|
|
999
995
|
const nano = Object.create(MatchProto);
|
|
1000
996
|
nano[args] = fa;
|
|
1001
997
|
nano[contA] = opts.onSuccess;
|
|
@@ -1018,7 +1014,7 @@ var ProvideServiceProto = {
|
|
|
1018
1014
|
...fiber._services,
|
|
1019
1015
|
[tag.key]: value
|
|
1020
1016
|
};
|
|
1021
|
-
return
|
|
1017
|
+
return match(fa, {
|
|
1022
1018
|
onSuccess: (_) => {
|
|
1023
1019
|
fiber._services = prevServices;
|
|
1024
1020
|
return succeed(_);
|
|
@@ -1061,7 +1057,7 @@ var CachedProto = {
|
|
|
1061
1057
|
fiber._cache[type] = cache;
|
|
1062
1058
|
const cached2 = cache.get(key);
|
|
1063
1059
|
if (cached2) return cached2;
|
|
1064
|
-
return
|
|
1060
|
+
return match(fa, {
|
|
1065
1061
|
onSuccess: (_) => {
|
|
1066
1062
|
cache.set(key, succeed(_));
|
|
1067
1063
|
return succeed(_);
|
|
@@ -1137,44 +1133,50 @@ function parse(config) {
|
|
|
1137
1133
|
var TypeScriptApi = Tag("TypeScriptApi");
|
|
1138
1134
|
var TypeScriptProgram = Tag("TypeScriptProgram");
|
|
1139
1135
|
var ChangeTracker = Tag("ChangeTracker");
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1136
|
+
|
|
1137
|
+
// src/core/TypeScriptUtils.ts
|
|
1138
|
+
var TypeScriptUtils = Tag("TypeScriptUtils");
|
|
1139
|
+
var nanoLayer = (fa) => pipe(
|
|
1140
|
+
service(TypeScriptApi),
|
|
1141
|
+
flatMap2((ts) => pipe(fa, provideService(TypeScriptUtils, makeTypeScriptUtils(ts))))
|
|
1142
|
+
);
|
|
1143
|
+
function makeTypeScriptUtils(ts) {
|
|
1144
|
+
function parsePackageContentNameAndVersionFromScope(v) {
|
|
1145
|
+
if (!isObject(v)) return;
|
|
1146
|
+
if (!hasProperty(v, "packageJsonScope")) return;
|
|
1147
|
+
if (!v.packageJsonScope) return;
|
|
1148
|
+
const packageJsonScope = v.packageJsonScope;
|
|
1149
|
+
if (!hasProperty(packageJsonScope, "contents")) return;
|
|
1150
|
+
if (!hasProperty(packageJsonScope.contents, "packageJsonContent")) return;
|
|
1151
|
+
const packageJsonContent = packageJsonScope.contents.packageJsonContent;
|
|
1152
|
+
if (!hasProperty(packageJsonContent, "name")) return;
|
|
1153
|
+
if (!hasProperty(packageJsonContent, "version")) return;
|
|
1154
|
+
if (!hasProperty(packageJsonScope, "packageDirectory")) return;
|
|
1155
|
+
if (!isString(packageJsonScope.packageDirectory)) return;
|
|
1156
|
+
const { name, version } = packageJsonContent;
|
|
1157
|
+
if (!isString(name)) return;
|
|
1158
|
+
if (!isString(version)) return;
|
|
1159
|
+
const hasEffectInPeerDependencies = hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) && hasProperty(packageJsonContent.peerDependencies, "effect");
|
|
1160
|
+
const referencedPackages = Object.keys({
|
|
1161
|
+
...hasProperty(packageJsonContent, "dependencies") && isObject(packageJsonContent.dependencies) ? packageJsonContent.dependencies : {},
|
|
1162
|
+
...hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) ? packageJsonContent.peerDependencies : {},
|
|
1163
|
+
...hasProperty(packageJsonContent, "devDependencies") && isObject(packageJsonContent.devDependencies) ? packageJsonContent.devDependencies : {}
|
|
1164
|
+
});
|
|
1165
|
+
const exportsKeys = Object.keys(
|
|
1166
|
+
hasProperty(packageJsonContent, "exports") && isObject(packageJsonContent.exports) ? packageJsonContent.exports : {}
|
|
1167
|
+
);
|
|
1168
|
+
return {
|
|
1169
|
+
name: name.toLowerCase(),
|
|
1170
|
+
version: version.toLowerCase(),
|
|
1171
|
+
hasEffectInPeerDependencies,
|
|
1172
|
+
contents: packageJsonContent,
|
|
1173
|
+
packageDirectory: packageJsonScope.packageDirectory,
|
|
1174
|
+
referencedPackages,
|
|
1175
|
+
exportsKeys
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
function resolveModulePattern(sourceFile, pattern) {
|
|
1176
1179
|
if (pattern.indexOf("*") === -1) return [pattern.toLowerCase()];
|
|
1177
|
-
const ts = yield* service(TypeScriptApi);
|
|
1178
1180
|
const packageJsonScope = parsePackageContentNameAndVersionFromScope(sourceFile);
|
|
1179
1181
|
const referencedPackages = [];
|
|
1180
1182
|
for (const statement of sourceFile.statements) {
|
|
@@ -1193,19 +1195,338 @@ var resolveModulePattern = fn("resolveModulePattern")(
|
|
|
1193
1195
|
)
|
|
1194
1196
|
);
|
|
1195
1197
|
}
|
|
1196
|
-
)
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1198
|
+
function makeGetModuleSpecifier() {
|
|
1199
|
+
if (!(hasProperty(ts, "moduleSpecifiers") && hasProperty(ts.moduleSpecifiers, "getModuleSpecifier") && isFunction2(ts.moduleSpecifiers.getModuleSpecifier))) return;
|
|
1200
|
+
const _internal = ts.moduleSpecifiers.getModuleSpecifier;
|
|
1201
|
+
return (compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, options) => {
|
|
1202
|
+
return _internal(
|
|
1203
|
+
compilerOptions,
|
|
1204
|
+
importingSourceFile,
|
|
1205
|
+
importingSourceFileName,
|
|
1206
|
+
toFileName,
|
|
1207
|
+
host,
|
|
1208
|
+
options
|
|
1209
|
+
);
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
function findNodeWithLeadingCommentAtPosition(sourceFile, position) {
|
|
1213
|
+
const sourceText = sourceFile.text;
|
|
1214
|
+
let result;
|
|
1215
|
+
function find(node) {
|
|
1216
|
+
const leading = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
1217
|
+
if (leading) {
|
|
1218
|
+
for (const commentRange of leading) {
|
|
1219
|
+
if (commentRange.pos <= position && position < commentRange.end) {
|
|
1220
|
+
result = { node, commentRange };
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
if (node.getFullStart() <= position && position < node.getEnd()) {
|
|
1226
|
+
node.forEachChild(find);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
find(sourceFile);
|
|
1230
|
+
return result;
|
|
1231
|
+
}
|
|
1232
|
+
function collectSelfAndAncestorNodesInRange(node, textRange) {
|
|
1233
|
+
let result = empty();
|
|
1234
|
+
let parent = node;
|
|
1235
|
+
while (parent) {
|
|
1236
|
+
if (parent.end >= textRange.end) {
|
|
1237
|
+
result = pipe(result, append(parent));
|
|
1238
|
+
}
|
|
1239
|
+
parent = parent.parent;
|
|
1240
|
+
}
|
|
1241
|
+
return result;
|
|
1242
|
+
}
|
|
1243
|
+
function findNodeAtPosition(sourceFile, position) {
|
|
1244
|
+
function find(node) {
|
|
1245
|
+
if (position >= node.getStart() && position < node.getEnd()) {
|
|
1246
|
+
return ts.forEachChild(node, find) || node;
|
|
1247
|
+
}
|
|
1248
|
+
return void 0;
|
|
1249
|
+
}
|
|
1250
|
+
return find(sourceFile);
|
|
1251
|
+
}
|
|
1252
|
+
function findNodeAtPositionIncludingTrivia(sourceFile, position) {
|
|
1253
|
+
function find(node) {
|
|
1254
|
+
if (position >= node.pos && position < node.end) {
|
|
1255
|
+
return ts.forEachChild(node, find) || node;
|
|
1256
|
+
}
|
|
1257
|
+
return void 0;
|
|
1258
|
+
}
|
|
1259
|
+
return find(sourceFile);
|
|
1260
|
+
}
|
|
1261
|
+
function getAncestorNodesInRange(sourceFile, textRange) {
|
|
1262
|
+
const nodeAtPosition = findNodeAtPosition(sourceFile, textRange.pos);
|
|
1263
|
+
if (!nodeAtPosition) return empty();
|
|
1264
|
+
return collectSelfAndAncestorNodesInRange(nodeAtPosition, textRange);
|
|
1265
|
+
}
|
|
1266
|
+
function getCommentAtPosition(sourceFile, pos) {
|
|
1267
|
+
const token = findNodeAtPositionIncludingTrivia(sourceFile, pos);
|
|
1268
|
+
if (token === void 0 || token.kind === ts.SyntaxKind.JsxText || pos >= token.end - (ts.tokenToString(token.kind) || "").length) {
|
|
1269
|
+
return;
|
|
1270
|
+
}
|
|
1271
|
+
const startPos = token.pos === 0 ? (ts.getShebang(sourceFile.text) || "").length : token.pos;
|
|
1272
|
+
if (startPos === 0) return;
|
|
1273
|
+
const result = ts.forEachTrailingCommentRange(sourceFile.text, startPos, isCommentInRange, pos) || ts.forEachLeadingCommentRange(sourceFile.text, startPos, isCommentInRange, pos);
|
|
1274
|
+
return result;
|
|
1275
|
+
}
|
|
1276
|
+
function isCommentInRange(pos, end, kind, _nl, at) {
|
|
1277
|
+
return at >= pos && at < end ? { pos, end, kind } : void 0;
|
|
1278
|
+
}
|
|
1279
|
+
function toTextRange(positionOrRange) {
|
|
1280
|
+
return typeof positionOrRange === "number" ? { end: positionOrRange, pos: positionOrRange } : positionOrRange;
|
|
1281
|
+
}
|
|
1282
|
+
function isNodeInRange(textRange) {
|
|
1283
|
+
return (node) => node.pos <= textRange.pos && node.end >= textRange.end;
|
|
1284
|
+
}
|
|
1285
|
+
function transformAsyncAwaitToEffectGen(node, effectModuleName, onAwait) {
|
|
1286
|
+
function visitor(_) {
|
|
1287
|
+
if (ts.isAwaitExpression(_)) {
|
|
1288
|
+
const expression = ts.visitEachChild(_.expression, visitor, ts.nullTransformationContext);
|
|
1289
|
+
return ts.factory.createYieldExpression(
|
|
1290
|
+
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
1291
|
+
onAwait(expression)
|
|
1292
|
+
);
|
|
1293
|
+
}
|
|
1294
|
+
return ts.visitEachChild(_, visitor, ts.nullTransformationContext);
|
|
1295
|
+
}
|
|
1296
|
+
const generatorBody = visitor(node.body);
|
|
1297
|
+
const effectGenCallExp = createEffectGenCallExpression(effectModuleName, generatorBody);
|
|
1298
|
+
let currentFlags = ts.getCombinedModifierFlags(node);
|
|
1299
|
+
currentFlags &= ~ts.ModifierFlags.Async;
|
|
1300
|
+
const newModifiers = ts.factory.createModifiersFromModifierFlags(currentFlags);
|
|
1301
|
+
if (ts.isArrowFunction(node)) {
|
|
1302
|
+
return ts.factory.createArrowFunction(
|
|
1303
|
+
newModifiers,
|
|
1304
|
+
node.typeParameters,
|
|
1305
|
+
node.parameters,
|
|
1306
|
+
void 0,
|
|
1307
|
+
node.equalsGreaterThanToken,
|
|
1308
|
+
effectGenCallExp
|
|
1309
|
+
);
|
|
1310
|
+
}
|
|
1311
|
+
const newBody = ts.factory.createBlock([
|
|
1312
|
+
ts.factory.createReturnStatement(effectGenCallExp)
|
|
1313
|
+
]);
|
|
1314
|
+
if (ts.isFunctionDeclaration(node)) {
|
|
1315
|
+
return ts.factory.createFunctionDeclaration(
|
|
1316
|
+
newModifiers,
|
|
1317
|
+
node.asteriskToken,
|
|
1318
|
+
node.name,
|
|
1319
|
+
node.typeParameters,
|
|
1320
|
+
node.parameters,
|
|
1321
|
+
void 0,
|
|
1322
|
+
newBody
|
|
1323
|
+
);
|
|
1324
|
+
}
|
|
1325
|
+
return ts.factory.createFunctionExpression(
|
|
1326
|
+
newModifiers,
|
|
1327
|
+
node.asteriskToken,
|
|
1328
|
+
node.name,
|
|
1329
|
+
node.typeParameters,
|
|
1330
|
+
node.parameters,
|
|
1331
|
+
void 0,
|
|
1332
|
+
newBody
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
function findImportedModuleIdentifier(sourceFile, test) {
|
|
1336
|
+
for (const statement of sourceFile.statements) {
|
|
1337
|
+
if (!ts.isImportDeclaration(statement)) continue;
|
|
1338
|
+
const importClause = statement.importClause;
|
|
1339
|
+
if (!importClause) continue;
|
|
1340
|
+
const namedBindings = importClause.namedBindings;
|
|
1341
|
+
if (!namedBindings) continue;
|
|
1342
|
+
if (ts.isNamespaceImport(namedBindings)) {
|
|
1343
|
+
if (test(namedBindings.name, statement.moduleSpecifier, none2())) {
|
|
1344
|
+
return namedBindings.name.text;
|
|
1345
|
+
}
|
|
1346
|
+
} else if (ts.isNamedImports(namedBindings)) {
|
|
1347
|
+
for (const importSpecifier of namedBindings.elements) {
|
|
1348
|
+
const importProperty = fromNullable(importSpecifier.propertyName).pipe(
|
|
1349
|
+
orElse(() => some2(importSpecifier.name))
|
|
1350
|
+
);
|
|
1351
|
+
if (test(importSpecifier.name, statement.moduleSpecifier, importProperty)) {
|
|
1352
|
+
return importSpecifier.name.text;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
function findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, packageName, moduleName) {
|
|
1359
|
+
return findImportedModuleIdentifier(
|
|
1360
|
+
sourceFile,
|
|
1361
|
+
(_, fromModule, importProperty) => {
|
|
1362
|
+
if (isNone2(importProperty) && ts.isStringLiteral(fromModule) && fromModule.text === packageName + "/" + moduleName) {
|
|
1363
|
+
return true;
|
|
1364
|
+
}
|
|
1365
|
+
if (isSome2(importProperty) && ts.isIdentifier(importProperty.value) && importProperty.value.text === moduleName && ts.isStringLiteral(fromModule) && fromModule.text === packageName) {
|
|
1366
|
+
return true;
|
|
1367
|
+
}
|
|
1368
|
+
return false;
|
|
1369
|
+
}
|
|
1370
|
+
);
|
|
1371
|
+
}
|
|
1372
|
+
function simplifyTypeNode(typeNode) {
|
|
1373
|
+
function collectCallable(typeNode2) {
|
|
1374
|
+
if (ts.isParenthesizedTypeNode(typeNode2)) return collectCallable(typeNode2.type);
|
|
1375
|
+
if (ts.isFunctionTypeNode(typeNode2)) {
|
|
1376
|
+
return some2([
|
|
1377
|
+
ts.factory.createCallSignature(typeNode2.typeParameters, typeNode2.parameters, typeNode2.type)
|
|
1378
|
+
]);
|
|
1379
|
+
}
|
|
1380
|
+
if (ts.isTypeLiteralNode(typeNode2)) {
|
|
1381
|
+
const allCallSignatures = typeNode2.members.every(ts.isCallSignatureDeclaration);
|
|
1382
|
+
if (allCallSignatures) {
|
|
1383
|
+
return some2(typeNode2.members);
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
if (ts.isIntersectionTypeNode(typeNode2)) {
|
|
1387
|
+
const members = typeNode2.types.map((node) => collectCallable(node));
|
|
1388
|
+
if (members.every(isSome2)) {
|
|
1389
|
+
return some2(members.map((_) => isSome2(_) ? _.value : []).flat());
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
return none2();
|
|
1393
|
+
}
|
|
1394
|
+
const callSignatures = collectCallable(typeNode);
|
|
1395
|
+
if (isSome2(callSignatures) && callSignatures.value.length > 1) {
|
|
1396
|
+
return ts.factory.createTypeLiteralNode(callSignatures.value);
|
|
1397
|
+
}
|
|
1398
|
+
return typeNode;
|
|
1399
|
+
}
|
|
1400
|
+
function tryPreserveDeclarationSemantics(nodeToReplace, node) {
|
|
1401
|
+
if (!ts.isExpression(node)) return node;
|
|
1402
|
+
if (ts.isFunctionDeclaration(nodeToReplace)) {
|
|
1403
|
+
if (!nodeToReplace.name) return node;
|
|
1404
|
+
return ts.factory.createVariableStatement(
|
|
1405
|
+
nodeToReplace.modifiers,
|
|
1406
|
+
ts.factory.createVariableDeclarationList(
|
|
1407
|
+
[ts.factory.createVariableDeclaration(
|
|
1408
|
+
nodeToReplace.name,
|
|
1409
|
+
void 0,
|
|
1410
|
+
void 0,
|
|
1411
|
+
node
|
|
1412
|
+
)],
|
|
1413
|
+
ts.NodeFlags.Const
|
|
1414
|
+
)
|
|
1415
|
+
);
|
|
1416
|
+
} else if (ts.isMethodDeclaration(nodeToReplace)) {
|
|
1417
|
+
return ts.factory.createPropertyDeclaration(
|
|
1418
|
+
nodeToReplace.modifiers,
|
|
1419
|
+
nodeToReplace.name,
|
|
1420
|
+
void 0,
|
|
1421
|
+
void 0,
|
|
1422
|
+
node
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
return node;
|
|
1426
|
+
}
|
|
1427
|
+
function parseAccessedExpressionForCompletion(sourceFile, position) {
|
|
1428
|
+
const precedingToken = ts.findPrecedingToken(position, sourceFile, void 0, true);
|
|
1429
|
+
if (!precedingToken) return;
|
|
1430
|
+
let accessedObject = precedingToken;
|
|
1431
|
+
let replacementSpan = ts.createTextSpan(position, 0);
|
|
1432
|
+
let outerNode = precedingToken;
|
|
1433
|
+
if (ts.isIdentifier(precedingToken) && precedingToken.parent && ts.isPropertyAccessExpression(precedingToken.parent)) {
|
|
1434
|
+
replacementSpan = ts.createTextSpan(
|
|
1435
|
+
precedingToken.parent.getStart(sourceFile),
|
|
1436
|
+
precedingToken.end - precedingToken.parent.getStart(sourceFile)
|
|
1437
|
+
);
|
|
1438
|
+
accessedObject = precedingToken.parent.expression;
|
|
1439
|
+
outerNode = precedingToken.parent;
|
|
1440
|
+
} else if (ts.isToken(precedingToken) && precedingToken.kind === ts.SyntaxKind.DotToken && ts.isPropertyAccessExpression(precedingToken.parent)) {
|
|
1441
|
+
replacementSpan = ts.createTextSpan(
|
|
1442
|
+
precedingToken.parent.getStart(sourceFile),
|
|
1443
|
+
precedingToken.end - precedingToken.parent.getStart(sourceFile)
|
|
1444
|
+
);
|
|
1445
|
+
accessedObject = precedingToken.parent.expression;
|
|
1446
|
+
outerNode = precedingToken.parent;
|
|
1447
|
+
} else if (ts.isIdentifier(precedingToken) && precedingToken.parent) {
|
|
1448
|
+
replacementSpan = ts.createTextSpan(
|
|
1449
|
+
precedingToken.getStart(sourceFile),
|
|
1450
|
+
precedingToken.end - precedingToken.getStart(sourceFile)
|
|
1451
|
+
);
|
|
1452
|
+
accessedObject = precedingToken;
|
|
1453
|
+
outerNode = precedingToken;
|
|
1454
|
+
} else {
|
|
1455
|
+
return;
|
|
1456
|
+
}
|
|
1457
|
+
return { accessedObject, outerNode, replacementSpan };
|
|
1458
|
+
}
|
|
1459
|
+
function parseDataForExtendsClassCompletion(sourceFile, position) {
|
|
1460
|
+
const maybeInfos = parseAccessedExpressionForCompletion(sourceFile, position);
|
|
1461
|
+
if (!maybeInfos) return;
|
|
1462
|
+
const { accessedObject, outerNode, replacementSpan } = maybeInfos;
|
|
1463
|
+
if (!ts.isIdentifier(accessedObject)) return;
|
|
1464
|
+
let classDeclaration = outerNode.parent;
|
|
1465
|
+
while (ts.isExpressionWithTypeArguments(classDeclaration) || ts.isHeritageClause(classDeclaration)) {
|
|
1466
|
+
if (!classDeclaration.parent) break;
|
|
1467
|
+
classDeclaration = classDeclaration.parent;
|
|
1468
|
+
}
|
|
1469
|
+
if (!ts.isClassDeclaration(classDeclaration)) return;
|
|
1470
|
+
if (!classDeclaration.name) return;
|
|
1471
|
+
return {
|
|
1472
|
+
accessedObject,
|
|
1473
|
+
classDeclaration,
|
|
1474
|
+
className: classDeclaration.name,
|
|
1475
|
+
replacementSpan
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1478
|
+
function createEffectGenCallExpression(effectModuleIdentifierName, node) {
|
|
1479
|
+
const generator = ts.factory.createFunctionExpression(
|
|
1480
|
+
void 0,
|
|
1481
|
+
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
1482
|
+
void 0,
|
|
1483
|
+
[],
|
|
1484
|
+
[],
|
|
1485
|
+
void 0,
|
|
1486
|
+
node
|
|
1487
|
+
// NOTE(mattia): intended, to use same routine for both ConciseBody and Body
|
|
1208
1488
|
);
|
|
1489
|
+
return ts.factory.createCallExpression(
|
|
1490
|
+
ts.factory.createPropertyAccessExpression(
|
|
1491
|
+
ts.factory.createIdentifier(effectModuleIdentifierName),
|
|
1492
|
+
"gen"
|
|
1493
|
+
),
|
|
1494
|
+
void 0,
|
|
1495
|
+
[generator]
|
|
1496
|
+
);
|
|
1497
|
+
}
|
|
1498
|
+
function createEffectGenCallExpressionWithBlock(effectModuleIdentifierName, statement) {
|
|
1499
|
+
return createEffectGenCallExpression(
|
|
1500
|
+
effectModuleIdentifierName,
|
|
1501
|
+
ts.factory.createBlock(isArray(statement) ? statement : [statement], false)
|
|
1502
|
+
);
|
|
1503
|
+
}
|
|
1504
|
+
function createReturnYieldStarStatement(expr) {
|
|
1505
|
+
return ts.factory.createReturnStatement(
|
|
1506
|
+
ts.factory.createYieldExpression(
|
|
1507
|
+
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
1508
|
+
expr
|
|
1509
|
+
)
|
|
1510
|
+
);
|
|
1511
|
+
}
|
|
1512
|
+
return {
|
|
1513
|
+
findNodeAtPositionIncludingTrivia,
|
|
1514
|
+
parsePackageContentNameAndVersionFromScope,
|
|
1515
|
+
resolveModulePattern,
|
|
1516
|
+
findNodeWithLeadingCommentAtPosition,
|
|
1517
|
+
getCommentAtPosition,
|
|
1518
|
+
getAncestorNodesInRange,
|
|
1519
|
+
toTextRange,
|
|
1520
|
+
isNodeInRange,
|
|
1521
|
+
transformAsyncAwaitToEffectGen,
|
|
1522
|
+
findImportedModuleIdentifierByPackageAndNameOrBarrel,
|
|
1523
|
+
simplifyTypeNode,
|
|
1524
|
+
tryPreserveDeclarationSemantics,
|
|
1525
|
+
parseDataForExtendsClassCompletion,
|
|
1526
|
+
createEffectGenCallExpressionWithBlock,
|
|
1527
|
+
createReturnYieldStarStatement,
|
|
1528
|
+
makeGetModuleSpecifier,
|
|
1529
|
+
parseAccessedExpressionForCompletion
|
|
1209
1530
|
};
|
|
1210
1531
|
}
|
|
1211
1532
|
|
|
@@ -1213,6 +1534,9 @@ function makeGetModuleSpecifier(ts) {
|
|
|
1213
1534
|
var RefactorNotApplicableError = class {
|
|
1214
1535
|
_tag = "@effect/language-service/RefactorNotApplicableError";
|
|
1215
1536
|
};
|
|
1537
|
+
function createRefactor(definition) {
|
|
1538
|
+
return definition;
|
|
1539
|
+
}
|
|
1216
1540
|
function createDiagnostic(definition) {
|
|
1217
1541
|
return definition;
|
|
1218
1542
|
}
|
|
@@ -1275,27 +1599,8 @@ var getCompletionsAtPosition = fn("LSP.getCompletionsAtPosition")(function* (com
|
|
|
1275
1599
|
var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
1276
1600
|
function* (sourceFile) {
|
|
1277
1601
|
const ts = yield* service(TypeScriptApi);
|
|
1602
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
1278
1603
|
const pluginOptions = yield* service(LanguageServicePluginOptions);
|
|
1279
|
-
function findNodeWithLeadingCommentAtPosition(position) {
|
|
1280
|
-
const sourceText = sourceFile.text;
|
|
1281
|
-
let result;
|
|
1282
|
-
function find(node) {
|
|
1283
|
-
const leading = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
1284
|
-
if (leading) {
|
|
1285
|
-
for (const r of leading) {
|
|
1286
|
-
if (r.pos <= position && position < r.end) {
|
|
1287
|
-
result = node;
|
|
1288
|
-
return;
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
if (node.getFullStart() <= position && position < node.getEnd()) {
|
|
1293
|
-
node.forEachChild(find);
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
|
-
find(sourceFile);
|
|
1297
|
-
return result;
|
|
1298
|
-
}
|
|
1299
1604
|
function findParentStatementForDisableNextLine(node) {
|
|
1300
1605
|
let result;
|
|
1301
1606
|
function find(node2) {
|
|
@@ -1313,10 +1618,10 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1313
1618
|
const sectionOverrides = {};
|
|
1314
1619
|
const skippedRules = [];
|
|
1315
1620
|
const regex = /@effect-diagnostics(-next-line)?((?:\s[a-zA-Z0-9/]+:(?:off|warning|error|message|suggestion|skip-file))+)?/gm;
|
|
1316
|
-
let
|
|
1317
|
-
while ((
|
|
1318
|
-
const nextLineCaptureGroup =
|
|
1319
|
-
const rulesCaptureGroup =
|
|
1621
|
+
let match2;
|
|
1622
|
+
while ((match2 = regex.exec(sourceFile.text)) !== null) {
|
|
1623
|
+
const nextLineCaptureGroup = match2[1];
|
|
1624
|
+
const rulesCaptureGroup = match2[2];
|
|
1320
1625
|
if (rulesCaptureGroup) {
|
|
1321
1626
|
const trimmedRuleString = rulesCaptureGroup.trim();
|
|
1322
1627
|
if (trimmedRuleString) {
|
|
@@ -1328,19 +1633,19 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1328
1633
|
if (ruleLevel === "skip-file") skippedRules.push(ruleName);
|
|
1329
1634
|
const isOverrideNextLine = nextLineCaptureGroup && nextLineCaptureGroup.trim().toLowerCase() === "-next-line";
|
|
1330
1635
|
if (isOverrideNextLine) {
|
|
1331
|
-
const
|
|
1332
|
-
if (
|
|
1636
|
+
const foundNode = tsUtils.findNodeWithLeadingCommentAtPosition(sourceFile, match2.index);
|
|
1637
|
+
if (foundNode) {
|
|
1333
1638
|
lineOverrides[ruleName] = lineOverrides[ruleName] || [];
|
|
1334
1639
|
lineOverrides[ruleName].unshift({
|
|
1335
|
-
pos: node.getFullStart(),
|
|
1336
|
-
end: node.end,
|
|
1640
|
+
pos: foundNode.node.getFullStart(),
|
|
1641
|
+
end: foundNode.node.end,
|
|
1337
1642
|
level: ruleLevel
|
|
1338
1643
|
});
|
|
1339
1644
|
}
|
|
1340
1645
|
} else {
|
|
1341
1646
|
sectionOverrides[ruleName] = sectionOverrides[ruleName] || [];
|
|
1342
1647
|
sectionOverrides[ruleName].unshift({
|
|
1343
|
-
pos:
|
|
1648
|
+
pos: match2.index,
|
|
1344
1649
|
level: ruleLevel
|
|
1345
1650
|
});
|
|
1346
1651
|
}
|
|
@@ -1355,7 +1660,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1355
1660
|
message: ts.DiagnosticCategory.Message,
|
|
1356
1661
|
suggestion: ts.DiagnosticCategory.Suggestion
|
|
1357
1662
|
};
|
|
1358
|
-
const execute =
|
|
1663
|
+
const execute = (rule) => gen(function* () {
|
|
1359
1664
|
const diagnostics2 = [];
|
|
1360
1665
|
const codeFixes = [];
|
|
1361
1666
|
const ruleNameLowered = rule.name.toLowerCase();
|
|
@@ -1364,13 +1669,13 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1364
1669
|
if (defaultLevel === "off" && (lineOverrides[ruleNameLowered] || sectionOverrides[ruleNameLowered] || []).length === 0) {
|
|
1365
1670
|
return { diagnostics: diagnostics2, codeFixes };
|
|
1366
1671
|
}
|
|
1367
|
-
const fixByDisableNextLine = (
|
|
1672
|
+
const fixByDisableNextLine = (node) => ({
|
|
1368
1673
|
fixName: rule.name + "_skipNextLine",
|
|
1369
1674
|
description: "Disable " + rule.name + " for this line",
|
|
1370
1675
|
apply: flatMap2(
|
|
1371
1676
|
service(ChangeTracker),
|
|
1372
|
-
(changeTracker) =>
|
|
1373
|
-
const disableAtNode = findParentStatementForDisableNextLine(
|
|
1677
|
+
(changeTracker) => gen(function* () {
|
|
1678
|
+
const disableAtNode = findParentStatementForDisableNextLine(node);
|
|
1374
1679
|
const { line } = ts.getLineAndCharacterOfPosition(sourceFile, disableAtNode.getStart());
|
|
1375
1680
|
changeTracker.insertCommentBeforeLine(
|
|
1376
1681
|
sourceFile,
|
|
@@ -1398,29 +1703,30 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1398
1703
|
};
|
|
1399
1704
|
const applicableDiagnostics = [];
|
|
1400
1705
|
yield* rule.apply(sourceFile, (entry) => {
|
|
1706
|
+
const range = "getEnd" in entry.location ? { pos: entry.location.getStart(sourceFile), end: entry.location.getEnd() } : entry.location;
|
|
1707
|
+
const node = "getEnd" in entry.location ? entry.location : tsUtils.findNodeAtPositionIncludingTrivia(sourceFile, entry.location.pos);
|
|
1401
1708
|
applicableDiagnostics.push({
|
|
1402
|
-
|
|
1403
|
-
|
|
1709
|
+
range,
|
|
1710
|
+
messageText: entry.messageText,
|
|
1711
|
+
fixes: entry.fixes.concat(node ? [fixByDisableNextLine(node)] : []).concat([fixByDisableEntireFile])
|
|
1404
1712
|
});
|
|
1405
1713
|
});
|
|
1406
1714
|
for (const emitted of applicableDiagnostics.slice(0)) {
|
|
1407
1715
|
let newLevel = defaultLevel;
|
|
1408
1716
|
const lineOverride = (lineOverrides[ruleNameLowered] || []).find(
|
|
1409
|
-
(_) => _.pos < emitted.
|
|
1717
|
+
(_) => _.pos < emitted.range.pos && _.end >= emitted.range.end
|
|
1410
1718
|
);
|
|
1411
1719
|
if (lineOverride) {
|
|
1412
1720
|
newLevel = lineOverride.level;
|
|
1413
1721
|
} else {
|
|
1414
|
-
const sectionOverride = (sectionOverrides[ruleNameLowered] || []).find(
|
|
1415
|
-
(_) => _.pos < emitted.node.getStart(sourceFile)
|
|
1416
|
-
);
|
|
1722
|
+
const sectionOverride = (sectionOverrides[ruleNameLowered] || []).find((_) => _.pos < emitted.range.pos);
|
|
1417
1723
|
if (sectionOverride) newLevel = sectionOverride.level;
|
|
1418
1724
|
}
|
|
1419
1725
|
if (!(newLevel in levelToDiagnosticCategory)) continue;
|
|
1420
1726
|
diagnostics2.push({
|
|
1421
1727
|
file: sourceFile,
|
|
1422
|
-
start: emitted.
|
|
1423
|
-
length: emitted.
|
|
1728
|
+
start: emitted.range.pos,
|
|
1729
|
+
length: emitted.range.end - emitted.range.pos,
|
|
1424
1730
|
messageText: emitted.messageText,
|
|
1425
1731
|
category: levelToDiagnosticCategory[newLevel],
|
|
1426
1732
|
code: rule.code,
|
|
@@ -1430,8 +1736,8 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1430
1736
|
codeFixes.push({
|
|
1431
1737
|
...fix,
|
|
1432
1738
|
code: rule.code,
|
|
1433
|
-
start: emitted.
|
|
1434
|
-
end: emitted.
|
|
1739
|
+
start: emitted.range.pos,
|
|
1740
|
+
end: emitted.range.end
|
|
1435
1741
|
});
|
|
1436
1742
|
}
|
|
1437
1743
|
}
|
|
@@ -1440,15 +1746,85 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1440
1746
|
return { execute };
|
|
1441
1747
|
}
|
|
1442
1748
|
);
|
|
1749
|
+
var cyrb53 = (str, seed = 0) => {
|
|
1750
|
+
let h1 = 3735928559 ^ seed, h2 = 1103547991 ^ seed;
|
|
1751
|
+
for (let i = 0, ch; i < str.length; i++) {
|
|
1752
|
+
ch = str.charCodeAt(i);
|
|
1753
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
1754
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
1755
|
+
}
|
|
1756
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507);
|
|
1757
|
+
h1 ^= Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
1758
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507);
|
|
1759
|
+
h2 ^= Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
1760
|
+
return (h2 >>> 0).toString(16).padStart(8, "0") + (h1 >>> 0).toString(16).padStart(8, "0");
|
|
1761
|
+
};
|
|
1762
|
+
var CodegenNotApplicableError = class {
|
|
1763
|
+
constructor(cause) {
|
|
1764
|
+
this.cause = cause;
|
|
1765
|
+
}
|
|
1766
|
+
_tag = "@effect/language-service/CodegenNotApplicableError";
|
|
1767
|
+
};
|
|
1768
|
+
function createCodegen(definition) {
|
|
1769
|
+
return definition;
|
|
1770
|
+
}
|
|
1771
|
+
var getCodegensForSourceFile = fn("LSP.getApplicableCodegens")(function* (codegens2, sourceFile) {
|
|
1772
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
1773
|
+
const result = [];
|
|
1774
|
+
const regex = /@effect-codegens((?:\s[a-zA-Z0-9]+(?::(?:[a-zA-Z0-9]+))?)+)+/gmid;
|
|
1775
|
+
let match2;
|
|
1776
|
+
while ((match2 = regex.exec(sourceFile.text)) !== null) {
|
|
1777
|
+
const pos = match2.indices?.[0]?.[0];
|
|
1778
|
+
if (!pos) continue;
|
|
1779
|
+
const commentRange = tsUtils.getCommentAtPosition(sourceFile, pos);
|
|
1780
|
+
if (!commentRange) continue;
|
|
1781
|
+
const commentText = sourceFile.text.slice(pos, commentRange.end);
|
|
1782
|
+
const codegenRegex = /(\s+)(\w+)(?::(\w+))?/gmi;
|
|
1783
|
+
let codegenMatch;
|
|
1784
|
+
while ((codegenMatch = codegenRegex.exec(commentText)) !== null) {
|
|
1785
|
+
const whitespace = codegenMatch[1] || "";
|
|
1786
|
+
const codegenName = codegenMatch[2] || "";
|
|
1787
|
+
const codegenHash = codegenMatch[3] || "";
|
|
1788
|
+
const range = {
|
|
1789
|
+
pos: codegenMatch.index + pos + whitespace.length,
|
|
1790
|
+
end: codegenMatch.index + pos + codegenMatch[0].length
|
|
1791
|
+
};
|
|
1792
|
+
const codegen = codegens2.find((codegen2) => codegen2.name === codegenName);
|
|
1793
|
+
if (!codegen) continue;
|
|
1794
|
+
result.push({ codegen, hash: codegenHash, range });
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
return result;
|
|
1798
|
+
});
|
|
1799
|
+
var getEditsForCodegen = fn("LSP.getEditsForCodegen")(function* (codegens2, sourceFile, textRange) {
|
|
1800
|
+
const applicableCodegens = yield* getCodegensForSourceFile(codegens2, sourceFile);
|
|
1801
|
+
const inRangeCodegens = applicableCodegens.filter(
|
|
1802
|
+
(codegen2) => codegen2.range.pos <= textRange.pos && codegen2.range.end >= textRange.end
|
|
1803
|
+
);
|
|
1804
|
+
if (inRangeCodegens.length !== 1) {
|
|
1805
|
+
return yield* fail(new CodegenNotApplicableError("zero or multiple codegens in range"));
|
|
1806
|
+
}
|
|
1807
|
+
const { codegen, range } = inRangeCodegens[0];
|
|
1808
|
+
const edit = yield* codegen.apply(sourceFile, range);
|
|
1809
|
+
const updateHashComment = pipe(
|
|
1810
|
+
service(ChangeTracker),
|
|
1811
|
+
map3((changeTracker) => {
|
|
1812
|
+
changeTracker.deleteRange(sourceFile, range);
|
|
1813
|
+
changeTracker.insertText(sourceFile, range.pos, `${codegen.name}:${edit.hash}`);
|
|
1814
|
+
})
|
|
1815
|
+
);
|
|
1816
|
+
return {
|
|
1817
|
+
...edit,
|
|
1818
|
+
apply: pipe(
|
|
1819
|
+
edit.apply,
|
|
1820
|
+
flatMap2(() => updateHashComment)
|
|
1821
|
+
),
|
|
1822
|
+
ignore: updateHashComment
|
|
1823
|
+
};
|
|
1824
|
+
});
|
|
1443
1825
|
|
|
1444
1826
|
// src/core/TypeCheckerApi.ts
|
|
1445
1827
|
var TypeCheckerApi = Tag("TypeChecker");
|
|
1446
|
-
var TypeCheckerApiCache = Tag("TypeCheckerApiCache");
|
|
1447
|
-
function makeTypeCheckerApiCache() {
|
|
1448
|
-
return {
|
|
1449
|
-
expectedAndRealType: /* @__PURE__ */ new WeakMap()
|
|
1450
|
-
};
|
|
1451
|
-
}
|
|
1452
1828
|
var deterministicTypeOrder = gen(function* () {
|
|
1453
1829
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
1454
1830
|
return make((a, b) => {
|
|
@@ -1547,517 +1923,184 @@ var getInferredReturnType = fn("TypeCheckerApi.getInferredReturnType")(function*
|
|
|
1547
1923
|
}
|
|
1548
1924
|
return returnType;
|
|
1549
1925
|
});
|
|
1550
|
-
var expectedAndRealType =
|
|
1551
|
-
|
|
1552
|
-
const resultCached = cache.expectedAndRealType.get(sourceFile);
|
|
1553
|
-
if (resultCached) return resultCached;
|
|
1554
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
1555
|
-
const ts = yield* service(TypeScriptApi);
|
|
1556
|
-
const result = [];
|
|
1557
|
-
const nodeToVisit = [sourceFile];
|
|
1558
|
-
const appendNodeToVisit = (node) => {
|
|
1559
|
-
nodeToVisit.push(node);
|
|
1560
|
-
return void 0;
|
|
1561
|
-
};
|
|
1562
|
-
while (nodeToVisit.length > 0) {
|
|
1563
|
-
const node = nodeToVisit.shift();
|
|
1564
|
-
if (ts.isVariableDeclaration(node) && node.initializer) {
|
|
1565
|
-
const expectedType = typeChecker.getTypeAtLocation(node.name);
|
|
1566
|
-
const realType = typeChecker.getTypeAtLocation(node.initializer);
|
|
1567
|
-
result.push([node.name, expectedType, node.initializer, realType]);
|
|
1568
|
-
appendNodeToVisit(node.initializer);
|
|
1569
|
-
continue;
|
|
1570
|
-
} else if (ts.isCallExpression(node)) {
|
|
1571
|
-
const resolvedSignature = typeChecker.getResolvedSignature(node);
|
|
1572
|
-
if (resolvedSignature) {
|
|
1573
|
-
resolvedSignature.getParameters().map((parameter, index) => {
|
|
1574
|
-
const expectedType = typeChecker.getTypeOfSymbolAtLocation(parameter, node);
|
|
1575
|
-
const realType = typeChecker.getTypeAtLocation(node.arguments[index]);
|
|
1576
|
-
result.push([
|
|
1577
|
-
node.arguments[index],
|
|
1578
|
-
expectedType,
|
|
1579
|
-
node.arguments[index],
|
|
1580
|
-
realType
|
|
1581
|
-
]);
|
|
1582
|
-
});
|
|
1583
|
-
}
|
|
1584
|
-
ts.forEachChild(node, appendNodeToVisit);
|
|
1585
|
-
continue;
|
|
1586
|
-
} else if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
|
|
1587
|
-
const parent = node.parent;
|
|
1588
|
-
if (ts.isObjectLiteralElement(parent)) {
|
|
1589
|
-
if (ts.isObjectLiteralExpression(parent.parent) && parent.name === node) {
|
|
1590
|
-
const type = typeChecker.getContextualType(parent.parent);
|
|
1591
|
-
if (type) {
|
|
1592
|
-
const symbol3 = typeChecker.getPropertyOfType(type, node.text);
|
|
1593
|
-
if (symbol3) {
|
|
1594
|
-
const expectedType = typeChecker.getTypeOfSymbolAtLocation(symbol3, node);
|
|
1595
|
-
const realType = typeChecker.getTypeAtLocation(node);
|
|
1596
|
-
result.push([node, expectedType, node, realType]);
|
|
1597
|
-
}
|
|
1598
|
-
}
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
|
-
ts.forEachChild(node, appendNodeToVisit);
|
|
1602
|
-
continue;
|
|
1603
|
-
} else if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
1604
|
-
const expectedType = typeChecker.getTypeAtLocation(node.left);
|
|
1605
|
-
const realType = typeChecker.getTypeAtLocation(node.right);
|
|
1606
|
-
result.push([node.left, expectedType, node.right, realType]);
|
|
1607
|
-
appendNodeToVisit(node.right);
|
|
1608
|
-
continue;
|
|
1609
|
-
} else if (ts.isReturnStatement(node) && node.expression) {
|
|
1610
|
-
const parentDeclaration = yield* option(getAncestorConvertibleDeclaration(node));
|
|
1611
|
-
if (isSome2(parentDeclaration)) {
|
|
1612
|
-
const expectedType = yield* option(getInferredReturnType(parentDeclaration.value));
|
|
1613
|
-
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
1614
|
-
if (isSome2(expectedType)) {
|
|
1615
|
-
result.push([node, expectedType.value, node, realType]);
|
|
1616
|
-
}
|
|
1617
|
-
}
|
|
1618
|
-
ts.forEachChild(node, appendNodeToVisit);
|
|
1619
|
-
continue;
|
|
1620
|
-
} else if (ts.isArrowFunction(node) && (node.typeParameters || []).length === 0 && ts.isExpression(node.body)) {
|
|
1621
|
-
const body = node.body;
|
|
1622
|
-
const expectedType = typeChecker.getContextualType(body);
|
|
1623
|
-
const realType = typeChecker.getTypeAtLocation(body);
|
|
1624
|
-
if (expectedType) {
|
|
1625
|
-
result.push([body, expectedType, body, realType]);
|
|
1626
|
-
}
|
|
1627
|
-
ts.forEachChild(body, appendNodeToVisit);
|
|
1628
|
-
continue;
|
|
1629
|
-
} else if (ts.isArrowFunction(node) && (node.typeParameters || []).length > 0 && ts.isExpression(node.body)) {
|
|
1630
|
-
const body = node.body;
|
|
1631
|
-
const expectedType = yield* option(getInferredReturnType(node));
|
|
1632
|
-
const realType = typeChecker.getTypeAtLocation(body);
|
|
1633
|
-
if (isSome2(expectedType)) {
|
|
1634
|
-
result.push([body, expectedType.value, body, realType]);
|
|
1635
|
-
}
|
|
1636
|
-
ts.forEachChild(body, appendNodeToVisit);
|
|
1637
|
-
continue;
|
|
1638
|
-
} else if (ts.isSatisfiesExpression(node)) {
|
|
1639
|
-
const expectedType = typeChecker.getTypeAtLocation(node.type);
|
|
1640
|
-
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
1641
|
-
result.push([node.expression, expectedType, node.expression, realType]);
|
|
1642
|
-
appendNodeToVisit(node.expression);
|
|
1643
|
-
continue;
|
|
1644
|
-
}
|
|
1645
|
-
ts.forEachChild(node, appendNodeToVisit);
|
|
1646
|
-
}
|
|
1647
|
-
cache.expectedAndRealType.set(sourceFile, result);
|
|
1648
|
-
return result;
|
|
1649
|
-
});
|
|
1650
|
-
var unrollUnionMembers = (type) => {
|
|
1651
|
-
const result = [];
|
|
1652
|
-
let toTest = [type];
|
|
1653
|
-
while (toTest.length > 0) {
|
|
1654
|
-
const type2 = toTest.pop();
|
|
1655
|
-
if (type2.isUnion()) {
|
|
1656
|
-
toTest = toTest.concat(type2.types);
|
|
1657
|
-
} else {
|
|
1658
|
-
result.push(type2);
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
return result;
|
|
1662
|
-
};
|
|
1663
|
-
var appendToUniqueTypesMap = fn(
|
|
1664
|
-
"TypeCheckerApi.appendToUniqueTypesMap"
|
|
1665
|
-
)(
|
|
1666
|
-
function* (memory, initialType, shouldExclude) {
|
|
1926
|
+
var expectedAndRealType = cachedBy(
|
|
1927
|
+
fn("TypeCheckerApi.expectedAndRealType")(function* (sourceFile) {
|
|
1667
1928
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
1668
|
-
const
|
|
1669
|
-
const
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1929
|
+
const ts = yield* service(TypeScriptApi);
|
|
1930
|
+
const result = [];
|
|
1931
|
+
const nodeToVisit = [sourceFile];
|
|
1932
|
+
const appendNodeToVisit = (node) => {
|
|
1933
|
+
nodeToVisit.push(node);
|
|
1934
|
+
return void 0;
|
|
1935
|
+
};
|
|
1936
|
+
while (nodeToVisit.length > 0) {
|
|
1937
|
+
const node = nodeToVisit.shift();
|
|
1938
|
+
if (ts.isVariableDeclaration(node) && node.initializer) {
|
|
1939
|
+
const expectedType = typeChecker.getTypeAtLocation(node.name);
|
|
1940
|
+
const realType = typeChecker.getTypeAtLocation(node.initializer);
|
|
1941
|
+
result.push([node.name, expectedType, node.initializer, realType]);
|
|
1942
|
+
appendNodeToVisit(node.initializer);
|
|
1675
1943
|
continue;
|
|
1676
|
-
}
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
const newId = "t" + (memory.size + 1);
|
|
1690
|
-
memory.set(newId, type);
|
|
1691
|
-
newIndexes.add(newId);
|
|
1692
|
-
} else {
|
|
1693
|
-
knownIndexes.add(foundMatch[0]);
|
|
1944
|
+
} else if (ts.isCallExpression(node)) {
|
|
1945
|
+
const resolvedSignature = typeChecker.getResolvedSignature(node);
|
|
1946
|
+
if (resolvedSignature) {
|
|
1947
|
+
resolvedSignature.getParameters().map((parameter, index) => {
|
|
1948
|
+
const expectedType = typeChecker.getTypeOfSymbolAtLocation(parameter, node);
|
|
1949
|
+
const realType = typeChecker.getTypeAtLocation(node.arguments[index]);
|
|
1950
|
+
result.push([
|
|
1951
|
+
node.arguments[index],
|
|
1952
|
+
expectedType,
|
|
1953
|
+
node.arguments[index],
|
|
1954
|
+
realType
|
|
1955
|
+
]);
|
|
1956
|
+
});
|
|
1694
1957
|
}
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
);
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
const _internal = typeChecker.resolveExternalModuleName;
|
|
1712
|
-
return (moduleSpecifier) => {
|
|
1713
|
-
return _internal(moduleSpecifier);
|
|
1714
|
-
};
|
|
1715
|
-
}
|
|
1716
|
-
|
|
1717
|
-
// src/core/AST.ts
|
|
1718
|
-
function collectSelfAndAncestorNodesInRange(node, textRange) {
|
|
1719
|
-
return sync(() => {
|
|
1720
|
-
let result = empty();
|
|
1721
|
-
let parent = node;
|
|
1722
|
-
while (parent) {
|
|
1723
|
-
if (parent.end >= textRange.end) {
|
|
1724
|
-
result = pipe(result, append(parent));
|
|
1725
|
-
}
|
|
1726
|
-
parent = parent.parent;
|
|
1727
|
-
}
|
|
1728
|
-
return result;
|
|
1729
|
-
});
|
|
1730
|
-
}
|
|
1731
|
-
var getAncestorNodesInRange = fn("AST.getAncestorNodesInRange")(function* (sourceFile, textRange) {
|
|
1732
|
-
const nodeAtPosition = yield* option(findNodeAtPosition(sourceFile, textRange.pos));
|
|
1733
|
-
if (isNone2(nodeAtPosition)) return empty();
|
|
1734
|
-
return yield* collectSelfAndAncestorNodesInRange(nodeAtPosition.value, textRange);
|
|
1735
|
-
});
|
|
1736
|
-
var NodeNotFoundError = class {
|
|
1737
|
-
_tag = "@effect/language-service/NodeNotFoundError";
|
|
1738
|
-
};
|
|
1739
|
-
var findNodeAtPosition = fn("AST.findNodeAtPosition")(function* (sourceFile, position) {
|
|
1740
|
-
const ts = yield* service(TypeScriptApi);
|
|
1741
|
-
function find(node) {
|
|
1742
|
-
if (position >= node.getStart() && position < node.getEnd()) {
|
|
1743
|
-
return ts.forEachChild(node, find) || node;
|
|
1744
|
-
}
|
|
1745
|
-
return void 0;
|
|
1746
|
-
}
|
|
1747
|
-
const result = find(sourceFile);
|
|
1748
|
-
if (!result) return yield* fail(new NodeNotFoundError());
|
|
1749
|
-
return result;
|
|
1750
|
-
});
|
|
1751
|
-
var getCommentAtPosition = fn("TypeScriptApi.getCommentAtPosition")(function* (sourceFile, pos) {
|
|
1752
|
-
const ts = yield* service(TypeScriptApi);
|
|
1753
|
-
const token = yield* findNodeAtPosition(sourceFile, pos);
|
|
1754
|
-
if (token === void 0 || token.kind === ts.SyntaxKind.JsxText || pos >= token.end - (ts.tokenToString(token.kind) || "").length) {
|
|
1755
|
-
return yield* fail(new NodeNotFoundError());
|
|
1756
|
-
}
|
|
1757
|
-
const startPos = token.pos === 0 ? (ts.getShebang(sourceFile.text) || "").length : token.pos;
|
|
1758
|
-
if (startPos === 0) return yield* fail(new NodeNotFoundError());
|
|
1759
|
-
const result = ts.forEachTrailingCommentRange(sourceFile.text, startPos, isCommentInRange, pos) || ts.forEachLeadingCommentRange(sourceFile.text, startPos, isCommentInRange, pos);
|
|
1760
|
-
if (!result) return yield* fail(new NodeNotFoundError());
|
|
1761
|
-
return result;
|
|
1762
|
-
});
|
|
1763
|
-
function isCommentInRange(pos, end, kind, _nl, at) {
|
|
1764
|
-
return at >= pos && at < end ? { pos, end, kind } : void 0;
|
|
1765
|
-
}
|
|
1766
|
-
var transformAsyncAwaitToEffectGen = fn("AST.transformAsyncAwaitToEffectGen")(
|
|
1767
|
-
function* (node, effectModuleName, onAwait) {
|
|
1768
|
-
const ts = yield* service(TypeScriptApi);
|
|
1769
|
-
function visitor(_) {
|
|
1770
|
-
if (ts.isAwaitExpression(_)) {
|
|
1771
|
-
const expression = ts.visitEachChild(_.expression, visitor, ts.nullTransformationContext);
|
|
1772
|
-
return ts.factory.createYieldExpression(
|
|
1773
|
-
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
1774
|
-
onAwait(expression)
|
|
1775
|
-
);
|
|
1776
|
-
}
|
|
1777
|
-
return ts.visitEachChild(_, visitor, ts.nullTransformationContext);
|
|
1778
|
-
}
|
|
1779
|
-
const generatorBody = visitor(node.body);
|
|
1780
|
-
const effectGenCallExp = yield* createEffectGenCallExpression(effectModuleName, generatorBody);
|
|
1781
|
-
let currentFlags = ts.getCombinedModifierFlags(node);
|
|
1782
|
-
currentFlags &= ~ts.ModifierFlags.Async;
|
|
1783
|
-
const newModifiers = ts.factory.createModifiersFromModifierFlags(currentFlags);
|
|
1784
|
-
if (ts.isArrowFunction(node)) {
|
|
1785
|
-
return ts.factory.createArrowFunction(
|
|
1786
|
-
newModifiers,
|
|
1787
|
-
node.typeParameters,
|
|
1788
|
-
node.parameters,
|
|
1789
|
-
void 0,
|
|
1790
|
-
node.equalsGreaterThanToken,
|
|
1791
|
-
effectGenCallExp
|
|
1792
|
-
);
|
|
1793
|
-
}
|
|
1794
|
-
const newBody = ts.factory.createBlock([
|
|
1795
|
-
ts.factory.createReturnStatement(effectGenCallExp)
|
|
1796
|
-
]);
|
|
1797
|
-
if (ts.isFunctionDeclaration(node)) {
|
|
1798
|
-
return ts.factory.createFunctionDeclaration(
|
|
1799
|
-
newModifiers,
|
|
1800
|
-
node.asteriskToken,
|
|
1801
|
-
node.name,
|
|
1802
|
-
node.typeParameters,
|
|
1803
|
-
node.parameters,
|
|
1804
|
-
void 0,
|
|
1805
|
-
newBody
|
|
1806
|
-
);
|
|
1807
|
-
}
|
|
1808
|
-
return ts.factory.createFunctionExpression(
|
|
1809
|
-
newModifiers,
|
|
1810
|
-
node.asteriskToken,
|
|
1811
|
-
node.name,
|
|
1812
|
-
node.typeParameters,
|
|
1813
|
-
node.parameters,
|
|
1814
|
-
void 0,
|
|
1815
|
-
newBody
|
|
1816
|
-
);
|
|
1817
|
-
}
|
|
1818
|
-
);
|
|
1819
|
-
var addReturnTypeAnnotation = fn("AST.addReturnTypeAnnotation")(function* (sourceFile, declaration, typeNode) {
|
|
1820
|
-
const ts = yield* service(TypeScriptApi);
|
|
1821
|
-
const changes = yield* service(ChangeTracker);
|
|
1822
|
-
const closeParen = ts.findChildOfKind(declaration, ts.SyntaxKind.CloseParenToken, sourceFile);
|
|
1823
|
-
const needParens = ts.isArrowFunction(declaration) && closeParen === void 0;
|
|
1824
|
-
const endNode = needParens ? declaration.parameters[0] : closeParen;
|
|
1825
|
-
if (endNode) {
|
|
1826
|
-
if (needParens) {
|
|
1827
|
-
changes.insertNodeBefore(
|
|
1828
|
-
sourceFile,
|
|
1829
|
-
endNode,
|
|
1830
|
-
ts.factory.createToken(ts.SyntaxKind.OpenParenToken)
|
|
1831
|
-
);
|
|
1832
|
-
changes.insertNodeAfter(
|
|
1833
|
-
sourceFile,
|
|
1834
|
-
endNode,
|
|
1835
|
-
ts.factory.createToken(ts.SyntaxKind.CloseParenToken)
|
|
1836
|
-
);
|
|
1837
|
-
}
|
|
1838
|
-
changes.insertNodeAt(sourceFile, endNode.end, typeNode, { prefix: ": " });
|
|
1839
|
-
}
|
|
1840
|
-
});
|
|
1841
|
-
var removeReturnTypeAnnotation = fn("AST.removeReturnTypeAnnotation")(function* (sourceFile, declaration) {
|
|
1842
|
-
const ts = yield* service(TypeScriptApi);
|
|
1843
|
-
const changes = yield* service(ChangeTracker);
|
|
1844
|
-
const closeParen = ts.findChildOfKind(declaration, ts.SyntaxKind.CloseParenToken, sourceFile);
|
|
1845
|
-
const needParens = ts.isArrowFunction(declaration) && closeParen === void 0;
|
|
1846
|
-
const endNode = needParens ? declaration.parameters[0] : closeParen;
|
|
1847
|
-
if (endNode && declaration.type) {
|
|
1848
|
-
changes.deleteRange(sourceFile, { pos: endNode.end, end: declaration.type.end });
|
|
1849
|
-
}
|
|
1850
|
-
});
|
|
1851
|
-
var ImportModuleIdentifierNotFoundError = class {
|
|
1852
|
-
_tag = "@effect/language-service/ImportModuleIdentifierNotFoundError";
|
|
1853
|
-
};
|
|
1854
|
-
var findImportedModuleIdentifier = fn("AST.findImportedModuleIdentifier")(
|
|
1855
|
-
function* (sourceFile, test) {
|
|
1856
|
-
const ts = yield* service(TypeScriptApi);
|
|
1857
|
-
for (const statement of sourceFile.statements) {
|
|
1858
|
-
if (!ts.isImportDeclaration(statement)) continue;
|
|
1859
|
-
const importClause = statement.importClause;
|
|
1860
|
-
if (!importClause) continue;
|
|
1861
|
-
const namedBindings = importClause.namedBindings;
|
|
1862
|
-
if (!namedBindings) continue;
|
|
1863
|
-
if (ts.isNamespaceImport(namedBindings)) {
|
|
1864
|
-
if (yield* test(namedBindings.name, statement.moduleSpecifier, none2())) {
|
|
1865
|
-
return namedBindings.name;
|
|
1958
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
1959
|
+
continue;
|
|
1960
|
+
} else if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
|
|
1961
|
+
const parent = node.parent;
|
|
1962
|
+
if (ts.isObjectLiteralElement(parent)) {
|
|
1963
|
+
if (ts.isObjectLiteralExpression(parent.parent) && parent.name === node) {
|
|
1964
|
+
const type = typeChecker.getContextualType(parent.parent);
|
|
1965
|
+
if (type) {
|
|
1966
|
+
const symbol3 = typeChecker.getPropertyOfType(type, node.text);
|
|
1967
|
+
if (symbol3) {
|
|
1968
|
+
const expectedType = typeChecker.getTypeOfSymbolAtLocation(symbol3, node);
|
|
1969
|
+
const realType = typeChecker.getTypeAtLocation(node);
|
|
1970
|
+
result.push([node, expectedType, node, realType]);
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1866
1974
|
}
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1975
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
1976
|
+
continue;
|
|
1977
|
+
} else if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
1978
|
+
const expectedType = typeChecker.getTypeAtLocation(node.left);
|
|
1979
|
+
const realType = typeChecker.getTypeAtLocation(node.right);
|
|
1980
|
+
result.push([node.left, expectedType, node.right, realType]);
|
|
1981
|
+
appendNodeToVisit(node.right);
|
|
1982
|
+
continue;
|
|
1983
|
+
} else if (ts.isReturnStatement(node) && node.expression) {
|
|
1984
|
+
const parentDeclaration = yield* option(getAncestorConvertibleDeclaration(node));
|
|
1985
|
+
if (isSome2(parentDeclaration)) {
|
|
1986
|
+
const expectedType = yield* option(getInferredReturnType(parentDeclaration.value));
|
|
1987
|
+
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
1988
|
+
if (isSome2(expectedType)) {
|
|
1989
|
+
result.push([node, expectedType.value, node, realType]);
|
|
1874
1990
|
}
|
|
1875
1991
|
}
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
);
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
ts.factory.createCallSignature(typeNode2.typeParameters, typeNode2.parameters, typeNode2.type)
|
|
1905
|
-
]);
|
|
1906
|
-
}
|
|
1907
|
-
if (ts.isTypeLiteralNode(typeNode2)) {
|
|
1908
|
-
const allCallSignatures = typeNode2.members.every(ts.isCallSignatureDeclaration);
|
|
1909
|
-
if (allCallSignatures) {
|
|
1910
|
-
return some2(typeNode2.members);
|
|
1911
|
-
}
|
|
1912
|
-
}
|
|
1913
|
-
if (ts.isIntersectionTypeNode(typeNode2)) {
|
|
1914
|
-
const members = typeNode2.types.map((node) => collectCallable(node));
|
|
1915
|
-
if (members.every(isSome2)) {
|
|
1916
|
-
return some2(members.map((_) => isSome2(_) ? _.value : []).flat());
|
|
1917
|
-
}
|
|
1918
|
-
}
|
|
1919
|
-
return none2();
|
|
1920
|
-
}
|
|
1921
|
-
const callSignatures = collectCallable(typeNode);
|
|
1922
|
-
if (isSome2(callSignatures) && callSignatures.value.length > 1) {
|
|
1923
|
-
return ts.factory.createTypeLiteralNode(callSignatures.value);
|
|
1924
|
-
}
|
|
1925
|
-
return typeNode;
|
|
1926
|
-
});
|
|
1927
|
-
var tryPreserveDeclarationSemantics = fn("AST.tryPreserveDeclarationSemantics")(
|
|
1928
|
-
function* (nodeToReplace, node) {
|
|
1929
|
-
const ts = yield* service(TypeScriptApi);
|
|
1930
|
-
if (!ts.isExpression(node)) return node;
|
|
1931
|
-
if (ts.isFunctionDeclaration(nodeToReplace)) {
|
|
1932
|
-
if (!nodeToReplace.name) return node;
|
|
1933
|
-
return ts.factory.createVariableStatement(
|
|
1934
|
-
nodeToReplace.modifiers,
|
|
1935
|
-
ts.factory.createVariableDeclarationList(
|
|
1936
|
-
[ts.factory.createVariableDeclaration(
|
|
1937
|
-
nodeToReplace.name,
|
|
1938
|
-
void 0,
|
|
1939
|
-
void 0,
|
|
1940
|
-
node
|
|
1941
|
-
)],
|
|
1942
|
-
ts.NodeFlags.Const
|
|
1943
|
-
)
|
|
1944
|
-
);
|
|
1945
|
-
} else if (ts.isMethodDeclaration(nodeToReplace)) {
|
|
1946
|
-
return ts.factory.createPropertyDeclaration(
|
|
1947
|
-
nodeToReplace.modifiers,
|
|
1948
|
-
nodeToReplace.name,
|
|
1949
|
-
void 0,
|
|
1950
|
-
void 0,
|
|
1951
|
-
node
|
|
1952
|
-
);
|
|
1992
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
1993
|
+
continue;
|
|
1994
|
+
} else if (ts.isArrowFunction(node) && (node.typeParameters || []).length === 0 && ts.isExpression(node.body)) {
|
|
1995
|
+
const body = node.body;
|
|
1996
|
+
const expectedType = typeChecker.getContextualType(body);
|
|
1997
|
+
const realType = typeChecker.getTypeAtLocation(body);
|
|
1998
|
+
if (expectedType) {
|
|
1999
|
+
result.push([body, expectedType, body, realType]);
|
|
2000
|
+
}
|
|
2001
|
+
ts.forEachChild(body, appendNodeToVisit);
|
|
2002
|
+
continue;
|
|
2003
|
+
} else if (ts.isArrowFunction(node) && (node.typeParameters || []).length > 0 && ts.isExpression(node.body)) {
|
|
2004
|
+
const body = node.body;
|
|
2005
|
+
const expectedType = yield* option(getInferredReturnType(node));
|
|
2006
|
+
const realType = typeChecker.getTypeAtLocation(body);
|
|
2007
|
+
if (isSome2(expectedType)) {
|
|
2008
|
+
result.push([body, expectedType.value, body, realType]);
|
|
2009
|
+
}
|
|
2010
|
+
ts.forEachChild(body, appendNodeToVisit);
|
|
2011
|
+
continue;
|
|
2012
|
+
} else if (ts.isSatisfiesExpression(node)) {
|
|
2013
|
+
const expectedType = typeChecker.getTypeAtLocation(node.type);
|
|
2014
|
+
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
2015
|
+
result.push([node.expression, expectedType, node.expression, realType]);
|
|
2016
|
+
appendNodeToVisit(node.expression);
|
|
2017
|
+
continue;
|
|
2018
|
+
}
|
|
2019
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
1953
2020
|
}
|
|
1954
|
-
return
|
|
1955
|
-
}
|
|
2021
|
+
return result;
|
|
2022
|
+
}),
|
|
2023
|
+
"TypeCheckerApi.expectedAndRealType",
|
|
2024
|
+
(sourceFile) => sourceFile
|
|
1956
2025
|
);
|
|
1957
|
-
var
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
const
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
let accessedObject = precedingToken;
|
|
1965
|
-
let replacementSpan = ts.createTextSpan(position, 0);
|
|
1966
|
-
let outerNode = precedingToken;
|
|
1967
|
-
if (ts.isIdentifier(precedingToken) && precedingToken.parent && ts.isPropertyAccessExpression(precedingToken.parent)) {
|
|
1968
|
-
replacementSpan = ts.createTextSpan(
|
|
1969
|
-
precedingToken.parent.getStart(sourceFile),
|
|
1970
|
-
precedingToken.end - precedingToken.parent.getStart(sourceFile)
|
|
1971
|
-
);
|
|
1972
|
-
accessedObject = precedingToken.parent.expression;
|
|
1973
|
-
outerNode = precedingToken.parent;
|
|
1974
|
-
} else if (ts.isToken(precedingToken) && precedingToken.kind === ts.SyntaxKind.DotToken && ts.isPropertyAccessExpression(precedingToken.parent)) {
|
|
1975
|
-
replacementSpan = ts.createTextSpan(
|
|
1976
|
-
precedingToken.parent.getStart(sourceFile),
|
|
1977
|
-
precedingToken.end - precedingToken.parent.getStart(sourceFile)
|
|
1978
|
-
);
|
|
1979
|
-
accessedObject = precedingToken.parent.expression;
|
|
1980
|
-
outerNode = precedingToken.parent;
|
|
1981
|
-
} else if (ts.isIdentifier(precedingToken) && precedingToken.parent) {
|
|
1982
|
-
replacementSpan = ts.createTextSpan(
|
|
1983
|
-
precedingToken.getStart(sourceFile),
|
|
1984
|
-
precedingToken.end - precedingToken.getStart(sourceFile)
|
|
1985
|
-
);
|
|
1986
|
-
accessedObject = precedingToken;
|
|
1987
|
-
outerNode = precedingToken;
|
|
2026
|
+
var unrollUnionMembers = (type) => {
|
|
2027
|
+
const result = [];
|
|
2028
|
+
let toTest = [type];
|
|
2029
|
+
while (toTest.length > 0) {
|
|
2030
|
+
const type2 = toTest.pop();
|
|
2031
|
+
if (type2.isUnion()) {
|
|
2032
|
+
toTest = toTest.concat(type2.types);
|
|
1988
2033
|
} else {
|
|
1989
|
-
|
|
2034
|
+
result.push(type2);
|
|
1990
2035
|
}
|
|
1991
|
-
return { accessedObject, outerNode, replacementSpan };
|
|
1992
2036
|
}
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
[generator]
|
|
2036
|
-
);
|
|
2037
|
-
});
|
|
2038
|
-
var createEffectGenCallExpressionWithBlock = fn(
|
|
2039
|
-
"AST.createEffectGenCallExpressionWithBlock"
|
|
2040
|
-
)(function* (effectModuleIdentifierName, statement) {
|
|
2041
|
-
const ts = yield* service(TypeScriptApi);
|
|
2042
|
-
return yield* createEffectGenCallExpression(
|
|
2043
|
-
effectModuleIdentifierName,
|
|
2044
|
-
ts.factory.createBlock(Array.isArray(statement) ? statement : [statement], false)
|
|
2045
|
-
);
|
|
2046
|
-
});
|
|
2047
|
-
var createReturnYieldStarStatement = fn("AST.createReturnYieldStarStatement")(
|
|
2048
|
-
function* (expr) {
|
|
2049
|
-
const ts = yield* service(TypeScriptApi);
|
|
2050
|
-
return ts.factory.createReturnStatement(
|
|
2051
|
-
ts.factory.createYieldExpression(
|
|
2052
|
-
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
2053
|
-
expr
|
|
2037
|
+
return result;
|
|
2038
|
+
};
|
|
2039
|
+
var appendToUniqueTypesMap = fn(
|
|
2040
|
+
"TypeCheckerApi.appendToUniqueTypesMap"
|
|
2041
|
+
)(
|
|
2042
|
+
function* (memory, initialType, shouldExclude) {
|
|
2043
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
2044
|
+
const newIndexes = /* @__PURE__ */ new Set();
|
|
2045
|
+
const knownIndexes = /* @__PURE__ */ new Set();
|
|
2046
|
+
let toTest = [initialType];
|
|
2047
|
+
while (toTest.length > 0) {
|
|
2048
|
+
const type = toTest.pop();
|
|
2049
|
+
if (!type) break;
|
|
2050
|
+
if (yield* shouldExclude(type)) {
|
|
2051
|
+
continue;
|
|
2052
|
+
}
|
|
2053
|
+
if (type.isUnion()) {
|
|
2054
|
+
toTest = toTest.concat(type.types);
|
|
2055
|
+
} else {
|
|
2056
|
+
const foundMatch = [];
|
|
2057
|
+
for (const [typeId, knownType] of memory.entries()) {
|
|
2058
|
+
const areSame = typeChecker.isTypeAssignableTo(knownType, type) && typeChecker.isTypeAssignableTo(type, knownType);
|
|
2059
|
+
if (areSame) {
|
|
2060
|
+
foundMatch.push(typeId);
|
|
2061
|
+
break;
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
if (foundMatch.length === 0) {
|
|
2065
|
+
const newId = "t" + (memory.size + 1);
|
|
2066
|
+
memory.set(newId, type);
|
|
2067
|
+
newIndexes.add(newId);
|
|
2068
|
+
} else {
|
|
2069
|
+
knownIndexes.add(foundMatch[0]);
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
return {
|
|
2074
|
+
newIndexes,
|
|
2075
|
+
knownIndexes,
|
|
2076
|
+
allIndexes: pipe(
|
|
2077
|
+
fromIterable(newIndexes),
|
|
2078
|
+
appendAll(fromIterable(knownIndexes))
|
|
2054
2079
|
)
|
|
2055
|
-
|
|
2080
|
+
};
|
|
2056
2081
|
}
|
|
2057
2082
|
);
|
|
2083
|
+
function makeResolveExternalModuleName(typeChecker) {
|
|
2084
|
+
if (!(hasProperty(typeChecker, "resolveExternalModuleName") && isFunction(typeChecker.resolveExternalModuleName))) {
|
|
2085
|
+
return;
|
|
2086
|
+
}
|
|
2087
|
+
const _internal = typeChecker.resolveExternalModuleName;
|
|
2088
|
+
return (moduleSpecifier) => {
|
|
2089
|
+
return _internal(moduleSpecifier);
|
|
2090
|
+
};
|
|
2091
|
+
}
|
|
2058
2092
|
|
|
2059
2093
|
// src/core/TypeParser.ts
|
|
2060
2094
|
var TypeParser = Tag("@effect/language-service/TypeParser");
|
|
2095
|
+
var nanoLayer2 = (fa) => gen(function* () {
|
|
2096
|
+
const ts = yield* service(TypeScriptApi);
|
|
2097
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
2098
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
2099
|
+
return yield* pipe(
|
|
2100
|
+
fa,
|
|
2101
|
+
provideService(TypeParser, make2(ts, tsUtils, typeChecker))
|
|
2102
|
+
);
|
|
2103
|
+
});
|
|
2061
2104
|
var TypeParserIssue = class _TypeParserIssue {
|
|
2062
2105
|
_tag = "@effect/language-service/TypeParserIssue";
|
|
2063
2106
|
static issue = fail(new _TypeParserIssue());
|
|
@@ -2065,7 +2108,7 @@ var TypeParserIssue = class _TypeParserIssue {
|
|
|
2065
2108
|
function typeParserIssue(_message, _type, _node) {
|
|
2066
2109
|
return TypeParserIssue.issue;
|
|
2067
2110
|
}
|
|
2068
|
-
function make2(ts, typeChecker) {
|
|
2111
|
+
function make2(ts, tsUtils, typeChecker) {
|
|
2069
2112
|
function covariantTypeArgument(type) {
|
|
2070
2113
|
const signatures = type.getCallSignatures();
|
|
2071
2114
|
if (signatures.length !== 1) {
|
|
@@ -2407,15 +2450,11 @@ function make2(ts, typeChecker) {
|
|
|
2407
2450
|
if (!explicitReturn && !(successType.flags & ts.TypeFlags.VoidLike)) {
|
|
2408
2451
|
replacementNode = pipe(
|
|
2409
2452
|
gen(function* () {
|
|
2410
|
-
const effectIdentifier =
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
onNone: () => "Effect",
|
|
2416
|
-
onSome: (_) => _.text
|
|
2417
|
-
})
|
|
2418
|
-
);
|
|
2453
|
+
const effectIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
2454
|
+
node.getSourceFile(),
|
|
2455
|
+
"effect",
|
|
2456
|
+
"Effect"
|
|
2457
|
+
) || "Effect";
|
|
2419
2458
|
return ts.factory.createCallExpression(
|
|
2420
2459
|
ts.factory.createPropertyAccessExpression(
|
|
2421
2460
|
ts.factory.createIdentifier(effectIdentifier),
|
|
@@ -2583,6 +2622,64 @@ function make2(ts, typeChecker) {
|
|
|
2583
2622
|
"TypeParser.promiseLike",
|
|
2584
2623
|
(type) => type
|
|
2585
2624
|
);
|
|
2625
|
+
const extendsEffectService = cachedBy(
|
|
2626
|
+
fn("TypeParser.extendsEffectService")(function* (atLocation) {
|
|
2627
|
+
if (!atLocation.name) {
|
|
2628
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
2629
|
+
}
|
|
2630
|
+
const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
|
|
2631
|
+
if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
|
|
2632
|
+
const type = typeChecker.getTypeOfSymbol(classSym);
|
|
2633
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
2634
|
+
if (!heritageClauses) {
|
|
2635
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
2636
|
+
}
|
|
2637
|
+
for (const heritageClause of heritageClauses) {
|
|
2638
|
+
for (const typeX of heritageClause.types) {
|
|
2639
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
2640
|
+
const wholeCall = typeX.expression;
|
|
2641
|
+
if (ts.isCallExpression(wholeCall)) {
|
|
2642
|
+
const effectServiceCall = wholeCall.expression;
|
|
2643
|
+
if (ts.isCallExpression(effectServiceCall) && effectServiceCall.typeArguments && effectServiceCall.typeArguments.length > 0) {
|
|
2644
|
+
const effectServiceIdentifier = effectServiceCall.expression;
|
|
2645
|
+
const selfTypeNode = effectServiceCall.typeArguments[0];
|
|
2646
|
+
if (ts.isPropertyAccessExpression(effectServiceIdentifier) && ts.isIdentifier(effectServiceIdentifier.name) && effectServiceIdentifier.name.text === "Service") {
|
|
2647
|
+
const parsedContextTag = yield* pipe(
|
|
2648
|
+
importedEffectModule(effectServiceIdentifier.expression),
|
|
2649
|
+
flatMap2(() => contextTag(type, atLocation)),
|
|
2650
|
+
option
|
|
2651
|
+
);
|
|
2652
|
+
if (isSome2(parsedContextTag)) {
|
|
2653
|
+
let accessors2 = void 0;
|
|
2654
|
+
if (wholeCall.arguments.length >= 2) {
|
|
2655
|
+
const args2 = wholeCall.arguments[1];
|
|
2656
|
+
if (ts.isObjectLiteralExpression(args2)) {
|
|
2657
|
+
for (const property of args2.properties) {
|
|
2658
|
+
if (ts.isPropertyAssignment(property) && property.name && ts.isIdentifier(property.name) && property.name.text === "accessors" && property.initializer && property.initializer.kind === ts.SyntaxKind.TrueKeyword) {
|
|
2659
|
+
accessors2 = true;
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
return {
|
|
2665
|
+
...parsedContextTag.value,
|
|
2666
|
+
className: atLocation.name,
|
|
2667
|
+
selfTypeNode,
|
|
2668
|
+
args: wholeCall.arguments,
|
|
2669
|
+
accessors: accessors2
|
|
2670
|
+
};
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
return yield* typeParserIssue("Class does not extend Effect.Service", void 0, atLocation);
|
|
2679
|
+
}),
|
|
2680
|
+
"TypeParser.extendsEffectService",
|
|
2681
|
+
(atLocation) => atLocation
|
|
2682
|
+
);
|
|
2586
2683
|
return {
|
|
2587
2684
|
effectType,
|
|
2588
2685
|
strictEffectType,
|
|
@@ -2599,7 +2696,8 @@ function make2(ts, typeChecker) {
|
|
|
2599
2696
|
pipeableType,
|
|
2600
2697
|
pipeCall,
|
|
2601
2698
|
scopeType,
|
|
2602
|
-
promiseLike
|
|
2699
|
+
promiseLike,
|
|
2700
|
+
extendsEffectService
|
|
2603
2701
|
};
|
|
2604
2702
|
}
|
|
2605
2703
|
|
|
@@ -2612,6 +2710,7 @@ var duplicatePackage = createDiagnostic({
|
|
|
2612
2710
|
severity: "warning",
|
|
2613
2711
|
apply: fn("duplicatePackage.apply")(function* (sourceFile, report) {
|
|
2614
2712
|
const program = yield* service(TypeScriptProgram);
|
|
2713
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
2615
2714
|
const options = yield* service(LanguageServicePluginOptions);
|
|
2616
2715
|
if (sourceFile.statements.length < 1) return;
|
|
2617
2716
|
let resolvedPackages = checkedPackagesCache.get(sourceFile.fileName) || {};
|
|
@@ -2621,7 +2720,7 @@ var duplicatePackage = createDiagnostic({
|
|
|
2621
2720
|
const seenPackages = /* @__PURE__ */ new Set();
|
|
2622
2721
|
resolvedPackages = {};
|
|
2623
2722
|
program.getSourceFiles().map((_) => {
|
|
2624
|
-
const packageInfo = parsePackageContentNameAndVersionFromScope(_);
|
|
2723
|
+
const packageInfo = tsUtils.parsePackageContentNameAndVersionFromScope(_);
|
|
2625
2724
|
if (!packageInfo) return;
|
|
2626
2725
|
const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
|
|
2627
2726
|
if (seenPackages.has(packageNameAndVersion)) return;
|
|
@@ -2638,7 +2737,7 @@ var duplicatePackage = createDiagnostic({
|
|
|
2638
2737
|
if (Object.keys(resolvedPackages[packageName]).length > 1) {
|
|
2639
2738
|
const versions = Object.keys(resolvedPackages[packageName]);
|
|
2640
2739
|
report({
|
|
2641
|
-
|
|
2740
|
+
location: sourceFile.statements[0],
|
|
2642
2741
|
messageText: `Package ${packageName} is referenced multiple times with different versions (${versions.join(", ")}) and may cause unexpected type errors.
|
|
2643
2742
|
Cleanup your dependencies and your package lockfile to avoid multiple instances of this package and reload the project.
|
|
2644
2743
|
If this is intended set the LSP config "allowedDuplicatedPackages" to ${JSON.stringify(options.allowedDuplicatedPackages.concat([packageName]))}.
|
|
@@ -2685,7 +2784,7 @@ var effectInVoidSuccess = createDiagnostic({
|
|
|
2685
2784
|
map3(({ voidedEffect }) => {
|
|
2686
2785
|
report(
|
|
2687
2786
|
{
|
|
2688
|
-
node,
|
|
2787
|
+
location: node,
|
|
2689
2788
|
messageText: `There is a nested '${typeChecker.typeToString(voidedEffect)}' in the 'void' success channel, beware that this could lead to nested Effect<Effect<...>> that won't be executed.`,
|
|
2690
2789
|
fixes: []
|
|
2691
2790
|
}
|
|
@@ -2734,7 +2833,7 @@ var floatingEffect = createDiagnostic({
|
|
|
2734
2833
|
);
|
|
2735
2834
|
if (isNone2(allowedFloatingEffects)) {
|
|
2736
2835
|
report({
|
|
2737
|
-
node,
|
|
2836
|
+
location: node,
|
|
2738
2837
|
messageText: `Effect must be yielded or assigned to a variable.`,
|
|
2739
2838
|
fixes: []
|
|
2740
2839
|
});
|
|
@@ -2777,7 +2876,7 @@ var genericEffectServices = createDiagnostic({
|
|
|
2777
2876
|
typeParser.contextTag(type, node),
|
|
2778
2877
|
map3(() => {
|
|
2779
2878
|
report({
|
|
2780
|
-
|
|
2879
|
+
location: reportAt,
|
|
2781
2880
|
messageText: `Effect Services with type parameters are not supported because they cannot be properly discriminated at runtime, which may cause unexpected behavior.`,
|
|
2782
2881
|
fixes: []
|
|
2783
2882
|
});
|
|
@@ -2799,17 +2898,16 @@ var importFromBarrel = createDiagnostic({
|
|
|
2799
2898
|
const languageServicePluginOptions = yield* service(LanguageServicePluginOptions);
|
|
2800
2899
|
if (languageServicePluginOptions.namespaceImportPackages.length === 0) return;
|
|
2801
2900
|
const ts = yield* service(TypeScriptApi);
|
|
2901
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
2802
2902
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2803
2903
|
const program = yield* service(TypeScriptProgram);
|
|
2804
2904
|
const packageNamesToCheck = flatten(
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
(packageName) => resolveModulePattern(sourceFile, packageName)
|
|
2808
|
-
)
|
|
2905
|
+
languageServicePluginOptions.namespaceImportPackages.map(
|
|
2906
|
+
(packageName) => tsUtils.resolveModulePattern(sourceFile, packageName)
|
|
2809
2907
|
)
|
|
2810
2908
|
);
|
|
2811
2909
|
const isImportedFromBarrelExport = (element) => {
|
|
2812
|
-
const getModuleSpecifier = makeGetModuleSpecifier(
|
|
2910
|
+
const getModuleSpecifier = tsUtils.makeGetModuleSpecifier();
|
|
2813
2911
|
const resolveExternalModuleName = makeResolveExternalModuleName(typeChecker);
|
|
2814
2912
|
if (!(getModuleSpecifier && resolveExternalModuleName)) return;
|
|
2815
2913
|
const importDeclaration = ts.findAncestor(element, (node) => ts.isImportDeclaration(node));
|
|
@@ -2885,7 +2983,7 @@ var importFromBarrel = createDiagnostic({
|
|
|
2885
2983
|
unbarrelledFileName
|
|
2886
2984
|
} = result;
|
|
2887
2985
|
report({
|
|
2888
|
-
node,
|
|
2986
|
+
location: node,
|
|
2889
2987
|
messageText: `Importing from barrel module ${barrelModuleName} is not allowed.`,
|
|
2890
2988
|
fixes: [
|
|
2891
2989
|
{
|
|
@@ -2999,7 +3097,7 @@ var leakingRequirements = createDiagnostic({
|
|
|
2999
3097
|
function reportLeakingRequirements(node, requirements) {
|
|
3000
3098
|
if (requirements.length === 0) return;
|
|
3001
3099
|
report({
|
|
3002
|
-
node,
|
|
3100
|
+
location: node,
|
|
3003
3101
|
messageText: `This Service is leaking the ${requirements.map((_) => typeChecker.typeToString(_)).join(" | ")} requirement.
|
|
3004
3102
|
If these requirements cannot be cached and are expected to be provided per method invocation (e.g. HttpServerRequest), you can safely disable this diagnostic for this line through quickfixes.
|
|
3005
3103
|
More info at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage`,
|
|
@@ -3079,7 +3177,7 @@ var missingEffectContext = createDiagnostic({
|
|
|
3079
3177
|
map3(
|
|
3080
3178
|
(missingTypes) => missingTypes.length > 0 ? report(
|
|
3081
3179
|
{
|
|
3082
|
-
node,
|
|
3180
|
+
location: node,
|
|
3083
3181
|
messageText: `Missing '${sortTypes(missingTypes).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect context.`,
|
|
3084
3182
|
fixes: []
|
|
3085
3183
|
}
|
|
@@ -3099,18 +3197,15 @@ var missingEffectError = createDiagnostic({
|
|
|
3099
3197
|
severity: "error",
|
|
3100
3198
|
apply: fn("missingEffectError.apply")(function* (sourceFile, report) {
|
|
3101
3199
|
const ts = yield* service(TypeScriptApi);
|
|
3200
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
3102
3201
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3103
3202
|
const typeParser = yield* service(TypeParser);
|
|
3104
3203
|
const typeOrder = yield* deterministicTypeOrder;
|
|
3105
|
-
const effectModuleIdentifier =
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
),
|
|
3111
|
-
map3((_) => _.text),
|
|
3112
|
-
orElse2(() => succeed("Effect"))
|
|
3113
|
-
);
|
|
3204
|
+
const effectModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3205
|
+
sourceFile,
|
|
3206
|
+
"effect",
|
|
3207
|
+
"Effect"
|
|
3208
|
+
) || "Effect";
|
|
3114
3209
|
const createDieMessage = (message) => ts.factory.createCallExpression(
|
|
3115
3210
|
ts.factory.createPropertyAccessExpression(
|
|
3116
3211
|
ts.factory.createIdentifier(effectModuleIdentifier),
|
|
@@ -3212,7 +3307,7 @@ var missingEffectError = createDiagnostic({
|
|
|
3212
3307
|
}
|
|
3213
3308
|
report(
|
|
3214
3309
|
{
|
|
3215
|
-
node,
|
|
3310
|
+
location: node,
|
|
3216
3311
|
messageText: `Missing '${sortTypes(result.missingErrorTypes).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect errors.`,
|
|
3217
3312
|
fixes
|
|
3218
3313
|
}
|
|
@@ -3276,7 +3371,7 @@ var missingReturnYieldStar = createDiagnostic({
|
|
|
3276
3371
|
})
|
|
3277
3372
|
}] : [];
|
|
3278
3373
|
report({
|
|
3279
|
-
node,
|
|
3374
|
+
location: node,
|
|
3280
3375
|
messageText: `Yielded Effect never succeeds, so it is best to use a 'return yield*' instead.`,
|
|
3281
3376
|
fixes: fix
|
|
3282
3377
|
});
|
|
@@ -3332,7 +3427,7 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
3332
3427
|
}
|
|
3333
3428
|
brokenGenerators.forEach(
|
|
3334
3429
|
(node) => report({
|
|
3335
|
-
node,
|
|
3430
|
+
location: node,
|
|
3336
3431
|
messageText: `Seems like you used yield instead of yield* inside this Effect.gen.`,
|
|
3337
3432
|
fixes: []
|
|
3338
3433
|
})
|
|
@@ -3354,7 +3449,7 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
3354
3449
|
})
|
|
3355
3450
|
}] : [];
|
|
3356
3451
|
report({
|
|
3357
|
-
node,
|
|
3452
|
+
location: node,
|
|
3358
3453
|
messageText: `When yielding Effects inside Effect.gen, you should use yield* instead of yield.`,
|
|
3359
3454
|
fixes: fix
|
|
3360
3455
|
});
|
|
@@ -3369,26 +3464,19 @@ var multipleEffectProvide = createDiagnostic({
|
|
|
3369
3464
|
severity: "warning",
|
|
3370
3465
|
apply: fn("multipleEffectProvide.apply")(function* (sourceFile, report) {
|
|
3371
3466
|
const ts = yield* service(TypeScriptApi);
|
|
3467
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
3372
3468
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3373
3469
|
const typeParser = yield* service(TypeParser);
|
|
3374
|
-
const effectModuleIdentifier =
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3385
|
-
sourceFile,
|
|
3386
|
-
"effect",
|
|
3387
|
-
"Layer"
|
|
3388
|
-
),
|
|
3389
|
-
map3((_) => _.text),
|
|
3390
|
-
orElse2(() => succeed("Layer"))
|
|
3391
|
-
);
|
|
3470
|
+
const effectModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3471
|
+
sourceFile,
|
|
3472
|
+
"effect",
|
|
3473
|
+
"Effect"
|
|
3474
|
+
) || "Effect";
|
|
3475
|
+
const layerModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3476
|
+
sourceFile,
|
|
3477
|
+
"effect",
|
|
3478
|
+
"Layer"
|
|
3479
|
+
) || "Layer";
|
|
3392
3480
|
const parseEffectProvideLayer = (node) => {
|
|
3393
3481
|
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && node.expression.name.text === "provide" && node.arguments.length > 0) {
|
|
3394
3482
|
const layer = node.arguments[0];
|
|
@@ -3418,8 +3506,8 @@ var multipleEffectProvide = createDiagnostic({
|
|
|
3418
3506
|
for (const chunk of previousLayers) {
|
|
3419
3507
|
if (chunk.length < 2) continue;
|
|
3420
3508
|
report({
|
|
3421
|
-
|
|
3422
|
-
messageText: "
|
|
3509
|
+
location: chunk[0].node,
|
|
3510
|
+
messageText: "Avoid chaining Effect.provide calls, as this can lead to service lifecycle issues. Instead, merge layers and provide them in a single call.",
|
|
3423
3511
|
fixes: [{
|
|
3424
3512
|
fixName: "multipleEffectProvide_fix",
|
|
3425
3513
|
description: "Combine into a single provide",
|
|
@@ -3466,6 +3554,327 @@ var multipleEffectProvide = createDiagnostic({
|
|
|
3466
3554
|
})
|
|
3467
3555
|
});
|
|
3468
3556
|
|
|
3557
|
+
// src/refactors/writeTagClassAccessors.ts
|
|
3558
|
+
var generate = fn("writeTagClassAccessors.generate")(function* (sourceFile, service2, className, atLocation, involvedMembers) {
|
|
3559
|
+
const ts = yield* service(TypeScriptApi);
|
|
3560
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
3561
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
3562
|
+
const typeParser = yield* service(TypeParser);
|
|
3563
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
3564
|
+
const insertLocation = atLocation.members.length > 0 ? atLocation.members[0].pos : atLocation.getEnd() - 1;
|
|
3565
|
+
const effectIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3566
|
+
sourceFile,
|
|
3567
|
+
"effect",
|
|
3568
|
+
"Effect"
|
|
3569
|
+
) || "Effect";
|
|
3570
|
+
const createFunctionProperty = (className2, propertyName, type, forceAny) => {
|
|
3571
|
+
const arrowBody = ts.factory.createCallExpression(
|
|
3572
|
+
ts.factory.createPropertyAccessExpression(
|
|
3573
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
3574
|
+
"andThen"
|
|
3575
|
+
),
|
|
3576
|
+
void 0,
|
|
3577
|
+
[
|
|
3578
|
+
ts.factory.createIdentifier(className2.text),
|
|
3579
|
+
ts.factory.createArrowFunction(
|
|
3580
|
+
void 0,
|
|
3581
|
+
void 0,
|
|
3582
|
+
[ts.factory.createParameterDeclaration(
|
|
3583
|
+
void 0,
|
|
3584
|
+
void 0,
|
|
3585
|
+
"_",
|
|
3586
|
+
void 0,
|
|
3587
|
+
forceAny ? ts.factory.createTypeReferenceNode("any") : void 0
|
|
3588
|
+
)],
|
|
3589
|
+
void 0,
|
|
3590
|
+
void 0,
|
|
3591
|
+
ts.factory.createCallExpression(
|
|
3592
|
+
ts.factory.createPropertyAccessExpression(
|
|
3593
|
+
ts.factory.createIdentifier("_"),
|
|
3594
|
+
propertyName
|
|
3595
|
+
),
|
|
3596
|
+
void 0,
|
|
3597
|
+
[
|
|
3598
|
+
ts.factory.createSpreadElement(ts.factory.createIdentifier("args"))
|
|
3599
|
+
]
|
|
3600
|
+
)
|
|
3601
|
+
)
|
|
3602
|
+
]
|
|
3603
|
+
);
|
|
3604
|
+
return ts.factory.createPropertyDeclaration(
|
|
3605
|
+
[ts.factory.createModifier(ts.SyntaxKind.StaticKeyword)],
|
|
3606
|
+
propertyName,
|
|
3607
|
+
void 0,
|
|
3608
|
+
type,
|
|
3609
|
+
ts.factory.createArrowFunction(
|
|
3610
|
+
void 0,
|
|
3611
|
+
void 0,
|
|
3612
|
+
[ts.factory.createParameterDeclaration(
|
|
3613
|
+
void 0,
|
|
3614
|
+
ts.factory.createToken(ts.SyntaxKind.DotDotDotToken),
|
|
3615
|
+
"args",
|
|
3616
|
+
void 0,
|
|
3617
|
+
forceAny ? ts.factory.createArrayTypeNode(ts.factory.createTypeReferenceNode("any")) : void 0
|
|
3618
|
+
)],
|
|
3619
|
+
void 0,
|
|
3620
|
+
void 0,
|
|
3621
|
+
forceAny ? ts.factory.createAsExpression(arrowBody, ts.factory.createTypeReferenceNode("any")) : arrowBody
|
|
3622
|
+
)
|
|
3623
|
+
);
|
|
3624
|
+
};
|
|
3625
|
+
const generateReturnType = (type, atLocation2, className2) => pipe(
|
|
3626
|
+
typeParser.effectType(type, atLocation2),
|
|
3627
|
+
flatMap2((returnedEffect) => {
|
|
3628
|
+
const contextType = returnedEffect.R.flags & ts.TypeFlags.Never ? ts.factory.createTypeReferenceNode(className2.text) : ts.factory.createUnionTypeNode(
|
|
3629
|
+
[
|
|
3630
|
+
ts.factory.createTypeReferenceNode(className2.text),
|
|
3631
|
+
typeChecker.typeToTypeNode(returnedEffect.R, atLocation2, ts.NodeBuilderFlags.NoTruncation)
|
|
3632
|
+
]
|
|
3633
|
+
);
|
|
3634
|
+
const successType = typeChecker.typeToTypeNode(
|
|
3635
|
+
returnedEffect.A,
|
|
3636
|
+
atLocation2,
|
|
3637
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
3638
|
+
);
|
|
3639
|
+
if (!successType) return fail("error generating success type");
|
|
3640
|
+
const failureType = typeChecker.typeToTypeNode(
|
|
3641
|
+
returnedEffect.E,
|
|
3642
|
+
atLocation2,
|
|
3643
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
3644
|
+
);
|
|
3645
|
+
if (!failureType) return fail("error generating failure type");
|
|
3646
|
+
const typeNode = ts.factory.createTypeReferenceNode(
|
|
3647
|
+
ts.factory.createQualifiedName(
|
|
3648
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
3649
|
+
ts.factory.createIdentifier("Effect")
|
|
3650
|
+
),
|
|
3651
|
+
[successType, failureType, contextType]
|
|
3652
|
+
);
|
|
3653
|
+
return succeed(typeNode);
|
|
3654
|
+
}),
|
|
3655
|
+
orElse2(
|
|
3656
|
+
() => pipe(
|
|
3657
|
+
typeParser.promiseLike(type, atLocation2),
|
|
3658
|
+
flatMap2(({ type: type2 }) => {
|
|
3659
|
+
const successType = typeChecker.typeToTypeNode(
|
|
3660
|
+
type2,
|
|
3661
|
+
atLocation2,
|
|
3662
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
3663
|
+
);
|
|
3664
|
+
if (!successType) return fail("error generating success type");
|
|
3665
|
+
return succeed(ts.factory.createTypeReferenceNode(
|
|
3666
|
+
ts.factory.createQualifiedName(
|
|
3667
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
3668
|
+
ts.factory.createIdentifier("Effect")
|
|
3669
|
+
),
|
|
3670
|
+
[
|
|
3671
|
+
successType,
|
|
3672
|
+
ts.factory.createTypeReferenceNode(
|
|
3673
|
+
ts.factory.createQualifiedName(
|
|
3674
|
+
ts.factory.createIdentifier("Cause"),
|
|
3675
|
+
ts.factory.createIdentifier("UnknownException")
|
|
3676
|
+
)
|
|
3677
|
+
),
|
|
3678
|
+
ts.factory.createTypeReferenceNode(className2.text)
|
|
3679
|
+
]
|
|
3680
|
+
));
|
|
3681
|
+
})
|
|
3682
|
+
)
|
|
3683
|
+
),
|
|
3684
|
+
orElse2(() => {
|
|
3685
|
+
const successType = typeChecker.typeToTypeNode(type, atLocation2, ts.NodeBuilderFlags.NoTruncation);
|
|
3686
|
+
if (!successType) return fail("error generating success type");
|
|
3687
|
+
const typeNode = ts.factory.createTypeReferenceNode(
|
|
3688
|
+
ts.factory.createQualifiedName(
|
|
3689
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
3690
|
+
ts.factory.createIdentifier("Effect")
|
|
3691
|
+
),
|
|
3692
|
+
[
|
|
3693
|
+
successType,
|
|
3694
|
+
ts.factory.createTypeReferenceNode("never"),
|
|
3695
|
+
ts.factory.createTypeReferenceNode(className2.text)
|
|
3696
|
+
]
|
|
3697
|
+
);
|
|
3698
|
+
return succeed(typeNode);
|
|
3699
|
+
})
|
|
3700
|
+
);
|
|
3701
|
+
const proxySignature = (signature, atLocation2, className2) => gen(function* () {
|
|
3702
|
+
const signatureDeclaration = typeChecker.signatureToSignatureDeclaration(
|
|
3703
|
+
signature,
|
|
3704
|
+
ts.SyntaxKind.FunctionType,
|
|
3705
|
+
atLocation2,
|
|
3706
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
3707
|
+
);
|
|
3708
|
+
if (!signatureDeclaration) return yield* fail("error generating signature");
|
|
3709
|
+
const returnType = yield* generateReturnType(signature.getReturnType(), atLocation2, className2);
|
|
3710
|
+
return ts.factory.createFunctionTypeNode(
|
|
3711
|
+
signatureDeclaration.typeParameters,
|
|
3712
|
+
signatureDeclaration.parameters,
|
|
3713
|
+
returnType
|
|
3714
|
+
);
|
|
3715
|
+
});
|
|
3716
|
+
for (const { property, propertyType } of involvedMembers) {
|
|
3717
|
+
const callSignatures = [];
|
|
3718
|
+
let propertyDeclaration = void 0;
|
|
3719
|
+
for (const signature of propertyType.getCallSignatures()) {
|
|
3720
|
+
yield* pipe(
|
|
3721
|
+
proxySignature(signature, atLocation, className),
|
|
3722
|
+
map3((sig) => {
|
|
3723
|
+
callSignatures.push(sig);
|
|
3724
|
+
}),
|
|
3725
|
+
ignore
|
|
3726
|
+
);
|
|
3727
|
+
}
|
|
3728
|
+
const allSignatures = ts.factory.createIntersectionTypeNode(callSignatures);
|
|
3729
|
+
const type = tsUtils.simplifyTypeNode(allSignatures);
|
|
3730
|
+
propertyDeclaration = createFunctionProperty(className, property.getName(), type, callSignatures.length > 1);
|
|
3731
|
+
const oldProperty = atLocation.members.filter(ts.isPropertyDeclaration).find((p) => {
|
|
3732
|
+
const symbol3 = typeChecker.getSymbolAtLocation(p.name);
|
|
3733
|
+
return symbol3?.getName() === property.getName();
|
|
3734
|
+
});
|
|
3735
|
+
if (oldProperty) {
|
|
3736
|
+
changeTracker.deleteRange(sourceFile, {
|
|
3737
|
+
pos: oldProperty.getStart(sourceFile),
|
|
3738
|
+
end: oldProperty.getEnd()
|
|
3739
|
+
});
|
|
3740
|
+
changeTracker.insertNodeAt(sourceFile, oldProperty.getStart(sourceFile), propertyDeclaration);
|
|
3741
|
+
} else {
|
|
3742
|
+
changeTracker.insertNodeAt(sourceFile, insertLocation, propertyDeclaration, { suffix: "\n" });
|
|
3743
|
+
}
|
|
3744
|
+
}
|
|
3745
|
+
});
|
|
3746
|
+
var parse2 = fn("writeTagClassAccessors.parse")(function* (node) {
|
|
3747
|
+
const ts = yield* service(TypeScriptApi);
|
|
3748
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
3749
|
+
const typeParser = yield* service(TypeParser);
|
|
3750
|
+
if (!ts.isClassDeclaration(node)) return yield* fail("not a class declaration");
|
|
3751
|
+
const { Service, accessors: accessors2, className } = yield* pipe(
|
|
3752
|
+
typeParser.extendsEffectService(node),
|
|
3753
|
+
orElse2(() => fail("not a class extending Effect.Service call"))
|
|
3754
|
+
);
|
|
3755
|
+
if (accessors2 !== true) return yield* fail("accessors are not enabled in the Effect.Service call");
|
|
3756
|
+
const involvedMembers = [];
|
|
3757
|
+
for (const property of typeChecker.getPropertiesOfType(Service)) {
|
|
3758
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(property, node);
|
|
3759
|
+
const callSignatures = propertyType.getCallSignatures();
|
|
3760
|
+
if (callSignatures.length > 0) {
|
|
3761
|
+
const withTypeParameters = callSignatures.filter((_) => _.typeParameters && _.typeParameters.length > 0);
|
|
3762
|
+
if (callSignatures.length > 1 || withTypeParameters.length > 0) involvedMembers.push({ property, propertyType });
|
|
3763
|
+
}
|
|
3764
|
+
}
|
|
3765
|
+
const hash2 = involvedMembers.map(({ property, propertyType }) => {
|
|
3766
|
+
return property.getName() + ": " + typeChecker.typeToString(propertyType);
|
|
3767
|
+
}).concat([className.text]).join("\n");
|
|
3768
|
+
return { Service, className, atLocation: node, hash: cyrb53(hash2), involvedMembers };
|
|
3769
|
+
});
|
|
3770
|
+
var writeTagClassAccessors = createRefactor({
|
|
3771
|
+
name: "writeTagClassAccessors",
|
|
3772
|
+
description: "Implement accessors methods with generics or multiple signatures",
|
|
3773
|
+
apply: fn("writeTagClassAccessors.apply")(function* (sourceFile, textRange) {
|
|
3774
|
+
const ts = yield* service(TypeScriptApi);
|
|
3775
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
3776
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
3777
|
+
const typeParser = yield* service(TypeParser);
|
|
3778
|
+
const parseNode = (node) => pipe(
|
|
3779
|
+
parse2(node),
|
|
3780
|
+
map3(({ Service, atLocation, className, involvedMembers }) => ({
|
|
3781
|
+
kind: "refactor.rewrite.effect.writeTagClassAccessors",
|
|
3782
|
+
description: "Implement Service accessors",
|
|
3783
|
+
apply: pipe(
|
|
3784
|
+
generate(sourceFile, Service, className, atLocation, involvedMembers),
|
|
3785
|
+
provideService(TypeScriptUtils, tsUtils),
|
|
3786
|
+
provideService(TypeParser, typeParser),
|
|
3787
|
+
provideService(TypeCheckerApi, typeChecker),
|
|
3788
|
+
provideService(TypeScriptApi, ts)
|
|
3789
|
+
)
|
|
3790
|
+
}))
|
|
3791
|
+
);
|
|
3792
|
+
const parentNodes = tsUtils.getAncestorNodesInRange(sourceFile, textRange);
|
|
3793
|
+
return yield* pipe(
|
|
3794
|
+
firstSuccessOf(parentNodes.map(parseNode)),
|
|
3795
|
+
orElse2(() => fail(new RefactorNotApplicableError()))
|
|
3796
|
+
);
|
|
3797
|
+
})
|
|
3798
|
+
});
|
|
3799
|
+
|
|
3800
|
+
// src/codegens/accessors.ts
|
|
3801
|
+
var accessors = createCodegen({
|
|
3802
|
+
name: "accessors",
|
|
3803
|
+
apply: fn("accessors.apply")(function* (sourceFile, textRange) {
|
|
3804
|
+
const ts = yield* service(TypeScriptApi);
|
|
3805
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
3806
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
3807
|
+
const typeParser = yield* service(TypeParser);
|
|
3808
|
+
const nodeAndCommentRange = tsUtils.findNodeWithLeadingCommentAtPosition(sourceFile, textRange.pos);
|
|
3809
|
+
if (!nodeAndCommentRange) return yield* fail(new CodegenNotApplicableError("no node and comment range"));
|
|
3810
|
+
return yield* pipe(
|
|
3811
|
+
parse2(nodeAndCommentRange.node),
|
|
3812
|
+
map3(
|
|
3813
|
+
(_) => ({
|
|
3814
|
+
hash: _.hash,
|
|
3815
|
+
description: "Generate accessors for the service",
|
|
3816
|
+
apply: pipe(
|
|
3817
|
+
generate(sourceFile, _.Service, _.className, _.atLocation, _.involvedMembers),
|
|
3818
|
+
provideService(TypeScriptApi, ts),
|
|
3819
|
+
provideService(TypeScriptUtils, tsUtils),
|
|
3820
|
+
provideService(TypeCheckerApi, typeChecker),
|
|
3821
|
+
provideService(TypeParser, typeParser)
|
|
3822
|
+
)
|
|
3823
|
+
})
|
|
3824
|
+
),
|
|
3825
|
+
orElse2((cause) => fail(new CodegenNotApplicableError(cause)))
|
|
3826
|
+
);
|
|
3827
|
+
})
|
|
3828
|
+
});
|
|
3829
|
+
|
|
3830
|
+
// src/codegens.ts
|
|
3831
|
+
var codegens = [accessors];
|
|
3832
|
+
|
|
3833
|
+
// src/diagnostics/outdatedEffectCodegen.ts
|
|
3834
|
+
var outdatedEffectCodegen = createDiagnostic({
|
|
3835
|
+
name: "outdatedEffectCodegen",
|
|
3836
|
+
code: 19,
|
|
3837
|
+
severity: "warning",
|
|
3838
|
+
apply: fn("outdatedEffectCodegen.apply")(function* (sourceFile, _report) {
|
|
3839
|
+
const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
|
|
3840
|
+
for (const { codegen, hash: hash2, range } of codegensWithRanges) {
|
|
3841
|
+
yield* pipe(
|
|
3842
|
+
getEditsForCodegen([codegen], sourceFile, range),
|
|
3843
|
+
map3((applicable) => {
|
|
3844
|
+
if (applicable.hash !== hash2) {
|
|
3845
|
+
_report({
|
|
3846
|
+
location: range,
|
|
3847
|
+
messageText: `Codegen ${codegen.name} result is outdated`,
|
|
3848
|
+
fixes: [
|
|
3849
|
+
{
|
|
3850
|
+
fixName: "outdatedEffectCodegen_fix",
|
|
3851
|
+
description: `Re-run ${codegen.name}`,
|
|
3852
|
+
apply: applicable.apply
|
|
3853
|
+
},
|
|
3854
|
+
{
|
|
3855
|
+
fixName: "outdatedEffectCodegen_ignore",
|
|
3856
|
+
description: `Ignore this ${codegen.name} update`,
|
|
3857
|
+
apply: applicable.ignore
|
|
3858
|
+
}
|
|
3859
|
+
]
|
|
3860
|
+
});
|
|
3861
|
+
}
|
|
3862
|
+
}),
|
|
3863
|
+
orElse2(
|
|
3864
|
+
(e) => sync(() => {
|
|
3865
|
+
_report({
|
|
3866
|
+
location: range,
|
|
3867
|
+
messageText: `Codegen ${codegen.name} is not applicable here: ${e.cause}`,
|
|
3868
|
+
fixes: []
|
|
3869
|
+
});
|
|
3870
|
+
})
|
|
3871
|
+
),
|
|
3872
|
+
ignore
|
|
3873
|
+
);
|
|
3874
|
+
}
|
|
3875
|
+
})
|
|
3876
|
+
});
|
|
3877
|
+
|
|
3469
3878
|
// src/diagnostics/returnEffectInGen.ts
|
|
3470
3879
|
var returnEffectInGen = createDiagnostic({
|
|
3471
3880
|
name: "returnEffectInGen",
|
|
@@ -3517,7 +3926,7 @@ var returnEffectInGen = createDiagnostic({
|
|
|
3517
3926
|
})
|
|
3518
3927
|
}] : [];
|
|
3519
3928
|
report({
|
|
3520
|
-
node,
|
|
3929
|
+
location: node,
|
|
3521
3930
|
messageText: `You are returning an Effect-able type inside a generator function, and will result in nested Effect<Effect<...>>.
|
|
3522
3931
|
Maybe you wanted to return yield* instead?
|
|
3523
3932
|
Nested Effect-able types may be intended if you plan to later manually flatten or unwrap this Effect, if so you can safely disable this diagnostic for this line through quickfixes.`,
|
|
@@ -3540,17 +3949,14 @@ var scopeInLayerEffect = createDiagnostic({
|
|
|
3540
3949
|
severity: "warning",
|
|
3541
3950
|
apply: fn("scopeInLayerEffect.apply")(function* (sourceFile, report) {
|
|
3542
3951
|
const ts = yield* service(TypeScriptApi);
|
|
3952
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
3543
3953
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3544
3954
|
const typeParser = yield* service(TypeParser);
|
|
3545
|
-
const layerModuleIdentifier =
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
),
|
|
3551
|
-
map3((_) => _.text),
|
|
3552
|
-
orElse2(() => succeed("Layer"))
|
|
3553
|
-
);
|
|
3955
|
+
const layerModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3956
|
+
sourceFile,
|
|
3957
|
+
"effect",
|
|
3958
|
+
"Layer"
|
|
3959
|
+
) || "Layer";
|
|
3554
3960
|
function parseLayerEffectApiCall(node) {
|
|
3555
3961
|
if (!ts.isCallExpression(node)) return;
|
|
3556
3962
|
const expression = node.expression;
|
|
@@ -3576,7 +3982,7 @@ var scopeInLayerEffect = createDiagnostic({
|
|
|
3576
3982
|
firstSuccessOf(entries.map((type2) => typeParser.scopeType(type2, node))),
|
|
3577
3983
|
map3(
|
|
3578
3984
|
() => report({
|
|
3579
|
-
node,
|
|
3985
|
+
location: node,
|
|
3580
3986
|
messageText: `Seems like you are constructing a layer with a scope in the requirements.
|
|
3581
3987
|
Consider using "scoped" instead to get rid of the scope in the requirements.`,
|
|
3582
3988
|
fixes: methodIdentifier ? [{
|
|
@@ -3692,7 +4098,7 @@ var strictBooleanExpressions = createDiagnostic({
|
|
|
3692
4098
|
if (type.flags & ts.TypeFlags.BooleanLiteral) continue;
|
|
3693
4099
|
const typeName = typeChecker.typeToString(type);
|
|
3694
4100
|
report({
|
|
3695
|
-
|
|
4101
|
+
location: nodeToCheck,
|
|
3696
4102
|
messageText: `Unexpected \`${typeName}\` type in condition, expected strictly a boolean instead.`,
|
|
3697
4103
|
fixes: []
|
|
3698
4104
|
});
|
|
@@ -3734,7 +4140,7 @@ var tryCatchInEffectGen = createDiagnostic({
|
|
|
3734
4140
|
orElse2(() => typeParser.effectFnGen(effectGenNode)),
|
|
3735
4141
|
map3(() => {
|
|
3736
4142
|
report({
|
|
3737
|
-
node,
|
|
4143
|
+
location: node,
|
|
3738
4144
|
messageText: "Avoid using try/catch inside Effect generators. Use Effect's error handling mechanisms instead (e.g., Effect.try, Effect.tryPromise, Effect.catchAll, Effect.catchTag).",
|
|
3739
4145
|
fixes: []
|
|
3740
4146
|
});
|
|
@@ -3769,7 +4175,7 @@ var unnecessaryEffectGen = createDiagnostic({
|
|
|
3769
4175
|
typeParser.unnecessaryEffectGen(node),
|
|
3770
4176
|
map3(
|
|
3771
4177
|
({ replacementNode }) => report({
|
|
3772
|
-
node,
|
|
4178
|
+
location: node,
|
|
3773
4179
|
messageText: `This Effect.gen contains a single return statement.`,
|
|
3774
4180
|
fixes: [{
|
|
3775
4181
|
fixName: "unnecessaryEffectGen_fix",
|
|
@@ -3813,7 +4219,7 @@ var unnecessaryPipe = createDiagnostic({
|
|
|
3813
4219
|
map3(({ args: args2, subject }) => {
|
|
3814
4220
|
if (args2.length === 0) {
|
|
3815
4221
|
report({
|
|
3816
|
-
node,
|
|
4222
|
+
location: node,
|
|
3817
4223
|
messageText: `This pipe call contains no arguments.`,
|
|
3818
4224
|
fixes: [{
|
|
3819
4225
|
fixName: "unnecessaryPipe_fix",
|
|
@@ -3860,7 +4266,7 @@ var unnecessaryPipeChain = createDiagnostic({
|
|
|
3860
4266
|
),
|
|
3861
4267
|
map3(({ innerCall, pipeCall }) => {
|
|
3862
4268
|
report({
|
|
3863
|
-
node,
|
|
4269
|
+
location: node,
|
|
3864
4270
|
messageText: `Chained pipe calls can be simplified to a single pipe call`,
|
|
3865
4271
|
fixes: [{
|
|
3866
4272
|
fixName: "unnecessaryPipeChain_fix",
|
|
@@ -3928,7 +4334,8 @@ var diagnostics = [
|
|
|
3928
4334
|
effectInVoidSuccess,
|
|
3929
4335
|
unnecessaryPipeChain,
|
|
3930
4336
|
strictBooleanExpressions,
|
|
3931
|
-
multipleEffectProvide
|
|
4337
|
+
multipleEffectProvide,
|
|
4338
|
+
outdatedEffectCodegen
|
|
3932
4339
|
];
|
|
3933
4340
|
|
|
3934
4341
|
// src/transform.ts
|
|
@@ -3937,14 +4344,11 @@ function transform_default(program, pluginConfig, { addDiagnostic, ts: tsInstanc
|
|
|
3937
4344
|
return (sourceFile) => {
|
|
3938
4345
|
pipe(
|
|
3939
4346
|
getSemanticDiagnosticsWithCodeFixes(diagnostics, sourceFile),
|
|
3940
|
-
|
|
3941
|
-
|
|
4347
|
+
nanoLayer2,
|
|
4348
|
+
nanoLayer,
|
|
3942
4349
|
provideService(TypeCheckerApi, program.getTypeChecker()),
|
|
3943
|
-
provideService(
|
|
3944
|
-
provideService(
|
|
3945
|
-
TypeCheckerApiCache,
|
|
3946
|
-
makeTypeCheckerApiCache()
|
|
3947
|
-
),
|
|
4350
|
+
provideService(TypeScriptProgram, program),
|
|
4351
|
+
provideService(TypeScriptApi, tsInstance),
|
|
3948
4352
|
provideService(
|
|
3949
4353
|
LanguageServicePluginOptions,
|
|
3950
4354
|
parse(pluginConfig)
|