Skip to content

Commit

Permalink
feat: support for modifier
Browse files Browse the repository at this point in the history
  • Loading branch information
ota-meshi committed Jul 28, 2023
1 parent 72e9b5a commit 9a4e1ac
Show file tree
Hide file tree
Showing 21 changed files with 1,107 additions and 74 deletions.
4 changes: 4 additions & 0 deletions scripts/update-fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ for (const filename of Object.keys(Visitor.fixturesData)) {
onExpressionCharacterClassEnter: enter,
onFlagsEnter: enter,
onGroupEnter: enter,
onModifierFlagsEnter: enter,
onModifiersEnter: enter,
onPatternEnter: enter,
onQuantifierEnter: enter,
onRegExpLiteralEnter: enter,
Expand All @@ -71,6 +73,8 @@ for (const filename of Object.keys(Visitor.fixturesData)) {
onExpressionCharacterClassLeave: leave,
onFlagsLeave: leave,
onGroupLeave: leave,
onModifierFlagsLeave: leave,
onModifiersLeave: leave,
onPatternLeave: leave,
onQuantifierLeave: leave,
onRegExpLiteralLeave: leave,
Expand Down
24 changes: 24 additions & 0 deletions src/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type BranchNode =
| ExpressionCharacterClass
| Group
| LookaroundAssertion
| Modifiers
| Pattern
| Quantifier
| RegExpLiteral
Expand All @@ -31,6 +32,7 @@ export type LeafNode =
| Character
| CharacterSet
| Flags
| ModifierFlags

/**
* The type which includes all atom nodes.
Expand Down Expand Up @@ -122,6 +124,7 @@ export interface Alternative extends NodeBase {
export interface Group extends NodeBase {
type: "Group"
parent: Alternative | Quantifier
modifiers: Modifiers | null
alternatives: Alternative[]
}

Expand Down Expand Up @@ -415,6 +418,27 @@ export interface Backreference extends NodeBase {
resolved: CapturingGroup
}

/**
* The modifiers.
*/
export interface Modifiers extends NodeBase {
type: "Modifiers"
parent: Group
add: ModifierFlags | null
remove: ModifierFlags | null
}

/**
* The modifier flags.
*/
export interface ModifierFlags extends NodeBase {
type: "ModifierFlags"
parent: Modifiers
dotAll: boolean
ignoreCase: boolean
multiline: boolean
}

/**
* The flags.
*/
Expand Down
83 changes: 83 additions & 0 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
UnicodeSetsCharacterClass,
ExpressionCharacterClass,
StringAlternative,
Modifiers,
} from "./ast"
import type { EcmaVersion } from "./ecma-versions"
import { latestEcmaVersion } from "./ecma-versions"
Expand All @@ -33,6 +34,7 @@ type AppendableNode =
| ClassStringDisjunction
| Group
| LookaroundAssertion
| Modifiers
| Pattern
| StringAlternative

Expand Down Expand Up @@ -202,6 +204,7 @@ class RegExpParserState {
start,
end: start,
raw: "",
modifiers: null,
alternatives: [],
}
parent.elements.push(this._node)
Expand All @@ -218,6 +221,85 @@ class RegExpParserState {
this._node = node.parent
}

public onModifiersEnter(start: number): void {
const parent = this._node
if (parent.type !== "Group") {
throw new Error("UnknownError")
}

this._node = {
type: "Modifiers",
parent,
start,
end: start,
raw: "",
add: null,
remove: null,
}
parent.modifiers = this._node
}

public onModifiersLeave(start: number, end: number): void {
const node = this._node
if (node.type !== "Modifiers" || node.parent.type !== "Group") {
throw new Error("UnknownError")
}

node.end = end
node.raw = this.source.slice(start, end)
this._node = node.parent
}

public onAddModifiers(
start: number,
end: number,
{
ignoreCase,
multiline,
dotAll,
}: { ignoreCase: boolean; multiline: boolean; dotAll: boolean },
): void {
const parent = this._node
if (parent.type !== "Modifiers") {
throw new Error("UnknownError")
}
parent.add = {
type: "ModifierFlags",
parent,
start,
end,
raw: this.source.slice(start, end),
ignoreCase,
multiline,
dotAll,
}
}

public onRemoveModifiers(
start: number,
end: number,
{
ignoreCase,
multiline,
dotAll,
}: { ignoreCase: boolean; multiline: boolean; dotAll: boolean },
): void {
const parent = this._node
if (parent.type !== "Modifiers") {
throw new Error("UnknownError")
}
parent.remove = {
type: "ModifierFlags",
parent,
start,
end,
raw: this.source.slice(start, end),
ignoreCase,
multiline,
dotAll,
}
}

public onCapturingGroupEnter(start: number, name: string | null): void {
const parent = this._node
if (parent.type !== "Alternative") {
Expand Down Expand Up @@ -755,6 +837,7 @@ export namespace RegExpParser {
* - `2022` added `d` flag.
* - `2023` added more valid Unicode Property Escapes.
* - `2024` added `v` flag.
* - `202x` added modifier.
*/
ecmaVersion?: EcmaVersion
}
Expand Down
Loading

0 comments on commit 9a4e1ac

Please sign in to comment.