@effect/language-service 0.20.1 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/index.js +848 -620
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +674 -446
- package/transform.js.map +1 -1
package/index.js
CHANGED
|
@@ -489,6 +489,7 @@ function compareBoth(self, that) {
|
|
|
489
489
|
return structuralRegionState.enabled && structuralRegionState.tester ? structuralRegionState.tester(self, that) : false;
|
|
490
490
|
}
|
|
491
491
|
var isEqual = (u) => hasProperty(u, symbol2);
|
|
492
|
+
var equivalence = () => equals;
|
|
492
493
|
|
|
493
494
|
// node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Inspectable.js
|
|
494
495
|
var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
|
|
@@ -947,6 +948,20 @@ var sort = /* @__PURE__ */ dual(2, (self, O) => {
|
|
|
947
948
|
out.sort(O);
|
|
948
949
|
return out;
|
|
949
950
|
});
|
|
951
|
+
var containsWith = (isEquivalent) => dual(2, (self, a) => {
|
|
952
|
+
for (const i of self) {
|
|
953
|
+
if (isEquivalent(a, i)) {
|
|
954
|
+
return true;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
return false;
|
|
958
|
+
});
|
|
959
|
+
var _equivalence = /* @__PURE__ */ equivalence();
|
|
960
|
+
var intersectionWith = (isEquivalent) => {
|
|
961
|
+
const has = containsWith(isEquivalent);
|
|
962
|
+
return dual(2, (self, that) => fromIterable(self).filter((a) => has(that, a)));
|
|
963
|
+
};
|
|
964
|
+
var intersection = /* @__PURE__ */ intersectionWith(_equivalence);
|
|
950
965
|
var empty = () => [];
|
|
951
966
|
var map3 = /* @__PURE__ */ dual(2, (self, f) => self.map(f));
|
|
952
967
|
var flatMap2 = /* @__PURE__ */ dual(2, (self, f) => {
|
|
@@ -1039,7 +1054,8 @@ function make3(run2) {
|
|
|
1039
1054
|
return result;
|
|
1040
1055
|
}
|
|
1041
1056
|
var unsafeRun = (fa) => {
|
|
1042
|
-
const
|
|
1057
|
+
const program = provideService(internalNanoCache, {})(fa);
|
|
1058
|
+
const result = program.run(contextEmpty);
|
|
1043
1059
|
switch (result._tag) {
|
|
1044
1060
|
case "Left":
|
|
1045
1061
|
return left2(result.value);
|
|
@@ -1076,14 +1092,14 @@ var orElse3 = (f) => (fa) => make3((ctx) => {
|
|
|
1076
1092
|
});
|
|
1077
1093
|
var firstSuccessOf = (arr) => arr.slice(1).reduce((arr2, fa) => orElse3(() => fa)(arr2), arr[0]);
|
|
1078
1094
|
var service = (tag) => make3(
|
|
1079
|
-
(ctx) => tag.key in ctx.value ?
|
|
1095
|
+
(ctx) => tag.key in ctx.value ? ctx.value[tag.key] : makeInternalDefect(`Cannot find service ${tag.key}`)
|
|
1080
1096
|
);
|
|
1081
1097
|
var provideService = (tag, value) => (fa) => make3((ctx) => {
|
|
1082
1098
|
return fa.run({
|
|
1083
1099
|
...ctx,
|
|
1084
1100
|
value: {
|
|
1085
1101
|
...ctx.value,
|
|
1086
|
-
[tag.key]: value
|
|
1102
|
+
[tag.key]: makeInternalSuccess(value)
|
|
1087
1103
|
}
|
|
1088
1104
|
});
|
|
1089
1105
|
});
|
|
@@ -1124,14 +1140,41 @@ var option = (fa) => make3((ctx) => {
|
|
|
1124
1140
|
return result;
|
|
1125
1141
|
}
|
|
1126
1142
|
});
|
|
1127
|
-
var
|
|
1143
|
+
var successUndefined = makeInternalSuccess(void 0);
|
|
1144
|
+
var void_2 = make3(() => successUndefined);
|
|
1145
|
+
var ignore = (fa) => make3((ctx) => {
|
|
1146
|
+
fa.run(ctx);
|
|
1147
|
+
return successUndefined;
|
|
1148
|
+
});
|
|
1149
|
+
var all2 = (...args) => make3((ctx) => {
|
|
1128
1150
|
const results = [];
|
|
1129
1151
|
for (const arg of args) {
|
|
1130
|
-
const result =
|
|
1131
|
-
|
|
1152
|
+
const result = arg.run(ctx);
|
|
1153
|
+
if (result._tag !== "Right") return result;
|
|
1154
|
+
results.push(result.value);
|
|
1132
1155
|
}
|
|
1133
|
-
return results;
|
|
1156
|
+
return makeInternalSuccess(results);
|
|
1134
1157
|
});
|
|
1158
|
+
var internalNanoCache = Tag(
|
|
1159
|
+
"@effect/language-service/internalNanoCache"
|
|
1160
|
+
);
|
|
1161
|
+
function cachedBy(fa, key, lookupKey) {
|
|
1162
|
+
return (...args) => make3((ctx) => {
|
|
1163
|
+
const cacheObj = ctx.value[internalNanoCache.key];
|
|
1164
|
+
let cache = cacheObj[key];
|
|
1165
|
+
if (!cache) {
|
|
1166
|
+
cache = /* @__PURE__ */ new Map();
|
|
1167
|
+
cacheObj[key] = cache;
|
|
1168
|
+
}
|
|
1169
|
+
const lookup = lookupKey(...args);
|
|
1170
|
+
if (cache.has(lookup)) {
|
|
1171
|
+
return cache.get(lookup);
|
|
1172
|
+
}
|
|
1173
|
+
const result = fa(...args).run(ctx);
|
|
1174
|
+
cache.set(lookup, result);
|
|
1175
|
+
return result;
|
|
1176
|
+
});
|
|
1177
|
+
}
|
|
1135
1178
|
|
|
1136
1179
|
// src/core/TypeScriptApi.ts
|
|
1137
1180
|
var TypeScriptApi = Tag("TypeScriptApi");
|
|
@@ -1924,6 +1967,511 @@ var effectSelfInClasses = createCompletion({
|
|
|
1924
1967
|
})
|
|
1925
1968
|
});
|
|
1926
1969
|
|
|
1970
|
+
// src/core/TypeParser.ts
|
|
1971
|
+
var TypeParser = Tag("@effect/language-service/TypeParser");
|
|
1972
|
+
var TypeParserIssue = class _TypeParserIssue {
|
|
1973
|
+
_tag = "@effect/language-service/TypeParserIssue";
|
|
1974
|
+
static issue = fail(new _TypeParserIssue());
|
|
1975
|
+
};
|
|
1976
|
+
function make4(ts, typeChecker) {
|
|
1977
|
+
function typeParserIssue(_message, _type, _node) {
|
|
1978
|
+
return TypeParserIssue.issue;
|
|
1979
|
+
}
|
|
1980
|
+
function covariantTypeArgument(type) {
|
|
1981
|
+
const signatures = type.getCallSignatures();
|
|
1982
|
+
if (signatures.length !== 1) {
|
|
1983
|
+
return typeParserIssue("Covariant type has no call signature", type);
|
|
1984
|
+
}
|
|
1985
|
+
return succeed(signatures[0].getReturnType());
|
|
1986
|
+
}
|
|
1987
|
+
function contravariantTypeArgument(type) {
|
|
1988
|
+
const signatures = type.getCallSignatures();
|
|
1989
|
+
if (signatures.length !== 1) {
|
|
1990
|
+
return typeParserIssue("Contravariant type has no call signature", type);
|
|
1991
|
+
}
|
|
1992
|
+
return succeed(signatures[0].getTypeParameterAtPosition(0));
|
|
1993
|
+
}
|
|
1994
|
+
function invariantTypeArgument(type) {
|
|
1995
|
+
const signatures = type.getCallSignatures();
|
|
1996
|
+
if (signatures.length !== 1) {
|
|
1997
|
+
return typeParserIssue("Invariant type has no call signature", type);
|
|
1998
|
+
}
|
|
1999
|
+
return succeed(signatures[0].getReturnType());
|
|
2000
|
+
}
|
|
2001
|
+
const pipeableType = cachedBy(
|
|
2002
|
+
fn("TypeParser.pipeableType")(function* (type, atLocation) {
|
|
2003
|
+
const pipeSymbol = typeChecker.getPropertyOfType(type, "pipe");
|
|
2004
|
+
if (!pipeSymbol) {
|
|
2005
|
+
return yield* typeParserIssue("Type has no 'pipe' property", type, atLocation);
|
|
2006
|
+
}
|
|
2007
|
+
const pipeType = typeChecker.getTypeOfSymbolAtLocation(pipeSymbol, atLocation);
|
|
2008
|
+
const signatures = pipeType.getCallSignatures();
|
|
2009
|
+
if (signatures.length === 0) {
|
|
2010
|
+
return yield* typeParserIssue("'pipe' property is not callable", type, atLocation);
|
|
2011
|
+
}
|
|
2012
|
+
return type;
|
|
2013
|
+
}),
|
|
2014
|
+
"TypeParser.pipeableType",
|
|
2015
|
+
(type) => type
|
|
2016
|
+
);
|
|
2017
|
+
const varianceStructCovariantType = (type, atLocation, propertyName) => {
|
|
2018
|
+
const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
|
|
2019
|
+
if (!propertySymbol) {
|
|
2020
|
+
return typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
|
|
2021
|
+
}
|
|
2022
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2023
|
+
return covariantTypeArgument(propertyType);
|
|
2024
|
+
};
|
|
2025
|
+
const varianceStructContravariantType = (type, atLocation, propertyName) => {
|
|
2026
|
+
const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
|
|
2027
|
+
if (!propertySymbol) {
|
|
2028
|
+
return typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
|
|
2029
|
+
}
|
|
2030
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2031
|
+
return contravariantTypeArgument(propertyType);
|
|
2032
|
+
};
|
|
2033
|
+
const varianceStructInvariantType = (type, atLocation, propertyName) => {
|
|
2034
|
+
const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
|
|
2035
|
+
if (!propertySymbol) {
|
|
2036
|
+
return typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
|
|
2037
|
+
}
|
|
2038
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2039
|
+
return invariantTypeArgument(propertyType);
|
|
2040
|
+
};
|
|
2041
|
+
const effectVarianceStruct = (type, atLocation) => map4(
|
|
2042
|
+
all2(
|
|
2043
|
+
varianceStructCovariantType(type, atLocation, "_A"),
|
|
2044
|
+
varianceStructCovariantType(type, atLocation, "_E"),
|
|
2045
|
+
varianceStructCovariantType(type, atLocation, "_R")
|
|
2046
|
+
),
|
|
2047
|
+
([A, E, R]) => ({ A, E, R })
|
|
2048
|
+
);
|
|
2049
|
+
const layerVarianceStruct = (type, atLocation) => map4(
|
|
2050
|
+
all2(
|
|
2051
|
+
varianceStructContravariantType(type, atLocation, "_ROut"),
|
|
2052
|
+
varianceStructCovariantType(type, atLocation, "_E"),
|
|
2053
|
+
varianceStructCovariantType(type, atLocation, "_RIn")
|
|
2054
|
+
),
|
|
2055
|
+
([ROut, E, RIn]) => ({ ROut, E, RIn })
|
|
2056
|
+
);
|
|
2057
|
+
const effectType = cachedBy(
|
|
2058
|
+
fn("TypeParser.effectType")(function* (type, atLocation) {
|
|
2059
|
+
yield* pipeableType(type, atLocation);
|
|
2060
|
+
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2061
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2062
|
+
);
|
|
2063
|
+
propertiesSymbols.sort((a, b) => b.name.indexOf("EffectTypeId") - a.name.indexOf("EffectTypeId"));
|
|
2064
|
+
for (const propertySymbol of propertiesSymbols) {
|
|
2065
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2066
|
+
const varianceArgs = yield* option(effectVarianceStruct(
|
|
2067
|
+
propertyType,
|
|
2068
|
+
atLocation
|
|
2069
|
+
));
|
|
2070
|
+
if (isSome2(varianceArgs)) {
|
|
2071
|
+
return varianceArgs.value;
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
|
|
2075
|
+
}),
|
|
2076
|
+
"TypeParser.effectType",
|
|
2077
|
+
(type) => type
|
|
2078
|
+
);
|
|
2079
|
+
const layerType = cachedBy(
|
|
2080
|
+
fn("TypeParser.layerType")(function* (type, atLocation) {
|
|
2081
|
+
yield* pipeableType(type, atLocation);
|
|
2082
|
+
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2083
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2084
|
+
);
|
|
2085
|
+
propertiesSymbols.sort((a, b) => b.name.indexOf("LayerTypeId") - a.name.indexOf("LayerTypeId"));
|
|
2086
|
+
for (const propertySymbol of propertiesSymbols) {
|
|
2087
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2088
|
+
const varianceArgs = yield* option(layerVarianceStruct(
|
|
2089
|
+
propertyType,
|
|
2090
|
+
atLocation
|
|
2091
|
+
));
|
|
2092
|
+
if (isSome2(varianceArgs)) {
|
|
2093
|
+
return varianceArgs.value;
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
return yield* typeParserIssue("Type has no layer variance struct", type, atLocation);
|
|
2097
|
+
}),
|
|
2098
|
+
"TypeParser.layerType",
|
|
2099
|
+
(type) => type
|
|
2100
|
+
);
|
|
2101
|
+
const fiberType = cachedBy(
|
|
2102
|
+
fn("TypeParser.fiberType")(function* (type, atLocation) {
|
|
2103
|
+
const awaitSymbol = typeChecker.getPropertyOfType(type, "await");
|
|
2104
|
+
const pollSymbol = typeChecker.getPropertyOfType(type, "poll");
|
|
2105
|
+
if (!awaitSymbol || !pollSymbol) {
|
|
2106
|
+
return yield* typeParserIssue(
|
|
2107
|
+
"Type is not a fiber because it does not have 'await' or 'poll' property",
|
|
2108
|
+
type,
|
|
2109
|
+
atLocation
|
|
2110
|
+
);
|
|
2111
|
+
}
|
|
2112
|
+
return yield* effectType(type, atLocation);
|
|
2113
|
+
}),
|
|
2114
|
+
"TypeParser.fiberType",
|
|
2115
|
+
(type) => type
|
|
2116
|
+
);
|
|
2117
|
+
const effectSubtype = cachedBy(
|
|
2118
|
+
fn("TypeParser.effectSubtype")(function* (type, atLocation) {
|
|
2119
|
+
const tagSymbol = typeChecker.getPropertyOfType(type, "_tag");
|
|
2120
|
+
const getSymbol = typeChecker.getPropertyOfType(type, "get");
|
|
2121
|
+
if (!(tagSymbol || getSymbol)) {
|
|
2122
|
+
return yield* typeParserIssue(
|
|
2123
|
+
"Type is not a subtype of effect because it does not have '_tag' or 'get' property",
|
|
2124
|
+
type,
|
|
2125
|
+
atLocation
|
|
2126
|
+
);
|
|
2127
|
+
}
|
|
2128
|
+
return yield* effectType(type, atLocation);
|
|
2129
|
+
}),
|
|
2130
|
+
"TypeParser.effectSubtype",
|
|
2131
|
+
(type) => type
|
|
2132
|
+
);
|
|
2133
|
+
const importedEffectModule = cachedBy(
|
|
2134
|
+
fn("TypeParser.importedEffectModule")(function* (node) {
|
|
2135
|
+
const type = typeChecker.getTypeAtLocation(node);
|
|
2136
|
+
const propertySymbol = typeChecker.getPropertyOfType(type, "never");
|
|
2137
|
+
if (!propertySymbol) {
|
|
2138
|
+
return yield* typeParserIssue("Type has no 'never' property", type, node);
|
|
2139
|
+
}
|
|
2140
|
+
if (!ts.isExpression(node)) {
|
|
2141
|
+
return yield* typeParserIssue("Node is not an expression", type, node);
|
|
2142
|
+
}
|
|
2143
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, node);
|
|
2144
|
+
yield* effectType(propertyType, node);
|
|
2145
|
+
return node;
|
|
2146
|
+
}),
|
|
2147
|
+
"TypeParser.importedEffectModule",
|
|
2148
|
+
(node) => node
|
|
2149
|
+
);
|
|
2150
|
+
const effectGen = cachedBy(
|
|
2151
|
+
fn("TypeParser.effectGen")(function* (node) {
|
|
2152
|
+
if (!ts.isCallExpression(node)) {
|
|
2153
|
+
return yield* typeParserIssue("Node is not a call expression", void 0, node);
|
|
2154
|
+
}
|
|
2155
|
+
if (node.arguments.length === 0) {
|
|
2156
|
+
return yield* typeParserIssue("Node has no arguments", void 0, node);
|
|
2157
|
+
}
|
|
2158
|
+
const generatorFunction = node.arguments[0];
|
|
2159
|
+
if (!ts.isFunctionExpression(generatorFunction)) {
|
|
2160
|
+
return yield* typeParserIssue("Node is not a function expression", void 0, node);
|
|
2161
|
+
}
|
|
2162
|
+
if (generatorFunction.asteriskToken === void 0) {
|
|
2163
|
+
return yield* typeParserIssue("Node is not a generator function", void 0, node);
|
|
2164
|
+
}
|
|
2165
|
+
if (!ts.isPropertyAccessExpression(node.expression)) {
|
|
2166
|
+
return yield* typeParserIssue("Node is not a property access expression", void 0, node);
|
|
2167
|
+
}
|
|
2168
|
+
const propertyAccess = node.expression;
|
|
2169
|
+
if (propertyAccess.name.text !== "gen") {
|
|
2170
|
+
return yield* typeParserIssue("Call expression name is not 'gen'", void 0, node);
|
|
2171
|
+
}
|
|
2172
|
+
const effectModule = yield* importedEffectModule(propertyAccess.expression);
|
|
2173
|
+
return {
|
|
2174
|
+
node,
|
|
2175
|
+
effectModule,
|
|
2176
|
+
generatorFunction,
|
|
2177
|
+
body: generatorFunction.body,
|
|
2178
|
+
functionStar: generatorFunction.getFirstToken()
|
|
2179
|
+
};
|
|
2180
|
+
}),
|
|
2181
|
+
"TypeParser.effectGen",
|
|
2182
|
+
(node) => node
|
|
2183
|
+
);
|
|
2184
|
+
const effectFnUntracedGen = cachedBy(
|
|
2185
|
+
fn("TypeParser.effectFnUntracedGen")(
|
|
2186
|
+
function* (node) {
|
|
2187
|
+
if (!ts.isCallExpression(node)) {
|
|
2188
|
+
return yield* typeParserIssue("Node is not a call expression", void 0, node);
|
|
2189
|
+
}
|
|
2190
|
+
if (node.arguments.length === 0) {
|
|
2191
|
+
return yield* typeParserIssue("Node has no arguments", void 0, node);
|
|
2192
|
+
}
|
|
2193
|
+
const generatorFunction = node.arguments[0];
|
|
2194
|
+
if (!ts.isFunctionExpression(generatorFunction)) {
|
|
2195
|
+
return yield* typeParserIssue("Node is not a function expression", void 0, node);
|
|
2196
|
+
}
|
|
2197
|
+
if (generatorFunction.asteriskToken === void 0) {
|
|
2198
|
+
return yield* typeParserIssue(
|
|
2199
|
+
"Node is not a generator function",
|
|
2200
|
+
void 0,
|
|
2201
|
+
node
|
|
2202
|
+
);
|
|
2203
|
+
}
|
|
2204
|
+
if (!ts.isPropertyAccessExpression(node.expression)) {
|
|
2205
|
+
return yield* typeParserIssue(
|
|
2206
|
+
"Node is not a property access expression",
|
|
2207
|
+
void 0,
|
|
2208
|
+
node
|
|
2209
|
+
);
|
|
2210
|
+
}
|
|
2211
|
+
const propertyAccess = node.expression;
|
|
2212
|
+
if (propertyAccess.name.text !== "fnUntraced") {
|
|
2213
|
+
return yield* typeParserIssue(
|
|
2214
|
+
"Call expression name is not 'fnUntraced'",
|
|
2215
|
+
void 0,
|
|
2216
|
+
node
|
|
2217
|
+
);
|
|
2218
|
+
}
|
|
2219
|
+
const effectModule = yield* importedEffectModule(propertyAccess.expression);
|
|
2220
|
+
return {
|
|
2221
|
+
node,
|
|
2222
|
+
effectModule,
|
|
2223
|
+
generatorFunction,
|
|
2224
|
+
body: generatorFunction.body,
|
|
2225
|
+
functionStar: generatorFunction.getFirstToken()
|
|
2226
|
+
};
|
|
2227
|
+
}
|
|
2228
|
+
),
|
|
2229
|
+
"TypeParser.effectFnUntracedGen",
|
|
2230
|
+
(node) => node
|
|
2231
|
+
);
|
|
2232
|
+
const effectFnGen = cachedBy(
|
|
2233
|
+
fn("TypeParser.effectFnGen")(function* (node) {
|
|
2234
|
+
if (!ts.isCallExpression(node)) {
|
|
2235
|
+
return yield* typeParserIssue("Node is not a call expression", void 0, node);
|
|
2236
|
+
}
|
|
2237
|
+
if (node.arguments.length === 0) {
|
|
2238
|
+
return yield* typeParserIssue("Node has no arguments", void 0, node);
|
|
2239
|
+
}
|
|
2240
|
+
const generatorFunction = node.arguments[0];
|
|
2241
|
+
if (!ts.isFunctionExpression(generatorFunction)) {
|
|
2242
|
+
return yield* typeParserIssue(
|
|
2243
|
+
"Node is not a function expression",
|
|
2244
|
+
void 0,
|
|
2245
|
+
node
|
|
2246
|
+
);
|
|
2247
|
+
}
|
|
2248
|
+
if (generatorFunction.asteriskToken === void 0) {
|
|
2249
|
+
return yield* typeParserIssue(
|
|
2250
|
+
"Node is not a generator function",
|
|
2251
|
+
void 0,
|
|
2252
|
+
node
|
|
2253
|
+
);
|
|
2254
|
+
}
|
|
2255
|
+
const expressionToTest = ts.isCallExpression(node.expression) ? node.expression.expression : node.expression;
|
|
2256
|
+
if (!ts.isPropertyAccessExpression(expressionToTest)) {
|
|
2257
|
+
return yield* typeParserIssue(
|
|
2258
|
+
"Node is not a property access expression",
|
|
2259
|
+
void 0,
|
|
2260
|
+
node
|
|
2261
|
+
);
|
|
2262
|
+
}
|
|
2263
|
+
const propertyAccess = expressionToTest;
|
|
2264
|
+
if (propertyAccess.name.text !== "fn") {
|
|
2265
|
+
return yield* typeParserIssue(
|
|
2266
|
+
"Call expression name is not 'fn'",
|
|
2267
|
+
void 0,
|
|
2268
|
+
node
|
|
2269
|
+
);
|
|
2270
|
+
}
|
|
2271
|
+
const effectModule = yield* importedEffectModule(propertyAccess.expression);
|
|
2272
|
+
return {
|
|
2273
|
+
node,
|
|
2274
|
+
generatorFunction,
|
|
2275
|
+
effectModule,
|
|
2276
|
+
body: generatorFunction.body,
|
|
2277
|
+
functionStar: generatorFunction.getFirstToken()
|
|
2278
|
+
};
|
|
2279
|
+
}),
|
|
2280
|
+
"TypeParser.effectFnGen",
|
|
2281
|
+
(node) => node
|
|
2282
|
+
);
|
|
2283
|
+
const unnecessaryEffectGen2 = cachedBy(
|
|
2284
|
+
fn("TypeParser.unnecessaryEffectGen")(function* (node) {
|
|
2285
|
+
const { body } = yield* effectGen(node);
|
|
2286
|
+
if (body.statements.length !== 1) {
|
|
2287
|
+
return yield* typeParserIssue(
|
|
2288
|
+
"Generator body should have a single statement",
|
|
2289
|
+
void 0,
|
|
2290
|
+
node
|
|
2291
|
+
);
|
|
2292
|
+
}
|
|
2293
|
+
let explicitReturn = false;
|
|
2294
|
+
let nodeToCheck = body.statements[0];
|
|
2295
|
+
while (nodeToCheck) {
|
|
2296
|
+
if (ts.isReturnStatement(nodeToCheck) && nodeToCheck.expression) {
|
|
2297
|
+
nodeToCheck = nodeToCheck.expression;
|
|
2298
|
+
explicitReturn = true;
|
|
2299
|
+
continue;
|
|
2300
|
+
}
|
|
2301
|
+
if (ts.isExpressionStatement(nodeToCheck)) {
|
|
2302
|
+
nodeToCheck = nodeToCheck.expression;
|
|
2303
|
+
continue;
|
|
2304
|
+
}
|
|
2305
|
+
if (ts.isYieldExpression(nodeToCheck) && nodeToCheck.asteriskToken && nodeToCheck.expression) {
|
|
2306
|
+
const yieldedExpression = nodeToCheck.expression;
|
|
2307
|
+
const type = typeChecker.getTypeAtLocation(yieldedExpression);
|
|
2308
|
+
const { A: successType } = yield* effectType(type, yieldedExpression);
|
|
2309
|
+
let replacementNode = succeed(yieldedExpression);
|
|
2310
|
+
if (!explicitReturn && !(successType.flags & ts.TypeFlags.VoidLike)) {
|
|
2311
|
+
replacementNode = pipe(
|
|
2312
|
+
gen2(function* () {
|
|
2313
|
+
const effectIdentifier = pipe(
|
|
2314
|
+
yield* option(
|
|
2315
|
+
findImportedModuleIdentifierByPackageAndNameOrBarrel(node.getSourceFile(), "effect", "Effect")
|
|
2316
|
+
),
|
|
2317
|
+
match2({
|
|
2318
|
+
onNone: () => "Effect",
|
|
2319
|
+
onSome: (_) => _.text
|
|
2320
|
+
})
|
|
2321
|
+
);
|
|
2322
|
+
return ts.factory.createCallExpression(
|
|
2323
|
+
ts.factory.createPropertyAccessExpression(
|
|
2324
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
2325
|
+
"asVoid"
|
|
2326
|
+
),
|
|
2327
|
+
void 0,
|
|
2328
|
+
[
|
|
2329
|
+
yieldedExpression
|
|
2330
|
+
]
|
|
2331
|
+
);
|
|
2332
|
+
}),
|
|
2333
|
+
provideService(TypeScriptApi, ts)
|
|
2334
|
+
);
|
|
2335
|
+
}
|
|
2336
|
+
return { node, body, yieldedExpression, replacementNode };
|
|
2337
|
+
}
|
|
2338
|
+
break;
|
|
2339
|
+
}
|
|
2340
|
+
return yield* typeParserIssue(
|
|
2341
|
+
"Not an handled node",
|
|
2342
|
+
void 0,
|
|
2343
|
+
node
|
|
2344
|
+
);
|
|
2345
|
+
}),
|
|
2346
|
+
"TypeParser.unnecessaryEffectGen",
|
|
2347
|
+
(node) => node
|
|
2348
|
+
);
|
|
2349
|
+
const effectSchemaVarianceStruct = (type, atLocation) => map4(
|
|
2350
|
+
all2(
|
|
2351
|
+
varianceStructInvariantType(type, atLocation, "_A"),
|
|
2352
|
+
varianceStructInvariantType(type, atLocation, "_I"),
|
|
2353
|
+
varianceStructCovariantType(type, atLocation, "_R")
|
|
2354
|
+
),
|
|
2355
|
+
([A, I, R]) => ({ A, I, R })
|
|
2356
|
+
);
|
|
2357
|
+
const effectSchemaType = cachedBy(
|
|
2358
|
+
fn("TypeParser.effectSchemaType")(function* (type, atLocation) {
|
|
2359
|
+
yield* pipeableType(type, atLocation);
|
|
2360
|
+
const ast = typeChecker.getPropertyOfType(type, "ast");
|
|
2361
|
+
if (!ast) return yield* typeParserIssue("Has no 'ast' property", type, atLocation);
|
|
2362
|
+
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2363
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2364
|
+
);
|
|
2365
|
+
propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
|
|
2366
|
+
for (const propertySymbol of propertiesSymbols) {
|
|
2367
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2368
|
+
const varianceArgs = yield* option(effectSchemaVarianceStruct(
|
|
2369
|
+
propertyType,
|
|
2370
|
+
atLocation
|
|
2371
|
+
));
|
|
2372
|
+
if (isSome2(varianceArgs)) {
|
|
2373
|
+
return varianceArgs.value;
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
return yield* typeParserIssue("Type has no schema variance struct", type, atLocation);
|
|
2377
|
+
}),
|
|
2378
|
+
"TypeParser.effectSchemaType",
|
|
2379
|
+
(type) => type
|
|
2380
|
+
);
|
|
2381
|
+
const contextTagVarianceStruct = (type, atLocation) => map4(
|
|
2382
|
+
all2(
|
|
2383
|
+
varianceStructInvariantType(type, atLocation, "_Identifier"),
|
|
2384
|
+
varianceStructInvariantType(type, atLocation, "_Service")
|
|
2385
|
+
),
|
|
2386
|
+
([Identifier, Service]) => ({ Identifier, Service })
|
|
2387
|
+
);
|
|
2388
|
+
const contextTag = cachedBy(
|
|
2389
|
+
fn("TypeParser.contextTag")(function* (type, atLocation) {
|
|
2390
|
+
yield* pipeableType(type, atLocation);
|
|
2391
|
+
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2392
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2393
|
+
);
|
|
2394
|
+
propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
|
|
2395
|
+
for (const propertySymbol of propertiesSymbols) {
|
|
2396
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2397
|
+
const varianceArgs = yield* option(contextTagVarianceStruct(
|
|
2398
|
+
propertyType,
|
|
2399
|
+
atLocation
|
|
2400
|
+
));
|
|
2401
|
+
if (isSome2(varianceArgs)) {
|
|
2402
|
+
return varianceArgs.value;
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
return yield* typeParserIssue("Type has no tag variance struct", type, atLocation);
|
|
2406
|
+
}),
|
|
2407
|
+
"TypeParser.contextTag",
|
|
2408
|
+
(type) => type
|
|
2409
|
+
);
|
|
2410
|
+
return {
|
|
2411
|
+
effectType,
|
|
2412
|
+
layerType,
|
|
2413
|
+
fiberType,
|
|
2414
|
+
effectSubtype,
|
|
2415
|
+
importedEffectModule,
|
|
2416
|
+
effectGen,
|
|
2417
|
+
effectFnUntracedGen,
|
|
2418
|
+
effectFnGen,
|
|
2419
|
+
unnecessaryEffectGen: unnecessaryEffectGen2,
|
|
2420
|
+
effectSchemaType,
|
|
2421
|
+
contextTag
|
|
2422
|
+
};
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2425
|
+
// src/completions/fnFunctionStar.ts
|
|
2426
|
+
var fnFunctionStar = createCompletion({
|
|
2427
|
+
name: "fnFunctionStar",
|
|
2428
|
+
apply: fn("fnFunctionStar")(function* (sourceFile, position) {
|
|
2429
|
+
const ts = yield* service(TypeScriptApi);
|
|
2430
|
+
const typeParser = yield* service(TypeParser);
|
|
2431
|
+
const maybeInfos = yield* option(
|
|
2432
|
+
parseAccessedExpressionForCompletion(sourceFile, position)
|
|
2433
|
+
);
|
|
2434
|
+
if (isNone2(maybeInfos)) return [];
|
|
2435
|
+
const { accessedObject } = maybeInfos.value;
|
|
2436
|
+
const isEffectModule = yield* option(typeParser.importedEffectModule(accessedObject));
|
|
2437
|
+
if (isNone2(isEffectModule)) return [];
|
|
2438
|
+
const span = ts.createTextSpan(
|
|
2439
|
+
accessedObject.end + 1,
|
|
2440
|
+
Math.max(0, position - accessedObject.end - 1)
|
|
2441
|
+
);
|
|
2442
|
+
const maybeFnName = pipe(
|
|
2443
|
+
yield* getAncestorNodesInRange(sourceFile, toTextRange(accessedObject.pos)),
|
|
2444
|
+
filter(ts.isVariableDeclaration),
|
|
2445
|
+
map3((_) => _.name && ts.isIdentifier(_.name) ? _.name.text : ""),
|
|
2446
|
+
filter((_) => _.length > 0),
|
|
2447
|
+
head,
|
|
2448
|
+
map2((name) => [
|
|
2449
|
+
{
|
|
2450
|
+
name: `fn("${name}")`,
|
|
2451
|
+
kind: ts.ScriptElementKind.constElement,
|
|
2452
|
+
insertText: `fn("${name}")(function*(${"${1}"}){${"${0}"}})`,
|
|
2453
|
+
replacementSpan: span,
|
|
2454
|
+
isSnippet: true
|
|
2455
|
+
}
|
|
2456
|
+
]),
|
|
2457
|
+
getOrElse2(() => [])
|
|
2458
|
+
);
|
|
2459
|
+
return maybeFnName.concat([{
|
|
2460
|
+
name: `fn(function*(){})`,
|
|
2461
|
+
kind: ts.ScriptElementKind.constElement,
|
|
2462
|
+
insertText: `fn(function*(${"${1}"}){${"${0}"}})`,
|
|
2463
|
+
replacementSpan: span,
|
|
2464
|
+
isSnippet: true
|
|
2465
|
+
}, {
|
|
2466
|
+
name: `fnUntraced(function*(){})`,
|
|
2467
|
+
kind: ts.ScriptElementKind.constElement,
|
|
2468
|
+
insertText: `fnUntraced(function*(${"${1}"}){${"${0}"}})`,
|
|
2469
|
+
replacementSpan: span,
|
|
2470
|
+
isSnippet: true
|
|
2471
|
+
}]);
|
|
2472
|
+
})
|
|
2473
|
+
});
|
|
2474
|
+
|
|
1927
2475
|
// src/core/TypeCheckerApi.ts
|
|
1928
2476
|
var TypeCheckerApi = Tag("TypeChecker");
|
|
1929
2477
|
var TypeCheckerApiCache = Tag("TypeCheckerApiCache");
|
|
@@ -2071,554 +2619,109 @@ var expectedAndRealType = fn("TypeCheckerApi.expectedAndRealType")(function* (so
|
|
|
2071
2619
|
if (ts.isObjectLiteralExpression(parent.parent) && parent.name === node) {
|
|
2072
2620
|
const type = typeChecker.getContextualType(parent.parent);
|
|
2073
2621
|
if (type) {
|
|
2074
|
-
const symbol3 = typeChecker.getPropertyOfType(type, node.text);
|
|
2075
|
-
if (symbol3) {
|
|
2076
|
-
const expectedType = typeChecker.getTypeOfSymbolAtLocation(symbol3, node);
|
|
2077
|
-
const realType = typeChecker.getTypeAtLocation(node);
|
|
2078
|
-
result.push([node, expectedType, node, realType]);
|
|
2079
|
-
}
|
|
2080
|
-
}
|
|
2081
|
-
}
|
|
2082
|
-
}
|
|
2083
|
-
ts.forEachChild(node, appendNodeToVisit);
|
|
2084
|
-
continue;
|
|
2085
|
-
} else if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
2086
|
-
const expectedType = typeChecker.getTypeAtLocation(node.left);
|
|
2087
|
-
const realType = typeChecker.getTypeAtLocation(node.right);
|
|
2088
|
-
result.push([node.left, expectedType, node.right, realType]);
|
|
2089
|
-
appendNodeToVisit(node.right);
|
|
2090
|
-
continue;
|
|
2091
|
-
} else if (ts.isReturnStatement(node) && node.expression) {
|
|
2092
|
-
const parentDeclaration = yield* option(getAncestorConvertibleDeclaration(node));
|
|
2093
|
-
if (isSome2(parentDeclaration)) {
|
|
2094
|
-
const expectedType = yield* option(getInferredReturnType(parentDeclaration.value));
|
|
2095
|
-
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
2096
|
-
if (isSome2(expectedType)) {
|
|
2097
|
-
result.push([node, expectedType.value, node, realType]);
|
|
2098
|
-
}
|
|
2099
|
-
}
|
|
2100
|
-
ts.forEachChild(node, appendNodeToVisit);
|
|
2101
|
-
continue;
|
|
2102
|
-
} else if (ts.isArrowFunction(node) && (node.typeParameters || []).length === 0 && ts.isExpression(node.body)) {
|
|
2103
|
-
const body = node.body;
|
|
2104
|
-
const expectedType = typeChecker.getContextualType(body);
|
|
2105
|
-
const realType = typeChecker.getTypeAtLocation(body);
|
|
2106
|
-
if (expectedType) {
|
|
2107
|
-
result.push([body, expectedType, body, realType]);
|
|
2108
|
-
}
|
|
2109
|
-
ts.forEachChild(body, appendNodeToVisit);
|
|
2110
|
-
continue;
|
|
2111
|
-
} else if (ts.isArrowFunction(node) && (node.typeParameters || []).length > 0 && ts.isExpression(node.body)) {
|
|
2112
|
-
const body = node.body;
|
|
2113
|
-
const expectedType = yield* option(getInferredReturnType(node));
|
|
2114
|
-
const realType = typeChecker.getTypeAtLocation(body);
|
|
2115
|
-
if (isSome2(expectedType)) {
|
|
2116
|
-
result.push([body, expectedType.value, body, realType]);
|
|
2117
|
-
}
|
|
2118
|
-
ts.forEachChild(body, appendNodeToVisit);
|
|
2119
|
-
continue;
|
|
2120
|
-
} else if (ts.isSatisfiesExpression(node)) {
|
|
2121
|
-
const expectedType = typeChecker.getTypeAtLocation(node.type);
|
|
2122
|
-
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
2123
|
-
result.push([node.expression, expectedType, node.expression, realType]);
|
|
2124
|
-
appendNodeToVisit(node.expression);
|
|
2125
|
-
continue;
|
|
2126
|
-
}
|
|
2127
|
-
ts.forEachChild(node, appendNodeToVisit);
|
|
2128
|
-
}
|
|
2129
|
-
cache.expectedAndRealType.set(sourceFile, result);
|
|
2130
|
-
return result;
|
|
2131
|
-
});
|
|
2132
|
-
var appendToUniqueTypesMap = fn(
|
|
2133
|
-
"TypeCheckerApi.appendToUniqueTypesMap"
|
|
2134
|
-
)(
|
|
2135
|
-
function* (memory, initialType, excludeNever) {
|
|
2136
|
-
const ts = yield* service(TypeScriptApi);
|
|
2137
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2138
|
-
const newIndexes = /* @__PURE__ */ new Set();
|
|
2139
|
-
const knownIndexes = /* @__PURE__ */ new Set();
|
|
2140
|
-
let toTest = [initialType];
|
|
2141
|
-
while (toTest.length > 0) {
|
|
2142
|
-
const type = toTest.pop();
|
|
2143
|
-
if (!type) break;
|
|
2144
|
-
if (excludeNever && type.flags & ts.TypeFlags.Never) {
|
|
2145
|
-
continue;
|
|
2146
|
-
}
|
|
2147
|
-
if (type.isUnion()) {
|
|
2148
|
-
toTest = toTest.concat(type.types);
|
|
2149
|
-
} else {
|
|
2150
|
-
const foundMatch = [];
|
|
2151
|
-
for (const [typeId, knownType] of memory.entries()) {
|
|
2152
|
-
const areSame = typeChecker.isTypeAssignableTo(knownType, type) && typeChecker.isTypeAssignableTo(type, knownType);
|
|
2153
|
-
if (areSame) {
|
|
2154
|
-
foundMatch.push(typeId);
|
|
2155
|
-
break;
|
|
2156
|
-
}
|
|
2157
|
-
}
|
|
2158
|
-
if (foundMatch.length === 0) {
|
|
2159
|
-
const newId = "t" + (memory.size + 1);
|
|
2160
|
-
memory.set(newId, type);
|
|
2161
|
-
newIndexes.add(newId);
|
|
2162
|
-
} else {
|
|
2163
|
-
knownIndexes.add(foundMatch[0]);
|
|
2164
|
-
}
|
|
2165
|
-
}
|
|
2166
|
-
}
|
|
2167
|
-
return {
|
|
2168
|
-
newIndexes,
|
|
2169
|
-
knownIndexes,
|
|
2170
|
-
allIndexes: pipe(
|
|
2171
|
-
fromIterable(newIndexes),
|
|
2172
|
-
appendAll(fromIterable(knownIndexes))
|
|
2173
|
-
)
|
|
2174
|
-
};
|
|
2175
|
-
}
|
|
2176
|
-
);
|
|
2177
|
-
|
|
2178
|
-
// src/utils/TypeParser.ts
|
|
2179
|
-
var TypeParserIssue = class {
|
|
2180
|
-
constructor(type, node, message) {
|
|
2181
|
-
this.type = type;
|
|
2182
|
-
this.node = node;
|
|
2183
|
-
this.message = message;
|
|
2184
|
-
}
|
|
2185
|
-
_tag = "@effect/language-service/TypeParserIssue";
|
|
2186
|
-
};
|
|
2187
|
-
function typeParserIssue(message, type, node) {
|
|
2188
|
-
return fail(new TypeParserIssue(type, node, message));
|
|
2189
|
-
}
|
|
2190
|
-
function covariantTypeArgument(type) {
|
|
2191
|
-
const signatures = type.getCallSignatures();
|
|
2192
|
-
if (signatures.length !== 1) {
|
|
2193
|
-
return typeParserIssue("Covariant type has no call signature", type);
|
|
2194
|
-
}
|
|
2195
|
-
return succeed(signatures[0].getReturnType());
|
|
2196
|
-
}
|
|
2197
|
-
function contravariantTypeArgument(type) {
|
|
2198
|
-
const signatures = type.getCallSignatures();
|
|
2199
|
-
if (signatures.length !== 1) {
|
|
2200
|
-
return typeParserIssue("Contravariant type has no call signature", type);
|
|
2201
|
-
}
|
|
2202
|
-
return succeed(signatures[0].getTypeParameterAtPosition(0));
|
|
2203
|
-
}
|
|
2204
|
-
function invariantTypeArgument(type) {
|
|
2205
|
-
const signatures = type.getCallSignatures();
|
|
2206
|
-
if (signatures.length !== 1) {
|
|
2207
|
-
return typeParserIssue("Invariant type has no call signature", type);
|
|
2208
|
-
}
|
|
2209
|
-
return succeed(signatures[0].getReturnType());
|
|
2210
|
-
}
|
|
2211
|
-
var pipeableType = fn("TypeParser.pipeableType")(function* (type, atLocation) {
|
|
2212
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2213
|
-
const pipeSymbol = typeChecker.getPropertyOfType(type, "pipe");
|
|
2214
|
-
if (!pipeSymbol) {
|
|
2215
|
-
return yield* typeParserIssue("Type has no 'pipe' property", type, atLocation);
|
|
2216
|
-
}
|
|
2217
|
-
const pipeType = typeChecker.getTypeOfSymbolAtLocation(pipeSymbol, atLocation);
|
|
2218
|
-
const signatures = pipeType.getCallSignatures();
|
|
2219
|
-
if (signatures.length === 0) {
|
|
2220
|
-
return yield* typeParserIssue("'pipe' property is not callable", type, atLocation);
|
|
2221
|
-
}
|
|
2222
|
-
return type;
|
|
2223
|
-
});
|
|
2224
|
-
var varianceStructCovariantType = fn("TypeParser.varianceStructCovariantType")(
|
|
2225
|
-
function* (type, atLocation, propertyName) {
|
|
2226
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2227
|
-
const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
|
|
2228
|
-
if (!propertySymbol) {
|
|
2229
|
-
return yield* typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
|
|
2230
|
-
}
|
|
2231
|
-
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2232
|
-
return yield* covariantTypeArgument(propertyType);
|
|
2233
|
-
}
|
|
2234
|
-
);
|
|
2235
|
-
var varianceStructContravariantType = fn(
|
|
2236
|
-
"TypeParser.varianceStructContravariantType"
|
|
2237
|
-
)(
|
|
2238
|
-
function* (type, atLocation, propertyName) {
|
|
2239
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2240
|
-
const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
|
|
2241
|
-
if (!propertySymbol) {
|
|
2242
|
-
return yield* typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
|
|
2243
|
-
}
|
|
2244
|
-
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2245
|
-
return yield* contravariantTypeArgument(propertyType);
|
|
2246
|
-
}
|
|
2247
|
-
);
|
|
2248
|
-
var varianceStructInvariantType = fn("TypeParser.varianceStructInvariantType")(
|
|
2249
|
-
function* (type, atLocation, propertyName) {
|
|
2250
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2251
|
-
const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
|
|
2252
|
-
if (!propertySymbol) {
|
|
2253
|
-
return yield* typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
|
|
2254
|
-
}
|
|
2255
|
-
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2256
|
-
return yield* invariantTypeArgument(propertyType);
|
|
2257
|
-
}
|
|
2258
|
-
);
|
|
2259
|
-
var effectVarianceStruct = fn("TypeParser.effectVarianceStruct")(function* (type, atLocation) {
|
|
2260
|
-
return {
|
|
2261
|
-
A: yield* varianceStructCovariantType(type, atLocation, "_A"),
|
|
2262
|
-
E: yield* varianceStructCovariantType(type, atLocation, "_E"),
|
|
2263
|
-
R: yield* varianceStructCovariantType(type, atLocation, "_R")
|
|
2264
|
-
};
|
|
2265
|
-
});
|
|
2266
|
-
var layerVarianceStruct = fn("TypeParser.layerVarianceStruct")(function* (type, atLocation) {
|
|
2267
|
-
return {
|
|
2268
|
-
ROut: yield* varianceStructContravariantType(type, atLocation, "_ROut"),
|
|
2269
|
-
E: yield* varianceStructCovariantType(type, atLocation, "_E"),
|
|
2270
|
-
RIn: yield* varianceStructCovariantType(type, atLocation, "_RIn")
|
|
2271
|
-
};
|
|
2272
|
-
});
|
|
2273
|
-
var effectType = fn("TypeParser.effectType")(function* (type, atLocation) {
|
|
2274
|
-
const ts = yield* service(TypeScriptApi);
|
|
2275
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2276
|
-
yield* pipeableType(type, atLocation);
|
|
2277
|
-
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2278
|
-
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2279
|
-
);
|
|
2280
|
-
propertiesSymbols.sort((a, b) => b.name.indexOf("EffectTypeId") - a.name.indexOf("EffectTypeId"));
|
|
2281
|
-
for (const propertySymbol of propertiesSymbols) {
|
|
2282
|
-
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2283
|
-
const varianceArgs = yield* option(effectVarianceStruct(
|
|
2284
|
-
propertyType,
|
|
2285
|
-
atLocation
|
|
2286
|
-
));
|
|
2287
|
-
if (isSome2(varianceArgs)) {
|
|
2288
|
-
return varianceArgs.value;
|
|
2289
|
-
}
|
|
2290
|
-
}
|
|
2291
|
-
return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
|
|
2292
|
-
});
|
|
2293
|
-
var layerType = fn("TypeParser.layerType")(function* (type, atLocation) {
|
|
2294
|
-
const ts = yield* service(TypeScriptApi);
|
|
2295
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2296
|
-
yield* pipeableType(type, atLocation);
|
|
2297
|
-
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2298
|
-
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2299
|
-
);
|
|
2300
|
-
propertiesSymbols.sort((a, b) => b.name.indexOf("LayerTypeId") - a.name.indexOf("LayerTypeId"));
|
|
2301
|
-
for (const propertySymbol of propertiesSymbols) {
|
|
2302
|
-
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2303
|
-
const varianceArgs = yield* option(layerVarianceStruct(
|
|
2304
|
-
propertyType,
|
|
2305
|
-
atLocation
|
|
2306
|
-
));
|
|
2307
|
-
if (isSome2(varianceArgs)) {
|
|
2308
|
-
return varianceArgs.value;
|
|
2309
|
-
}
|
|
2310
|
-
}
|
|
2311
|
-
return yield* typeParserIssue("Type has no layer variance struct", type, atLocation);
|
|
2312
|
-
});
|
|
2313
|
-
var fiberType = fn("TypeParser.fiberType")(function* (type, atLocation) {
|
|
2314
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2315
|
-
const awaitSymbol = typeChecker.getPropertyOfType(type, "await");
|
|
2316
|
-
const pollSymbol = typeChecker.getPropertyOfType(type, "poll");
|
|
2317
|
-
if (!awaitSymbol || !pollSymbol) {
|
|
2318
|
-
return yield* typeParserIssue(
|
|
2319
|
-
"Type is not a fiber because it does not have 'await' or 'poll' property",
|
|
2320
|
-
type,
|
|
2321
|
-
atLocation
|
|
2322
|
-
);
|
|
2323
|
-
}
|
|
2324
|
-
return yield* effectType(type, atLocation);
|
|
2325
|
-
});
|
|
2326
|
-
var effectSubtype = fn("TypeParser.effectSubtype")(function* (type, atLocation) {
|
|
2327
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2328
|
-
const tagSymbol = typeChecker.getPropertyOfType(type, "_tag");
|
|
2329
|
-
const getSymbol = typeChecker.getPropertyOfType(type, "get");
|
|
2330
|
-
if (!(tagSymbol || getSymbol)) {
|
|
2331
|
-
return yield* typeParserIssue(
|
|
2332
|
-
"Type is not a subtype of effect because it does not have '_tag' or 'get' property",
|
|
2333
|
-
type,
|
|
2334
|
-
atLocation
|
|
2335
|
-
);
|
|
2336
|
-
}
|
|
2337
|
-
return yield* effectType(type, atLocation);
|
|
2338
|
-
});
|
|
2339
|
-
var importedEffectModule = fn("TypeParser.importedEffectModule")(function* (node) {
|
|
2340
|
-
const ts = yield* service(TypeScriptApi);
|
|
2341
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2342
|
-
const type = typeChecker.getTypeAtLocation(node);
|
|
2343
|
-
const propertySymbol = typeChecker.getPropertyOfType(type, "never");
|
|
2344
|
-
if (!propertySymbol) {
|
|
2345
|
-
return yield* typeParserIssue("Type has no 'never' property", type, node);
|
|
2346
|
-
}
|
|
2347
|
-
if (!ts.isExpression(node)) {
|
|
2348
|
-
return yield* typeParserIssue("Node is not an expression", type, node);
|
|
2349
|
-
}
|
|
2350
|
-
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, node);
|
|
2351
|
-
yield* effectType(propertyType, node);
|
|
2352
|
-
return node;
|
|
2353
|
-
});
|
|
2354
|
-
var effectGen = fn("TypeParser.effectGen")(function* (node) {
|
|
2355
|
-
const ts = yield* service(TypeScriptApi);
|
|
2356
|
-
if (!ts.isCallExpression(node)) {
|
|
2357
|
-
return yield* typeParserIssue("Node is not a call expression", void 0, node);
|
|
2358
|
-
}
|
|
2359
|
-
if (node.arguments.length === 0) {
|
|
2360
|
-
return yield* typeParserIssue("Node has no arguments", void 0, node);
|
|
2361
|
-
}
|
|
2362
|
-
const generatorFunction = node.arguments[0];
|
|
2363
|
-
if (!ts.isFunctionExpression(generatorFunction)) {
|
|
2364
|
-
return yield* typeParserIssue("Node is not a function expression", void 0, node);
|
|
2365
|
-
}
|
|
2366
|
-
if (generatorFunction.asteriskToken === void 0) {
|
|
2367
|
-
return yield* typeParserIssue("Node is not a generator function", void 0, node);
|
|
2368
|
-
}
|
|
2369
|
-
if (!ts.isPropertyAccessExpression(node.expression)) {
|
|
2370
|
-
return yield* typeParserIssue("Node is not a property access expression", void 0, node);
|
|
2371
|
-
}
|
|
2372
|
-
const propertyAccess = node.expression;
|
|
2373
|
-
if (propertyAccess.name.text !== "gen") {
|
|
2374
|
-
return yield* typeParserIssue("Call expression name is not 'gen'", void 0, node);
|
|
2375
|
-
}
|
|
2376
|
-
const effectModule = yield* importedEffectModule(propertyAccess.expression);
|
|
2377
|
-
return {
|
|
2378
|
-
node,
|
|
2379
|
-
effectModule,
|
|
2380
|
-
generatorFunction,
|
|
2381
|
-
body: generatorFunction.body,
|
|
2382
|
-
functionStar: generatorFunction.getFirstToken()
|
|
2383
|
-
};
|
|
2384
|
-
});
|
|
2385
|
-
var effectFnUntracedGen = fn("TypeParser.effectFnUntracedGen")(
|
|
2386
|
-
function* (node) {
|
|
2387
|
-
const ts = yield* service(TypeScriptApi);
|
|
2388
|
-
if (!ts.isCallExpression(node)) {
|
|
2389
|
-
return yield* typeParserIssue("Node is not a call expression", void 0, node);
|
|
2390
|
-
}
|
|
2391
|
-
if (node.arguments.length === 0) {
|
|
2392
|
-
return yield* typeParserIssue("Node has no arguments", void 0, node);
|
|
2393
|
-
}
|
|
2394
|
-
const generatorFunction = node.arguments[0];
|
|
2395
|
-
if (!ts.isFunctionExpression(generatorFunction)) {
|
|
2396
|
-
return yield* typeParserIssue("Node is not a function expression", void 0, node);
|
|
2397
|
-
}
|
|
2398
|
-
if (generatorFunction.asteriskToken === void 0) {
|
|
2399
|
-
return yield* typeParserIssue(
|
|
2400
|
-
"Node is not a generator function",
|
|
2401
|
-
void 0,
|
|
2402
|
-
node
|
|
2403
|
-
);
|
|
2404
|
-
}
|
|
2405
|
-
if (!ts.isPropertyAccessExpression(node.expression)) {
|
|
2406
|
-
return yield* typeParserIssue(
|
|
2407
|
-
"Node is not a property access expression",
|
|
2408
|
-
void 0,
|
|
2409
|
-
node
|
|
2410
|
-
);
|
|
2411
|
-
}
|
|
2412
|
-
const propertyAccess = node.expression;
|
|
2413
|
-
if (propertyAccess.name.text !== "fnUntraced") {
|
|
2414
|
-
return yield* typeParserIssue(
|
|
2415
|
-
"Call expression name is not 'fnUntraced'",
|
|
2416
|
-
void 0,
|
|
2417
|
-
node
|
|
2418
|
-
);
|
|
2419
|
-
}
|
|
2420
|
-
const effectModule = yield* importedEffectModule(propertyAccess.expression);
|
|
2421
|
-
return {
|
|
2422
|
-
node,
|
|
2423
|
-
effectModule,
|
|
2424
|
-
generatorFunction,
|
|
2425
|
-
body: generatorFunction.body,
|
|
2426
|
-
functionStar: generatorFunction.getFirstToken()
|
|
2427
|
-
};
|
|
2428
|
-
}
|
|
2429
|
-
);
|
|
2430
|
-
var effectFnGen = fn("TypeParser.effectFnGen")(function* (node) {
|
|
2431
|
-
const ts = yield* service(TypeScriptApi);
|
|
2432
|
-
if (!ts.isCallExpression(node)) {
|
|
2433
|
-
return yield* typeParserIssue("Node is not a call expression", void 0, node);
|
|
2434
|
-
}
|
|
2435
|
-
if (node.arguments.length === 0) {
|
|
2436
|
-
return yield* typeParserIssue("Node has no arguments", void 0, node);
|
|
2437
|
-
}
|
|
2438
|
-
const generatorFunction = node.arguments[0];
|
|
2439
|
-
if (!ts.isFunctionExpression(generatorFunction)) {
|
|
2440
|
-
return yield* typeParserIssue(
|
|
2441
|
-
"Node is not a function expression",
|
|
2442
|
-
void 0,
|
|
2443
|
-
node
|
|
2444
|
-
);
|
|
2445
|
-
}
|
|
2446
|
-
if (generatorFunction.asteriskToken === void 0) {
|
|
2447
|
-
return yield* typeParserIssue(
|
|
2448
|
-
"Node is not a generator function",
|
|
2449
|
-
void 0,
|
|
2450
|
-
node
|
|
2451
|
-
);
|
|
2452
|
-
}
|
|
2453
|
-
const expressionToTest = ts.isCallExpression(node.expression) ? node.expression.expression : node.expression;
|
|
2454
|
-
if (!ts.isPropertyAccessExpression(expressionToTest)) {
|
|
2455
|
-
return yield* typeParserIssue(
|
|
2456
|
-
"Node is not a property access expression",
|
|
2457
|
-
void 0,
|
|
2458
|
-
node
|
|
2459
|
-
);
|
|
2460
|
-
}
|
|
2461
|
-
const propertyAccess = expressionToTest;
|
|
2462
|
-
if (propertyAccess.name.text !== "fn") {
|
|
2463
|
-
return yield* typeParserIssue(
|
|
2464
|
-
"Call expression name is not 'fn'",
|
|
2465
|
-
void 0,
|
|
2466
|
-
node
|
|
2467
|
-
);
|
|
2468
|
-
}
|
|
2469
|
-
const effectModule = yield* importedEffectModule(propertyAccess.expression);
|
|
2470
|
-
return {
|
|
2471
|
-
node,
|
|
2472
|
-
generatorFunction,
|
|
2473
|
-
effectModule,
|
|
2474
|
-
body: generatorFunction.body,
|
|
2475
|
-
functionStar: generatorFunction.getFirstToken()
|
|
2476
|
-
};
|
|
2477
|
-
});
|
|
2478
|
-
var unnecessaryEffectGen = fn("TypeParser.unnecessaryEffectGen")(function* (node) {
|
|
2479
|
-
const ts = yield* service(TypeScriptApi);
|
|
2480
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2481
|
-
const { body } = yield* effectGen(node);
|
|
2482
|
-
if (body.statements.length !== 1) {
|
|
2483
|
-
return yield* typeParserIssue(
|
|
2484
|
-
"Generator body should have a single statement",
|
|
2485
|
-
void 0,
|
|
2486
|
-
node
|
|
2487
|
-
);
|
|
2488
|
-
}
|
|
2489
|
-
let explicitReturn = false;
|
|
2490
|
-
let nodeToCheck = body.statements[0];
|
|
2491
|
-
while (nodeToCheck) {
|
|
2492
|
-
if (ts.isReturnStatement(nodeToCheck) && nodeToCheck.expression) {
|
|
2493
|
-
nodeToCheck = nodeToCheck.expression;
|
|
2494
|
-
explicitReturn = true;
|
|
2622
|
+
const symbol3 = typeChecker.getPropertyOfType(type, node.text);
|
|
2623
|
+
if (symbol3) {
|
|
2624
|
+
const expectedType = typeChecker.getTypeOfSymbolAtLocation(symbol3, node);
|
|
2625
|
+
const realType = typeChecker.getTypeAtLocation(node);
|
|
2626
|
+
result.push([node, expectedType, node, realType]);
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2631
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
2495
2632
|
continue;
|
|
2496
|
-
}
|
|
2497
|
-
|
|
2498
|
-
|
|
2633
|
+
} else if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
2634
|
+
const expectedType = typeChecker.getTypeAtLocation(node.left);
|
|
2635
|
+
const realType = typeChecker.getTypeAtLocation(node.right);
|
|
2636
|
+
result.push([node.left, expectedType, node.right, realType]);
|
|
2637
|
+
appendNodeToVisit(node.right);
|
|
2499
2638
|
continue;
|
|
2500
|
-
}
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
]
|
|
2527
|
-
);
|
|
2528
|
-
}),
|
|
2529
|
-
provideService(TypeScriptApi, ts)
|
|
2530
|
-
);
|
|
2639
|
+
} else if (ts.isReturnStatement(node) && node.expression) {
|
|
2640
|
+
const parentDeclaration = yield* option(getAncestorConvertibleDeclaration(node));
|
|
2641
|
+
if (isSome2(parentDeclaration)) {
|
|
2642
|
+
const expectedType = yield* option(getInferredReturnType(parentDeclaration.value));
|
|
2643
|
+
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
2644
|
+
if (isSome2(expectedType)) {
|
|
2645
|
+
result.push([node, expectedType.value, node, realType]);
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
2649
|
+
continue;
|
|
2650
|
+
} else if (ts.isArrowFunction(node) && (node.typeParameters || []).length === 0 && ts.isExpression(node.body)) {
|
|
2651
|
+
const body = node.body;
|
|
2652
|
+
const expectedType = typeChecker.getContextualType(body);
|
|
2653
|
+
const realType = typeChecker.getTypeAtLocation(body);
|
|
2654
|
+
if (expectedType) {
|
|
2655
|
+
result.push([body, expectedType, body, realType]);
|
|
2656
|
+
}
|
|
2657
|
+
ts.forEachChild(body, appendNodeToVisit);
|
|
2658
|
+
continue;
|
|
2659
|
+
} else if (ts.isArrowFunction(node) && (node.typeParameters || []).length > 0 && ts.isExpression(node.body)) {
|
|
2660
|
+
const body = node.body;
|
|
2661
|
+
const expectedType = yield* option(getInferredReturnType(node));
|
|
2662
|
+
const realType = typeChecker.getTypeAtLocation(body);
|
|
2663
|
+
if (isSome2(expectedType)) {
|
|
2664
|
+
result.push([body, expectedType.value, body, realType]);
|
|
2531
2665
|
}
|
|
2532
|
-
|
|
2666
|
+
ts.forEachChild(body, appendNodeToVisit);
|
|
2667
|
+
continue;
|
|
2668
|
+
} else if (ts.isSatisfiesExpression(node)) {
|
|
2669
|
+
const expectedType = typeChecker.getTypeAtLocation(node.type);
|
|
2670
|
+
const realType = typeChecker.getTypeAtLocation(node.expression);
|
|
2671
|
+
result.push([node.expression, expectedType, node.expression, realType]);
|
|
2672
|
+
appendNodeToVisit(node.expression);
|
|
2673
|
+
continue;
|
|
2533
2674
|
}
|
|
2534
|
-
|
|
2675
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
2535
2676
|
}
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
void 0,
|
|
2539
|
-
node
|
|
2540
|
-
);
|
|
2677
|
+
cache.expectedAndRealType.set(sourceFile, result);
|
|
2678
|
+
return result;
|
|
2541
2679
|
});
|
|
2542
|
-
var
|
|
2543
|
-
|
|
2680
|
+
var appendToUniqueTypesMap = fn(
|
|
2681
|
+
"TypeCheckerApi.appendToUniqueTypesMap"
|
|
2682
|
+
)(
|
|
2683
|
+
function* (memory, initialType, excludeNever) {
|
|
2684
|
+
const ts = yield* service(TypeScriptApi);
|
|
2685
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
2686
|
+
const newIndexes = /* @__PURE__ */ new Set();
|
|
2687
|
+
const knownIndexes = /* @__PURE__ */ new Set();
|
|
2688
|
+
let toTest = [initialType];
|
|
2689
|
+
while (toTest.length > 0) {
|
|
2690
|
+
const type = toTest.pop();
|
|
2691
|
+
if (!type) break;
|
|
2692
|
+
if (excludeNever && type.flags & ts.TypeFlags.Never) {
|
|
2693
|
+
continue;
|
|
2694
|
+
}
|
|
2695
|
+
if (type.isUnion()) {
|
|
2696
|
+
toTest = toTest.concat(type.types);
|
|
2697
|
+
} else {
|
|
2698
|
+
const foundMatch = [];
|
|
2699
|
+
for (const [typeId, knownType] of memory.entries()) {
|
|
2700
|
+
const areSame = typeChecker.isTypeAssignableTo(knownType, type) && typeChecker.isTypeAssignableTo(type, knownType);
|
|
2701
|
+
if (areSame) {
|
|
2702
|
+
foundMatch.push(typeId);
|
|
2703
|
+
break;
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
if (foundMatch.length === 0) {
|
|
2707
|
+
const newId = "t" + (memory.size + 1);
|
|
2708
|
+
memory.set(newId, type);
|
|
2709
|
+
newIndexes.add(newId);
|
|
2710
|
+
} else {
|
|
2711
|
+
knownIndexes.add(foundMatch[0]);
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2544
2715
|
return {
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2716
|
+
newIndexes,
|
|
2717
|
+
knownIndexes,
|
|
2718
|
+
allIndexes: pipe(
|
|
2719
|
+
fromIterable(newIndexes),
|
|
2720
|
+
appendAll(fromIterable(knownIndexes))
|
|
2721
|
+
)
|
|
2548
2722
|
};
|
|
2549
2723
|
}
|
|
2550
2724
|
);
|
|
2551
|
-
var effectSchemaType = fn("TypeParser.effectSchemaType")(function* (type, atLocation) {
|
|
2552
|
-
const ts = yield* service(TypeScriptApi);
|
|
2553
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2554
|
-
yield* pipeableType(type, atLocation);
|
|
2555
|
-
const ast = typeChecker.getPropertyOfType(type, "ast");
|
|
2556
|
-
if (!ast) return yield* typeParserIssue("Has no 'ast' property", type, atLocation);
|
|
2557
|
-
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2558
|
-
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2559
|
-
);
|
|
2560
|
-
propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
|
|
2561
|
-
for (const propertySymbol of propertiesSymbols) {
|
|
2562
|
-
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2563
|
-
const varianceArgs = yield* option(effectSchemaVarianceStruct(
|
|
2564
|
-
propertyType,
|
|
2565
|
-
atLocation
|
|
2566
|
-
));
|
|
2567
|
-
if (isSome2(varianceArgs)) {
|
|
2568
|
-
return varianceArgs.value;
|
|
2569
|
-
}
|
|
2570
|
-
}
|
|
2571
|
-
return yield* typeParserIssue("Type has no schema variance struct", type, atLocation);
|
|
2572
|
-
});
|
|
2573
|
-
|
|
2574
|
-
// src/completions/fnFunctionStar.ts
|
|
2575
|
-
var fnFunctionStar = createCompletion({
|
|
2576
|
-
name: "fnFunctionStar",
|
|
2577
|
-
apply: fn("fnFunctionStar")(function* (sourceFile, position) {
|
|
2578
|
-
const ts = yield* service(TypeScriptApi);
|
|
2579
|
-
const maybeInfos = yield* option(
|
|
2580
|
-
parseAccessedExpressionForCompletion(sourceFile, position)
|
|
2581
|
-
);
|
|
2582
|
-
if (isNone2(maybeInfos)) return [];
|
|
2583
|
-
const { accessedObject } = maybeInfos.value;
|
|
2584
|
-
const isEffectModule = yield* option(importedEffectModule(accessedObject));
|
|
2585
|
-
if (isNone2(isEffectModule)) return [];
|
|
2586
|
-
const span = ts.createTextSpan(
|
|
2587
|
-
accessedObject.end + 1,
|
|
2588
|
-
Math.max(0, position - accessedObject.end - 1)
|
|
2589
|
-
);
|
|
2590
|
-
const maybeFnName = pipe(
|
|
2591
|
-
yield* getAncestorNodesInRange(sourceFile, toTextRange(accessedObject.pos)),
|
|
2592
|
-
filter(ts.isVariableDeclaration),
|
|
2593
|
-
map3((_) => _.name && ts.isIdentifier(_.name) ? _.name.text : ""),
|
|
2594
|
-
filter((_) => _.length > 0),
|
|
2595
|
-
head,
|
|
2596
|
-
map2((name) => [
|
|
2597
|
-
{
|
|
2598
|
-
name: `fn("${name}")`,
|
|
2599
|
-
kind: ts.ScriptElementKind.constElement,
|
|
2600
|
-
insertText: `fn("${name}")(function*(${"${1}"}){${"${0}"}})`,
|
|
2601
|
-
replacementSpan: span,
|
|
2602
|
-
isSnippet: true
|
|
2603
|
-
}
|
|
2604
|
-
]),
|
|
2605
|
-
getOrElse2(() => [])
|
|
2606
|
-
);
|
|
2607
|
-
return maybeFnName.concat([{
|
|
2608
|
-
name: `fn(function*(){})`,
|
|
2609
|
-
kind: ts.ScriptElementKind.constElement,
|
|
2610
|
-
insertText: `fn(function*(${"${1}"}){${"${0}"}})`,
|
|
2611
|
-
replacementSpan: span,
|
|
2612
|
-
isSnippet: true
|
|
2613
|
-
}, {
|
|
2614
|
-
name: `fnUntraced(function*(){})`,
|
|
2615
|
-
kind: ts.ScriptElementKind.constElement,
|
|
2616
|
-
insertText: `fnUntraced(function*(${"${1}"}){${"${0}"}})`,
|
|
2617
|
-
replacementSpan: span,
|
|
2618
|
-
isSnippet: true
|
|
2619
|
-
}]);
|
|
2620
|
-
})
|
|
2621
|
-
});
|
|
2622
2725
|
|
|
2623
2726
|
// src/completions/genFunctionStar.ts
|
|
2624
2727
|
var genFunctionStar = createCompletion({
|
|
@@ -2701,6 +2804,7 @@ function parse(config) {
|
|
|
2701
2804
|
diagnostics: isObject(config) && hasProperty(config, "diagnostics") && isBoolean(config.diagnostics) ? config.diagnostics : true,
|
|
2702
2805
|
quickinfo: isObject(config) && hasProperty(config, "quickinfo") && isBoolean(config.quickinfo) ? config.quickinfo : true,
|
|
2703
2806
|
completions: isObject(config) && hasProperty(config, "completions") && isBoolean(config.completions) ? config.completions : true,
|
|
2807
|
+
goto: isObject(config) && hasProperty(config, "goto") && isBoolean(config.goto) ? config.goto : true,
|
|
2704
2808
|
allowedDuplicatedPackages: isObject(config) && hasProperty(config, "allowedDuplicatedPackages") && isArray(config.allowedDuplicatedPackages) && config.allowedDuplicatedPackages.every(isString) ? config.allowedDuplicatedPackages.map((_) => _.toLowerCase()) : []
|
|
2705
2809
|
};
|
|
2706
2810
|
}
|
|
@@ -2761,6 +2865,7 @@ var floatingEffect = createDiagnostic({
|
|
|
2761
2865
|
apply: fn("floatingEffect.apply")(function* (sourceFile) {
|
|
2762
2866
|
const ts = yield* service(TypeScriptApi);
|
|
2763
2867
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2868
|
+
const typeParser = yield* service(TypeParser);
|
|
2764
2869
|
function isFloatingExpression(node) {
|
|
2765
2870
|
if (!ts.isExpressionStatement(node)) return false;
|
|
2766
2871
|
if (!(ts.isBlock(node.parent) || ts.isSourceFile(node.parent))) return false;
|
|
@@ -2780,11 +2885,11 @@ var floatingEffect = createDiagnostic({
|
|
|
2780
2885
|
ts.forEachChild(node, appendNodeToVisit);
|
|
2781
2886
|
if (!isFloatingExpression(node)) continue;
|
|
2782
2887
|
const type = typeChecker.getTypeAtLocation(node.expression);
|
|
2783
|
-
const effect = yield* option(effectType(type, node.expression));
|
|
2888
|
+
const effect = yield* option(typeParser.effectType(type, node.expression));
|
|
2784
2889
|
if (isSome2(effect)) {
|
|
2785
2890
|
const allowedFloatingEffects = yield* pipe(
|
|
2786
|
-
fiberType(type, node.expression),
|
|
2787
|
-
orElse3(() => effectSubtype(type, node.expression)),
|
|
2891
|
+
typeParser.fiberType(type, node.expression),
|
|
2892
|
+
orElse3(() => typeParser.effectSubtype(type, node.expression)),
|
|
2788
2893
|
option
|
|
2789
2894
|
);
|
|
2790
2895
|
if (isNone2(allowedFloatingEffects)) {
|
|
@@ -2801,6 +2906,112 @@ var floatingEffect = createDiagnostic({
|
|
|
2801
2906
|
})
|
|
2802
2907
|
});
|
|
2803
2908
|
|
|
2909
|
+
// src/diagnostics/leakingRequirements.ts
|
|
2910
|
+
var leakingRequirements = createDiagnostic({
|
|
2911
|
+
name: "leakingRequirements",
|
|
2912
|
+
code: 8,
|
|
2913
|
+
apply: fn("leakingRequirements.apply")(function* (sourceFile) {
|
|
2914
|
+
const ts = yield* service(TypeScriptApi);
|
|
2915
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
2916
|
+
const typeParser = yield* service(TypeParser);
|
|
2917
|
+
const typeOrder = yield* deterministicTypeOrder;
|
|
2918
|
+
const effectDiagnostics = [];
|
|
2919
|
+
const parseLeakedRequirements = cachedBy(
|
|
2920
|
+
fn("leakingServices.checkServiceLeaking")(
|
|
2921
|
+
function* (service2, atLocation) {
|
|
2922
|
+
const properties = typeChecker.getPropertiesOfType(service2);
|
|
2923
|
+
if (properties.length < 1) return [];
|
|
2924
|
+
const memory = /* @__PURE__ */ new Map();
|
|
2925
|
+
let sharedRequirementsKeys = void 0;
|
|
2926
|
+
let effectMembers = 0;
|
|
2927
|
+
for (const property of properties) {
|
|
2928
|
+
const servicePropertyType = typeChecker.getTypeOfSymbolAtLocation(property, atLocation);
|
|
2929
|
+
let effectContextType = void 0;
|
|
2930
|
+
yield* pipe(
|
|
2931
|
+
typeParser.effectType(servicePropertyType, atLocation),
|
|
2932
|
+
map4((_) => effectContextType = _.R),
|
|
2933
|
+
orElse3(() => {
|
|
2934
|
+
const servicePropertyCallSignatures = servicePropertyType.getCallSignatures();
|
|
2935
|
+
if (servicePropertyCallSignatures.length === 1) {
|
|
2936
|
+
return pipe(
|
|
2937
|
+
typeParser.effectType(servicePropertyCallSignatures[0].getReturnType(), atLocation),
|
|
2938
|
+
map4((_) => {
|
|
2939
|
+
effectContextType = _.R;
|
|
2940
|
+
})
|
|
2941
|
+
);
|
|
2942
|
+
}
|
|
2943
|
+
return void_2;
|
|
2944
|
+
}),
|
|
2945
|
+
ignore
|
|
2946
|
+
);
|
|
2947
|
+
if (effectContextType) {
|
|
2948
|
+
effectMembers++;
|
|
2949
|
+
const { allIndexes } = yield* appendToUniqueTypesMap(memory, effectContextType, true);
|
|
2950
|
+
if (!sharedRequirementsKeys) {
|
|
2951
|
+
sharedRequirementsKeys = allIndexes;
|
|
2952
|
+
} else {
|
|
2953
|
+
sharedRequirementsKeys = intersection(sharedRequirementsKeys, allIndexes);
|
|
2954
|
+
if (sharedRequirementsKeys.length === 0) return [];
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
if (sharedRequirementsKeys && sharedRequirementsKeys.length > 0 && effectMembers >= 2) {
|
|
2959
|
+
return sharedRequirementsKeys.map((key) => memory.get(key));
|
|
2960
|
+
}
|
|
2961
|
+
return [];
|
|
2962
|
+
}
|
|
2963
|
+
),
|
|
2964
|
+
"leakingServices.checkServiceLeaking",
|
|
2965
|
+
(_, service2) => service2
|
|
2966
|
+
);
|
|
2967
|
+
function reportLeakingRequirements(node, requirements) {
|
|
2968
|
+
if (requirements.length === 0) return;
|
|
2969
|
+
effectDiagnostics.push({
|
|
2970
|
+
node,
|
|
2971
|
+
category: ts.DiagnosticCategory.Warning,
|
|
2972
|
+
messageText: `This Service is leaking the ${requirements.map((_) => typeChecker.typeToString(_)).join(" | ")} requirement`,
|
|
2973
|
+
fixes: []
|
|
2974
|
+
});
|
|
2975
|
+
}
|
|
2976
|
+
const nodeToVisit = [];
|
|
2977
|
+
const appendNodeToVisit = (node) => {
|
|
2978
|
+
nodeToVisit.push(node);
|
|
2979
|
+
return void 0;
|
|
2980
|
+
};
|
|
2981
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
2982
|
+
while (nodeToVisit.length > 0) {
|
|
2983
|
+
const node = nodeToVisit.shift();
|
|
2984
|
+
const typesToCheck = [];
|
|
2985
|
+
if (ts.isCallExpression(node)) {
|
|
2986
|
+
typesToCheck.push([typeChecker.getTypeAtLocation(node), node]);
|
|
2987
|
+
} else if (ts.isClassDeclaration(node) && node.name) {
|
|
2988
|
+
const classSym = typeChecker.getSymbolAtLocation(node.name);
|
|
2989
|
+
if (classSym) {
|
|
2990
|
+
const type = typeChecker.getTypeOfSymbol(classSym);
|
|
2991
|
+
typesToCheck.push([type, node.name]);
|
|
2992
|
+
}
|
|
2993
|
+
} else {
|
|
2994
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
2995
|
+
continue;
|
|
2996
|
+
}
|
|
2997
|
+
for (const [type, reportAt] of typesToCheck) {
|
|
2998
|
+
yield* pipe(
|
|
2999
|
+
typeParser.contextTag(type, node),
|
|
3000
|
+
flatMap3(
|
|
3001
|
+
({ Service }) => pipe(
|
|
3002
|
+
parseLeakedRequirements(Service, node),
|
|
3003
|
+
map4((requirements) => reportLeakingRequirements(reportAt, sort(requirements, typeOrder)))
|
|
3004
|
+
)
|
|
3005
|
+
),
|
|
3006
|
+
orElse3(() => sync(() => ts.forEachChild(node, appendNodeToVisit))),
|
|
3007
|
+
ignore
|
|
3008
|
+
);
|
|
3009
|
+
}
|
|
3010
|
+
}
|
|
3011
|
+
return effectDiagnostics;
|
|
3012
|
+
})
|
|
3013
|
+
});
|
|
3014
|
+
|
|
2804
3015
|
// src/diagnostics/missingEffectContext.ts
|
|
2805
3016
|
var missingEffectContext = createDiagnostic({
|
|
2806
3017
|
name: "missingEffectContext",
|
|
@@ -2808,15 +3019,16 @@ var missingEffectContext = createDiagnostic({
|
|
|
2808
3019
|
apply: fn("missingEffectContext.apply")(function* (sourceFile) {
|
|
2809
3020
|
const ts = yield* service(TypeScriptApi);
|
|
2810
3021
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3022
|
+
const typeParser = yield* service(TypeParser);
|
|
2811
3023
|
const typeOrder = yield* deterministicTypeOrder;
|
|
2812
3024
|
const checkForMissingContextTypes = fn(
|
|
2813
3025
|
"missingEffectContext.apply.checkForMissingContextTypes"
|
|
2814
3026
|
)(function* (node, expectedType, valueNode, realType) {
|
|
2815
|
-
const expectedEffect = yield* effectType(
|
|
3027
|
+
const expectedEffect = yield* typeParser.effectType(
|
|
2816
3028
|
expectedType,
|
|
2817
3029
|
node
|
|
2818
3030
|
);
|
|
2819
|
-
const realEffect = yield* effectType(
|
|
3031
|
+
const realEffect = yield* typeParser.effectType(
|
|
2820
3032
|
realType,
|
|
2821
3033
|
valueNode
|
|
2822
3034
|
);
|
|
@@ -2860,14 +3072,15 @@ var missingEffectError = createDiagnostic({
|
|
|
2860
3072
|
apply: fn("missingEffectError.apply")(function* (sourceFile) {
|
|
2861
3073
|
const ts = yield* service(TypeScriptApi);
|
|
2862
3074
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3075
|
+
const typeParser = yield* service(TypeParser);
|
|
2863
3076
|
const typeOrder = yield* deterministicTypeOrder;
|
|
2864
3077
|
const checkForMissingErrorTypes = fn("missingEffectError.apply.checkForMissingErrorTypes")(
|
|
2865
3078
|
function* (node, expectedType, valueNode, realType) {
|
|
2866
|
-
const expectedEffect = yield* effectType(
|
|
3079
|
+
const expectedEffect = yield* typeParser.effectType(
|
|
2867
3080
|
expectedType,
|
|
2868
3081
|
node
|
|
2869
3082
|
);
|
|
2870
|
-
const realEffect = yield* effectType(
|
|
3083
|
+
const realEffect = yield* typeParser.effectType(
|
|
2871
3084
|
realType,
|
|
2872
3085
|
valueNode
|
|
2873
3086
|
);
|
|
@@ -2912,6 +3125,7 @@ var missingReturnYieldStar = createDiagnostic({
|
|
|
2912
3125
|
apply: fn("missingReturnYieldStar.apply")(function* (sourceFile) {
|
|
2913
3126
|
const ts = yield* service(TypeScriptApi);
|
|
2914
3127
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3128
|
+
const typeParser = yield* service(TypeParser);
|
|
2915
3129
|
const effectDiagnostics = [];
|
|
2916
3130
|
const brokenYields = /* @__PURE__ */ new Set();
|
|
2917
3131
|
const nodeToVisit = [];
|
|
@@ -2925,7 +3139,7 @@ var missingReturnYieldStar = createDiagnostic({
|
|
|
2925
3139
|
ts.forEachChild(node, appendNodeToVisit);
|
|
2926
3140
|
if (ts.isYieldExpression(node) && node.expression && node.asteriskToken) {
|
|
2927
3141
|
const type = typeChecker.getTypeAtLocation(node.expression);
|
|
2928
|
-
const maybeEffect = yield* option(effectType(type, node.expression));
|
|
3142
|
+
const maybeEffect = yield* option(typeParser.effectType(type, node.expression));
|
|
2929
3143
|
if (isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never) {
|
|
2930
3144
|
const generatorFunctionOrReturnStatement = ts.findAncestor(
|
|
2931
3145
|
node,
|
|
@@ -2935,9 +3149,9 @@ var missingReturnYieldStar = createDiagnostic({
|
|
|
2935
3149
|
if (generatorFunctionOrReturnStatement && generatorFunctionOrReturnStatement.parent) {
|
|
2936
3150
|
const effectGenNode = generatorFunctionOrReturnStatement.parent;
|
|
2937
3151
|
const effectGenLike = yield* pipe(
|
|
2938
|
-
effectGen(effectGenNode),
|
|
2939
|
-
orElse3(() => effectFnUntracedGen(effectGenNode)),
|
|
2940
|
-
orElse3(() => effectFnGen(effectGenNode)),
|
|
3152
|
+
typeParser.effectGen(effectGenNode),
|
|
3153
|
+
orElse3(() => typeParser.effectFnUntracedGen(effectGenNode)),
|
|
3154
|
+
orElse3(() => typeParser.effectFnGen(effectGenNode)),
|
|
2941
3155
|
option
|
|
2942
3156
|
);
|
|
2943
3157
|
if (isSome2(effectGenLike)) {
|
|
@@ -2980,6 +3194,7 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
2980
3194
|
code: 4,
|
|
2981
3195
|
apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile) {
|
|
2982
3196
|
const ts = yield* service(TypeScriptApi);
|
|
3197
|
+
const typeParser = yield* service(TypeParser);
|
|
2983
3198
|
const effectDiagnostics = [];
|
|
2984
3199
|
const brokenGenerators = /* @__PURE__ */ new Set();
|
|
2985
3200
|
const brokenYields = /* @__PURE__ */ new Set();
|
|
@@ -2999,18 +3214,18 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
2999
3214
|
);
|
|
3000
3215
|
if (functionStarNode && functionStarNode.parent) {
|
|
3001
3216
|
const effectGenNode = functionStarNode.parent;
|
|
3002
|
-
|
|
3003
|
-
effectGen(effectGenNode),
|
|
3004
|
-
orElse3(() => effectFnUntracedGen(effectGenNode)),
|
|
3005
|
-
orElse3(() => effectFnGen(effectGenNode)),
|
|
3006
|
-
|
|
3217
|
+
yield* pipe(
|
|
3218
|
+
typeParser.effectGen(effectGenNode),
|
|
3219
|
+
orElse3(() => typeParser.effectFnUntracedGen(effectGenNode)),
|
|
3220
|
+
orElse3(() => typeParser.effectFnGen(effectGenNode)),
|
|
3221
|
+
map4(({ functionStar }) => {
|
|
3222
|
+
if (functionStar) {
|
|
3223
|
+
brokenGenerators.add(functionStar);
|
|
3224
|
+
}
|
|
3225
|
+
brokenYields.add(node);
|
|
3226
|
+
}),
|
|
3227
|
+
ignore
|
|
3007
3228
|
);
|
|
3008
|
-
if (isSome2(effectGenLike)) {
|
|
3009
|
-
if (effectGenLike.value.functionStar) {
|
|
3010
|
-
brokenGenerators.add(effectGenLike.value.functionStar);
|
|
3011
|
-
}
|
|
3012
|
-
brokenYields.add(node);
|
|
3013
|
-
}
|
|
3014
3229
|
}
|
|
3015
3230
|
}
|
|
3016
3231
|
}
|
|
@@ -3050,11 +3265,12 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
3050
3265
|
});
|
|
3051
3266
|
|
|
3052
3267
|
// src/diagnostics/unnecessaryEffectGen.ts
|
|
3053
|
-
var
|
|
3268
|
+
var unnecessaryEffectGen = createDiagnostic({
|
|
3054
3269
|
name: "unnecessaryEffectGen",
|
|
3055
3270
|
code: 5,
|
|
3056
3271
|
apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile) {
|
|
3057
3272
|
const ts = yield* service(TypeScriptApi);
|
|
3273
|
+
const typeParser = yield* service(TypeParser);
|
|
3058
3274
|
const effectDiagnostics = [];
|
|
3059
3275
|
const unnecessaryGenerators = /* @__PURE__ */ new Map();
|
|
3060
3276
|
const nodeToVisit = [];
|
|
@@ -3066,9 +3282,12 @@ var unnecessaryEffectGen2 = createDiagnostic({
|
|
|
3066
3282
|
while (nodeToVisit.length > 0) {
|
|
3067
3283
|
const node = nodeToVisit.shift();
|
|
3068
3284
|
ts.forEachChild(node, appendNodeToVisit);
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3285
|
+
if (ts.isCallExpression(node)) {
|
|
3286
|
+
yield* pipe(
|
|
3287
|
+
typeParser.unnecessaryEffectGen(node),
|
|
3288
|
+
map4(({ replacementNode }) => unnecessaryGenerators.set(node, replacementNode)),
|
|
3289
|
+
ignore
|
|
3290
|
+
);
|
|
3072
3291
|
}
|
|
3073
3292
|
}
|
|
3074
3293
|
unnecessaryGenerators.forEach(
|
|
@@ -3099,8 +3318,9 @@ var diagnostics = [
|
|
|
3099
3318
|
missingEffectError,
|
|
3100
3319
|
floatingEffect,
|
|
3101
3320
|
missingStarInYieldEffectGen,
|
|
3102
|
-
|
|
3103
|
-
missingReturnYieldStar
|
|
3321
|
+
unnecessaryEffectGen,
|
|
3322
|
+
missingReturnYieldStar,
|
|
3323
|
+
leakingRequirements
|
|
3104
3324
|
];
|
|
3105
3325
|
|
|
3106
3326
|
// src/goto/effectRpcDefinition.ts
|
|
@@ -3242,6 +3462,7 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
|
|
|
3242
3462
|
gen2(function* () {
|
|
3243
3463
|
const ts = yield* service(TypeScriptApi);
|
|
3244
3464
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3465
|
+
const typeParser = yield* service(TypeParser);
|
|
3245
3466
|
const maybeNode = pipe(
|
|
3246
3467
|
yield* getAncestorNodesInRange(sourceFile, toTextRange(position)),
|
|
3247
3468
|
head
|
|
@@ -3251,13 +3472,13 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
|
|
|
3251
3472
|
const hasTruncationHappened = quickInfo2 && ts.displayPartsToString(quickInfo2.displayParts).indexOf("...") > -1;
|
|
3252
3473
|
const nodeForType = !quickInfo2 && ts.isYieldExpression(node) && node.asteriskToken && node.expression ? node.expression : hasTruncationHappened ? node : void 0;
|
|
3253
3474
|
if (!nodeForType) return quickInfo2;
|
|
3254
|
-
const
|
|
3475
|
+
const effectType = yield* typeParser.effectType(
|
|
3255
3476
|
typeChecker.getTypeAtLocation(nodeForType),
|
|
3256
3477
|
nodeForType
|
|
3257
3478
|
);
|
|
3258
3479
|
const effectTypeArgsDocumentation = [{
|
|
3259
3480
|
kind: "text",
|
|
3260
|
-
text: "```ts\n/* Effect Type Parameters */\n" + (yield* formatTypeForQuickInfo(
|
|
3481
|
+
text: "```ts\n/* Effect Type Parameters */\n" + (yield* formatTypeForQuickInfo(effectType.A, "Success")) + "\n" + (yield* formatTypeForQuickInfo(effectType.E, "Failure")) + "\n" + (yield* formatTypeForQuickInfo(effectType.R, "Requirements")) + "\n```\n"
|
|
3261
3482
|
}];
|
|
3262
3483
|
if (!quickInfo2) {
|
|
3263
3484
|
const start = node.getStart();
|
|
@@ -3315,6 +3536,7 @@ function processLayerGraphNode(ctx, node, pipedInGraphNode) {
|
|
|
3315
3536
|
return gen2(function* () {
|
|
3316
3537
|
const ts = yield* service(TypeScriptApi);
|
|
3317
3538
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3539
|
+
const typeParser = yield* service(TypeParser);
|
|
3318
3540
|
const maybePipe = yield* option(parsePipeCall(node));
|
|
3319
3541
|
if (isSome2(maybePipe)) {
|
|
3320
3542
|
let graphNode = yield* processLayerGraphNode(ctx, maybePipe.value.subject, void 0);
|
|
@@ -3325,7 +3547,7 @@ function processLayerGraphNode(ctx, node, pipedInGraphNode) {
|
|
|
3325
3547
|
}
|
|
3326
3548
|
if (ts.isCallExpression(node)) {
|
|
3327
3549
|
const type = typeChecker.getTypeAtLocation(node);
|
|
3328
|
-
const maybeLayer = yield* option(layerType(type, node));
|
|
3550
|
+
const maybeLayer = yield* option(typeParser.layerType(type, node));
|
|
3329
3551
|
if (isSome2(maybeLayer)) {
|
|
3330
3552
|
const argNodes = yield* option(
|
|
3331
3553
|
all2(...node.arguments.map((_) => processLayerGraphNode(ctx, _, void 0)))
|
|
@@ -3358,7 +3580,7 @@ function processLayerGraphNode(ctx, node, pipedInGraphNode) {
|
|
|
3358
3580
|
if (callSignatures.length === 1) {
|
|
3359
3581
|
const [signature] = callSignatures;
|
|
3360
3582
|
const returnType = signature.getReturnType();
|
|
3361
|
-
const maybeLayer = yield* option(layerType(returnType, node));
|
|
3583
|
+
const maybeLayer = yield* option(typeParser.layerType(returnType, node));
|
|
3362
3584
|
if (isSome2(maybeLayer)) {
|
|
3363
3585
|
const { allIndexes: outTypes } = yield* appendToUniqueTypesMap(
|
|
3364
3586
|
ctx.services,
|
|
@@ -3408,7 +3630,7 @@ function processLayerGraphNode(ctx, node, pipedInGraphNode) {
|
|
|
3408
3630
|
}
|
|
3409
3631
|
if (ts.isExpression(node)) {
|
|
3410
3632
|
const type = typeChecker.getTypeAtLocation(node);
|
|
3411
|
-
const maybeLayer = yield* option(layerType(type, node));
|
|
3633
|
+
const maybeLayer = yield* option(typeParser.layerType(type, node));
|
|
3412
3634
|
if (isSome2(maybeLayer)) {
|
|
3413
3635
|
const { allIndexes: outTypes } = yield* appendToUniqueTypesMap(
|
|
3414
3636
|
ctx.services,
|
|
@@ -3547,6 +3769,7 @@ function layerInfo(sourceFile, position, quickInfo2) {
|
|
|
3547
3769
|
gen2(function* () {
|
|
3548
3770
|
const ts = yield* service(TypeScriptApi);
|
|
3549
3771
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3772
|
+
const typeParser = yield* service(TypeParser);
|
|
3550
3773
|
const range = toTextRange(position);
|
|
3551
3774
|
const maybeNode = pipe(
|
|
3552
3775
|
yield* getAncestorNodesInRange(sourceFile, range),
|
|
@@ -3557,8 +3780,8 @@ function layerInfo(sourceFile, position, quickInfo2) {
|
|
|
3557
3780
|
if (isNone2(maybeNode)) return quickInfo2;
|
|
3558
3781
|
const node = maybeNode.value;
|
|
3559
3782
|
const layerNode = node.initializer ? node.initializer : node;
|
|
3560
|
-
const
|
|
3561
|
-
const maybeLayer = yield* option(layerType(
|
|
3783
|
+
const layerType = typeChecker.getTypeAtLocation(layerNode);
|
|
3784
|
+
const maybeLayer = yield* option(typeParser.layerType(layerType, layerNode));
|
|
3562
3785
|
if (isNone2(maybeLayer)) return quickInfo2;
|
|
3563
3786
|
let lastId = 0;
|
|
3564
3787
|
const graphCtx = {
|
|
@@ -3662,6 +3885,7 @@ var asyncAwaitToGen = createRefactor({
|
|
|
3662
3885
|
apply: fn("asyncAwaitToGen.apply")(function* (sourceFile, textRange) {
|
|
3663
3886
|
const ts = yield* service(TypeScriptApi);
|
|
3664
3887
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3888
|
+
const typeParser = yield* service(TypeParser);
|
|
3665
3889
|
const maybeNode = pipe(
|
|
3666
3890
|
yield* getAncestorNodesInRange(sourceFile, textRange),
|
|
3667
3891
|
filter(
|
|
@@ -3684,7 +3908,7 @@ var asyncAwaitToGen = createRefactor({
|
|
|
3684
3908
|
findImportedModuleIdentifier(
|
|
3685
3909
|
sourceFile,
|
|
3686
3910
|
(node2) => pipe(
|
|
3687
|
-
importedEffectModule(node2),
|
|
3911
|
+
typeParser.importedEffectModule(node2),
|
|
3688
3912
|
option,
|
|
3689
3913
|
map4(isSome2)
|
|
3690
3914
|
)
|
|
@@ -3732,6 +3956,7 @@ var asyncAwaitToGenTryPromise = createRefactor({
|
|
|
3732
3956
|
apply: fn("asyncAwaitToGenTryPromise.apply")(function* (sourceFile, textRange) {
|
|
3733
3957
|
const ts = yield* service(TypeScriptApi);
|
|
3734
3958
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
3959
|
+
const typeParser = yield* service(TypeParser);
|
|
3735
3960
|
const maybeNode = pipe(
|
|
3736
3961
|
yield* getAncestorNodesInRange(sourceFile, textRange),
|
|
3737
3962
|
filter(
|
|
@@ -3754,7 +3979,7 @@ var asyncAwaitToGenTryPromise = createRefactor({
|
|
|
3754
3979
|
findImportedModuleIdentifier(
|
|
3755
3980
|
sourceFile,
|
|
3756
3981
|
(node2) => pipe(
|
|
3757
|
-
importedEffectModule(node2),
|
|
3982
|
+
typeParser.importedEffectModule(node2),
|
|
3758
3983
|
option,
|
|
3759
3984
|
map4(isSome2)
|
|
3760
3985
|
)
|
|
@@ -3831,17 +4056,18 @@ var effectGenToFn = createRefactor({
|
|
|
3831
4056
|
description: "Convert to Effect.fn",
|
|
3832
4057
|
apply: fn("effectGenToFn.apply")(function* (sourceFile, textRange) {
|
|
3833
4058
|
const ts = yield* service(TypeScriptApi);
|
|
4059
|
+
const typeParser = yield* service(TypeParser);
|
|
3834
4060
|
const parseEffectGenNode = fn("asyncAwaitToGen.apply")(function* (node) {
|
|
3835
|
-
const
|
|
4061
|
+
const effectGen = yield* typeParser.effectGen(node);
|
|
3836
4062
|
let pipeArgs2 = ts.factory.createNodeArray([]);
|
|
3837
4063
|
let nodeToReplace2 = node;
|
|
3838
4064
|
while (nodeToReplace2.parent) {
|
|
3839
4065
|
const parent = nodeToReplace2.parent;
|
|
3840
4066
|
if (ts.isConciseBody(nodeToReplace2) && ts.isArrowFunction(parent) && parent.body === nodeToReplace2) {
|
|
3841
|
-
return { ...
|
|
4067
|
+
return { ...effectGen, pipeArgs: pipeArgs2, nodeToReplace: parent };
|
|
3842
4068
|
}
|
|
3843
4069
|
if ((ts.isFunctionDeclaration(parent) || ts.isMethodDeclaration(parent)) && parent.body === nodeToReplace2) {
|
|
3844
|
-
return { ...
|
|
4070
|
+
return { ...effectGen, pipeArgs: pipeArgs2, nodeToReplace: parent };
|
|
3845
4071
|
}
|
|
3846
4072
|
if (ts.isBlock(parent) && parent.statements.length === 1 && parent.statements[0] === nodeToReplace2) {
|
|
3847
4073
|
nodeToReplace2 = parent;
|
|
@@ -3978,6 +4204,7 @@ var _findSchemaVariableDeclaration = fn(
|
|
|
3978
4204
|
function* (sourceFile, textRange) {
|
|
3979
4205
|
const ts = yield* service(TypeScriptApi);
|
|
3980
4206
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
4207
|
+
const typeParser = yield* service(TypeParser);
|
|
3981
4208
|
const findSchema = fn("makeSchemaOpaque.apply.findSchema")(
|
|
3982
4209
|
function* (node) {
|
|
3983
4210
|
if (!ts.isVariableDeclaration(node)) {
|
|
@@ -3996,7 +4223,7 @@ var _findSchemaVariableDeclaration = fn(
|
|
|
3996
4223
|
return yield* fail("parent not variable declaration statement");
|
|
3997
4224
|
}
|
|
3998
4225
|
const type = typeChecker.getTypeAtLocation(initializer);
|
|
3999
|
-
const types = yield* effectSchemaType(type, initializer);
|
|
4226
|
+
const types = yield* typeParser.effectSchemaType(type, initializer);
|
|
4000
4227
|
return { identifier, variableStatement, variableDeclarationList, types };
|
|
4001
4228
|
}
|
|
4002
4229
|
);
|
|
@@ -4343,8 +4570,9 @@ var removeUnnecessaryEffectGen = createRefactor({
|
|
|
4343
4570
|
name: "removeUnnecessaryEffectGen",
|
|
4344
4571
|
description: "Remove unnecessary Effect.gen",
|
|
4345
4572
|
apply: fn("removeUnnecessaryEffectGen.apply")(function* (sourceFile, textRange) {
|
|
4573
|
+
const typeParser = yield* service(TypeParser);
|
|
4346
4574
|
for (const nodeToReplace of yield* getAncestorNodesInRange(sourceFile, textRange)) {
|
|
4347
|
-
const maybeNode = yield* option(unnecessaryEffectGen(nodeToReplace));
|
|
4575
|
+
const maybeNode = yield* option(typeParser.unnecessaryEffectGen(nodeToReplace));
|
|
4348
4576
|
if (isNone2(maybeNode)) continue;
|
|
4349
4577
|
const replacementNode = maybeNode.value.replacementNode;
|
|
4350
4578
|
return {
|
|
@@ -5027,13 +5255,14 @@ var wrapWithEffectGen = createRefactor({
|
|
|
5027
5255
|
apply: fn("wrapWithEffectGen.apply")(function* (sourceFile, textRange) {
|
|
5028
5256
|
const ts = yield* service(TypeScriptApi);
|
|
5029
5257
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
5258
|
+
const typeParser = yield* service(TypeParser);
|
|
5030
5259
|
const findEffectToWrap = fn("wrapWithEffectGen.apply.findEffectToWrap")(
|
|
5031
5260
|
function* (node) {
|
|
5032
5261
|
if (!ts.isExpression(node)) return yield* fail("is not an expression");
|
|
5033
5262
|
const parent = node.parent;
|
|
5034
5263
|
if (parent != null && ts.isVariableDeclaration(parent) && parent.initializer !== node) return yield* fail("is LHS of variable declaration");
|
|
5035
5264
|
const type = typeChecker.getTypeAtLocation(node);
|
|
5036
|
-
yield* effectType(type, node);
|
|
5265
|
+
yield* typeParser.effectType(type, node);
|
|
5037
5266
|
return node;
|
|
5038
5267
|
}
|
|
5039
5268
|
);
|
|
@@ -5044,19 +5273,35 @@ var wrapWithEffectGen = createRefactor({
|
|
|
5044
5273
|
option
|
|
5045
5274
|
);
|
|
5046
5275
|
if (isNone2(maybeNode)) return yield* fail(new RefactorNotApplicableError());
|
|
5276
|
+
const effectModuleIdentifier = match2(
|
|
5277
|
+
yield* option(
|
|
5278
|
+
findImportedModuleIdentifier(
|
|
5279
|
+
sourceFile,
|
|
5280
|
+
(node) => pipe(
|
|
5281
|
+
typeParser.importedEffectModule(node),
|
|
5282
|
+
option,
|
|
5283
|
+
map4(isSome2)
|
|
5284
|
+
)
|
|
5285
|
+
)
|
|
5286
|
+
),
|
|
5287
|
+
{
|
|
5288
|
+
onNone: () => "Effect",
|
|
5289
|
+
onSome: (node) => node.text
|
|
5290
|
+
}
|
|
5291
|
+
);
|
|
5047
5292
|
return {
|
|
5048
5293
|
kind: "refactor.rewrite.effect.wrapWithEffectGen",
|
|
5049
5294
|
description: `Wrap with Effect.gen`,
|
|
5050
5295
|
apply: pipe(
|
|
5051
5296
|
gen2(function* () {
|
|
5052
5297
|
const changeTracker = yield* service(ChangeTracker);
|
|
5053
|
-
const
|
|
5298
|
+
const effectGen = yield* pipe(
|
|
5054
5299
|
createEffectGenCallExpressionWithBlock(
|
|
5055
|
-
|
|
5300
|
+
effectModuleIdentifier,
|
|
5056
5301
|
yield* createReturnYieldStarStatement(maybeNode.value)
|
|
5057
5302
|
)
|
|
5058
5303
|
);
|
|
5059
|
-
changeTracker.replaceNode(sourceFile, maybeNode.value,
|
|
5304
|
+
changeTracker.replaceNode(sourceFile, maybeNode.value, effectGen);
|
|
5060
5305
|
}),
|
|
5061
5306
|
provideService(TypeScriptApi, ts),
|
|
5062
5307
|
provideService(TypeCheckerApi, typeChecker)
|
|
@@ -5064,26 +5309,6 @@ var wrapWithEffectGen = createRefactor({
|
|
|
5064
5309
|
};
|
|
5065
5310
|
})
|
|
5066
5311
|
});
|
|
5067
|
-
var getEffectModuleIdentifierName = fn("getEffectModuleIdentifierName")(
|
|
5068
|
-
function* (sourceFile) {
|
|
5069
|
-
return match2(
|
|
5070
|
-
yield* option(
|
|
5071
|
-
findImportedModuleIdentifier(
|
|
5072
|
-
sourceFile,
|
|
5073
|
-
(node) => pipe(
|
|
5074
|
-
importedEffectModule(node),
|
|
5075
|
-
option,
|
|
5076
|
-
map4(isSome2)
|
|
5077
|
-
)
|
|
5078
|
-
)
|
|
5079
|
-
),
|
|
5080
|
-
{
|
|
5081
|
-
onNone: () => "Effect",
|
|
5082
|
-
onSome: (node) => node.text
|
|
5083
|
-
}
|
|
5084
|
-
);
|
|
5085
|
-
}
|
|
5086
|
-
);
|
|
5087
5312
|
|
|
5088
5313
|
// src/refactors/wrapWithPipe.ts
|
|
5089
5314
|
var wrapWithPipe = createRefactor({
|
|
@@ -5148,6 +5373,7 @@ var init = (modules) => {
|
|
|
5148
5373
|
function runNano(program) {
|
|
5149
5374
|
return (fa) => pipe(
|
|
5150
5375
|
fa,
|
|
5376
|
+
provideService(TypeParser, make4(modules.typescript, program.getTypeChecker())),
|
|
5151
5377
|
provideService(TypeScriptProgram, program),
|
|
5152
5378
|
provideService(TypeCheckerApi, program.getTypeChecker()),
|
|
5153
5379
|
provideService(
|
|
@@ -5358,15 +5584,17 @@ var init = (modules) => {
|
|
|
5358
5584
|
};
|
|
5359
5585
|
proxy.getDefinitionAndBoundSpan = (fileName, position, ...args) => {
|
|
5360
5586
|
const applicableDefinition = languageService.getDefinitionAndBoundSpan(fileName, position, ...args);
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5587
|
+
if (languageServicePluginOptions.goto) {
|
|
5588
|
+
const program = languageService.getProgram();
|
|
5589
|
+
if (program) {
|
|
5590
|
+
const sourceFile = program.getSourceFile(fileName);
|
|
5591
|
+
if (sourceFile) {
|
|
5592
|
+
return pipe(
|
|
5593
|
+
goto(applicableDefinition, sourceFile, position),
|
|
5594
|
+
runNano(program),
|
|
5595
|
+
Either_exports.getOrElse(() => applicableDefinition)
|
|
5596
|
+
);
|
|
5597
|
+
}
|
|
5370
5598
|
}
|
|
5371
5599
|
}
|
|
5372
5600
|
return applicableDefinition;
|