Skip to content

Commit

Permalink
refactor: pack let binding check to binding flags
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed Jan 31, 2023
1 parent dcfb945 commit b105ec0
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 33 deletions.
13 changes: 2 additions & 11 deletions packages/babel-parser/src/parser/lval.ts
Expand Up @@ -29,7 +29,7 @@ import { NodeUtils, type Undone } from "./node";
import {
type BindingTypes,
BIND_NONE,
BIND_SCOPE_LEXICAL,
BIND_FLAGS_NO_LET_IN_LEXICAL,
} from "../util/scopeflags";
import type { ExpressionErrors } from "./util";
import { Errors, type LValAncestor } from "../parse-error";
Expand Down Expand Up @@ -560,10 +560,6 @@ export default abstract class LValParser extends NodeUtils {
* `checkLVal` will add checked identifier name to `checkClashes` It is
* used in tracking duplicates in function parameter lists. If it is
* false, `checkLVal` will skip duplicate checks
* @param options.allowingSloppyLetBinding
* Whether an identifier named "let" should be allowed in sloppy mode.
* Defaults to `true` unless lexical scope its being used. This property
* is only relevant if the parser's state is in sloppy mode.
* @param options.strictModeChanged
* Whether an identifier has been parsed in a sloppy context but should
* be reinterpreted as strict-mode. e.g. `(arguments) => { "use strict "}`
Expand All @@ -579,14 +575,12 @@ export default abstract class LValParser extends NodeUtils {
binding = BIND_NONE,
checkClashes = false,
strictModeChanged = false,
allowingSloppyLetBinding = !(binding & BIND_SCOPE_LEXICAL),
hasParenthesizedAncestor = false,
}: {
in: LValAncestor;
binding?: BindingTypes;
checkClashes?: Set<string> | false;
strictModeChanged?: boolean;
allowingSloppyLetBinding?: boolean;
hasParenthesizedAncestor?: boolean;
},
): void {
Expand All @@ -609,7 +603,6 @@ export default abstract class LValParser extends NodeUtils {
expression as Identifier,
binding,
strictModeChanged,
allowingSloppyLetBinding,
);

const { name } = expression as Identifier;
Expand Down Expand Up @@ -658,7 +651,6 @@ export default abstract class LValParser extends NodeUtils {
in: nextAncestor,
binding,
checkClashes,
allowingSloppyLetBinding,
strictModeChanged,
hasParenthesizedAncestor: isParenthesizedExpression,
});
Expand All @@ -670,7 +662,6 @@ export default abstract class LValParser extends NodeUtils {
at: Identifier,
bindingType: BindingTypes,
strictModeChanged: boolean = false,
allowLetBinding: boolean = !(bindingType & BIND_SCOPE_LEXICAL),
) {
if (
this.state.strict &&
Expand All @@ -688,7 +679,7 @@ export default abstract class LValParser extends NodeUtils {
}
}

if (!allowLetBinding && at.name === "let") {
if (bindingType & BIND_FLAGS_NO_LET_IN_LEXICAL && at.name === "let") {
this.raise(Errors.LetInLexicalBinding, { at });
}

Expand Down
4 changes: 2 additions & 2 deletions packages/babel-parser/src/parser/statement.ts
Expand Up @@ -29,6 +29,7 @@ import {
CLASS_ELEMENT_STATIC_GETTER,
CLASS_ELEMENT_STATIC_SETTER,
type BindingTypes,
BIND_CATCH_PARAM,
} from "../util/scopeflags";
import { ExpressionErrors } from "./util";
import { PARAM, functionFlags } from "../util/production-parameter";
Expand Down Expand Up @@ -1076,8 +1077,7 @@ export default abstract class StatementParser extends ExpressionParser {
this.scope.enter(simple ? SCOPE_SIMPLE_CATCH : 0);
this.checkLVal(param, {
in: { type: "CatchClause" },
binding: BIND_LEXICAL,
allowingSloppyLetBinding: true,
binding: BIND_CATCH_PARAM,
});

return param;
Expand Down
43 changes: 23 additions & 20 deletions packages/babel-parser/src/util/scopeflags.ts
Expand Up @@ -26,42 +26,45 @@ export type ScopeFlags =

// These flags are meant to be _only_ used inside the Scope class (or subclasses).
// prettier-ignore
export const BIND_KIND_VALUE = 0b000000_0000_01,
BIND_KIND_TYPE = 0b000000_0000_10,
export const BIND_KIND_VALUE = 0b0000000_0000_01,
BIND_KIND_TYPE = 0b0000000_0000_10,
// Used in checkLVal and declareName to determine the type of a binding
BIND_SCOPE_VAR = 0b000000_0001_00, // Var-style binding
BIND_SCOPE_LEXICAL = 0b000000_0010_00, // Let- or const-style binding
BIND_SCOPE_FUNCTION = 0b000000_0100_00, // Function declaration
BIND_SCOPE_OUTSIDE = 0b000000_1000_00, // Special case for function names as
BIND_SCOPE_VAR = 0b0000000_0001_00, // Var-style binding
BIND_SCOPE_LEXICAL = 0b0000000_0010_00, // Let- or const-style binding
BIND_SCOPE_FUNCTION = 0b0000000_0100_00, // Function declaration
BIND_SCOPE_OUTSIDE = 0b0000000_1000_00, // Special case for function names as
// bound inside the function
// Misc flags
BIND_FLAGS_NONE = 0b0000001_0000_00,
BIND_FLAGS_CLASS = 0b0000010_0000_00,
BIND_FLAGS_TS_ENUM = 0b0000100_0000_00,
BIND_FLAGS_TS_CONST_ENUM = 0b0001000_0000_00,
BIND_FLAGS_TS_EXPORT_ONLY = 0b0010000_0000_00,
BIND_FLAGS_FLOW_DECLARE_FN = 0b0100000_0000_00,
BIND_FLAGS_TS_IMPORT = 0b1000000_0000_00;
BIND_FLAGS_NONE = 0b00000001_0000_00,
BIND_FLAGS_CLASS = 0b00000010_0000_00,
BIND_FLAGS_TS_ENUM = 0b00000100_0000_00,
BIND_FLAGS_TS_CONST_ENUM = 0b00001000_0000_00,
BIND_FLAGS_TS_EXPORT_ONLY = 0b00010000_0000_00,
BIND_FLAGS_FLOW_DECLARE_FN = 0b00100000_0000_00,
BIND_FLAGS_TS_IMPORT = 0b01000000_0000_00,
// Whether "let" should be allowed in bound names in sloppy mode
BIND_FLAGS_NO_LET_IN_LEXICAL = 0b10000000_0000_00;

// These flags are meant to be _only_ used by Scope consumers
// prettier-ignore
/* = is value? | is type? | scope | misc flags */
export const BIND_CLASS = BIND_KIND_VALUE | BIND_KIND_TYPE | BIND_SCOPE_LEXICAL | BIND_FLAGS_CLASS ,
BIND_LEXICAL = BIND_KIND_VALUE | 0 | BIND_SCOPE_LEXICAL | 0 ,
export const BIND_CLASS = BIND_KIND_VALUE | BIND_KIND_TYPE | BIND_SCOPE_LEXICAL | BIND_FLAGS_CLASS|BIND_FLAGS_NO_LET_IN_LEXICAL,
BIND_LEXICAL = BIND_KIND_VALUE | 0 | BIND_SCOPE_LEXICAL | BIND_FLAGS_NO_LET_IN_LEXICAL,
BIND_CATCH_PARAM = BIND_KIND_VALUE | 0 | BIND_SCOPE_LEXICAL | 0 ,
BIND_VAR = BIND_KIND_VALUE | 0 | BIND_SCOPE_VAR | 0 ,
BIND_FUNCTION = BIND_KIND_VALUE | 0 | BIND_SCOPE_FUNCTION | 0 ,
BIND_TS_INTERFACE = 0 | BIND_KIND_TYPE | 0 | BIND_FLAGS_CLASS ,
BIND_TS_TYPE = 0 | BIND_KIND_TYPE | 0 | 0 ,
BIND_TS_ENUM = BIND_KIND_VALUE | BIND_KIND_TYPE | BIND_SCOPE_LEXICAL | BIND_FLAGS_TS_ENUM,
BIND_TS_ENUM = BIND_KIND_VALUE | BIND_KIND_TYPE | BIND_SCOPE_LEXICAL | BIND_FLAGS_TS_ENUM|BIND_FLAGS_NO_LET_IN_LEXICAL,
BIND_TS_AMBIENT = 0 | 0 | 0 | BIND_FLAGS_TS_EXPORT_ONLY,
// These bindings don't introduce anything in the scope. They are used for assignments and
// function expressions IDs.
BIND_NONE = 0 | 0 | 0 | BIND_FLAGS_NONE ,
BIND_OUTSIDE = BIND_KIND_VALUE | 0 | 0 | BIND_FLAGS_NONE ,
BIND_NONE = 0 | 0 | 0 | BIND_FLAGS_NONE ,
BIND_OUTSIDE = BIND_KIND_VALUE | 0 | 0 | BIND_FLAGS_NONE ,

BIND_TS_CONST_ENUM = BIND_TS_ENUM | BIND_FLAGS_TS_CONST_ENUM ,
BIND_TS_CONST_ENUM = BIND_TS_ENUM | BIND_FLAGS_TS_CONST_ENUM ,
BIND_TS_NAMESPACE = 0 | 0 | 0 | BIND_FLAGS_TS_EXPORT_ONLY,
BIND_TS_TYPE_IMPORT= 0 | BIND_KIND_TYPE | 0 | BIND_FLAGS_TS_IMPORT,
BIND_TS_TYPE_IMPORT= 0 | BIND_KIND_TYPE | 0 | BIND_FLAGS_TS_IMPORT ,

BIND_FLOW_DECLARE_FN = BIND_FLAGS_FLOW_DECLARE_FN;

Expand Down

0 comments on commit b105ec0

Please sign in to comment.