@effect/language-service 0.5.1 → 0.6.1
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/index.js +334 -199
- package/index.js.map +1 -1
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -115,6 +115,7 @@ var globalValue = (id, compute) => {
|
|
|
115
115
|
};
|
|
116
116
|
|
|
117
117
|
// node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Predicate.js
|
|
118
|
+
var isBoolean = (input) => typeof input === "boolean";
|
|
118
119
|
var isFunction2 = isFunction;
|
|
119
120
|
var isRecordOrArray = (input) => typeof input === "object" && input !== null;
|
|
120
121
|
var isObject = (input) => isRecordOrArray(input) || isFunction2(input);
|
|
@@ -814,12 +815,14 @@ function effectGen(ts, typeChecker) {
|
|
|
814
815
|
if (!ts.isPropertyAccessExpression(node.expression)) return yield* none2();
|
|
815
816
|
const propertyAccess = node.expression;
|
|
816
817
|
if (propertyAccess.name.text !== "gen") return yield* none2();
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
818
|
+
const effectModule = yield* importedEffectModule(ts, typeChecker)(propertyAccess.expression);
|
|
819
|
+
return {
|
|
820
|
+
node,
|
|
821
|
+
effectModule,
|
|
822
|
+
generatorFunction,
|
|
823
|
+
body: generatorFunction.body,
|
|
824
|
+
functionStar: generatorFunction.getFirstToken()
|
|
825
|
+
};
|
|
823
826
|
});
|
|
824
827
|
}
|
|
825
828
|
function effectFnUntracedGen(ts, typeChecker) {
|
|
@@ -832,12 +835,14 @@ function effectFnUntracedGen(ts, typeChecker) {
|
|
|
832
835
|
if (!ts.isPropertyAccessExpression(node.expression)) return yield* none2();
|
|
833
836
|
const propertyAccess = node.expression;
|
|
834
837
|
if (propertyAccess.name.text !== "fnUntraced") return yield* none2();
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
838
|
+
const effectModule = yield* importedEffectModule(ts, typeChecker)(propertyAccess.expression);
|
|
839
|
+
return {
|
|
840
|
+
node,
|
|
841
|
+
effectModule,
|
|
842
|
+
generatorFunction,
|
|
843
|
+
body: generatorFunction.body,
|
|
844
|
+
functionStar: generatorFunction.getFirstToken()
|
|
845
|
+
};
|
|
841
846
|
});
|
|
842
847
|
}
|
|
843
848
|
function effectFnGen(ts, typeChecker) {
|
|
@@ -851,71 +856,16 @@ function effectFnGen(ts, typeChecker) {
|
|
|
851
856
|
if (!ts.isPropertyAccessExpression(expressionToTest)) return yield* none2();
|
|
852
857
|
const propertyAccess = expressionToTest;
|
|
853
858
|
if (propertyAccess.name.text !== "fn") return yield* none2();
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
859
|
+
const effectModule = yield* importedEffectModule(ts, typeChecker)(propertyAccess.expression);
|
|
860
|
+
return {
|
|
861
|
+
node,
|
|
862
|
+
generatorFunction,
|
|
863
|
+
effectModule,
|
|
864
|
+
body: generatorFunction.body,
|
|
865
|
+
functionStar: generatorFunction.getFirstToken()
|
|
866
|
+
};
|
|
860
867
|
});
|
|
861
868
|
}
|
|
862
|
-
function expectedAndRealType(ts, typeChecker) {
|
|
863
|
-
return (node) => {
|
|
864
|
-
if (ts.isVariableDeclaration(node) && node.initializer) {
|
|
865
|
-
const expectedType = typeChecker.getTypeAtLocation(node.name);
|
|
866
|
-
const realType = typeChecker.getTypeAtLocation(node.initializer);
|
|
867
|
-
return [[node.name, expectedType, node.initializer, realType]];
|
|
868
|
-
}
|
|
869
|
-
if (ts.isCallExpression(node)) {
|
|
870
|
-
const resolvedSignature = typeChecker.getResolvedSignature(node);
|
|
871
|
-
if (resolvedSignature) {
|
|
872
|
-
return resolvedSignature.getParameters().map((parameter, index) => {
|
|
873
|
-
const expectedType = typeChecker.getTypeOfSymbolAtLocation(parameter, node);
|
|
874
|
-
const realType = typeChecker.getTypeAtLocation(node.arguments[index]);
|
|
875
|
-
return [node.arguments[index], expectedType, node.arguments[index], realType];
|
|
876
|
-
});
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
|
|
880
|
-
const parent = node.parent;
|
|
881
|
-
if (ts.isObjectLiteralElement(parent)) {
|
|
882
|
-
if (ts.isObjectLiteralExpression(parent.parent) && parent.name === node) {
|
|
883
|
-
const type = typeChecker.getContextualType(parent.parent);
|
|
884
|
-
if (type) {
|
|
885
|
-
const symbol3 = typeChecker.getPropertyOfType(type, node.text);
|
|
886
|
-
if (symbol3) {
|
|
887
|
-
const expectedType = typeChecker.getTypeOfSymbolAtLocation(symbol3, node);
|
|
888
|
-
const realType = typeChecker.getTypeAtLocation(node);
|
|
889
|
-
return [[node, expectedType, node, realType]];
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
896
|
-
const expectedType = typeChecker.getTypeAtLocation(node.left);
|
|
897
|
-
const realType = typeChecker.getTypeAtLocation(node.right);
|
|
898
|
-
return [[node.left, expectedType, node.right, realType]];
|
|
899
|
-
}
|
|
900
|
-
if (ts.isReturnStatement(node) && node.expression) {
|
|
901
|
-
const expectedType = typeChecker.getContextualType(node.expression);
|
|
902
|
-
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
903
|
-
if (expectedType) return [[node, expectedType, node, realType]];
|
|
904
|
-
}
|
|
905
|
-
if (ts.isArrowFunction(node) && ts.isExpression(node.body)) {
|
|
906
|
-
const body = node.body;
|
|
907
|
-
const expectedType = typeChecker.getContextualType(body);
|
|
908
|
-
const realType = typeChecker.getTypeAtLocation(body);
|
|
909
|
-
if (expectedType) return [[body, expectedType, body, realType]];
|
|
910
|
-
}
|
|
911
|
-
if (ts.isSatisfiesExpression(node)) {
|
|
912
|
-
const expectedType = typeChecker.getTypeAtLocation(node.type);
|
|
913
|
-
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
914
|
-
return [[node.expression, expectedType, node.expression, realType]];
|
|
915
|
-
}
|
|
916
|
-
return [];
|
|
917
|
-
};
|
|
918
|
-
}
|
|
919
869
|
|
|
920
870
|
// src/diagnostics/floatingEffect.ts
|
|
921
871
|
var floatingEffect = createDiagnostic({
|
|
@@ -958,6 +908,25 @@ var floatingEffect = createDiagnostic({
|
|
|
958
908
|
// node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/internal/array.js
|
|
959
909
|
var isNonEmptyArray = (self) => self.length > 0;
|
|
960
910
|
|
|
911
|
+
// node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Iterable.js
|
|
912
|
+
var findFirst = /* @__PURE__ */ dual(2, (self, f) => {
|
|
913
|
+
let i = 0;
|
|
914
|
+
for (const a of self) {
|
|
915
|
+
const o = f(a, i);
|
|
916
|
+
if (isBoolean(o)) {
|
|
917
|
+
if (o) {
|
|
918
|
+
return some2(a);
|
|
919
|
+
}
|
|
920
|
+
} else {
|
|
921
|
+
if (isSome2(o)) {
|
|
922
|
+
return o;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
i++;
|
|
926
|
+
}
|
|
927
|
+
return none2();
|
|
928
|
+
});
|
|
929
|
+
|
|
961
930
|
// node_modules/.pnpm/effect@3.12.5/node_modules/effect/dist/esm/Array.js
|
|
962
931
|
var fromIterable = (collection) => Array.isArray(collection) ? collection : Array.from(collection);
|
|
963
932
|
var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
|
|
@@ -979,6 +948,7 @@ var unsafeGet = /* @__PURE__ */ dual(2, (self, index) => {
|
|
|
979
948
|
var head = /* @__PURE__ */ get(0);
|
|
980
949
|
var headNonEmpty = /* @__PURE__ */ unsafeGet(0);
|
|
981
950
|
var tailNonEmpty = (self) => self.slice(1);
|
|
951
|
+
var findFirst2 = findFirst;
|
|
982
952
|
var sort = /* @__PURE__ */ dual(2, (self, O) => {
|
|
983
953
|
const out = Array.from(self);
|
|
984
954
|
out.sort(O);
|
|
@@ -1033,71 +1003,8 @@ function toTextRange(positionOrRange) {
|
|
|
1033
1003
|
function isNodeInRange(textRange) {
|
|
1034
1004
|
return (node) => node.pos <= textRange.pos && node.end >= textRange.end;
|
|
1035
1005
|
}
|
|
1036
|
-
function findModuleNamedBindings(ts) {
|
|
1037
|
-
return (sourceFile, moduleName) => fromNullable(ts.forEachChild(sourceFile, (node) => {
|
|
1038
|
-
if (!ts.isImportDeclaration(node)) return;
|
|
1039
|
-
const moduleSpecifier = node.moduleSpecifier;
|
|
1040
|
-
if (!ts.isStringLiteral(moduleSpecifier)) return;
|
|
1041
|
-
if (moduleSpecifier.text !== moduleName) return;
|
|
1042
|
-
const importClause = node.importClause;
|
|
1043
|
-
if (!importClause) return;
|
|
1044
|
-
const namedBindings = importClause.namedBindings;
|
|
1045
|
-
if (!namedBindings) return;
|
|
1046
|
-
return namedBindings;
|
|
1047
|
-
}));
|
|
1048
|
-
}
|
|
1049
|
-
function findModuleNamespaceImportIdentifierName(ts) {
|
|
1050
|
-
return (sourceFile, moduleName) => pipe(
|
|
1051
|
-
findModuleNamedBindings(ts)(sourceFile, moduleName),
|
|
1052
|
-
map(
|
|
1053
|
-
(namedBindings) => {
|
|
1054
|
-
if (!ts.isNamespaceImport(namedBindings)) return;
|
|
1055
|
-
return namedBindings.name.text;
|
|
1056
|
-
}
|
|
1057
|
-
),
|
|
1058
|
-
flatMap(fromNullable)
|
|
1059
|
-
);
|
|
1060
|
-
}
|
|
1061
|
-
function findModuleNamedImportIdentifierName(ts) {
|
|
1062
|
-
return (sourceFile, moduleName, namedImport) => pipe(
|
|
1063
|
-
findModuleNamedBindings(ts)(sourceFile, moduleName),
|
|
1064
|
-
map((namedBindings) => {
|
|
1065
|
-
if (!ts.isNamedImports(namedBindings)) return;
|
|
1066
|
-
for (const importSpecifier of namedBindings.elements) {
|
|
1067
|
-
if (importSpecifier.propertyName?.getText() === namedImport) {
|
|
1068
|
-
return importSpecifier.name?.escapedText || importSpecifier.propertyName?.getText();
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
}),
|
|
1072
|
-
flatMap(fromNullable)
|
|
1073
|
-
);
|
|
1074
|
-
}
|
|
1075
|
-
function findModuleImportIdentifierNameViaTypeChecker(ts, typeChecker) {
|
|
1076
|
-
return (sourceFile, importName) => {
|
|
1077
|
-
return fromNullable(ts.forEachChild(sourceFile, (node) => {
|
|
1078
|
-
if (!ts.isImportDeclaration(node)) return;
|
|
1079
|
-
if (!node.importClause) return;
|
|
1080
|
-
const namedBindings = node.importClause.namedBindings;
|
|
1081
|
-
if (!namedBindings) return;
|
|
1082
|
-
if (ts.isNamespaceImport(namedBindings)) {
|
|
1083
|
-
const symbol3 = typeChecker.getTypeAtLocation(namedBindings).getSymbol();
|
|
1084
|
-
if (!symbol3 || !symbol3.exports) return;
|
|
1085
|
-
if (!symbol3.exports.has(importName)) return;
|
|
1086
|
-
return namedBindings.name.escapedText;
|
|
1087
|
-
}
|
|
1088
|
-
if (ts.isNamedImports(namedBindings)) {
|
|
1089
|
-
for (const importSpecifier of namedBindings.elements) {
|
|
1090
|
-
const symbol3 = typeChecker.getTypeAtLocation(importSpecifier).getSymbol();
|
|
1091
|
-
if (!symbol3 || !symbol3.exports) return;
|
|
1092
|
-
if (!symbol3.exports.has(importName)) return;
|
|
1093
|
-
return importSpecifier.name?.escapedText || importSpecifier.propertyName?.getText();
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
}));
|
|
1097
|
-
};
|
|
1098
|
-
}
|
|
1099
1006
|
function transformAsyncAwaitToEffectGen(ts) {
|
|
1100
|
-
return (node,
|
|
1007
|
+
return (node, effectModuleName, onAwait) => {
|
|
1101
1008
|
function visitor(_) {
|
|
1102
1009
|
if (ts.isAwaitExpression(_)) {
|
|
1103
1010
|
const expression = ts.visitEachChild(_.expression, visitor, ts.nullTransformationContext);
|
|
@@ -1121,7 +1028,7 @@ function transformAsyncAwaitToEffectGen(ts) {
|
|
|
1121
1028
|
);
|
|
1122
1029
|
const effectGenCallExp = ts.factory.createCallExpression(
|
|
1123
1030
|
ts.factory.createPropertyAccessExpression(
|
|
1124
|
-
ts.factory.createIdentifier(
|
|
1031
|
+
ts.factory.createIdentifier(effectModuleName),
|
|
1125
1032
|
"gen"
|
|
1126
1033
|
),
|
|
1127
1034
|
void 0,
|
|
@@ -1197,17 +1104,24 @@ function removeReturnTypeAnnotation(ts, changes) {
|
|
|
1197
1104
|
}
|
|
1198
1105
|
};
|
|
1199
1106
|
}
|
|
1200
|
-
function
|
|
1201
|
-
return (sourceFile) =>
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
()
|
|
1209
|
-
|
|
1210
|
-
|
|
1107
|
+
function findImportedModuleIdentifier(ts) {
|
|
1108
|
+
return (test) => (sourceFile) => {
|
|
1109
|
+
for (const statement of sourceFile.statements) {
|
|
1110
|
+
if (!ts.isImportDeclaration(statement)) continue;
|
|
1111
|
+
const importClause = statement.importClause;
|
|
1112
|
+
if (!importClause) continue;
|
|
1113
|
+
const namedBindings = importClause.namedBindings;
|
|
1114
|
+
if (!namedBindings) continue;
|
|
1115
|
+
if (ts.isNamespaceImport(namedBindings)) {
|
|
1116
|
+
if (test(namedBindings.name)) return some2(namedBindings.name);
|
|
1117
|
+
} else if (ts.isNamedImports(namedBindings)) {
|
|
1118
|
+
for (const importSpecifier of namedBindings.elements) {
|
|
1119
|
+
if (test(importSpecifier.name)) return some2(importSpecifier.name);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
return none2();
|
|
1124
|
+
};
|
|
1211
1125
|
}
|
|
1212
1126
|
function simplifyTypeNode(ts) {
|
|
1213
1127
|
function collectCallable(typeNode) {
|
|
@@ -1278,6 +1192,35 @@ function deterministicTypeOrder(ts, typeChecker) {
|
|
|
1278
1192
|
return 0;
|
|
1279
1193
|
});
|
|
1280
1194
|
}
|
|
1195
|
+
function tryPreserveDeclarationSemantics(ts) {
|
|
1196
|
+
return (nodeToReplace, node) => {
|
|
1197
|
+
if (!ts.isExpression(node)) return node;
|
|
1198
|
+
if (ts.isFunctionDeclaration(nodeToReplace)) {
|
|
1199
|
+
if (!nodeToReplace.name) return node;
|
|
1200
|
+
return ts.factory.createVariableStatement(
|
|
1201
|
+
nodeToReplace.modifiers,
|
|
1202
|
+
ts.factory.createVariableDeclarationList(
|
|
1203
|
+
[ts.factory.createVariableDeclaration(
|
|
1204
|
+
nodeToReplace.name,
|
|
1205
|
+
void 0,
|
|
1206
|
+
void 0,
|
|
1207
|
+
node
|
|
1208
|
+
)],
|
|
1209
|
+
ts.NodeFlags.Const
|
|
1210
|
+
)
|
|
1211
|
+
);
|
|
1212
|
+
} else if (ts.isMethodDeclaration(nodeToReplace)) {
|
|
1213
|
+
return ts.factory.createPropertyDeclaration(
|
|
1214
|
+
nodeToReplace.modifiers,
|
|
1215
|
+
nodeToReplace.name,
|
|
1216
|
+
void 0,
|
|
1217
|
+
void 0,
|
|
1218
|
+
node
|
|
1219
|
+
);
|
|
1220
|
+
}
|
|
1221
|
+
return node;
|
|
1222
|
+
};
|
|
1223
|
+
}
|
|
1281
1224
|
|
|
1282
1225
|
// src/utils/TypeCheckerApi.ts
|
|
1283
1226
|
function getMissingTypeEntriesInTargetType(ts, typeChecker) {
|
|
@@ -1299,6 +1242,110 @@ function getMissingTypeEntriesInTargetType(ts, typeChecker) {
|
|
|
1299
1242
|
return result;
|
|
1300
1243
|
};
|
|
1301
1244
|
}
|
|
1245
|
+
function getInferredReturnType(ts, typeChecker) {
|
|
1246
|
+
function isConvertibleDeclaration(node) {
|
|
1247
|
+
switch (node.kind) {
|
|
1248
|
+
case ts.SyntaxKind.FunctionDeclaration:
|
|
1249
|
+
case ts.SyntaxKind.FunctionExpression:
|
|
1250
|
+
case ts.SyntaxKind.ArrowFunction:
|
|
1251
|
+
case ts.SyntaxKind.MethodDeclaration:
|
|
1252
|
+
return true;
|
|
1253
|
+
default:
|
|
1254
|
+
return false;
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
return (node) => {
|
|
1258
|
+
let declaration = node;
|
|
1259
|
+
while (declaration && !isConvertibleDeclaration(declaration)) {
|
|
1260
|
+
declaration = declaration.parent;
|
|
1261
|
+
}
|
|
1262
|
+
if (!isConvertibleDeclaration(declaration)) return none2();
|
|
1263
|
+
if (!declaration || !declaration.body) {
|
|
1264
|
+
return none2();
|
|
1265
|
+
}
|
|
1266
|
+
let returnType;
|
|
1267
|
+
if (typeChecker.isImplementationOfOverload(declaration)) {
|
|
1268
|
+
const signatures = typeChecker.getTypeAtLocation(declaration).getCallSignatures();
|
|
1269
|
+
if (signatures.length > 1) {
|
|
1270
|
+
returnType = typeChecker.getUnionType(
|
|
1271
|
+
signatures.map((s) => s.getReturnType()).filter((_) => !!_)
|
|
1272
|
+
);
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
if (!returnType) {
|
|
1276
|
+
const signature = typeChecker.getSignatureFromDeclaration(declaration);
|
|
1277
|
+
if (signature) {
|
|
1278
|
+
const typePredicate = typeChecker.getTypePredicateOfSignature(signature);
|
|
1279
|
+
if (typePredicate && typePredicate.type) {
|
|
1280
|
+
return some2(typePredicate.type);
|
|
1281
|
+
} else {
|
|
1282
|
+
returnType = typeChecker.getReturnTypeOfSignature(signature);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
if (!returnType) {
|
|
1287
|
+
return none2();
|
|
1288
|
+
}
|
|
1289
|
+
return some2(returnType);
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
function expectedAndRealType(ts, typeChecker) {
|
|
1293
|
+
return (node) => {
|
|
1294
|
+
if (ts.isVariableDeclaration(node) && node.initializer) {
|
|
1295
|
+
const expectedType = typeChecker.getTypeAtLocation(node.name);
|
|
1296
|
+
const realType = typeChecker.getTypeAtLocation(node.initializer);
|
|
1297
|
+
return [[node.name, expectedType, node.initializer, realType]];
|
|
1298
|
+
}
|
|
1299
|
+
if (ts.isCallExpression(node)) {
|
|
1300
|
+
const resolvedSignature = typeChecker.getResolvedSignature(node);
|
|
1301
|
+
if (resolvedSignature) {
|
|
1302
|
+
return resolvedSignature.getParameters().map((parameter, index) => {
|
|
1303
|
+
const expectedType = typeChecker.getTypeOfSymbolAtLocation(parameter, node);
|
|
1304
|
+
const realType = typeChecker.getTypeAtLocation(node.arguments[index]);
|
|
1305
|
+
return [node.arguments[index], expectedType, node.arguments[index], realType];
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
|
|
1310
|
+
const parent = node.parent;
|
|
1311
|
+
if (ts.isObjectLiteralElement(parent)) {
|
|
1312
|
+
if (ts.isObjectLiteralExpression(parent.parent) && parent.name === node) {
|
|
1313
|
+
const type = typeChecker.getContextualType(parent.parent);
|
|
1314
|
+
if (type) {
|
|
1315
|
+
const symbol3 = typeChecker.getPropertyOfType(type, node.text);
|
|
1316
|
+
if (symbol3) {
|
|
1317
|
+
const expectedType = typeChecker.getTypeOfSymbolAtLocation(symbol3, node);
|
|
1318
|
+
const realType = typeChecker.getTypeAtLocation(node);
|
|
1319
|
+
return [[node, expectedType, node, realType]];
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
1326
|
+
const expectedType = typeChecker.getTypeAtLocation(node.left);
|
|
1327
|
+
const realType = typeChecker.getTypeAtLocation(node.right);
|
|
1328
|
+
return [[node.left, expectedType, node.right, realType]];
|
|
1329
|
+
}
|
|
1330
|
+
if (ts.isReturnStatement(node) && node.expression) {
|
|
1331
|
+
const expectedType = getOrUndefined(getInferredReturnType(ts, typeChecker)(node));
|
|
1332
|
+
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
1333
|
+
if (expectedType) return [[node, expectedType, node, realType]];
|
|
1334
|
+
}
|
|
1335
|
+
if (ts.isArrowFunction(node) && ts.isExpression(node.body)) {
|
|
1336
|
+
const body = node.body;
|
|
1337
|
+
const expectedType = typeChecker.getContextualType(body);
|
|
1338
|
+
const realType = typeChecker.getTypeAtLocation(body);
|
|
1339
|
+
if (expectedType) return [[body, expectedType, body, realType]];
|
|
1340
|
+
}
|
|
1341
|
+
if (ts.isSatisfiesExpression(node)) {
|
|
1342
|
+
const expectedType = typeChecker.getTypeAtLocation(node.type);
|
|
1343
|
+
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
1344
|
+
return [[node.expression, expectedType, node.expression, realType]];
|
|
1345
|
+
}
|
|
1346
|
+
return [];
|
|
1347
|
+
};
|
|
1348
|
+
}
|
|
1302
1349
|
|
|
1303
1350
|
// src/diagnostics/missingEffectContext.ts
|
|
1304
1351
|
var missingEffectContext = createDiagnostic({
|
|
@@ -1544,7 +1591,9 @@ var asyncAwaitToGen = createRefactor({
|
|
|
1544
1591
|
description: "Convert to Effect.gen",
|
|
1545
1592
|
apply: (ts, program) => (sourceFile, textRange) => pipe(
|
|
1546
1593
|
getNodesContainingRange(ts)(sourceFile, textRange),
|
|
1547
|
-
filter(
|
|
1594
|
+
filter(
|
|
1595
|
+
(node) => ts.isFunctionDeclaration(node) || ts.isArrowFunction(node) || ts.isFunctionExpression(node)
|
|
1596
|
+
),
|
|
1548
1597
|
filter((node) => !!node.body),
|
|
1549
1598
|
filter(
|
|
1550
1599
|
(node) => !!(ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Async)
|
|
@@ -1554,15 +1603,25 @@ var asyncAwaitToGen = createRefactor({
|
|
|
1554
1603
|
kind: "refactor.rewrite.effect.asyncAwaitToGen",
|
|
1555
1604
|
description: "Rewrite to Effect.gen",
|
|
1556
1605
|
apply: (changeTracker) => {
|
|
1557
|
-
const
|
|
1606
|
+
const isImportedEffectModule = importedEffectModule(
|
|
1607
|
+
ts,
|
|
1608
|
+
program.getTypeChecker()
|
|
1609
|
+
);
|
|
1610
|
+
const effectModuleIdentifierName = pipe(
|
|
1611
|
+
findImportedModuleIdentifier(ts)(
|
|
1612
|
+
(node2) => isSome2(isImportedEffectModule(node2))
|
|
1613
|
+
)(sourceFile),
|
|
1614
|
+
map((node2) => node2.text),
|
|
1615
|
+
getOrElse(() => "Effect")
|
|
1616
|
+
);
|
|
1558
1617
|
const newDeclaration = transformAsyncAwaitToEffectGen(
|
|
1559
1618
|
ts
|
|
1560
1619
|
)(
|
|
1561
1620
|
node,
|
|
1562
|
-
|
|
1621
|
+
effectModuleIdentifierName,
|
|
1563
1622
|
(expression) => ts.factory.createCallExpression(
|
|
1564
1623
|
ts.factory.createPropertyAccessExpression(
|
|
1565
|
-
ts.factory.createIdentifier(
|
|
1624
|
+
ts.factory.createIdentifier(effectModuleIdentifierName),
|
|
1566
1625
|
"promise"
|
|
1567
1626
|
),
|
|
1568
1627
|
void 0,
|
|
@@ -1590,7 +1649,9 @@ var asyncAwaitToGenTryPromise = createRefactor({
|
|
|
1590
1649
|
description: "Convert to Effect.gen with failures",
|
|
1591
1650
|
apply: (ts, program) => (sourceFile, textRange) => pipe(
|
|
1592
1651
|
getNodesContainingRange(ts)(sourceFile, textRange),
|
|
1593
|
-
filter(
|
|
1652
|
+
filter(
|
|
1653
|
+
(node) => ts.isFunctionDeclaration(node) || ts.isArrowFunction(node) || ts.isFunctionExpression(node)
|
|
1654
|
+
),
|
|
1594
1655
|
filter((node) => !!node.body),
|
|
1595
1656
|
filter(
|
|
1596
1657
|
(node) => !!(ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Async)
|
|
@@ -1600,7 +1661,17 @@ var asyncAwaitToGenTryPromise = createRefactor({
|
|
|
1600
1661
|
kind: "refactor.rewrite.effect.asyncAwaitToGenTryPromise",
|
|
1601
1662
|
description: "Rewrite to Effect.gen with failures",
|
|
1602
1663
|
apply: (changeTracker) => {
|
|
1603
|
-
const
|
|
1664
|
+
const isImportedEffectModule = importedEffectModule(
|
|
1665
|
+
ts,
|
|
1666
|
+
program.getTypeChecker()
|
|
1667
|
+
);
|
|
1668
|
+
const effectModuleIdentifierName = pipe(
|
|
1669
|
+
findImportedModuleIdentifier(ts)(
|
|
1670
|
+
(node2) => isSome2(isImportedEffectModule(node2))
|
|
1671
|
+
)(sourceFile),
|
|
1672
|
+
map((node2) => node2.text),
|
|
1673
|
+
getOrElse(() => "Effect")
|
|
1674
|
+
);
|
|
1604
1675
|
let errorCount = 0;
|
|
1605
1676
|
function createErrorADT() {
|
|
1606
1677
|
errorCount++;
|
|
@@ -1619,10 +1690,10 @@ var asyncAwaitToGenTryPromise = createRefactor({
|
|
|
1619
1690
|
ts
|
|
1620
1691
|
)(
|
|
1621
1692
|
node,
|
|
1622
|
-
|
|
1693
|
+
effectModuleIdentifierName,
|
|
1623
1694
|
(expression) => ts.factory.createCallExpression(
|
|
1624
1695
|
ts.factory.createPropertyAccessExpression(
|
|
1625
|
-
ts.factory.createIdentifier(
|
|
1696
|
+
ts.factory.createIdentifier(effectModuleIdentifierName),
|
|
1626
1697
|
"tryPromise"
|
|
1627
1698
|
),
|
|
1628
1699
|
void 0,
|
|
@@ -1660,6 +1731,78 @@ var asyncAwaitToGenTryPromise = createRefactor({
|
|
|
1660
1731
|
)
|
|
1661
1732
|
});
|
|
1662
1733
|
|
|
1734
|
+
// src/refactors/effectGenToFn.ts
|
|
1735
|
+
var effectGenToFn = createRefactor({
|
|
1736
|
+
name: "effect/effectGenToFn",
|
|
1737
|
+
description: "Convert to Effect.fn",
|
|
1738
|
+
apply: (ts, program) => (sourceFile, textRange) => pipe(
|
|
1739
|
+
getNodesContainingRange(ts)(sourceFile, textRange),
|
|
1740
|
+
findFirst2(
|
|
1741
|
+
(node) => gen(function* () {
|
|
1742
|
+
const effectGen2 = yield* effectGen(ts, program.getTypeChecker())(node);
|
|
1743
|
+
let pipeArgs = ts.factory.createNodeArray([]);
|
|
1744
|
+
let nodeToReplace = node.parent;
|
|
1745
|
+
if (ts.isPropertyAccessExpression(node.parent) && node.parent.name.text === "pipe" && ts.isCallExpression(node.parent.parent)) {
|
|
1746
|
+
pipeArgs = node.parent.parent.arguments;
|
|
1747
|
+
nodeToReplace = node.parent.parent.parent;
|
|
1748
|
+
}
|
|
1749
|
+
while (nodeToReplace) {
|
|
1750
|
+
if (ts.isArrowFunction(nodeToReplace) || ts.isFunctionDeclaration(nodeToReplace) || ts.isMethodDeclaration(nodeToReplace)) {
|
|
1751
|
+
return { ...effectGen2, pipeArgs, nodeToReplace };
|
|
1752
|
+
}
|
|
1753
|
+
if (ts.isConciseBody(nodeToReplace) || ts.isReturnStatement(nodeToReplace)) {
|
|
1754
|
+
nodeToReplace = nodeToReplace.parent;
|
|
1755
|
+
continue;
|
|
1756
|
+
}
|
|
1757
|
+
if (ts.isBlock(nodeToReplace) && nodeToReplace.statements.length === 1) {
|
|
1758
|
+
nodeToReplace = nodeToReplace.parent;
|
|
1759
|
+
continue;
|
|
1760
|
+
}
|
|
1761
|
+
break;
|
|
1762
|
+
}
|
|
1763
|
+
return yield* none2();
|
|
1764
|
+
})
|
|
1765
|
+
),
|
|
1766
|
+
map(
|
|
1767
|
+
({ effectModule, generatorFunction, nodeToReplace, pipeArgs }) => ({
|
|
1768
|
+
kind: "refactor.rewrite.effect.effectGenToFn",
|
|
1769
|
+
description: "Convert to Effect.fn",
|
|
1770
|
+
apply: (changeTracker) => {
|
|
1771
|
+
const effectFn = nodeToReplace.name && ts.isIdentifier(nodeToReplace.name) ? ts.factory.createCallExpression(
|
|
1772
|
+
ts.factory.createPropertyAccessExpression(
|
|
1773
|
+
effectModule,
|
|
1774
|
+
"fn"
|
|
1775
|
+
),
|
|
1776
|
+
void 0,
|
|
1777
|
+
[ts.factory.createStringLiteral(nodeToReplace.name.text)]
|
|
1778
|
+
) : ts.factory.createPropertyAccessExpression(
|
|
1779
|
+
effectModule,
|
|
1780
|
+
"fn"
|
|
1781
|
+
);
|
|
1782
|
+
const effectFnCallWithGenerator = ts.factory.createCallExpression(
|
|
1783
|
+
effectFn,
|
|
1784
|
+
void 0,
|
|
1785
|
+
[ts.factory.createFunctionExpression(
|
|
1786
|
+
void 0,
|
|
1787
|
+
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
1788
|
+
void 0,
|
|
1789
|
+
nodeToReplace.typeParameters,
|
|
1790
|
+
nodeToReplace.parameters,
|
|
1791
|
+
nodeToReplace.type,
|
|
1792
|
+
generatorFunction.body
|
|
1793
|
+
)].concat(pipeArgs)
|
|
1794
|
+
);
|
|
1795
|
+
changeTracker.replaceNode(
|
|
1796
|
+
sourceFile,
|
|
1797
|
+
nodeToReplace,
|
|
1798
|
+
tryPreserveDeclarationSemantics(ts)(nodeToReplace, effectFnCallWithGenerator)
|
|
1799
|
+
);
|
|
1800
|
+
}
|
|
1801
|
+
})
|
|
1802
|
+
)
|
|
1803
|
+
)
|
|
1804
|
+
});
|
|
1805
|
+
|
|
1663
1806
|
// src/refactors/functionToArrow.ts
|
|
1664
1807
|
var functionToArrow = createRefactor({
|
|
1665
1808
|
name: "effect/functionToArrow",
|
|
@@ -1829,47 +1972,38 @@ var toggleReturnTypeAnnotation = createRefactor({
|
|
|
1829
1972
|
name: "effect/toggleReturnTypeAnnotation",
|
|
1830
1973
|
description: "Toggle return type annotation",
|
|
1831
1974
|
apply: (ts, program) => (sourceFile, textRange) => {
|
|
1832
|
-
function
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
return pipe(
|
|
1844
|
-
getNodesContainingRange(ts)(sourceFile, textRange),
|
|
1845
|
-
filter(isConvertibleDeclaration),
|
|
1846
|
-
head,
|
|
1847
|
-
map(
|
|
1848
|
-
(node) => ({
|
|
1975
|
+
return gen(function* () {
|
|
1976
|
+
const typeChecker = program.getTypeChecker();
|
|
1977
|
+
const node = yield* pipe(
|
|
1978
|
+
getNodesContainingRange(ts)(sourceFile, textRange),
|
|
1979
|
+
filter(
|
|
1980
|
+
(node2) => ts.isFunctionDeclaration(node2) || ts.isFunctionExpression(node2) || ts.isArrowFunction(node2) || ts.isMethodDeclaration(node2)
|
|
1981
|
+
),
|
|
1982
|
+
head
|
|
1983
|
+
);
|
|
1984
|
+
if (node.type) {
|
|
1985
|
+
return {
|
|
1849
1986
|
kind: "refactor.rewrite.effect.toggleReturnTypeAnnotation",
|
|
1850
1987
|
description: "Toggle return type annotation",
|
|
1851
|
-
apply: (changeTracker) =>
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
})
|
|
1871
|
-
)
|
|
1872
|
-
);
|
|
1988
|
+
apply: (changeTracker) => removeReturnTypeAnnotation(ts, changeTracker)(sourceFile, node)
|
|
1989
|
+
};
|
|
1990
|
+
}
|
|
1991
|
+
const returnType = yield* getInferredReturnType(ts, typeChecker)(node);
|
|
1992
|
+
const returnTypeNode = yield* fromNullable(
|
|
1993
|
+
typeChecker.typeToTypeNode(returnType, node, ts.NodeBuilderFlags.NoTruncation)
|
|
1994
|
+
);
|
|
1995
|
+
return {
|
|
1996
|
+
kind: "refactor.rewrite.effect.toggleReturnTypeAnnotation",
|
|
1997
|
+
description: "Toggle return type annotation",
|
|
1998
|
+
apply: (changeTracker) => {
|
|
1999
|
+
addReturnTypeAnnotation(ts, changeTracker)(
|
|
2000
|
+
sourceFile,
|
|
2001
|
+
node,
|
|
2002
|
+
simplifyTypeNode(ts)(returnTypeNode)
|
|
2003
|
+
);
|
|
2004
|
+
}
|
|
2005
|
+
};
|
|
2006
|
+
});
|
|
1873
2007
|
}
|
|
1874
2008
|
});
|
|
1875
2009
|
|
|
@@ -1953,7 +2087,8 @@ var refactors = {
|
|
|
1953
2087
|
toggleLazyConst,
|
|
1954
2088
|
toggleReturnTypeAnnotation,
|
|
1955
2089
|
toggleTypeAnnotation,
|
|
1956
|
-
wrapWithPipe
|
|
2090
|
+
wrapWithPipe,
|
|
2091
|
+
effectGenToFn
|
|
1957
2092
|
};
|
|
1958
2093
|
|
|
1959
2094
|
// src/index.ts
|