@effect/language-service 0.20.0 → 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 +852 -615
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +674 -446
- package/transform.js.map +1 -1
package/transform.js
CHANGED
|
@@ -3,9 +3,9 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target,
|
|
7
|
-
for (var name in
|
|
8
|
-
__defProp(target, name, { get:
|
|
6
|
+
var __export = (target, all2) => {
|
|
7
|
+
for (var name in all2)
|
|
8
|
+
__defProp(target, name, { get: all2[name], enumerable: true });
|
|
9
9
|
};
|
|
10
10
|
var __copyProps = (to, from, except, desc) => {
|
|
11
11
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
@@ -428,6 +428,7 @@ function compareBoth(self, that) {
|
|
|
428
428
|
return structuralRegionState.enabled && structuralRegionState.tester ? structuralRegionState.tester(self, that) : false;
|
|
429
429
|
}
|
|
430
430
|
var isEqual = (u) => hasProperty(u, symbol2);
|
|
431
|
+
var equivalence = () => equals;
|
|
431
432
|
|
|
432
433
|
// node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Inspectable.js
|
|
433
434
|
var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
|
|
@@ -759,6 +760,20 @@ var sort = /* @__PURE__ */ dual(2, (self, O) => {
|
|
|
759
760
|
out.sort(O);
|
|
760
761
|
return out;
|
|
761
762
|
});
|
|
763
|
+
var containsWith = (isEquivalent) => dual(2, (self, a) => {
|
|
764
|
+
for (const i of self) {
|
|
765
|
+
if (isEquivalent(a, i)) {
|
|
766
|
+
return true;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
return false;
|
|
770
|
+
});
|
|
771
|
+
var _equivalence = /* @__PURE__ */ equivalence();
|
|
772
|
+
var intersectionWith = (isEquivalent) => {
|
|
773
|
+
const has = containsWith(isEquivalent);
|
|
774
|
+
return dual(2, (self, that) => fromIterable(self).filter((a) => has(that, a)));
|
|
775
|
+
};
|
|
776
|
+
var intersection = /* @__PURE__ */ intersectionWith(_equivalence);
|
|
762
777
|
var empty = () => [];
|
|
763
778
|
var map2 = /* @__PURE__ */ dual(2, (self, f) => self.map(f));
|
|
764
779
|
var flatMap = /* @__PURE__ */ dual(2, (self, f) => {
|
|
@@ -837,7 +852,8 @@ function make2(run2) {
|
|
|
837
852
|
return result;
|
|
838
853
|
}
|
|
839
854
|
var unsafeRun = (fa) => {
|
|
840
|
-
const
|
|
855
|
+
const program = provideService(internalNanoCache, {})(fa);
|
|
856
|
+
const result = program.run(contextEmpty);
|
|
841
857
|
switch (result._tag) {
|
|
842
858
|
case "Left":
|
|
843
859
|
return left2(result.value);
|
|
@@ -873,14 +889,14 @@ var orElse2 = (f) => (fa) => make2((ctx) => {
|
|
|
873
889
|
return result;
|
|
874
890
|
});
|
|
875
891
|
var service = (tag) => make2(
|
|
876
|
-
(ctx) => tag.key in ctx.value ?
|
|
892
|
+
(ctx) => tag.key in ctx.value ? ctx.value[tag.key] : makeInternalDefect(`Cannot find service ${tag.key}`)
|
|
877
893
|
);
|
|
878
894
|
var provideService = (tag, value) => (fa) => make2((ctx) => {
|
|
879
895
|
return fa.run({
|
|
880
896
|
...ctx,
|
|
881
897
|
value: {
|
|
882
898
|
...ctx.value,
|
|
883
|
-
[tag.key]: value
|
|
899
|
+
[tag.key]: makeInternalSuccess(value)
|
|
884
900
|
}
|
|
885
901
|
});
|
|
886
902
|
});
|
|
@@ -921,6 +937,41 @@ var option = (fa) => make2((ctx) => {
|
|
|
921
937
|
return result;
|
|
922
938
|
}
|
|
923
939
|
});
|
|
940
|
+
var successUndefined = makeInternalSuccess(void 0);
|
|
941
|
+
var void_ = make2(() => successUndefined);
|
|
942
|
+
var ignore = (fa) => make2((ctx) => {
|
|
943
|
+
fa.run(ctx);
|
|
944
|
+
return successUndefined;
|
|
945
|
+
});
|
|
946
|
+
var all = (...args) => make2((ctx) => {
|
|
947
|
+
const results = [];
|
|
948
|
+
for (const arg of args) {
|
|
949
|
+
const result = arg.run(ctx);
|
|
950
|
+
if (result._tag !== "Right") return result;
|
|
951
|
+
results.push(result.value);
|
|
952
|
+
}
|
|
953
|
+
return makeInternalSuccess(results);
|
|
954
|
+
});
|
|
955
|
+
var internalNanoCache = Tag(
|
|
956
|
+
"@effect/language-service/internalNanoCache"
|
|
957
|
+
);
|
|
958
|
+
function cachedBy(fa, key, lookupKey) {
|
|
959
|
+
return (...args) => make2((ctx) => {
|
|
960
|
+
const cacheObj = ctx.value[internalNanoCache.key];
|
|
961
|
+
let cache = cacheObj[key];
|
|
962
|
+
if (!cache) {
|
|
963
|
+
cache = /* @__PURE__ */ new Map();
|
|
964
|
+
cacheObj[key] = cache;
|
|
965
|
+
}
|
|
966
|
+
const lookup = lookupKey(...args);
|
|
967
|
+
if (cache.has(lookup)) {
|
|
968
|
+
return cache.get(lookup);
|
|
969
|
+
}
|
|
970
|
+
const result = fa(...args).run(ctx);
|
|
971
|
+
cache.set(lookup, result);
|
|
972
|
+
return result;
|
|
973
|
+
});
|
|
974
|
+
}
|
|
924
975
|
|
|
925
976
|
// src/core/LanguageServicePluginOptions.ts
|
|
926
977
|
var LanguageServicePluginOptions = Tag("PluginOptions");
|
|
@@ -929,6 +980,7 @@ function parse(config) {
|
|
|
929
980
|
diagnostics: isObject(config) && hasProperty(config, "diagnostics") && isBoolean(config.diagnostics) ? config.diagnostics : true,
|
|
930
981
|
quickinfo: isObject(config) && hasProperty(config, "quickinfo") && isBoolean(config.quickinfo) ? config.quickinfo : true,
|
|
931
982
|
completions: isObject(config) && hasProperty(config, "completions") && isBoolean(config.completions) ? config.completions : true,
|
|
983
|
+
goto: isObject(config) && hasProperty(config, "goto") && isBoolean(config.goto) ? config.goto : true,
|
|
932
984
|
allowedDuplicatedPackages: isObject(config) && hasProperty(config, "allowedDuplicatedPackages") && isArray(config.allowedDuplicatedPackages) && config.allowedDuplicatedPackages.every(isString) ? config.allowedDuplicatedPackages.map((_) => _.toLowerCase()) : []
|
|
933
985
|
};
|
|
934
986
|
}
|
|
@@ -1452,55 +1504,6 @@ var appendToUniqueTypesMap = fn(
|
|
|
1452
1504
|
}
|
|
1453
1505
|
);
|
|
1454
1506
|
|
|
1455
|
-
// src/diagnostics/duplicatePackage.ts
|
|
1456
|
-
var checkedPackagesCache = /* @__PURE__ */ new Map();
|
|
1457
|
-
var programResolvedCacheSize = /* @__PURE__ */ new Map();
|
|
1458
|
-
var duplicatePackage = createDiagnostic({
|
|
1459
|
-
name: "duplicatePackage",
|
|
1460
|
-
code: 6,
|
|
1461
|
-
apply: fn("duplicatePackage.apply")(function* (sourceFile) {
|
|
1462
|
-
const ts = yield* service(TypeScriptApi);
|
|
1463
|
-
const program = yield* service(TypeScriptProgram);
|
|
1464
|
-
const options = yield* service(LanguageServicePluginOptions);
|
|
1465
|
-
const effectDiagnostics = [];
|
|
1466
|
-
if (sourceFile.statements.length < 1) return [];
|
|
1467
|
-
let resolvedPackages = checkedPackagesCache.get(sourceFile.fileName) || {};
|
|
1468
|
-
const newResolvedModuleSize = hasProperty(program, "resolvedModules") && hasProperty(program.resolvedModules, "size") && isNumber(program.resolvedModules.size) ? program.resolvedModules.size : 0;
|
|
1469
|
-
const oldResolvedSize = programResolvedCacheSize.get(sourceFile.fileName) || -1;
|
|
1470
|
-
if (newResolvedModuleSize !== oldResolvedSize) {
|
|
1471
|
-
const seenPackages = /* @__PURE__ */ new Set();
|
|
1472
|
-
resolvedPackages = {};
|
|
1473
|
-
program.getSourceFiles().map((_) => {
|
|
1474
|
-
const packageInfo = parsePackageContentNameAndVersionFromScope(_);
|
|
1475
|
-
if (!packageInfo) return;
|
|
1476
|
-
const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
|
|
1477
|
-
if (seenPackages.has(packageNameAndVersion)) return;
|
|
1478
|
-
seenPackages.add(packageNameAndVersion);
|
|
1479
|
-
if (!(packageInfo.name === "effect" || packageInfo.hasEffectInPeerDependencies)) return;
|
|
1480
|
-
if (options.allowedDuplicatedPackages.indexOf(packageInfo.name) > -1) return;
|
|
1481
|
-
resolvedPackages[packageInfo.name] = resolvedPackages[packageInfo.name] || {};
|
|
1482
|
-
resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.contents;
|
|
1483
|
-
});
|
|
1484
|
-
checkedPackagesCache.set(sourceFile.fileName, resolvedPackages);
|
|
1485
|
-
programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
|
|
1486
|
-
}
|
|
1487
|
-
for (const packageName of Object.keys(resolvedPackages)) {
|
|
1488
|
-
if (Object.keys(resolvedPackages[packageName]).length > 1) {
|
|
1489
|
-
const versions = Object.keys(resolvedPackages[packageName]);
|
|
1490
|
-
effectDiagnostics.push({
|
|
1491
|
-
node: sourceFile.statements[0],
|
|
1492
|
-
category: ts.DiagnosticCategory.Warning,
|
|
1493
|
-
messageText: `Package ${packageName} is referenced multiple times with different versions (${versions.join(", ")}) and may cause unexpected type errors.
|
|
1494
|
-
Cleanup your dependencies and your package lockfile to avoid multiple instances of this package and reload the project.
|
|
1495
|
-
If this is intended set the LSP config "allowedDuplicatedPackages" to ${JSON.stringify(options.allowedDuplicatedPackages.concat([packageName]))}.`,
|
|
1496
|
-
fixes: []
|
|
1497
|
-
});
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
|
-
return effectDiagnostics;
|
|
1501
|
-
})
|
|
1502
|
-
});
|
|
1503
|
-
|
|
1504
1507
|
// src/core/AST.ts
|
|
1505
1508
|
function collectSelfAndAncestorNodesInRange(node, textRange) {
|
|
1506
1509
|
return sync(() => {
|
|
@@ -1856,400 +1859,508 @@ var parsePipeCall = fn("AST.parsePipeCall")(
|
|
|
1856
1859
|
}
|
|
1857
1860
|
);
|
|
1858
1861
|
|
|
1859
|
-
// src/
|
|
1860
|
-
var
|
|
1861
|
-
|
|
1862
|
-
this.type = type;
|
|
1863
|
-
this.node = node;
|
|
1864
|
-
this.message = message;
|
|
1865
|
-
}
|
|
1862
|
+
// src/core/TypeParser.ts
|
|
1863
|
+
var TypeParser = Tag("@effect/language-service/TypeParser");
|
|
1864
|
+
var TypeParserIssue = class _TypeParserIssue {
|
|
1866
1865
|
_tag = "@effect/language-service/TypeParserIssue";
|
|
1866
|
+
static issue = fail(new _TypeParserIssue());
|
|
1867
1867
|
};
|
|
1868
|
-
function
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
function contravariantTypeArgument(type) {
|
|
1879
|
-
const signatures = type.getCallSignatures();
|
|
1880
|
-
if (signatures.length !== 1) {
|
|
1881
|
-
return typeParserIssue("Contravariant type has no call signature", type);
|
|
1882
|
-
}
|
|
1883
|
-
return succeed(signatures[0].getTypeParameterAtPosition(0));
|
|
1884
|
-
}
|
|
1885
|
-
function invariantTypeArgument(type) {
|
|
1886
|
-
const signatures = type.getCallSignatures();
|
|
1887
|
-
if (signatures.length !== 1) {
|
|
1888
|
-
return typeParserIssue("Invariant type has no call signature", type);
|
|
1868
|
+
function make3(ts, typeChecker) {
|
|
1869
|
+
function typeParserIssue(_message, _type, _node) {
|
|
1870
|
+
return TypeParserIssue.issue;
|
|
1871
|
+
}
|
|
1872
|
+
function covariantTypeArgument(type) {
|
|
1873
|
+
const signatures = type.getCallSignatures();
|
|
1874
|
+
if (signatures.length !== 1) {
|
|
1875
|
+
return typeParserIssue("Covariant type has no call signature", type);
|
|
1876
|
+
}
|
|
1877
|
+
return succeed(signatures[0].getReturnType());
|
|
1889
1878
|
}
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
return yield* typeParserIssue("Type has no 'pipe' property", type, atLocation);
|
|
1879
|
+
function contravariantTypeArgument(type) {
|
|
1880
|
+
const signatures = type.getCallSignatures();
|
|
1881
|
+
if (signatures.length !== 1) {
|
|
1882
|
+
return typeParserIssue("Contravariant type has no call signature", type);
|
|
1883
|
+
}
|
|
1884
|
+
return succeed(signatures[0].getTypeParameterAtPosition(0));
|
|
1897
1885
|
}
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1886
|
+
function invariantTypeArgument(type) {
|
|
1887
|
+
const signatures = type.getCallSignatures();
|
|
1888
|
+
if (signatures.length !== 1) {
|
|
1889
|
+
return typeParserIssue("Invariant type has no call signature", type);
|
|
1890
|
+
}
|
|
1891
|
+
return succeed(signatures[0].getReturnType());
|
|
1902
1892
|
}
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1893
|
+
const pipeableType = cachedBy(
|
|
1894
|
+
fn("TypeParser.pipeableType")(function* (type, atLocation) {
|
|
1895
|
+
const pipeSymbol = typeChecker.getPropertyOfType(type, "pipe");
|
|
1896
|
+
if (!pipeSymbol) {
|
|
1897
|
+
return yield* typeParserIssue("Type has no 'pipe' property", type, atLocation);
|
|
1898
|
+
}
|
|
1899
|
+
const pipeType = typeChecker.getTypeOfSymbolAtLocation(pipeSymbol, atLocation);
|
|
1900
|
+
const signatures = pipeType.getCallSignatures();
|
|
1901
|
+
if (signatures.length === 0) {
|
|
1902
|
+
return yield* typeParserIssue("'pipe' property is not callable", type, atLocation);
|
|
1903
|
+
}
|
|
1904
|
+
return type;
|
|
1905
|
+
}),
|
|
1906
|
+
"TypeParser.pipeableType",
|
|
1907
|
+
(type) => type
|
|
1908
|
+
);
|
|
1909
|
+
const varianceStructCovariantType = (type, atLocation, propertyName) => {
|
|
1908
1910
|
const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
|
|
1909
1911
|
if (!propertySymbol) {
|
|
1910
|
-
return
|
|
1912
|
+
return typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
|
|
1911
1913
|
}
|
|
1912
1914
|
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
1913
|
-
return
|
|
1914
|
-
}
|
|
1915
|
-
)
|
|
1916
|
-
var varianceStructContravariantType = fn(
|
|
1917
|
-
"TypeParser.varianceStructContravariantType"
|
|
1918
|
-
)(
|
|
1919
|
-
function* (type, atLocation, propertyName) {
|
|
1920
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
1915
|
+
return covariantTypeArgument(propertyType);
|
|
1916
|
+
};
|
|
1917
|
+
const varianceStructContravariantType = (type, atLocation, propertyName) => {
|
|
1921
1918
|
const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
|
|
1922
1919
|
if (!propertySymbol) {
|
|
1923
|
-
return
|
|
1920
|
+
return typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
|
|
1924
1921
|
}
|
|
1925
1922
|
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
1926
|
-
return
|
|
1927
|
-
}
|
|
1928
|
-
)
|
|
1929
|
-
var varianceStructInvariantType = fn("TypeParser.varianceStructInvariantType")(
|
|
1930
|
-
function* (type, atLocation, propertyName) {
|
|
1931
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
1923
|
+
return contravariantTypeArgument(propertyType);
|
|
1924
|
+
};
|
|
1925
|
+
const varianceStructInvariantType = (type, atLocation, propertyName) => {
|
|
1932
1926
|
const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
|
|
1933
1927
|
if (!propertySymbol) {
|
|
1934
|
-
return
|
|
1928
|
+
return typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
|
|
1935
1929
|
}
|
|
1936
1930
|
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
1937
|
-
return
|
|
1938
|
-
}
|
|
1939
|
-
);
|
|
1940
|
-
var effectVarianceStruct = fn("TypeParser.effectVarianceStruct")(function* (type, atLocation) {
|
|
1941
|
-
return {
|
|
1942
|
-
A: yield* varianceStructCovariantType(type, atLocation, "_A"),
|
|
1943
|
-
E: yield* varianceStructCovariantType(type, atLocation, "_E"),
|
|
1944
|
-
R: yield* varianceStructCovariantType(type, atLocation, "_R")
|
|
1931
|
+
return invariantTypeArgument(propertyType);
|
|
1945
1932
|
};
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
});
|
|
1954
|
-
var effectType = fn("TypeParser.effectType")(function* (type, atLocation) {
|
|
1955
|
-
const ts = yield* service(TypeScriptApi);
|
|
1956
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
1957
|
-
yield* pipeableType(type, atLocation);
|
|
1958
|
-
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
1959
|
-
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
1933
|
+
const effectVarianceStruct = (type, atLocation) => map3(
|
|
1934
|
+
all(
|
|
1935
|
+
varianceStructCovariantType(type, atLocation, "_A"),
|
|
1936
|
+
varianceStructCovariantType(type, atLocation, "_E"),
|
|
1937
|
+
varianceStructCovariantType(type, atLocation, "_R")
|
|
1938
|
+
),
|
|
1939
|
+
([A, E, R]) => ({ A, E, R })
|
|
1960
1940
|
);
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
))
|
|
1968
|
-
if (isSome2(varianceArgs)) {
|
|
1969
|
-
return varianceArgs.value;
|
|
1970
|
-
}
|
|
1971
|
-
}
|
|
1972
|
-
return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
|
|
1973
|
-
});
|
|
1974
|
-
var layerType = fn("TypeParser.layerType")(function* (type, atLocation) {
|
|
1975
|
-
const ts = yield* service(TypeScriptApi);
|
|
1976
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
1977
|
-
yield* pipeableType(type, atLocation);
|
|
1978
|
-
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
1979
|
-
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
1941
|
+
const layerVarianceStruct = (type, atLocation) => map3(
|
|
1942
|
+
all(
|
|
1943
|
+
varianceStructContravariantType(type, atLocation, "_ROut"),
|
|
1944
|
+
varianceStructCovariantType(type, atLocation, "_E"),
|
|
1945
|
+
varianceStructCovariantType(type, atLocation, "_RIn")
|
|
1946
|
+
),
|
|
1947
|
+
([ROut, E, RIn]) => ({ ROut, E, RIn })
|
|
1980
1948
|
);
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
atLocation
|
|
1987
|
-
));
|
|
1988
|
-
if (isSome2(varianceArgs)) {
|
|
1989
|
-
return varianceArgs.value;
|
|
1990
|
-
}
|
|
1991
|
-
}
|
|
1992
|
-
return yield* typeParserIssue("Type has no layer variance struct", type, atLocation);
|
|
1993
|
-
});
|
|
1994
|
-
var fiberType = fn("TypeParser.fiberType")(function* (type, atLocation) {
|
|
1995
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
1996
|
-
const awaitSymbol = typeChecker.getPropertyOfType(type, "await");
|
|
1997
|
-
const pollSymbol = typeChecker.getPropertyOfType(type, "poll");
|
|
1998
|
-
if (!awaitSymbol || !pollSymbol) {
|
|
1999
|
-
return yield* typeParserIssue(
|
|
2000
|
-
"Type is not a fiber because it does not have 'await' or 'poll' property",
|
|
2001
|
-
type,
|
|
2002
|
-
atLocation
|
|
2003
|
-
);
|
|
2004
|
-
}
|
|
2005
|
-
return yield* effectType(type, atLocation);
|
|
2006
|
-
});
|
|
2007
|
-
var effectSubtype = fn("TypeParser.effectSubtype")(function* (type, atLocation) {
|
|
2008
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2009
|
-
const tagSymbol = typeChecker.getPropertyOfType(type, "_tag");
|
|
2010
|
-
const getSymbol = typeChecker.getPropertyOfType(type, "get");
|
|
2011
|
-
if (!(tagSymbol || getSymbol)) {
|
|
2012
|
-
return yield* typeParserIssue(
|
|
2013
|
-
"Type is not a subtype of effect because it does not have '_tag' or 'get' property",
|
|
2014
|
-
type,
|
|
2015
|
-
atLocation
|
|
2016
|
-
);
|
|
2017
|
-
}
|
|
2018
|
-
return yield* effectType(type, atLocation);
|
|
2019
|
-
});
|
|
2020
|
-
var importedEffectModule = fn("TypeParser.importedEffectModule")(function* (node) {
|
|
2021
|
-
const ts = yield* service(TypeScriptApi);
|
|
2022
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2023
|
-
const type = typeChecker.getTypeAtLocation(node);
|
|
2024
|
-
const propertySymbol = typeChecker.getPropertyOfType(type, "never");
|
|
2025
|
-
if (!propertySymbol) {
|
|
2026
|
-
return yield* typeParserIssue("Type has no 'never' property", type, node);
|
|
2027
|
-
}
|
|
2028
|
-
if (!ts.isExpression(node)) {
|
|
2029
|
-
return yield* typeParserIssue("Node is not an expression", type, node);
|
|
2030
|
-
}
|
|
2031
|
-
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, node);
|
|
2032
|
-
yield* effectType(propertyType, node);
|
|
2033
|
-
return node;
|
|
2034
|
-
});
|
|
2035
|
-
var effectGen = fn("TypeParser.effectGen")(function* (node) {
|
|
2036
|
-
const ts = yield* service(TypeScriptApi);
|
|
2037
|
-
if (!ts.isCallExpression(node)) {
|
|
2038
|
-
return yield* typeParserIssue("Node is not a call expression", void 0, node);
|
|
2039
|
-
}
|
|
2040
|
-
if (node.arguments.length === 0) {
|
|
2041
|
-
return yield* typeParserIssue("Node has no arguments", void 0, node);
|
|
2042
|
-
}
|
|
2043
|
-
const generatorFunction = node.arguments[0];
|
|
2044
|
-
if (!ts.isFunctionExpression(generatorFunction)) {
|
|
2045
|
-
return yield* typeParserIssue("Node is not a function expression", void 0, node);
|
|
2046
|
-
}
|
|
2047
|
-
if (generatorFunction.asteriskToken === void 0) {
|
|
2048
|
-
return yield* typeParserIssue("Node is not a generator function", void 0, node);
|
|
2049
|
-
}
|
|
2050
|
-
if (!ts.isPropertyAccessExpression(node.expression)) {
|
|
2051
|
-
return yield* typeParserIssue("Node is not a property access expression", void 0, node);
|
|
2052
|
-
}
|
|
2053
|
-
const propertyAccess = node.expression;
|
|
2054
|
-
if (propertyAccess.name.text !== "gen") {
|
|
2055
|
-
return yield* typeParserIssue("Call expression name is not 'gen'", void 0, node);
|
|
2056
|
-
}
|
|
2057
|
-
const effectModule = yield* importedEffectModule(propertyAccess.expression);
|
|
2058
|
-
return {
|
|
2059
|
-
node,
|
|
2060
|
-
effectModule,
|
|
2061
|
-
generatorFunction,
|
|
2062
|
-
body: generatorFunction.body,
|
|
2063
|
-
functionStar: generatorFunction.getFirstToken()
|
|
2064
|
-
};
|
|
2065
|
-
});
|
|
2066
|
-
var effectFnUntracedGen = fn("TypeParser.effectFnUntracedGen")(
|
|
2067
|
-
function* (node) {
|
|
2068
|
-
const ts = yield* service(TypeScriptApi);
|
|
2069
|
-
if (!ts.isCallExpression(node)) {
|
|
2070
|
-
return yield* typeParserIssue("Node is not a call expression", void 0, node);
|
|
2071
|
-
}
|
|
2072
|
-
if (node.arguments.length === 0) {
|
|
2073
|
-
return yield* typeParserIssue("Node has no arguments", void 0, node);
|
|
2074
|
-
}
|
|
2075
|
-
const generatorFunction = node.arguments[0];
|
|
2076
|
-
if (!ts.isFunctionExpression(generatorFunction)) {
|
|
2077
|
-
return yield* typeParserIssue("Node is not a function expression", void 0, node);
|
|
2078
|
-
}
|
|
2079
|
-
if (generatorFunction.asteriskToken === void 0) {
|
|
2080
|
-
return yield* typeParserIssue(
|
|
2081
|
-
"Node is not a generator function",
|
|
2082
|
-
void 0,
|
|
2083
|
-
node
|
|
1949
|
+
const effectType = cachedBy(
|
|
1950
|
+
fn("TypeParser.effectType")(function* (type, atLocation) {
|
|
1951
|
+
yield* pipeableType(type, atLocation);
|
|
1952
|
+
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
1953
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2084
1954
|
);
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
1955
|
+
propertiesSymbols.sort((a, b) => b.name.indexOf("EffectTypeId") - a.name.indexOf("EffectTypeId"));
|
|
1956
|
+
for (const propertySymbol of propertiesSymbols) {
|
|
1957
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
1958
|
+
const varianceArgs = yield* option(effectVarianceStruct(
|
|
1959
|
+
propertyType,
|
|
1960
|
+
atLocation
|
|
1961
|
+
));
|
|
1962
|
+
if (isSome2(varianceArgs)) {
|
|
1963
|
+
return varianceArgs.value;
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
|
|
1967
|
+
}),
|
|
1968
|
+
"TypeParser.effectType",
|
|
1969
|
+
(type) => type
|
|
1970
|
+
);
|
|
1971
|
+
const layerType = cachedBy(
|
|
1972
|
+
fn("TypeParser.layerType")(function* (type, atLocation) {
|
|
1973
|
+
yield* pipeableType(type, atLocation);
|
|
1974
|
+
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
1975
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2091
1976
|
);
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
1977
|
+
propertiesSymbols.sort((a, b) => b.name.indexOf("LayerTypeId") - a.name.indexOf("LayerTypeId"));
|
|
1978
|
+
for (const propertySymbol of propertiesSymbols) {
|
|
1979
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
1980
|
+
const varianceArgs = yield* option(layerVarianceStruct(
|
|
1981
|
+
propertyType,
|
|
1982
|
+
atLocation
|
|
1983
|
+
));
|
|
1984
|
+
if (isSome2(varianceArgs)) {
|
|
1985
|
+
return varianceArgs.value;
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
return yield* typeParserIssue("Type has no layer variance struct", type, atLocation);
|
|
1989
|
+
}),
|
|
1990
|
+
"TypeParser.layerType",
|
|
1991
|
+
(type) => type
|
|
1992
|
+
);
|
|
1993
|
+
const fiberType = cachedBy(
|
|
1994
|
+
fn("TypeParser.fiberType")(function* (type, atLocation) {
|
|
1995
|
+
const awaitSymbol = typeChecker.getPropertyOfType(type, "await");
|
|
1996
|
+
const pollSymbol = typeChecker.getPropertyOfType(type, "poll");
|
|
1997
|
+
if (!awaitSymbol || !pollSymbol) {
|
|
1998
|
+
return yield* typeParserIssue(
|
|
1999
|
+
"Type is not a fiber because it does not have 'await' or 'poll' property",
|
|
2000
|
+
type,
|
|
2001
|
+
atLocation
|
|
2002
|
+
);
|
|
2003
|
+
}
|
|
2004
|
+
return yield* effectType(type, atLocation);
|
|
2005
|
+
}),
|
|
2006
|
+
"TypeParser.fiberType",
|
|
2007
|
+
(type) => type
|
|
2008
|
+
);
|
|
2009
|
+
const effectSubtype = cachedBy(
|
|
2010
|
+
fn("TypeParser.effectSubtype")(function* (type, atLocation) {
|
|
2011
|
+
const tagSymbol = typeChecker.getPropertyOfType(type, "_tag");
|
|
2012
|
+
const getSymbol = typeChecker.getPropertyOfType(type, "get");
|
|
2013
|
+
if (!(tagSymbol || getSymbol)) {
|
|
2014
|
+
return yield* typeParserIssue(
|
|
2015
|
+
"Type is not a subtype of effect because it does not have '_tag' or 'get' property",
|
|
2016
|
+
type,
|
|
2017
|
+
atLocation
|
|
2018
|
+
);
|
|
2019
|
+
}
|
|
2020
|
+
return yield* effectType(type, atLocation);
|
|
2021
|
+
}),
|
|
2022
|
+
"TypeParser.effectSubtype",
|
|
2023
|
+
(type) => type
|
|
2024
|
+
);
|
|
2025
|
+
const importedEffectModule = cachedBy(
|
|
2026
|
+
fn("TypeParser.importedEffectModule")(function* (node) {
|
|
2027
|
+
const type = typeChecker.getTypeAtLocation(node);
|
|
2028
|
+
const propertySymbol = typeChecker.getPropertyOfType(type, "never");
|
|
2029
|
+
if (!propertySymbol) {
|
|
2030
|
+
return yield* typeParserIssue("Type has no 'never' property", type, node);
|
|
2031
|
+
}
|
|
2032
|
+
if (!ts.isExpression(node)) {
|
|
2033
|
+
return yield* typeParserIssue("Node is not an expression", type, node);
|
|
2034
|
+
}
|
|
2035
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, node);
|
|
2036
|
+
yield* effectType(propertyType, node);
|
|
2037
|
+
return node;
|
|
2038
|
+
}),
|
|
2039
|
+
"TypeParser.importedEffectModule",
|
|
2040
|
+
(node) => node
|
|
2041
|
+
);
|
|
2042
|
+
const effectGen = cachedBy(
|
|
2043
|
+
fn("TypeParser.effectGen")(function* (node) {
|
|
2044
|
+
if (!ts.isCallExpression(node)) {
|
|
2045
|
+
return yield* typeParserIssue("Node is not a call expression", void 0, node);
|
|
2046
|
+
}
|
|
2047
|
+
if (node.arguments.length === 0) {
|
|
2048
|
+
return yield* typeParserIssue("Node has no arguments", void 0, node);
|
|
2049
|
+
}
|
|
2050
|
+
const generatorFunction = node.arguments[0];
|
|
2051
|
+
if (!ts.isFunctionExpression(generatorFunction)) {
|
|
2052
|
+
return yield* typeParserIssue("Node is not a function expression", void 0, node);
|
|
2053
|
+
}
|
|
2054
|
+
if (generatorFunction.asteriskToken === void 0) {
|
|
2055
|
+
return yield* typeParserIssue("Node is not a generator function", void 0, node);
|
|
2056
|
+
}
|
|
2057
|
+
if (!ts.isPropertyAccessExpression(node.expression)) {
|
|
2058
|
+
return yield* typeParserIssue("Node is not a property access expression", void 0, node);
|
|
2059
|
+
}
|
|
2060
|
+
const propertyAccess = node.expression;
|
|
2061
|
+
if (propertyAccess.name.text !== "gen") {
|
|
2062
|
+
return yield* typeParserIssue("Call expression name is not 'gen'", void 0, node);
|
|
2063
|
+
}
|
|
2064
|
+
const effectModule = yield* importedEffectModule(propertyAccess.expression);
|
|
2065
|
+
return {
|
|
2066
|
+
node,
|
|
2067
|
+
effectModule,
|
|
2068
|
+
generatorFunction,
|
|
2069
|
+
body: generatorFunction.body,
|
|
2070
|
+
functionStar: generatorFunction.getFirstToken()
|
|
2071
|
+
};
|
|
2072
|
+
}),
|
|
2073
|
+
"TypeParser.effectGen",
|
|
2074
|
+
(node) => node
|
|
2075
|
+
);
|
|
2076
|
+
const effectFnUntracedGen = cachedBy(
|
|
2077
|
+
fn("TypeParser.effectFnUntracedGen")(
|
|
2078
|
+
function* (node) {
|
|
2079
|
+
if (!ts.isCallExpression(node)) {
|
|
2080
|
+
return yield* typeParserIssue("Node is not a call expression", void 0, node);
|
|
2081
|
+
}
|
|
2082
|
+
if (node.arguments.length === 0) {
|
|
2083
|
+
return yield* typeParserIssue("Node has no arguments", void 0, node);
|
|
2084
|
+
}
|
|
2085
|
+
const generatorFunction = node.arguments[0];
|
|
2086
|
+
if (!ts.isFunctionExpression(generatorFunction)) {
|
|
2087
|
+
return yield* typeParserIssue("Node is not a function expression", void 0, node);
|
|
2088
|
+
}
|
|
2089
|
+
if (generatorFunction.asteriskToken === void 0) {
|
|
2090
|
+
return yield* typeParserIssue(
|
|
2091
|
+
"Node is not a generator function",
|
|
2092
|
+
void 0,
|
|
2093
|
+
node
|
|
2094
|
+
);
|
|
2095
|
+
}
|
|
2096
|
+
if (!ts.isPropertyAccessExpression(node.expression)) {
|
|
2097
|
+
return yield* typeParserIssue(
|
|
2098
|
+
"Node is not a property access expression",
|
|
2099
|
+
void 0,
|
|
2100
|
+
node
|
|
2101
|
+
);
|
|
2102
|
+
}
|
|
2103
|
+
const propertyAccess = node.expression;
|
|
2104
|
+
if (propertyAccess.name.text !== "fnUntraced") {
|
|
2105
|
+
return yield* typeParserIssue(
|
|
2106
|
+
"Call expression name is not 'fnUntraced'",
|
|
2107
|
+
void 0,
|
|
2108
|
+
node
|
|
2109
|
+
);
|
|
2110
|
+
}
|
|
2111
|
+
const effectModule = yield* importedEffectModule(propertyAccess.expression);
|
|
2112
|
+
return {
|
|
2113
|
+
node,
|
|
2114
|
+
effectModule,
|
|
2115
|
+
generatorFunction,
|
|
2116
|
+
body: generatorFunction.body,
|
|
2117
|
+
functionStar: generatorFunction.getFirstToken()
|
|
2118
|
+
};
|
|
2119
|
+
}
|
|
2120
|
+
),
|
|
2121
|
+
"TypeParser.effectFnUntracedGen",
|
|
2122
|
+
(node) => node
|
|
2123
|
+
);
|
|
2124
|
+
const effectFnGen = cachedBy(
|
|
2125
|
+
fn("TypeParser.effectFnGen")(function* (node) {
|
|
2126
|
+
if (!ts.isCallExpression(node)) {
|
|
2127
|
+
return yield* typeParserIssue("Node is not a call expression", void 0, node);
|
|
2128
|
+
}
|
|
2129
|
+
if (node.arguments.length === 0) {
|
|
2130
|
+
return yield* typeParserIssue("Node has no arguments", void 0, node);
|
|
2131
|
+
}
|
|
2132
|
+
const generatorFunction = node.arguments[0];
|
|
2133
|
+
if (!ts.isFunctionExpression(generatorFunction)) {
|
|
2134
|
+
return yield* typeParserIssue(
|
|
2135
|
+
"Node is not a function expression",
|
|
2136
|
+
void 0,
|
|
2137
|
+
node
|
|
2138
|
+
);
|
|
2139
|
+
}
|
|
2140
|
+
if (generatorFunction.asteriskToken === void 0) {
|
|
2141
|
+
return yield* typeParserIssue(
|
|
2142
|
+
"Node is not a generator function",
|
|
2143
|
+
void 0,
|
|
2144
|
+
node
|
|
2145
|
+
);
|
|
2146
|
+
}
|
|
2147
|
+
const expressionToTest = ts.isCallExpression(node.expression) ? node.expression.expression : node.expression;
|
|
2148
|
+
if (!ts.isPropertyAccessExpression(expressionToTest)) {
|
|
2149
|
+
return yield* typeParserIssue(
|
|
2150
|
+
"Node is not a property access expression",
|
|
2151
|
+
void 0,
|
|
2152
|
+
node
|
|
2153
|
+
);
|
|
2154
|
+
}
|
|
2155
|
+
const propertyAccess = expressionToTest;
|
|
2156
|
+
if (propertyAccess.name.text !== "fn") {
|
|
2157
|
+
return yield* typeParserIssue(
|
|
2158
|
+
"Call expression name is not 'fn'",
|
|
2159
|
+
void 0,
|
|
2160
|
+
node
|
|
2161
|
+
);
|
|
2162
|
+
}
|
|
2163
|
+
const effectModule = yield* importedEffectModule(propertyAccess.expression);
|
|
2164
|
+
return {
|
|
2165
|
+
node,
|
|
2166
|
+
generatorFunction,
|
|
2167
|
+
effectModule,
|
|
2168
|
+
body: generatorFunction.body,
|
|
2169
|
+
functionStar: generatorFunction.getFirstToken()
|
|
2170
|
+
};
|
|
2171
|
+
}),
|
|
2172
|
+
"TypeParser.effectFnGen",
|
|
2173
|
+
(node) => node
|
|
2174
|
+
);
|
|
2175
|
+
const unnecessaryEffectGen2 = cachedBy(
|
|
2176
|
+
fn("TypeParser.unnecessaryEffectGen")(function* (node) {
|
|
2177
|
+
const { body } = yield* effectGen(node);
|
|
2178
|
+
if (body.statements.length !== 1) {
|
|
2179
|
+
return yield* typeParserIssue(
|
|
2180
|
+
"Generator body should have a single statement",
|
|
2181
|
+
void 0,
|
|
2182
|
+
node
|
|
2183
|
+
);
|
|
2184
|
+
}
|
|
2185
|
+
let explicitReturn = false;
|
|
2186
|
+
let nodeToCheck = body.statements[0];
|
|
2187
|
+
while (nodeToCheck) {
|
|
2188
|
+
if (ts.isReturnStatement(nodeToCheck) && nodeToCheck.expression) {
|
|
2189
|
+
nodeToCheck = nodeToCheck.expression;
|
|
2190
|
+
explicitReturn = true;
|
|
2191
|
+
continue;
|
|
2192
|
+
}
|
|
2193
|
+
if (ts.isExpressionStatement(nodeToCheck)) {
|
|
2194
|
+
nodeToCheck = nodeToCheck.expression;
|
|
2195
|
+
continue;
|
|
2196
|
+
}
|
|
2197
|
+
if (ts.isYieldExpression(nodeToCheck) && nodeToCheck.asteriskToken && nodeToCheck.expression) {
|
|
2198
|
+
const yieldedExpression = nodeToCheck.expression;
|
|
2199
|
+
const type = typeChecker.getTypeAtLocation(yieldedExpression);
|
|
2200
|
+
const { A: successType } = yield* effectType(type, yieldedExpression);
|
|
2201
|
+
let replacementNode = succeed(yieldedExpression);
|
|
2202
|
+
if (!explicitReturn && !(successType.flags & ts.TypeFlags.VoidLike)) {
|
|
2203
|
+
replacementNode = pipe(
|
|
2204
|
+
gen(function* () {
|
|
2205
|
+
const effectIdentifier = pipe(
|
|
2206
|
+
yield* option(
|
|
2207
|
+
findImportedModuleIdentifierByPackageAndNameOrBarrel(node.getSourceFile(), "effect", "Effect")
|
|
2208
|
+
),
|
|
2209
|
+
match({
|
|
2210
|
+
onNone: () => "Effect",
|
|
2211
|
+
onSome: (_) => _.text
|
|
2212
|
+
})
|
|
2213
|
+
);
|
|
2214
|
+
return ts.factory.createCallExpression(
|
|
2215
|
+
ts.factory.createPropertyAccessExpression(
|
|
2216
|
+
ts.factory.createIdentifier(effectIdentifier),
|
|
2217
|
+
"asVoid"
|
|
2218
|
+
),
|
|
2219
|
+
void 0,
|
|
2220
|
+
[
|
|
2221
|
+
yieldedExpression
|
|
2222
|
+
]
|
|
2223
|
+
);
|
|
2224
|
+
}),
|
|
2225
|
+
provideService(TypeScriptApi, ts)
|
|
2226
|
+
);
|
|
2227
|
+
}
|
|
2228
|
+
return { node, body, yieldedExpression, replacementNode };
|
|
2229
|
+
}
|
|
2230
|
+
break;
|
|
2231
|
+
}
|
|
2095
2232
|
return yield* typeParserIssue(
|
|
2096
|
-
"
|
|
2233
|
+
"Not an handled node",
|
|
2097
2234
|
void 0,
|
|
2098
2235
|
node
|
|
2099
2236
|
);
|
|
2100
|
-
}
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
)
|
|
2111
|
-
|
|
2112
|
-
const
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
)
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
)
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2237
|
+
}),
|
|
2238
|
+
"TypeParser.unnecessaryEffectGen",
|
|
2239
|
+
(node) => node
|
|
2240
|
+
);
|
|
2241
|
+
const effectSchemaVarianceStruct = (type, atLocation) => map3(
|
|
2242
|
+
all(
|
|
2243
|
+
varianceStructInvariantType(type, atLocation, "_A"),
|
|
2244
|
+
varianceStructInvariantType(type, atLocation, "_I"),
|
|
2245
|
+
varianceStructCovariantType(type, atLocation, "_R")
|
|
2246
|
+
),
|
|
2247
|
+
([A, I, R]) => ({ A, I, R })
|
|
2248
|
+
);
|
|
2249
|
+
const effectSchemaType = cachedBy(
|
|
2250
|
+
fn("TypeParser.effectSchemaType")(function* (type, atLocation) {
|
|
2251
|
+
yield* pipeableType(type, atLocation);
|
|
2252
|
+
const ast = typeChecker.getPropertyOfType(type, "ast");
|
|
2253
|
+
if (!ast) return yield* typeParserIssue("Has no 'ast' property", type, atLocation);
|
|
2254
|
+
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2255
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2256
|
+
);
|
|
2257
|
+
propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
|
|
2258
|
+
for (const propertySymbol of propertiesSymbols) {
|
|
2259
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2260
|
+
const varianceArgs = yield* option(effectSchemaVarianceStruct(
|
|
2261
|
+
propertyType,
|
|
2262
|
+
atLocation
|
|
2263
|
+
));
|
|
2264
|
+
if (isSome2(varianceArgs)) {
|
|
2265
|
+
return varianceArgs.value;
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
return yield* typeParserIssue("Type has no schema variance struct", type, atLocation);
|
|
2269
|
+
}),
|
|
2270
|
+
"TypeParser.effectSchemaType",
|
|
2271
|
+
(type) => type
|
|
2272
|
+
);
|
|
2273
|
+
const contextTagVarianceStruct = (type, atLocation) => map3(
|
|
2274
|
+
all(
|
|
2275
|
+
varianceStructInvariantType(type, atLocation, "_Identifier"),
|
|
2276
|
+
varianceStructInvariantType(type, atLocation, "_Service")
|
|
2277
|
+
),
|
|
2278
|
+
([Identifier, Service]) => ({ Identifier, Service })
|
|
2279
|
+
);
|
|
2280
|
+
const contextTag = cachedBy(
|
|
2281
|
+
fn("TypeParser.contextTag")(function* (type, atLocation) {
|
|
2282
|
+
yield* pipeableType(type, atLocation);
|
|
2283
|
+
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2284
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2285
|
+
);
|
|
2286
|
+
propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
|
|
2287
|
+
for (const propertySymbol of propertiesSymbols) {
|
|
2288
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2289
|
+
const varianceArgs = yield* option(contextTagVarianceStruct(
|
|
2290
|
+
propertyType,
|
|
2291
|
+
atLocation
|
|
2292
|
+
));
|
|
2293
|
+
if (isSome2(varianceArgs)) {
|
|
2294
|
+
return varianceArgs.value;
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
return yield* typeParserIssue("Type has no tag variance struct", type, atLocation);
|
|
2298
|
+
}),
|
|
2299
|
+
"TypeParser.contextTag",
|
|
2300
|
+
(type) => type
|
|
2301
|
+
);
|
|
2151
2302
|
return {
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2303
|
+
effectType,
|
|
2304
|
+
layerType,
|
|
2305
|
+
fiberType,
|
|
2306
|
+
effectSubtype,
|
|
2307
|
+
importedEffectModule,
|
|
2308
|
+
effectGen,
|
|
2309
|
+
effectFnUntracedGen,
|
|
2310
|
+
effectFnGen,
|
|
2311
|
+
unnecessaryEffectGen: unnecessaryEffectGen2,
|
|
2312
|
+
effectSchemaType,
|
|
2313
|
+
contextTag
|
|
2157
2314
|
};
|
|
2158
|
-
}
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
);
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
// src/diagnostics/duplicatePackage.ts
|
|
2318
|
+
var checkedPackagesCache = /* @__PURE__ */ new Map();
|
|
2319
|
+
var programResolvedCacheSize = /* @__PURE__ */ new Map();
|
|
2320
|
+
var duplicatePackage = createDiagnostic({
|
|
2321
|
+
name: "duplicatePackage",
|
|
2322
|
+
code: 6,
|
|
2323
|
+
apply: fn("duplicatePackage.apply")(function* (sourceFile) {
|
|
2324
|
+
const ts = yield* service(TypeScriptApi);
|
|
2325
|
+
const program = yield* service(TypeScriptProgram);
|
|
2326
|
+
const options = yield* service(LanguageServicePluginOptions);
|
|
2327
|
+
const effectDiagnostics = [];
|
|
2328
|
+
if (sourceFile.statements.length < 1) return [];
|
|
2329
|
+
let resolvedPackages = checkedPackagesCache.get(sourceFile.fileName) || {};
|
|
2330
|
+
const newResolvedModuleSize = hasProperty(program, "resolvedModules") && hasProperty(program.resolvedModules, "size") && isNumber(program.resolvedModules.size) ? program.resolvedModules.size : 0;
|
|
2331
|
+
const oldResolvedSize = programResolvedCacheSize.get(sourceFile.fileName) || -1;
|
|
2332
|
+
if (newResolvedModuleSize !== oldResolvedSize) {
|
|
2333
|
+
const seenPackages = /* @__PURE__ */ new Set();
|
|
2334
|
+
resolvedPackages = {};
|
|
2335
|
+
program.getSourceFiles().map((_) => {
|
|
2336
|
+
const packageInfo = parsePackageContentNameAndVersionFromScope(_);
|
|
2337
|
+
if (!packageInfo) return;
|
|
2338
|
+
const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
|
|
2339
|
+
if (seenPackages.has(packageNameAndVersion)) return;
|
|
2340
|
+
seenPackages.add(packageNameAndVersion);
|
|
2341
|
+
if (!(packageInfo.name === "effect" || packageInfo.hasEffectInPeerDependencies)) return;
|
|
2342
|
+
if (options.allowedDuplicatedPackages.indexOf(packageInfo.name) > -1) return;
|
|
2343
|
+
resolvedPackages[packageInfo.name] = resolvedPackages[packageInfo.name] || {};
|
|
2344
|
+
resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.contents;
|
|
2345
|
+
});
|
|
2346
|
+
checkedPackagesCache.set(sourceFile.fileName, resolvedPackages);
|
|
2347
|
+
programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
|
|
2181
2348
|
}
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
),
|
|
2194
|
-
match({
|
|
2195
|
-
onNone: () => "Effect",
|
|
2196
|
-
onSome: (_) => _.text
|
|
2197
|
-
})
|
|
2198
|
-
);
|
|
2199
|
-
return ts.factory.createCallExpression(
|
|
2200
|
-
ts.factory.createPropertyAccessExpression(
|
|
2201
|
-
ts.factory.createIdentifier(effectIdentifier),
|
|
2202
|
-
"asVoid"
|
|
2203
|
-
),
|
|
2204
|
-
void 0,
|
|
2205
|
-
[
|
|
2206
|
-
yieldedExpression
|
|
2207
|
-
]
|
|
2208
|
-
);
|
|
2209
|
-
}),
|
|
2210
|
-
provideService(TypeScriptApi, ts)
|
|
2211
|
-
);
|
|
2349
|
+
for (const packageName of Object.keys(resolvedPackages)) {
|
|
2350
|
+
if (Object.keys(resolvedPackages[packageName]).length > 1) {
|
|
2351
|
+
const versions = Object.keys(resolvedPackages[packageName]);
|
|
2352
|
+
effectDiagnostics.push({
|
|
2353
|
+
node: sourceFile.statements[0],
|
|
2354
|
+
category: ts.DiagnosticCategory.Warning,
|
|
2355
|
+
messageText: `Package ${packageName} is referenced multiple times with different versions (${versions.join(", ")}) and may cause unexpected type errors.
|
|
2356
|
+
Cleanup your dependencies and your package lockfile to avoid multiple instances of this package and reload the project.
|
|
2357
|
+
If this is intended set the LSP config "allowedDuplicatedPackages" to ${JSON.stringify(options.allowedDuplicatedPackages.concat([packageName]))}.`,
|
|
2358
|
+
fixes: []
|
|
2359
|
+
});
|
|
2212
2360
|
}
|
|
2213
|
-
return { node, body, yieldedExpression, replacementNode };
|
|
2214
2361
|
}
|
|
2215
|
-
|
|
2216
|
-
}
|
|
2217
|
-
return yield* typeParserIssue(
|
|
2218
|
-
"Not an handled node",
|
|
2219
|
-
void 0,
|
|
2220
|
-
node
|
|
2221
|
-
);
|
|
2222
|
-
});
|
|
2223
|
-
var effectSchemaVarianceStruct = fn("TypeParser.effectSchemaVarianceStruct")(
|
|
2224
|
-
function* (type, atLocation) {
|
|
2225
|
-
return {
|
|
2226
|
-
A: yield* varianceStructInvariantType(type, atLocation, "_A"),
|
|
2227
|
-
I: yield* varianceStructInvariantType(type, atLocation, "_I"),
|
|
2228
|
-
R: yield* varianceStructCovariantType(type, atLocation, "_R")
|
|
2229
|
-
};
|
|
2230
|
-
}
|
|
2231
|
-
);
|
|
2232
|
-
var effectSchemaType = fn("TypeParser.effectSchemaType")(function* (type, atLocation) {
|
|
2233
|
-
const ts = yield* service(TypeScriptApi);
|
|
2234
|
-
const typeChecker = yield* service(TypeCheckerApi);
|
|
2235
|
-
yield* pipeableType(type, atLocation);
|
|
2236
|
-
const ast = typeChecker.getPropertyOfType(type, "ast");
|
|
2237
|
-
if (!ast) return yield* typeParserIssue("Has no 'ast' property", type, atLocation);
|
|
2238
|
-
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2239
|
-
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2240
|
-
);
|
|
2241
|
-
propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
|
|
2242
|
-
for (const propertySymbol of propertiesSymbols) {
|
|
2243
|
-
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2244
|
-
const varianceArgs = yield* option(effectSchemaVarianceStruct(
|
|
2245
|
-
propertyType,
|
|
2246
|
-
atLocation
|
|
2247
|
-
));
|
|
2248
|
-
if (isSome2(varianceArgs)) {
|
|
2249
|
-
return varianceArgs.value;
|
|
2250
|
-
}
|
|
2251
|
-
}
|
|
2252
|
-
return yield* typeParserIssue("Type has no schema variance struct", type, atLocation);
|
|
2362
|
+
return effectDiagnostics;
|
|
2363
|
+
})
|
|
2253
2364
|
});
|
|
2254
2365
|
|
|
2255
2366
|
// src/diagnostics/floatingEffect.ts
|
|
@@ -2259,6 +2370,7 @@ var floatingEffect = createDiagnostic({
|
|
|
2259
2370
|
apply: fn("floatingEffect.apply")(function* (sourceFile) {
|
|
2260
2371
|
const ts = yield* service(TypeScriptApi);
|
|
2261
2372
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2373
|
+
const typeParser = yield* service(TypeParser);
|
|
2262
2374
|
function isFloatingExpression(node) {
|
|
2263
2375
|
if (!ts.isExpressionStatement(node)) return false;
|
|
2264
2376
|
if (!(ts.isBlock(node.parent) || ts.isSourceFile(node.parent))) return false;
|
|
@@ -2278,11 +2390,11 @@ var floatingEffect = createDiagnostic({
|
|
|
2278
2390
|
ts.forEachChild(node, appendNodeToVisit);
|
|
2279
2391
|
if (!isFloatingExpression(node)) continue;
|
|
2280
2392
|
const type = typeChecker.getTypeAtLocation(node.expression);
|
|
2281
|
-
const effect = yield* option(effectType(type, node.expression));
|
|
2393
|
+
const effect = yield* option(typeParser.effectType(type, node.expression));
|
|
2282
2394
|
if (isSome2(effect)) {
|
|
2283
2395
|
const allowedFloatingEffects = yield* pipe(
|
|
2284
|
-
fiberType(type, node.expression),
|
|
2285
|
-
orElse2(() => effectSubtype(type, node.expression)),
|
|
2396
|
+
typeParser.fiberType(type, node.expression),
|
|
2397
|
+
orElse2(() => typeParser.effectSubtype(type, node.expression)),
|
|
2286
2398
|
option
|
|
2287
2399
|
);
|
|
2288
2400
|
if (isNone2(allowedFloatingEffects)) {
|
|
@@ -2299,6 +2411,112 @@ var floatingEffect = createDiagnostic({
|
|
|
2299
2411
|
})
|
|
2300
2412
|
});
|
|
2301
2413
|
|
|
2414
|
+
// src/diagnostics/leakingRequirements.ts
|
|
2415
|
+
var leakingRequirements = createDiagnostic({
|
|
2416
|
+
name: "leakingRequirements",
|
|
2417
|
+
code: 8,
|
|
2418
|
+
apply: fn("leakingRequirements.apply")(function* (sourceFile) {
|
|
2419
|
+
const ts = yield* service(TypeScriptApi);
|
|
2420
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
2421
|
+
const typeParser = yield* service(TypeParser);
|
|
2422
|
+
const typeOrder = yield* deterministicTypeOrder;
|
|
2423
|
+
const effectDiagnostics = [];
|
|
2424
|
+
const parseLeakedRequirements = cachedBy(
|
|
2425
|
+
fn("leakingServices.checkServiceLeaking")(
|
|
2426
|
+
function* (service2, atLocation) {
|
|
2427
|
+
const properties = typeChecker.getPropertiesOfType(service2);
|
|
2428
|
+
if (properties.length < 1) return [];
|
|
2429
|
+
const memory = /* @__PURE__ */ new Map();
|
|
2430
|
+
let sharedRequirementsKeys = void 0;
|
|
2431
|
+
let effectMembers = 0;
|
|
2432
|
+
for (const property of properties) {
|
|
2433
|
+
const servicePropertyType = typeChecker.getTypeOfSymbolAtLocation(property, atLocation);
|
|
2434
|
+
let effectContextType = void 0;
|
|
2435
|
+
yield* pipe(
|
|
2436
|
+
typeParser.effectType(servicePropertyType, atLocation),
|
|
2437
|
+
map3((_) => effectContextType = _.R),
|
|
2438
|
+
orElse2(() => {
|
|
2439
|
+
const servicePropertyCallSignatures = servicePropertyType.getCallSignatures();
|
|
2440
|
+
if (servicePropertyCallSignatures.length === 1) {
|
|
2441
|
+
return pipe(
|
|
2442
|
+
typeParser.effectType(servicePropertyCallSignatures[0].getReturnType(), atLocation),
|
|
2443
|
+
map3((_) => {
|
|
2444
|
+
effectContextType = _.R;
|
|
2445
|
+
})
|
|
2446
|
+
);
|
|
2447
|
+
}
|
|
2448
|
+
return void_;
|
|
2449
|
+
}),
|
|
2450
|
+
ignore
|
|
2451
|
+
);
|
|
2452
|
+
if (effectContextType) {
|
|
2453
|
+
effectMembers++;
|
|
2454
|
+
const { allIndexes } = yield* appendToUniqueTypesMap(memory, effectContextType, true);
|
|
2455
|
+
if (!sharedRequirementsKeys) {
|
|
2456
|
+
sharedRequirementsKeys = allIndexes;
|
|
2457
|
+
} else {
|
|
2458
|
+
sharedRequirementsKeys = intersection(sharedRequirementsKeys, allIndexes);
|
|
2459
|
+
if (sharedRequirementsKeys.length === 0) return [];
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
if (sharedRequirementsKeys && sharedRequirementsKeys.length > 0 && effectMembers >= 2) {
|
|
2464
|
+
return sharedRequirementsKeys.map((key) => memory.get(key));
|
|
2465
|
+
}
|
|
2466
|
+
return [];
|
|
2467
|
+
}
|
|
2468
|
+
),
|
|
2469
|
+
"leakingServices.checkServiceLeaking",
|
|
2470
|
+
(_, service2) => service2
|
|
2471
|
+
);
|
|
2472
|
+
function reportLeakingRequirements(node, requirements) {
|
|
2473
|
+
if (requirements.length === 0) return;
|
|
2474
|
+
effectDiagnostics.push({
|
|
2475
|
+
node,
|
|
2476
|
+
category: ts.DiagnosticCategory.Warning,
|
|
2477
|
+
messageText: `This Service is leaking the ${requirements.map((_) => typeChecker.typeToString(_)).join(" | ")} requirement`,
|
|
2478
|
+
fixes: []
|
|
2479
|
+
});
|
|
2480
|
+
}
|
|
2481
|
+
const nodeToVisit = [];
|
|
2482
|
+
const appendNodeToVisit = (node) => {
|
|
2483
|
+
nodeToVisit.push(node);
|
|
2484
|
+
return void 0;
|
|
2485
|
+
};
|
|
2486
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
2487
|
+
while (nodeToVisit.length > 0) {
|
|
2488
|
+
const node = nodeToVisit.shift();
|
|
2489
|
+
const typesToCheck = [];
|
|
2490
|
+
if (ts.isCallExpression(node)) {
|
|
2491
|
+
typesToCheck.push([typeChecker.getTypeAtLocation(node), node]);
|
|
2492
|
+
} else if (ts.isClassDeclaration(node) && node.name) {
|
|
2493
|
+
const classSym = typeChecker.getSymbolAtLocation(node.name);
|
|
2494
|
+
if (classSym) {
|
|
2495
|
+
const type = typeChecker.getTypeOfSymbol(classSym);
|
|
2496
|
+
typesToCheck.push([type, node.name]);
|
|
2497
|
+
}
|
|
2498
|
+
} else {
|
|
2499
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
2500
|
+
continue;
|
|
2501
|
+
}
|
|
2502
|
+
for (const [type, reportAt] of typesToCheck) {
|
|
2503
|
+
yield* pipe(
|
|
2504
|
+
typeParser.contextTag(type, node),
|
|
2505
|
+
flatMap2(
|
|
2506
|
+
({ Service }) => pipe(
|
|
2507
|
+
parseLeakedRequirements(Service, node),
|
|
2508
|
+
map3((requirements) => reportLeakingRequirements(reportAt, sort(requirements, typeOrder)))
|
|
2509
|
+
)
|
|
2510
|
+
),
|
|
2511
|
+
orElse2(() => sync(() => ts.forEachChild(node, appendNodeToVisit))),
|
|
2512
|
+
ignore
|
|
2513
|
+
);
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
return effectDiagnostics;
|
|
2517
|
+
})
|
|
2518
|
+
});
|
|
2519
|
+
|
|
2302
2520
|
// src/diagnostics/missingEffectContext.ts
|
|
2303
2521
|
var missingEffectContext = createDiagnostic({
|
|
2304
2522
|
name: "missingEffectContext",
|
|
@@ -2306,15 +2524,16 @@ var missingEffectContext = createDiagnostic({
|
|
|
2306
2524
|
apply: fn("missingEffectContext.apply")(function* (sourceFile) {
|
|
2307
2525
|
const ts = yield* service(TypeScriptApi);
|
|
2308
2526
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2527
|
+
const typeParser = yield* service(TypeParser);
|
|
2309
2528
|
const typeOrder = yield* deterministicTypeOrder;
|
|
2310
2529
|
const checkForMissingContextTypes = fn(
|
|
2311
2530
|
"missingEffectContext.apply.checkForMissingContextTypes"
|
|
2312
2531
|
)(function* (node, expectedType, valueNode, realType) {
|
|
2313
|
-
const expectedEffect = yield* effectType(
|
|
2532
|
+
const expectedEffect = yield* typeParser.effectType(
|
|
2314
2533
|
expectedType,
|
|
2315
2534
|
node
|
|
2316
2535
|
);
|
|
2317
|
-
const realEffect = yield* effectType(
|
|
2536
|
+
const realEffect = yield* typeParser.effectType(
|
|
2318
2537
|
realType,
|
|
2319
2538
|
valueNode
|
|
2320
2539
|
);
|
|
@@ -2358,14 +2577,15 @@ var missingEffectError = createDiagnostic({
|
|
|
2358
2577
|
apply: fn("missingEffectError.apply")(function* (sourceFile) {
|
|
2359
2578
|
const ts = yield* service(TypeScriptApi);
|
|
2360
2579
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2580
|
+
const typeParser = yield* service(TypeParser);
|
|
2361
2581
|
const typeOrder = yield* deterministicTypeOrder;
|
|
2362
2582
|
const checkForMissingErrorTypes = fn("missingEffectError.apply.checkForMissingErrorTypes")(
|
|
2363
2583
|
function* (node, expectedType, valueNode, realType) {
|
|
2364
|
-
const expectedEffect = yield* effectType(
|
|
2584
|
+
const expectedEffect = yield* typeParser.effectType(
|
|
2365
2585
|
expectedType,
|
|
2366
2586
|
node
|
|
2367
2587
|
);
|
|
2368
|
-
const realEffect = yield* effectType(
|
|
2588
|
+
const realEffect = yield* typeParser.effectType(
|
|
2369
2589
|
realType,
|
|
2370
2590
|
valueNode
|
|
2371
2591
|
);
|
|
@@ -2410,6 +2630,7 @@ var missingReturnYieldStar = createDiagnostic({
|
|
|
2410
2630
|
apply: fn("missingReturnYieldStar.apply")(function* (sourceFile) {
|
|
2411
2631
|
const ts = yield* service(TypeScriptApi);
|
|
2412
2632
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2633
|
+
const typeParser = yield* service(TypeParser);
|
|
2413
2634
|
const effectDiagnostics = [];
|
|
2414
2635
|
const brokenYields = /* @__PURE__ */ new Set();
|
|
2415
2636
|
const nodeToVisit = [];
|
|
@@ -2423,7 +2644,7 @@ var missingReturnYieldStar = createDiagnostic({
|
|
|
2423
2644
|
ts.forEachChild(node, appendNodeToVisit);
|
|
2424
2645
|
if (ts.isYieldExpression(node) && node.expression && node.asteriskToken) {
|
|
2425
2646
|
const type = typeChecker.getTypeAtLocation(node.expression);
|
|
2426
|
-
const maybeEffect = yield* option(effectType(type, node.expression));
|
|
2647
|
+
const maybeEffect = yield* option(typeParser.effectType(type, node.expression));
|
|
2427
2648
|
if (isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never) {
|
|
2428
2649
|
const generatorFunctionOrReturnStatement = ts.findAncestor(
|
|
2429
2650
|
node,
|
|
@@ -2433,9 +2654,9 @@ var missingReturnYieldStar = createDiagnostic({
|
|
|
2433
2654
|
if (generatorFunctionOrReturnStatement && generatorFunctionOrReturnStatement.parent) {
|
|
2434
2655
|
const effectGenNode = generatorFunctionOrReturnStatement.parent;
|
|
2435
2656
|
const effectGenLike = yield* pipe(
|
|
2436
|
-
effectGen(effectGenNode),
|
|
2437
|
-
orElse2(() => effectFnUntracedGen(effectGenNode)),
|
|
2438
|
-
orElse2(() => effectFnGen(effectGenNode)),
|
|
2657
|
+
typeParser.effectGen(effectGenNode),
|
|
2658
|
+
orElse2(() => typeParser.effectFnUntracedGen(effectGenNode)),
|
|
2659
|
+
orElse2(() => typeParser.effectFnGen(effectGenNode)),
|
|
2439
2660
|
option
|
|
2440
2661
|
);
|
|
2441
2662
|
if (isSome2(effectGenLike)) {
|
|
@@ -2478,6 +2699,7 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
2478
2699
|
code: 4,
|
|
2479
2700
|
apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile) {
|
|
2480
2701
|
const ts = yield* service(TypeScriptApi);
|
|
2702
|
+
const typeParser = yield* service(TypeParser);
|
|
2481
2703
|
const effectDiagnostics = [];
|
|
2482
2704
|
const brokenGenerators = /* @__PURE__ */ new Set();
|
|
2483
2705
|
const brokenYields = /* @__PURE__ */ new Set();
|
|
@@ -2497,18 +2719,18 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
2497
2719
|
);
|
|
2498
2720
|
if (functionStarNode && functionStarNode.parent) {
|
|
2499
2721
|
const effectGenNode = functionStarNode.parent;
|
|
2500
|
-
|
|
2501
|
-
effectGen(effectGenNode),
|
|
2502
|
-
orElse2(() => effectFnUntracedGen(effectGenNode)),
|
|
2503
|
-
orElse2(() => effectFnGen(effectGenNode)),
|
|
2504
|
-
|
|
2722
|
+
yield* pipe(
|
|
2723
|
+
typeParser.effectGen(effectGenNode),
|
|
2724
|
+
orElse2(() => typeParser.effectFnUntracedGen(effectGenNode)),
|
|
2725
|
+
orElse2(() => typeParser.effectFnGen(effectGenNode)),
|
|
2726
|
+
map3(({ functionStar }) => {
|
|
2727
|
+
if (functionStar) {
|
|
2728
|
+
brokenGenerators.add(functionStar);
|
|
2729
|
+
}
|
|
2730
|
+
brokenYields.add(node);
|
|
2731
|
+
}),
|
|
2732
|
+
ignore
|
|
2505
2733
|
);
|
|
2506
|
-
if (isSome2(effectGenLike)) {
|
|
2507
|
-
if (effectGenLike.value.functionStar) {
|
|
2508
|
-
brokenGenerators.add(effectGenLike.value.functionStar);
|
|
2509
|
-
}
|
|
2510
|
-
brokenYields.add(node);
|
|
2511
|
-
}
|
|
2512
2734
|
}
|
|
2513
2735
|
}
|
|
2514
2736
|
}
|
|
@@ -2548,11 +2770,12 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
2548
2770
|
});
|
|
2549
2771
|
|
|
2550
2772
|
// src/diagnostics/unnecessaryEffectGen.ts
|
|
2551
|
-
var
|
|
2773
|
+
var unnecessaryEffectGen = createDiagnostic({
|
|
2552
2774
|
name: "unnecessaryEffectGen",
|
|
2553
2775
|
code: 5,
|
|
2554
2776
|
apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile) {
|
|
2555
2777
|
const ts = yield* service(TypeScriptApi);
|
|
2778
|
+
const typeParser = yield* service(TypeParser);
|
|
2556
2779
|
const effectDiagnostics = [];
|
|
2557
2780
|
const unnecessaryGenerators = /* @__PURE__ */ new Map();
|
|
2558
2781
|
const nodeToVisit = [];
|
|
@@ -2564,9 +2787,12 @@ var unnecessaryEffectGen2 = createDiagnostic({
|
|
|
2564
2787
|
while (nodeToVisit.length > 0) {
|
|
2565
2788
|
const node = nodeToVisit.shift();
|
|
2566
2789
|
ts.forEachChild(node, appendNodeToVisit);
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2790
|
+
if (ts.isCallExpression(node)) {
|
|
2791
|
+
yield* pipe(
|
|
2792
|
+
typeParser.unnecessaryEffectGen(node),
|
|
2793
|
+
map3(({ replacementNode }) => unnecessaryGenerators.set(node, replacementNode)),
|
|
2794
|
+
ignore
|
|
2795
|
+
);
|
|
2570
2796
|
}
|
|
2571
2797
|
}
|
|
2572
2798
|
unnecessaryGenerators.forEach(
|
|
@@ -2597,8 +2823,9 @@ var diagnostics = [
|
|
|
2597
2823
|
missingEffectError,
|
|
2598
2824
|
floatingEffect,
|
|
2599
2825
|
missingStarInYieldEffectGen,
|
|
2600
|
-
|
|
2601
|
-
missingReturnYieldStar
|
|
2826
|
+
unnecessaryEffectGen,
|
|
2827
|
+
missingReturnYieldStar,
|
|
2828
|
+
leakingRequirements
|
|
2602
2829
|
];
|
|
2603
2830
|
|
|
2604
2831
|
// src/transform.ts
|
|
@@ -2610,6 +2837,7 @@ function transform_default(program, pluginConfig, { addDiagnostic, ts: tsInstanc
|
|
|
2610
2837
|
provideService(TypeScriptApi, tsInstance),
|
|
2611
2838
|
provideService(TypeScriptProgram, program),
|
|
2612
2839
|
provideService(TypeCheckerApi, program.getTypeChecker()),
|
|
2840
|
+
provideService(TypeParser, make3(tsInstance, program.getTypeChecker())),
|
|
2613
2841
|
provideService(
|
|
2614
2842
|
TypeCheckerApiCache,
|
|
2615
2843
|
makeTypeCheckerApiCache()
|