@effect/language-service 0.33.2 → 0.35.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 +6 -4
- package/cli.js +139 -7
- package/cli.js.map +1 -1
- package/index.js +321 -54
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +164 -52
- package/transform.js.map +1 -1
package/README.md
CHANGED
|
@@ -53,6 +53,7 @@ And you're done! You'll now be able to use a set of refactors and diagnostics th
|
|
|
53
53
|
- Detect unnecessary pipe chains like `X.pipe(Y).pipe(Z)`
|
|
54
54
|
- Warn when using `Effect.Service` with `accessors: true` but methods have generics or multiple signatures
|
|
55
55
|
- Warn on missing service dependencies in `Effect.Service` declarations
|
|
56
|
+
- Warn when schema classes override the default constructor behavior
|
|
56
57
|
|
|
57
58
|
### Completions
|
|
58
59
|
|
|
@@ -68,6 +69,8 @@ And you're done! You'll now be able to use a set of refactors and diagnostics th
|
|
|
68
69
|
|
|
69
70
|
- Transform an async function definition, into an Effect by using Effect.gen.
|
|
70
71
|
- Transform an async function definition, into an Effect by using Effect.gen, and generating a tagged error for each promise call.
|
|
72
|
+
- Transform an async function definition, into an Effect by using Effect.fn.
|
|
73
|
+
- Transform an async function definition, into an Effect by using Effect.fn, and generating a tagged error for each promise call.
|
|
71
74
|
- Transform a function returning an Effect.gen into a Effect.fn
|
|
72
75
|
- Implement Service accessors in an `Effect.Service` or `Context.Tag` declaration
|
|
73
76
|
- Function calls to pipe: Transform a set of function calls to a pipe() call.
|
|
@@ -137,9 +140,8 @@ Your `tsconfig.json` should look like this:
|
|
|
137
140
|
To get diagnostics you need to install `ts-patch` which will make it possible to run `tspc`.
|
|
138
141
|
|
|
139
142
|
Running `tspc` in your project will now also run the plugin and give you the error diagnostics at compile time.
|
|
140
|
-
Effect diagnostics
|
|
141
|
-
|
|
142
|
-
If you use incremental builds, after enabling ts-patch, a full rebuild may be necessary to invalidate the previous diagnostics cache.
|
|
143
|
+
Effect error diagnostics will be shown only after standard TypeScript diagnostics have been satisfied.
|
|
144
|
+
Beware that setting noEmit will completely skip the effect diagnostics.
|
|
143
145
|
|
|
144
146
|
```ts
|
|
145
147
|
$ npx tspc
|
|
@@ -148,7 +150,7 @@ index.ts:3:1 - error TS3: Effect must be yielded or assigned to a variable.
|
|
|
148
150
|
3 Effect.succeed(1)
|
|
149
151
|
~~~~~~~~~~~~~~~~~
|
|
150
152
|
|
|
151
|
-
Found 1 error in index.ts:3
|
|
153
|
+
Found 1 error in index.ts:3
|
|
152
154
|
```
|
|
153
155
|
|
|
154
156
|
## Configuring diagnostics
|
package/cli.js
CHANGED
|
@@ -28495,6 +28495,31 @@ var NanoTag = class {
|
|
|
28495
28495
|
}
|
|
28496
28496
|
};
|
|
28497
28497
|
var Tag4 = (identifier2) => new NanoTag(identifier2);
|
|
28498
|
+
var SingleShotGen3 = class _SingleShotGen {
|
|
28499
|
+
called = false;
|
|
28500
|
+
self;
|
|
28501
|
+
constructor(self) {
|
|
28502
|
+
this.self = self;
|
|
28503
|
+
}
|
|
28504
|
+
/**
|
|
28505
|
+
* @since 2.0.0
|
|
28506
|
+
*/
|
|
28507
|
+
next(a) {
|
|
28508
|
+
return this.called ? {
|
|
28509
|
+
value: a,
|
|
28510
|
+
done: true
|
|
28511
|
+
} : (this.called = true, {
|
|
28512
|
+
value: this.self,
|
|
28513
|
+
done: false
|
|
28514
|
+
});
|
|
28515
|
+
}
|
|
28516
|
+
/**
|
|
28517
|
+
* @since 2.0.0
|
|
28518
|
+
*/
|
|
28519
|
+
[Symbol.iterator]() {
|
|
28520
|
+
return new _SingleShotGen(this.self);
|
|
28521
|
+
}
|
|
28522
|
+
};
|
|
28498
28523
|
var evaluate2 = Symbol.for("Nano.evaluate");
|
|
28499
28524
|
var contA = Symbol.for("Nano.contA");
|
|
28500
28525
|
var contE = Symbol.for("Nano.contE");
|
|
@@ -28509,7 +28534,7 @@ var NanoDefectException = class {
|
|
|
28509
28534
|
};
|
|
28510
28535
|
var PrimitiveProto = {
|
|
28511
28536
|
[Symbol.iterator]() {
|
|
28512
|
-
return new
|
|
28537
|
+
return new SingleShotGen3(this);
|
|
28513
28538
|
}
|
|
28514
28539
|
};
|
|
28515
28540
|
var SucceedProto = {
|
|
@@ -28632,7 +28657,7 @@ var FromIteratorProto = {
|
|
|
28632
28657
|
const state = this[args2][0].next(value5);
|
|
28633
28658
|
if (state.done) return succeed17(state.value);
|
|
28634
28659
|
fiber._stack.push(this);
|
|
28635
|
-
return
|
|
28660
|
+
return state.value;
|
|
28636
28661
|
},
|
|
28637
28662
|
[evaluate2](fiber) {
|
|
28638
28663
|
return this[contA](this[args2][1], fiber);
|
|
@@ -28961,7 +28986,7 @@ function makeTypeScriptUtils(ts2) {
|
|
|
28961
28986
|
function isNodeInRange(textRange) {
|
|
28962
28987
|
return (node) => node.pos <= textRange.pos && node.end >= textRange.end;
|
|
28963
28988
|
}
|
|
28964
|
-
function
|
|
28989
|
+
function transformAsyncAwaitToEffectGeneratorBody(body, onAwait) {
|
|
28965
28990
|
function visitor(_) {
|
|
28966
28991
|
if (ts2.isAwaitExpression(_)) {
|
|
28967
28992
|
const expression = ts2.visitEachChild(_.expression, visitor, ts2.nullTransformationContext);
|
|
@@ -28972,7 +28997,44 @@ function makeTypeScriptUtils(ts2) {
|
|
|
28972
28997
|
}
|
|
28973
28998
|
return ts2.visitEachChild(_, visitor, ts2.nullTransformationContext);
|
|
28974
28999
|
}
|
|
28975
|
-
|
|
29000
|
+
return visitor(body);
|
|
29001
|
+
}
|
|
29002
|
+
function transformAsyncAwaitToEffectFn(node, effectModuleName, onAwait) {
|
|
29003
|
+
const generatorBody = transformAsyncAwaitToEffectGeneratorBody(node.body, onAwait);
|
|
29004
|
+
const fnName = node.name && ts2.isIdentifier(node.name) ? node.name : ts2.isVariableDeclaration(node.parent) && ts2.isIdentifier(node.parent.name) && node.parent.initializer === node ? node.parent.name : void 0;
|
|
29005
|
+
let fnCall = ts2.factory.createPropertyAccessExpression(
|
|
29006
|
+
ts2.factory.createIdentifier(effectModuleName),
|
|
29007
|
+
"fn"
|
|
29008
|
+
);
|
|
29009
|
+
if (fnName) {
|
|
29010
|
+
fnCall = ts2.factory.createCallExpression(
|
|
29011
|
+
fnName,
|
|
29012
|
+
void 0,
|
|
29013
|
+
[ts2.factory.createStringLiteral(fnName.text)]
|
|
29014
|
+
);
|
|
29015
|
+
}
|
|
29016
|
+
return tryPreserveDeclarationSemantics(
|
|
29017
|
+
node,
|
|
29018
|
+
ts2.factory.createCallExpression(
|
|
29019
|
+
fnCall,
|
|
29020
|
+
void 0,
|
|
29021
|
+
[
|
|
29022
|
+
ts2.factory.createFunctionExpression(
|
|
29023
|
+
void 0,
|
|
29024
|
+
ts2.factory.createToken(ts2.SyntaxKind.AsteriskToken),
|
|
29025
|
+
void 0,
|
|
29026
|
+
node.typeParameters,
|
|
29027
|
+
node.parameters,
|
|
29028
|
+
void 0,
|
|
29029
|
+
ts2.isBlock(generatorBody) ? generatorBody : ts2.factory.createBlock([ts2.factory.createReturnStatement(generatorBody)])
|
|
29030
|
+
)
|
|
29031
|
+
]
|
|
29032
|
+
),
|
|
29033
|
+
true
|
|
29034
|
+
);
|
|
29035
|
+
}
|
|
29036
|
+
function transformAsyncAwaitToEffectGen(node, effectModuleName, onAwait) {
|
|
29037
|
+
const generatorBody = transformAsyncAwaitToEffectGeneratorBody(node.body, onAwait);
|
|
28976
29038
|
const effectGenCallExp = createEffectGenCallExpression(effectModuleName, generatorBody);
|
|
28977
29039
|
let currentFlags = ts2.getCombinedModifierFlags(node);
|
|
28978
29040
|
currentFlags &= ~ts2.ModifierFlags.Async;
|
|
@@ -29076,12 +29138,15 @@ function makeTypeScriptUtils(ts2) {
|
|
|
29076
29138
|
}
|
|
29077
29139
|
return typeNode;
|
|
29078
29140
|
}
|
|
29079
|
-
function tryPreserveDeclarationSemantics(nodeToReplace, node) {
|
|
29141
|
+
function tryPreserveDeclarationSemantics(nodeToReplace, node, dropAsync) {
|
|
29080
29142
|
if (!ts2.isExpression(node)) return node;
|
|
29081
29143
|
if (ts2.isFunctionDeclaration(nodeToReplace)) {
|
|
29082
29144
|
if (!nodeToReplace.name) return node;
|
|
29145
|
+
let currentFlags = ts2.getCombinedModifierFlags(nodeToReplace);
|
|
29146
|
+
currentFlags &= ~ts2.ModifierFlags.Async;
|
|
29147
|
+
const newModifiers = dropAsync ? ts2.factory.createModifiersFromModifierFlags(currentFlags) : nodeToReplace.modifiers;
|
|
29083
29148
|
return ts2.factory.createVariableStatement(
|
|
29084
|
-
|
|
29149
|
+
newModifiers,
|
|
29085
29150
|
ts2.factory.createVariableDeclarationList(
|
|
29086
29151
|
[ts2.factory.createVariableDeclaration(
|
|
29087
29152
|
nodeToReplace.name,
|
|
@@ -29093,8 +29158,11 @@ function makeTypeScriptUtils(ts2) {
|
|
|
29093
29158
|
)
|
|
29094
29159
|
);
|
|
29095
29160
|
} else if (ts2.isMethodDeclaration(nodeToReplace)) {
|
|
29161
|
+
let currentFlags = ts2.getCombinedModifierFlags(nodeToReplace);
|
|
29162
|
+
currentFlags &= ~ts2.ModifierFlags.Async;
|
|
29163
|
+
const newModifiers = dropAsync ? ts2.factory.createModifiersFromModifierFlags(currentFlags) : nodeToReplace.modifiers;
|
|
29096
29164
|
return ts2.factory.createPropertyDeclaration(
|
|
29097
|
-
|
|
29165
|
+
newModifiers,
|
|
29098
29166
|
nodeToReplace.name,
|
|
29099
29167
|
void 0,
|
|
29100
29168
|
void 0,
|
|
@@ -29197,6 +29265,7 @@ function makeTypeScriptUtils(ts2) {
|
|
|
29197
29265
|
getAncestorNodesInRange,
|
|
29198
29266
|
toTextRange,
|
|
29199
29267
|
isNodeInRange,
|
|
29268
|
+
transformAsyncAwaitToEffectFn,
|
|
29200
29269
|
transformAsyncAwaitToEffectGen,
|
|
29201
29270
|
findImportedModuleIdentifierByPackageAndNameOrBarrel,
|
|
29202
29271
|
simplifyTypeNode,
|
|
@@ -31969,6 +32038,68 @@ var outdatedEffectCodegen = createDiagnostic({
|
|
|
31969
32038
|
})
|
|
31970
32039
|
});
|
|
31971
32040
|
|
|
32041
|
+
// src/diagnostics/overriddenSchemaConstructor.ts
|
|
32042
|
+
var overriddenSchemaConstructor = createDiagnostic({
|
|
32043
|
+
name: "overriddenSchemaConstructor",
|
|
32044
|
+
code: 30,
|
|
32045
|
+
severity: "error",
|
|
32046
|
+
apply: fn("overriddenSchemaConstructor.apply")(function* (sourceFile, report) {
|
|
32047
|
+
const ts2 = yield* service2(TypeScriptApi);
|
|
32048
|
+
const typeParser = yield* service2(TypeParser);
|
|
32049
|
+
const typeChecker = yield* service2(TypeCheckerApi);
|
|
32050
|
+
const nodeToVisit = [];
|
|
32051
|
+
const appendNodeToVisit = (node) => {
|
|
32052
|
+
nodeToVisit.push(node);
|
|
32053
|
+
return void 0;
|
|
32054
|
+
};
|
|
32055
|
+
ts2.forEachChild(sourceFile, appendNodeToVisit);
|
|
32056
|
+
while (nodeToVisit.length > 0) {
|
|
32057
|
+
const node = nodeToVisit.shift();
|
|
32058
|
+
if (ts2.isClassDeclaration(node) && node.heritageClauses) {
|
|
32059
|
+
let extendsSchema = false;
|
|
32060
|
+
for (const heritageClause of node.heritageClauses) {
|
|
32061
|
+
if (heritageClause.token === ts2.SyntaxKind.ExtendsKeyword) {
|
|
32062
|
+
for (const type2 of heritageClause.types) {
|
|
32063
|
+
const typeAtLocation = typeChecker.getTypeAtLocation(type2.expression);
|
|
32064
|
+
const isSchema2 = yield* pipe(
|
|
32065
|
+
typeParser.effectSchemaType(typeAtLocation, type2.expression),
|
|
32066
|
+
map33(() => true),
|
|
32067
|
+
orElse14(() => succeed17(false))
|
|
32068
|
+
);
|
|
32069
|
+
if (isSchema2) {
|
|
32070
|
+
extendsSchema = true;
|
|
32071
|
+
break;
|
|
32072
|
+
}
|
|
32073
|
+
}
|
|
32074
|
+
}
|
|
32075
|
+
if (extendsSchema) break;
|
|
32076
|
+
}
|
|
32077
|
+
if (extendsSchema) {
|
|
32078
|
+
const members = node.members;
|
|
32079
|
+
for (const member of members) {
|
|
32080
|
+
if (ts2.isConstructorDeclaration(member)) {
|
|
32081
|
+
report({
|
|
32082
|
+
location: member,
|
|
32083
|
+
messageText: "Classes extending Schema must not override the constructor",
|
|
32084
|
+
fixes: [{
|
|
32085
|
+
fixName: "overriddenSchemaConstructor_fix",
|
|
32086
|
+
description: "Remove the constructor override",
|
|
32087
|
+
apply: gen3(function* () {
|
|
32088
|
+
const changeTracker = yield* service2(ChangeTracker);
|
|
32089
|
+
changeTracker.delete(sourceFile, member);
|
|
32090
|
+
})
|
|
32091
|
+
}]
|
|
32092
|
+
});
|
|
32093
|
+
break;
|
|
32094
|
+
}
|
|
32095
|
+
}
|
|
32096
|
+
}
|
|
32097
|
+
}
|
|
32098
|
+
ts2.forEachChild(node, appendNodeToVisit);
|
|
32099
|
+
}
|
|
32100
|
+
})
|
|
32101
|
+
});
|
|
32102
|
+
|
|
31972
32103
|
// src/diagnostics/returnEffectInGen.ts
|
|
31973
32104
|
var returnEffectInGen = createDiagnostic({
|
|
31974
32105
|
name: "returnEffectInGen",
|
|
@@ -32487,6 +32618,7 @@ var diagnostics = [
|
|
|
32487
32618
|
strictBooleanExpressions,
|
|
32488
32619
|
multipleEffectProvide,
|
|
32489
32620
|
outdatedEffectCodegen,
|
|
32621
|
+
overriddenSchemaConstructor,
|
|
32490
32622
|
unsupportedServiceAccessors
|
|
32491
32623
|
];
|
|
32492
32624
|
|