Disallow no unsafe finally
MODIFY
packages/@romejs/js-compiler/__rtests__/lint.ts
packages/@romejs/js-compiler/__rtests__/lint.ts
@@ -251,3 +251,98 @@ test('disallow var', async t => {
},
]);
});
+
+test('disallow unsafe usage of break, continue, throw and return', async t => {
+ const returnTest = await testLint(
+ `
+ function greet1() {
+ try {
+ throw new Error("Try")
+ } catch(err) {
+ throw err;
+ } finally {
+ return 1;
+ }
+ }
+
+ greet1();
+ `,
+ LINT_ENABLED_FORMAT_DISABLED_CONFIG,
+ );
+
+ t.truthy(
+ returnTest.diagnostics.find(
+ d => d.message === `Unsafe usage of ReturnStatement.`,
+ ),
+ );
+
+ const breakTest = await testLint(
+ `
+
+ function greet2() {
+ try {
+ throw new Error("Try")
+ } catch(err) {
+ throw err;
+ } finally {
+ break;
+ }
+ }
+
+ greet2();
+ `,
+ LINT_ENABLED_FORMAT_DISABLED_CONFIG,
+ );
+
+ t.truthy(
+ breakTest.diagnostics.find(
+ d => d.message === `Unsafe usage of BreakStatement.`,
+ ),
+ );
+
+ const continueTest = await testLint(
+ `
+ function greet3() {
+ try {
+ throw new Error("Try")
+ } catch(err) {
+ throw err;
+ } finally {
+ continue;
+ }
+ }
+
+ greet3();
+ `,
+ LINT_ENABLED_FORMAT_DISABLED_CONFIG,
+ );
+
+ t.truthy(
+ continueTest.diagnostics.find(
+ d => d.message === `Unsafe usage of ContinueStatement.`,
+ ),
+ );
+
+ const throwTest = await testLint(
+ `
+ function greet4() {
+ try {
+ throw new Error("Try")
+ } catch(err) {
+ throw err;
+ } finally {
+ throw new Error("Finally");
+ }
+ }
+
+ greet4();
+ `,
+ LINT_ENABLED_FORMAT_DISABLED_CONFIG,
+ );
+
+ t.truthy(
+ throwTest.diagnostics.find(
+ d => d.message === `Unsafe usage of ThrowStatement.`,
+ ),
+ );
+});

MODIFY
packages/@romejs/js-compiler/transforms/lint/index.ts
packages/@romejs/js-compiler/transforms/lint/index.ts
@@ -15,6 +15,7 @@ import noAsyncPromiseExecutor from './noAsyncPromiseExecutor';
import noLabelVar from './noLabelVar';
import noDuplicateKeys from './noDuplicateKeys';
import disallowVar from './disallowVar';
+import noUnsafeFinally from './noUnsafeFinally';
export const lintTransforms = [
undeclaredVariables,
@@ -27,4 +28,5 @@ export const lintTransforms = [
noLabelVar,
noDuplicateKeys,
disallowVar,
+ noUnsafeFinally,
];

ADD
packages/@romejs/js-compiler/transforms/lint/noUnsafeFinally.ts
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import {Path} from '@romejs/js-compiler';
+import {AnyNode} from '@romejs/js-ast';
+
+export default {
+ name: 'noUnsafeFinally',
+ enter(path: Path): AnyNode {
+ const {node, context} = path;
+
+ if (node.type === 'TryStatement') {
+ const {finalizer} = node;
+
+ if (finalizer && finalizer.type === 'BlockStatement') {
+ for (const statement of finalizer.body) {
+ if (
+ statement.type === 'ThrowStatement' ||
+ statement.type === 'ContinueStatement' ||
+ statement.type === 'BreakStatement' ||
+ statement.type === 'ReturnStatement'
+ ) {
+ context.addNodeDiagnostic(statement, {
+ category: 'lint/noUnsafeFinally',
+ message: `Unsafe usage of ${statement.type}.`,
+ });
+ }
+ }
+ }
+ }
+
+ return node;
+ },
+};

Disallow no unsafe finally