Skip to content

Commit 6c69614

Browse files
renovate[bot]github-actions[bot]
authored andcommitted
chore(deps): update typescript-go digest to 865ec14 (#259)
Coming soon: The Renovate bot (GitHub App) will be renamed to Mend. PRs from Renovate will soon appear from 'Mend'. Learn more [here](https://redirect.github.com/renovatebot/renovate/discussions/37842). This PR contains the following updates: | Package | Update | Change | |---|---|---| | typescript-go | digest | `1ca5a2d` -> `865ec14` | --- 📅 **Schedule**: Branch creation - "before 9am" in timezone Asia/Shanghai, Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/tsgolint). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS45Ny4xMCIsInVwZGF0ZWRJblZlciI6IjQxLjk3LjEwIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: github-actions <github-actions[bot]@users.noreply.github.com>
1 parent 4929b0b commit 6c69614

File tree

12 files changed

+764
-158
lines changed

12 files changed

+764
-158
lines changed

cmd/tsgolint/headless.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ func runHeadless(args []string) int {
354354
rules[i] = linter.ConfiguredRule{
355355
Name: r.Name,
356356
Run: func(ctx rule.RuleContext) rule.RuleListeners {
357-
return r.Run(ctx, nil)
357+
return r.Run(ctx, headlessRule.Options)
358358
},
359359
}
360360
}

cmd/tsgolint/payload.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ type headlessConfig struct {
2929
}
3030

3131
type headlessRule struct {
32-
Name string `json:"name"`
32+
Name string `json:"name"`
33+
Options any `json:"options,omitempty"`
3334
}
3435

3536
func deserializePayload(data []byte) (*headlessPayload, error) {

e2e/__snapshots__/snapshot.test.ts.snap

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,34 @@ exports[`TSGoLint E2E Snapshot Tests > should generate consistent diagnostics sn
716716
},
717717
"rule": "require-await",
718718
},
719+
{
720+
"file_path": "fixtures/basic/rules/no-floating-promises/void.ts",
721+
"fixes": [],
722+
"message": {
723+
"description": "This rule requires the \`strictNullChecks\` compiler option to be turned on to function correctly.",
724+
"id": "noStrictNullCheck",
725+
},
726+
"range": {
727+
"end": 0,
728+
"pos": 0,
729+
},
730+
"rule": "no-unnecessary-boolean-literal-compare",
731+
"suggestions": [],
732+
},
733+
{
734+
"file_path": "fixtures/basic/rules/no-floating-promises/void.ts",
735+
"fixes": [],
736+
"message": {
737+
"description": "Function has no 'await' expression.",
738+
"id": "missingAwait",
739+
},
740+
"range": {
741+
"end": 53,
742+
"pos": 0,
743+
},
744+
"rule": "require-await",
745+
"suggestions": [],
746+
},
719747
{
720748
"file_path": "fixtures/basic/rules/no-for-in-array/index.ts",
721749
"kind": 0,
@@ -4345,3 +4373,40 @@ exports[`TSGoLint E2E Snapshot Tests > should handle tsconfig diagnostics when T
43454373
},
43464374
]
43474375
`;
4376+
4377+
exports[`TSGoLint E2E Snapshot Tests > supports passing rule config 1`] = `
4378+
[
4379+
{
4380+
"file_path": "fixtures/basic/rules/no-floating-promises/void.ts",
4381+
"fixes": [],
4382+
"message": {
4383+
"description": "Promises must be awaited.",
4384+
"help": "The promise must end with a call to .catch, or end with a call to .then with a rejection handler.",
4385+
"id": "floating",
4386+
},
4387+
"range": {
4388+
"end": 76,
4389+
"pos": 54,
4390+
},
4391+
"rule": "no-floating-promises",
4392+
"suggestions": [
4393+
{
4394+
"fixes": [
4395+
{
4396+
"range": {
4397+
"end": 58,
4398+
"pos": 54,
4399+
},
4400+
"text": "await",
4401+
},
4402+
],
4403+
"message": {
4404+
"description": "Promises must be awaited.",
4405+
"help": "The promise must end with a call to .catch, or end with a call to .then with a rejection handler.",
4406+
"id": "floating",
4407+
},
4408+
},
4409+
],
4410+
},
4411+
]
4412+
`;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
async function returnsPromise() {
2+
return 'value';
3+
}
4+
void returnsPromise();

e2e/snapshot.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ async function getTestFiles(testPath: string): Promise<string[]> {
176176
return allFiles;
177177
}
178178

179+
function resolveTestFilePath(relativePath: string): string {
180+
return join(FIXTURES_DIR, relativePath);
181+
}
182+
179183
function generateConfig(files: string[], rules: readonly (typeof ALL_RULES)[number][] = ALL_RULES): string {
180184
// Headless payload format:
181185
// ```json
@@ -225,6 +229,43 @@ describe('TSGoLint E2E Snapshot Tests', () => {
225229
expect(diagnostics).toMatchSnapshot();
226230
});
227231

232+
it('supports passing rule config', async () => {
233+
const testFile = resolveTestFilePath('basic/rules/no-floating-promises/void.ts');
234+
const config = (ignoreVoid: boolean) => ({
235+
version: 2,
236+
configs: [
237+
{
238+
file_paths: [testFile],
239+
rules: [
240+
{
241+
name: 'no-floating-promises',
242+
options: { ignoreVoid },
243+
},
244+
],
245+
},
246+
],
247+
});
248+
249+
let output: Buffer;
250+
output = execFileSync(TSGOLINT_BIN, ['headless'], {
251+
input: JSON.stringify(config(false)),
252+
});
253+
254+
let diagnostics = parseHeadlessOutput(output);
255+
diagnostics = sortDiagnostics(diagnostics);
256+
257+
expect(diagnostics.length).toBeGreaterThan(0);
258+
expect(diagnostics).toMatchSnapshot();
259+
260+
// Re-run with ignoreVoid=true, should have no diagnostics
261+
output = execFileSync(TSGOLINT_BIN, ['headless'], {
262+
input: JSON.stringify(config(true)),
263+
});
264+
265+
diagnostics = parseHeadlessOutput(output);
266+
expect(diagnostics.length).toBe(0);
267+
});
268+
228269
it.runIf(process.platform === 'win32')(
229270
'should not panic with mixed forward/backslash paths from Rust (issue #143)',
230271
async () => {

internal/rules/no_floating_promises/no_floating_promises.go

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
package no_floating_promises
22

33
import (
4+
"encoding/json"
5+
46
"github.com/microsoft/typescript-go/shim/ast"
57
"github.com/microsoft/typescript-go/shim/checker"
68
"github.com/microsoft/typescript-go/shim/scanner"
79
"github.com/typescript-eslint/tsgolint/internal/rule"
810
"github.com/typescript-eslint/tsgolint/internal/utils"
911
)
1012

11-
type NoFloatingPromisesOptions struct {
12-
AllowForKnownSafeCalls []utils.TypeOrValueSpecifier
13-
AllowForKnownSafeCallsInline []string
14-
AllowForKnownSafePromises []utils.TypeOrValueSpecifier
15-
AllowForKnownSafePromisesInline []string
16-
CheckThenables *bool
17-
IgnoreIIFE *bool
18-
IgnoreVoid *bool
19-
}
13+
// type NoFloatingPromisesOptions struct {
14+
// AllowForKnownSafeCalls []utils.TypeOrValueSpecifier
15+
// AllowForKnownSafeCallsInline []string
16+
// AllowForKnownSafePromises []utils.TypeOrValueSpecifier
17+
// AllowForKnownSafePromisesInline []string
18+
// CheckThenables *bool
19+
// IgnoreIIFE *bool
20+
// IgnoreVoid *bool
21+
// }
2022

2123
var messageBase = "Promises must be awaited."
2224

@@ -87,23 +89,19 @@ func buildFloatingVoidMessage() rule.RuleMessage {
8789
var NoFloatingPromisesRule = rule.Rule{
8890
Name: "no-floating-promises",
8991
Run: func(ctx rule.RuleContext, options any) rule.RuleListeners {
90-
opts, ok := options.(NoFloatingPromisesOptions)
91-
if !ok {
92-
opts = NoFloatingPromisesOptions{
93-
AllowForKnownSafeCalls: []utils.TypeOrValueSpecifier{},
94-
AllowForKnownSafeCallsInline: []string{},
95-
AllowForKnownSafePromises: []utils.TypeOrValueSpecifier{},
96-
AllowForKnownSafePromisesInline: []string{},
92+
// If we already have options of the correct type, use them directly.
93+
var opts NoFloatingPromisesOptions
94+
if castOpts, ok := options.(NoFloatingPromisesOptions); ok {
95+
opts = castOpts
96+
} else {
97+
// Otherwise, attempt to unmarshal from JSON.
98+
optsBytes, err := json.Marshal(options)
99+
if err != nil {
100+
panic("NoFloatingPromisesRule: failed to marshal options: " + err.Error())
101+
}
102+
if err := json.Unmarshal(optsBytes, &opts); err != nil {
103+
panic("NoFloatingPromisesRule: failed to unmarshal options: " + err.Error())
97104
}
98-
}
99-
if opts.CheckThenables == nil {
100-
opts.CheckThenables = utils.Ref(false)
101-
}
102-
if opts.IgnoreIIFE == nil {
103-
opts.IgnoreIIFE = utils.Ref(false)
104-
}
105-
if opts.IgnoreVoid == nil {
106-
opts.IgnoreVoid = utils.Ref(true)
107105
}
108106

109107
isHigherPrecedenceThanUnary := func(node *ast.Node) bool {
@@ -163,10 +161,9 @@ var NoFloatingPromisesRule = rule.Rule{
163161
}
164162

165163
// The highest priority is to allow anything allowlisted
166-
if utils.TypeMatchesSomeSpecifier(
164+
if utils.TypeMatchesSomeSpecifierInterface(
167165
t,
168166
opts.AllowForKnownSafePromises,
169-
opts.AllowForKnownSafePromisesInline,
170167
ctx.Program,
171168
) {
172169
return false
@@ -181,7 +178,7 @@ var NoFloatingPromisesRule = rule.Rule{
181178
}
182179

183180
// ...and only check all Thenables if explicitly told to
184-
if !*opts.CheckThenables {
181+
if !opts.CheckThenables {
185182
return false
186183
}
187184

@@ -237,10 +234,9 @@ var NoFloatingPromisesRule = rule.Rule{
237234

238235
t := ctx.TypeChecker.GetTypeAtLocation(node.AsCallExpression().Expression)
239236

240-
return utils.TypeMatchesSomeSpecifier(
237+
return utils.TypeMatchesSomeSpecifierInterface(
241238
t,
242239
opts.AllowForKnownSafeCalls,
243-
opts.AllowForKnownSafeCallsInline,
244240
ctx.Program,
245241
)
246242
}
@@ -290,7 +286,7 @@ var NoFloatingPromisesRule = rule.Rule{
290286
return isUnhandledPromise(expr.Right)
291287
}
292288

293-
if !*opts.IgnoreVoid && ast.IsVoidExpression(node) {
289+
if !opts.IgnoreVoid && ast.IsVoidExpression(node) {
294290
// Similarly, a `void` expression always returns undefined, so we need to
295291
// see what's inside it without checking the type of the overall expression.
296292
return isUnhandledPromise(node.Expression())
@@ -379,7 +375,7 @@ var NoFloatingPromisesRule = rule.Rule{
379375
ast.KindExpressionStatement: func(node *ast.Node) {
380376
exprStatement := node.AsExpressionStatement()
381377

382-
if *opts.IgnoreIIFE && isAsyncIife(exprStatement) {
378+
if opts.IgnoreIIFE && isAsyncIife(exprStatement) {
383379
return
384380
}
385381

@@ -396,13 +392,13 @@ var NoFloatingPromisesRule = rule.Rule{
396392
}
397393
if promiseArray {
398394
var msg rule.RuleMessage
399-
if *opts.IgnoreVoid {
395+
if opts.IgnoreVoid {
400396
msg = buildFloatingPromiseArrayVoidMessage()
401397
} else {
402398
msg = buildFloatingPromiseArrayMessage()
403399
}
404400
ctx.ReportNode(node, msg)
405-
} else if *opts.IgnoreVoid {
401+
} else if opts.IgnoreVoid {
406402
var msg rule.RuleMessage
407403
if nonFunctionHandler {
408404
msg = buildFloatingUselessRejectionHandlerVoidMessage()

0 commit comments

Comments
 (0)