From 8d2e2d53c20a5c39b698d0499f2df8b71e275ac7 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 25 Apr 2024 15:22:21 -0700 Subject: [PATCH] Move RegExp flag version mapping to LanguageFeatureMinimumTarget (#58311) --- src/compiler/scanner.ts | 33 ++++++++++++++++----------------- src/compiler/types.ts | 5 +++++ 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index f8a8c52debf..2d26d915aa2 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -19,6 +19,7 @@ import { JSDocSyntaxKind, JsxTokenSyntaxKind, KeywordSyntaxKind, + LanguageFeatureMinimumTarget, LanguageVariant, last, LineAndCharacter, @@ -293,15 +294,12 @@ const charToRegExpFlag = new Map(Object.entries({ y: RegularExpressionFlags.Sticky, })); -const regExpFlagToFirstAvailableLanguageVersion = new Map([ - [RegularExpressionFlags.HasIndices, ScriptTarget.ES2022], - [RegularExpressionFlags.Global, ScriptTarget.ES3], - [RegularExpressionFlags.IgnoreCase, ScriptTarget.ES3], - [RegularExpressionFlags.Multiline, ScriptTarget.ES3], - [RegularExpressionFlags.DotAll, ScriptTarget.ES2018], - [RegularExpressionFlags.Unicode, ScriptTarget.ES2015], - [RegularExpressionFlags.UnicodeSets, ScriptTarget.ESNext], - [RegularExpressionFlags.Sticky, ScriptTarget.ES2015], +const regExpFlagToFirstAvailableLanguageVersion = new Map([ + [RegularExpressionFlags.HasIndices, LanguageFeatureMinimumTarget.RegularExpressionFlagsHasIndices], + [RegularExpressionFlags.DotAll, LanguageFeatureMinimumTarget.RegularExpressionFlagsDotAll], + [RegularExpressionFlags.Unicode, LanguageFeatureMinimumTarget.RegularExpressionFlagsUnicode], + [RegularExpressionFlags.UnicodeSets, LanguageFeatureMinimumTarget.RegularExpressionFlagsUnicodeSets], + [RegularExpressionFlags.Sticky, LanguageFeatureMinimumTarget.RegularExpressionFlagsSticky], ]); /* @@ -2461,10 +2459,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } else { regExpFlags |= flag; - const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag)!; - if (languageVersion < availableFrom) { - error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, p, 1, getNameOfScriptTarget(availableFrom)); - } + checkRegularExpressionFlagAvailable(flag, p); } } p++; @@ -2742,10 +2737,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } else { currFlags |= flag; - const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag)!; - if (languageVersion < availableFrom) { - error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, pos, 1, getNameOfScriptTarget(availableFrom)); - } + checkRegularExpressionFlagAvailable(flag, pos); } pos++; } @@ -3446,6 +3438,13 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } }); } + + function checkRegularExpressionFlagAvailable(flag: RegularExpressionFlags, pos: number) { + const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag) as ScriptTarget | undefined; + if (availableFrom && languageVersion < availableFrom) { + error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, pos, 1, getNameOfScriptTarget(availableFrom)); + } + } } function appendIfCommentDirective( diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 70397a75908..76f8193ae12 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8231,6 +8231,8 @@ export const enum LanguageFeatureMinimumTarget { ArrowFunctions = ScriptTarget.ES2015, BlockScopedVariables = ScriptTarget.ES2015, ObjectAssign = ScriptTarget.ES2015, + RegularExpressionFlagsUnicode = ScriptTarget.ES2015, + RegularExpressionFlagsSticky = ScriptTarget.ES2015, // ES2016 Features Exponentiation = ScriptTarget.ES2016, // `x ** y` @@ -8243,6 +8245,7 @@ export const enum LanguageFeatureMinimumTarget { AsyncGenerators = ScriptTarget.ES2018, // `async function * f() { }` AsyncIteration = ScriptTarget.ES2018, // `Symbol.asyncIterator` ObjectSpreadRest = ScriptTarget.ES2018, // `{ ...obj }` + RegularExpressionFlagsDotAll = ScriptTarget.ES2018, // ES2019 Features BindinglessCatch = ScriptTarget.ES2019, // `try { } catch { }` @@ -8259,6 +8262,7 @@ export const enum LanguageFeatureMinimumTarget { TopLevelAwait = ScriptTarget.ES2022, ClassFields = ScriptTarget.ES2022, PrivateNamesAndClassStaticBlocks = ScriptTarget.ES2022, // `class C { static {} #x = y, #m() {} }`, `#x in y` + RegularExpressionFlagsHasIndices = ScriptTarget.ES2022, // ES2023 Features ShebangComments = ScriptTarget.ESNext, @@ -8269,6 +8273,7 @@ export const enum LanguageFeatureMinimumTarget { // transformers/esnext.ts, commandLineParser.ts, and the contents of each lib/esnext.*.d.ts file. UsingAndAwaitUsing = ScriptTarget.ESNext, // `using x = y`, `await using x = y` ClassAndClassElementDecorators = ScriptTarget.ESNext, // `@dec class C {}`, `class C { @dec m() {} }` + RegularExpressionFlagsUnicodeSets = ScriptTarget.ESNext, } // dprint-ignore