@effect/language-service 0.26.0 → 0.27.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -1710,7 +1710,11 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1710
1710
  const diagnostics2 = [];
1711
1711
  const codeFixes = [];
1712
1712
  const ruleNameLowered = rule.name.toLowerCase();
1713
+ const defaultLevel = pluginOptions.diagnosticSeverity[ruleNameLowered] || rule.severity;
1713
1714
  if (skippedRules.indexOf(ruleNameLowered) > -1) return { diagnostics: diagnostics2, codeFixes };
1715
+ if (defaultLevel === "off" && (lineOverrides[ruleNameLowered] || sectionOverrides[ruleNameLowered] || []).length === 0) {
1716
+ return { diagnostics: diagnostics2, codeFixes };
1717
+ }
1714
1718
  const fixByDisableNextLine = (_) => ({
1715
1719
  fixName: rule.name + "_skipNextLine",
1716
1720
  description: "Disable " + rule.name + " for this line",
@@ -1751,7 +1755,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1751
1755
  });
1752
1756
  });
1753
1757
  for (const emitted of applicableDiagnostics.slice(0)) {
1754
- let newLevel = pluginOptions.diagnosticSeverity[ruleNameLowered] || rule.severity;
1758
+ let newLevel = defaultLevel;
1755
1759
  const lineOverride = (lineOverrides[ruleNameLowered] || []).find(
1756
1760
  (_) => _.pos < emitted.node.getStart(sourceFile) && _.end >= emitted.node.getEnd()
1757
1761
  );
@@ -3608,6 +3612,73 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
3608
3612
  })
3609
3613
  });
3610
3614
 
3615
+ // src/diagnostics/strictBooleanExpressions.ts
3616
+ var strictBooleanExpressions = createDiagnostic({
3617
+ name: "strictBooleanExpressions",
3618
+ code: 17,
3619
+ severity: "off",
3620
+ apply: fn("strictBooleanExpressions.apply")(function* (sourceFile, report) {
3621
+ const ts = yield* service(TypeScriptApi);
3622
+ const typeChecker = yield* service(TypeCheckerApi);
3623
+ const conditionChecks = /* @__PURE__ */ new WeakMap();
3624
+ const nodeToVisit = [];
3625
+ const appendNodeToVisit = (node) => {
3626
+ nodeToVisit.push(node);
3627
+ return void 0;
3628
+ };
3629
+ ts.forEachChild(sourceFile, appendNodeToVisit);
3630
+ while (nodeToVisit.length > 0) {
3631
+ const node = nodeToVisit.shift();
3632
+ ts.forEachChild(node, appendNodeToVisit);
3633
+ const nodes = [];
3634
+ if (ts.isIfStatement(node)) {
3635
+ conditionChecks.set(node, true);
3636
+ nodes.push(node.expression);
3637
+ } else if (ts.isWhileStatement(node)) {
3638
+ conditionChecks.set(node, true);
3639
+ nodes.push(node.expression);
3640
+ } else if (ts.isConditionalExpression(node)) {
3641
+ conditionChecks.set(node, true);
3642
+ nodes.push(node.condition);
3643
+ } else if (ts.isPrefixUnaryExpression(node) && node.operator === ts.SyntaxKind.ExclamationToken) {
3644
+ conditionChecks.set(node, true);
3645
+ nodes.push(node.operand);
3646
+ } else if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
3647
+ if (conditionChecks.has(node.parent)) conditionChecks.set(node, true);
3648
+ nodes.push(node.left);
3649
+ nodes.push(node.right);
3650
+ } else if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
3651
+ if (conditionChecks.has(node.parent)) conditionChecks.set(node, true);
3652
+ nodes.push(node.left);
3653
+ nodes.push(node.right);
3654
+ }
3655
+ for (const nodeToCheck of nodes) {
3656
+ if (!nodeToCheck) continue;
3657
+ if (!conditionChecks.has(nodeToCheck.parent)) continue;
3658
+ const nodeType = typeChecker.getTypeAtLocation(nodeToCheck);
3659
+ const constrainedType = typeChecker.getBaseConstraintOfType(nodeType);
3660
+ let typesToCheck = [constrainedType || nodeType];
3661
+ while (typesToCheck.length > 0) {
3662
+ const type = typesToCheck.pop();
3663
+ if (type.isUnion()) {
3664
+ typesToCheck = typesToCheck.concat(type.types);
3665
+ continue;
3666
+ }
3667
+ if (type.flags & ts.TypeFlags.Boolean) continue;
3668
+ if (type.flags & ts.TypeFlags.Never) continue;
3669
+ if (type.flags & ts.TypeFlags.BooleanLiteral) continue;
3670
+ const typeName = typeChecker.typeToString(type);
3671
+ report({
3672
+ node: nodeToCheck,
3673
+ messageText: `Unexpected \`${typeName}\` type in condition, expected strictly a boolean instead.`,
3674
+ fixes: []
3675
+ });
3676
+ }
3677
+ }
3678
+ }
3679
+ })
3680
+ });
3681
+
3611
3682
  // src/diagnostics/tryCatchInEffectGen.ts
3612
3683
  var tryCatchInEffectGen = createDiagnostic({
3613
3684
  name: "tryCatchInEffectGen",
@@ -3832,7 +3903,8 @@ var diagnostics = [
3832
3903
  importFromBarrel,
3833
3904
  scopeInLayerEffect,
3834
3905
  effectInVoidSuccess,
3835
- unnecessaryPipeChain
3906
+ unnecessaryPipeChain,
3907
+ strictBooleanExpressions
3836
3908
  ];
3837
3909
 
3838
3910
  // src/completions/effectDiagnosticsComment.ts
@@ -4065,6 +4137,55 @@ var rpcMakeClasses = createCompletion({
4065
4137
  })
4066
4138
  });
4067
4139
 
4140
+ // src/completions/schemaBrand.ts
4141
+ var schemaBrand = createCompletion({
4142
+ name: "schemaBrand",
4143
+ apply: fn("schemaBrand")(function* (sourceFile, position) {
4144
+ const ts = yield* service(TypeScriptApi);
4145
+ const maybeInfos = yield* option(
4146
+ parseAccessedExpressionForCompletion(sourceFile, position)
4147
+ );
4148
+ if (isNone2(maybeInfos)) return [];
4149
+ const { accessedObject } = maybeInfos.value;
4150
+ if (!ts.isIdentifier(accessedObject)) return [];
4151
+ const schemaName = match(
4152
+ yield* option(
4153
+ findImportedModuleIdentifierByPackageAndNameOrBarrel(
4154
+ sourceFile,
4155
+ "effect",
4156
+ "Schema"
4157
+ )
4158
+ ),
4159
+ {
4160
+ onNone: () => "Schema",
4161
+ onSome: (_) => _.text
4162
+ }
4163
+ );
4164
+ if (schemaName !== accessedObject.text) return [];
4165
+ const span = ts.createTextSpan(
4166
+ accessedObject.end + 1,
4167
+ Math.max(0, position - accessedObject.end - 1)
4168
+ );
4169
+ return pipe(
4170
+ yield* getAncestorNodesInRange(sourceFile, toTextRange(accessedObject.pos)),
4171
+ filter(ts.isVariableDeclaration),
4172
+ map3((_) => _.name && ts.isIdentifier(_.name) ? _.name.text : ""),
4173
+ filter((_) => _.length > 0),
4174
+ head,
4175
+ map2((name) => [
4176
+ {
4177
+ name: `brand("${name}")`,
4178
+ kind: ts.ScriptElementKind.constElement,
4179
+ insertText: `brand("${name}")`,
4180
+ replacementSpan: span,
4181
+ isSnippet: true
4182
+ }
4183
+ ]),
4184
+ getOrElse2(() => [])
4185
+ );
4186
+ })
4187
+ });
4188
+
4068
4189
  // src/completions.ts
4069
4190
  var completions = [
4070
4191
  effectSchemaSelfInClasses,
@@ -4075,7 +4196,8 @@ var completions = [
4075
4196
  fnFunctionStar,
4076
4197
  effectDataClasses,
4077
4198
  effectDiagnosticsComment,
4078
- durationInput
4199
+ durationInput,
4200
+ schemaBrand
4079
4201
  ];
4080
4202
 
4081
4203
  // src/completions/middlewareAutoImports.ts
@@ -9630,7 +9752,7 @@ var _createOpaqueTypes = fn("_createOpaqueTypes")(function* (effectSchemaName, i
9630
9752
  ts.factory.createIdentifier(inferFromName)
9631
9753
  )]
9632
9754
  );
9633
- const opaqueType = typeA.isUnion() ? ts.factory.createTypeAliasDeclaration(
9755
+ const opaqueType = !(typeA.flags & ts.TypeFlags.Object) ? ts.factory.createTypeAliasDeclaration(
9634
9756
  [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
9635
9757
  opaqueTypeName,
9636
9758
  [],
@@ -9657,7 +9779,7 @@ var _createOpaqueTypes = fn("_createOpaqueTypes")(function* (effectSchemaName, i
9657
9779
  ts.factory.createIdentifier(inferFromName)
9658
9780
  )]
9659
9781
  );
9660
- const encodedType = typeE.isUnion() ? ts.factory.createTypeAliasDeclaration(
9782
+ const encodedType = !(typeE.flags & ts.TypeFlags.Object) ? ts.factory.createTypeAliasDeclaration(
9661
9783
  [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
9662
9784
  opaqueEncodedName,
9663
9785
  [],